Using issue.metadata JSONB as a shared blackboard between agents, structured context schemas, avoiding metadata pollution in long-running workflows, and context size limits.
Implement shared memory between agents using the metadata JSONB field, a dedicated memory table, and the issue result chain pattern.
By default, each agent invocation is fresh — it receives only the current issue's system prompt and description. Agents in a team can't naturally "remember" what their colleagues found.
The simplest shared memory: each subsequent issue description includes the previous agent's result.
-- After researcher resolves, create writer issue with researcher's output
INSERT INTO issues (company_id, title, description, assigned_agent_id, parent_issue_id)
SELECT
i.company_id,
'Write: ' || topic,
'--- RESEARCH NOTES ---\n' || i.result || '\n\n--- WRITING TASK ---\nWrite a 700-word article based on the research above.',
writer_id,
i.parent_issue_id
FROM issues i WHERE ...;
Limitation: only passes one previous result. Breaks down for complex multi-agent chains.
A shared key-value store all agents in a company can read from via their task prompts:
CREATE TABLE company_memory (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
company_id uuid NOT NULL REFERENCES companies(id),
key text NOT NULL,
value jsonb NOT NULL,
created_by uuid REFERENCES agents(id),
updated_at timestamptz DEFAULT now(),
UNIQUE (company_id, key)
);
Agents write to memory by including a memory_write key in their JSON output:
{
"result": "The article is written...",
"memory_write": {
"brand_voice_guidelines": "Professional but approachable; use active voice; avoid jargon"
}
}
The heartbeat's post-processor detects memory_write and upserts:
if (result.memory_write) {
for (const [key, value] of Object.entries(result.memory_write)) {
await db.company_memory.upsert({ company_id, key, value });
}
}
Agents read memory by having it injected into their task prompts at invocation time.
For project-scoped shared memory, use the parent issue's metadata JSONB:
-- Researcher stores findings in parent metadata
UPDATE issues
SET metadata = jsonb_set(
COALESCE(metadata, '{}'),
'{research_findings}',
result_structured
)
WHERE id = parent_issue_id;
All sibling agents can read from the parent issue by joining on parent_issue_id.
| Pattern | Scope | Best for |
|---|---|---|
| Issue result chain | Single pipeline run | Sequential handoffs |
| Company memory | All agents, all time | Brand guidelines, persistent knowledge |
| Parent metadata | One project/task | Project-specific context |