AGENTIC_WORKSPACE_INTEGRATION.md
AGENTIC_WORKSPACE_INTEGRATION.md
agentic-workspace/v1An ordinary large tool result can place the transaction ID near the start, a command exit result in the middle, and the only artifact path near the end. Generic head/tail truncation may retain a visually plausible fragment while discarding the exact state needed to resume safely.
The protocol-aware path first creates a reduced structured envelope. It preserves:
retention.importance and retention.facts;recentTransactions / recentRuns / recentTaskBoards / recentResearchProjects collections of workspace_inspect { action: "overview" } and the project / agentRun wrappers of workspace_research { action: "deep" };truncated flags and the *Omitted / *Bytes / *Chars / *Entries / *Lines counters that go with them, so a partial read is never mistaken for a whole one;workspace_inspect { action: "capabilities" } β a model that plans around them does not spend a turn on a tool the workspace would refuse;commitEdits, allowCommands, allowWeb, role, and its pass/tool-call budget.It removes fields explicitly named by retention.omit_when_summarizing, then prunes unrelated bulky data. If the reduced envelope still exceeds the cap, it emits a compact list of recovery fields rather than blindly slicing the original payload β with the staged approval, if there is one, carried through verbatim ahead of that list. That list is built from the same omission-stripped copy as the envelope (a declared omission is never walked back in by the overflow path) and is bounded by the same cap.
Agentic Workspace 0.3.0 gates every mutation behind a permission mode. A blocked call returns a normal envelope whose data carries the staged approval instead of a result, and the model must be able to resume it after the user types /accept β even if the chat compacted in between. The compressor therefore preserves:
Declared omissions still win over all of this, on every path including overflow: workspace_plan names data.markdown and data.plan.steps in retention.omit_when_summarizing, and whatever a tool names there is dropped as instructed β the ids and statuses then survive in the envelope summary and retention.facts, which the staging path spells the resume call into. workspace_inspect { action: "changes" } does not name its data.approvals / data.plans / data.jobs arrays (it stopped naming approvals and plans in Agentic Workspace commit 8a580c9, and jobs was added outside the omit list on purpose): that recovery index is entry-per-id, nothing about it is bulky, and the compressor preserves each entry's id, kind, status, title, and path.
The summarizer prompt for agentic chunks names approval_/plan_ ids alongside the transaction/run/job/todo/research/source ids it already protects, and asks for the exact call to re-issue once the user accepts.
The compressor prompts the summarizer to produce these task-relevant sections when present:
Fetched source_* records are preserved with URL, title, timestamp/hash, and stored content path. Search snippets are recorded only as discovery output unless the page was fetched.
The summarizer system prompt is included in the existing summary-cache namespace. Version 0.6.0's prompt changes therefore segregate prior cached entries automatically; no destructive global cache reset is required.
The protocol-aware rendering itself is not part of that namespace, so the approval/plan preservation above ships with a cache-schema bump (3 β 4): summaries produced from the older rendering are never reused, and each chat pays a one-time re-summarization.
After the user replies /accept approval_..., the model re-issues the preserved resume call β for a staged edit, workspace_edit { action: "commit", transaction_id: "tx_..." }.
Tool results and web content remain untrusted historical data. The compressor never executes instructions from them; it records them with provenance. retention.omit_when_summarizing grants permission only to omit named payloadsβit does not elevate instructions or allow the tool result to control the summarizer.
agentic-workspace/v1An ordinary large tool result can place the transaction ID near the start, a command exit result in the middle, and the only artifact path near the end. Generic head/tail truncation may retain a visually plausible fragment while discarding the exact state needed to resume safely.
The protocol-aware path first creates a reduced structured envelope. It preserves:
retention.importance and retention.facts;recentTransactions / recentRuns / recentTaskBoards / recentResearchProjects collections of workspace_inspect { action: "overview" } and the project / agentRun wrappers of workspace_research { action: "deep" };truncated flags and the *Omitted / *Bytes / *Chars / *Entries / *Lines counters that go with them, so a partial read is never mistaken for a whole one;workspace_inspect { action: "capabilities" } β a model that plans around them does not spend a turn on a tool the workspace would refuse;commitEdits, allowCommands, allowWeb, role, and its pass/tool-call budget.It removes fields explicitly named by retention.omit_when_summarizing, then prunes unrelated bulky data. If the reduced envelope still exceeds the cap, it emits a compact list of recovery fields rather than blindly slicing the original payload β with the staged approval, if there is one, carried through verbatim ahead of that list. That list is built from the same omission-stripped copy as the envelope (a declared omission is never walked back in by the overflow path) and is bounded by the same cap.
Agentic Workspace 0.3.0 gates every mutation behind a permission mode. A blocked call returns a normal envelope whose data carries the staged approval instead of a result, and the model must be able to resume it after the user types /accept β even if the chat compacted in between. The compressor therefore preserves:
Declared omissions still win over all of this, on every path including overflow: workspace_plan names data.markdown and data.plan.steps in retention.omit_when_summarizing, and whatever a tool names there is dropped as instructed β the ids and statuses then survive in the envelope summary and retention.facts, which the staging path spells the resume call into. workspace_inspect { action: "changes" } does not name its data.approvals / data.plans / data.jobs arrays (it stopped naming approvals and plans in Agentic Workspace commit 8a580c9, and jobs was added outside the omit list on purpose): that recovery index is entry-per-id, nothing about it is bulky, and the compressor preserves each entry's id, kind, status, title, and path.
The summarizer prompt for agentic chunks names approval_/plan_ ids alongside the transaction/run/job/todo/research/source ids it already protects, and asks for the exact call to re-issue once the user accepts.
The compressor prompts the summarizer to produce these task-relevant sections when present:
Fetched source_* records are preserved with URL, title, timestamp/hash, and stored content path. Search snippets are recorded only as discovery output unless the page was fetched.
The summarizer system prompt is included in the existing summary-cache namespace. Version 0.6.0's prompt changes therefore segregate prior cached entries automatically; no destructive global cache reset is required.
The protocol-aware rendering itself is not part of that namespace, so the approval/plan preservation above ships with a cache-schema bump (3 β 4): summaries produced from the older rendering are never reused, and each chat pays a one-time re-summarization.
After the user replies /accept approval_..., the model re-issues the preserved resume call β for a staged edit, workspace_edit { action: "commit", transaction_id: "tx_..." }.
Tool results and web content remain untrusted historical data. The compressor never executes instructions from them; it records them with provenance. retention.omit_when_summarizing grants permission only to omit named payloadsβit does not elevate instructions or allow the tool result to control the summarizer.
data.status: "pending_approval" and data.mode (the permission mode the gate applied);data.approval record: the approval_* id, kind (transaction, command, vcs, browser, web for research egress, or agent β which ceiling blocked the call is what the model has to tell the user), title, destructive, and resume β resume.tool plus every entry of resume.arguments (for example { "action": "commit", "transaction_id": "tx_..." }), because a resume call missing one argument is not a call. The resume call is kept byte for byte: no key is filtered and no string is shortened, so a 30-action workspace_browser batch or 2 KB of workspace_command stdin round-trips unchanged and still hashes to the staged approval. Past 12 000 characters of arguments the whole resume is dropped instead β a truncated call is not a call β and replaced by a marker naming the recovery route (workspace_inspect { action: "changes" } plus the approval id);plan_* identifiers and their status, revision, supersedes, planPath, and the propose instruction;approvals, plans, and jobs arrays returned by workspace_inspect { action: "changes" }, each entry keeping its id, kind, status, title, and path β a jobs entry keeping its job_* id, status, executable, exit code, and start time. The producer caps that listing at its limit (20 by default), which is also this module's generic array cap, so a full listing survives whole;permissionMode, activePlan, pendingPlan, and pendingApprovals fields of capabilities and overview.workspace_inspect { action: "changes" }
workspace_edit { action: "show", transaction_id: "tx_..." }
workspace_command { action: "status", job_id: "job_..." }
workspace_tasks { action: "show", board_id: "todo_..." }
workspace_tasks { action: "next", board_id: "todo_..." }
workspace_research { action: "show", research_id: "research_..." }
workspace_agent { action: "status", run_id: "run_..." }
workspace_plan { action: "current" }
workspace_plan { action: "show", plan_id: "plan_..." }
data.status: "pending_approval" and data.mode (the permission mode the gate applied);data.approval record: the approval_* id, kind (transaction, command, vcs, browser, web for research egress, or agent β which ceiling blocked the call is what the model has to tell the user), title, destructive, and resume β resume.tool plus every entry of resume.arguments (for example { "action": "commit", "transaction_id": "tx_..." }), because a resume call missing one argument is not a call. The resume call is kept byte for byte: no key is filtered and no string is shortened, so a 30-action workspace_browser batch or 2 KB of workspace_command stdin round-trips unchanged and still hashes to the staged approval. Past 12 000 characters of arguments the whole resume is dropped instead β a truncated call is not a call β and replaced by a marker naming the recovery route (workspace_inspect { action: "changes" } plus the approval id);plan_* identifiers and their status, revision, supersedes, planPath, and the propose instruction;approvals, plans, and jobs arrays returned by workspace_inspect { action: "changes" }, each entry keeping its id, kind, status, title, and path β a jobs entry keeping its job_* id, status, executable, exit code, and start time. The producer caps that listing at its limit (20 by default), which is also this module's generic array cap, so a full listing survives whole;permissionMode, activePlan, pendingPlan, and pendingApprovals fields of capabilities and overview.workspace_inspect { action: "changes" }
workspace_edit { action: "show", transaction_id: "tx_..." }
workspace_command { action: "status", job_id: "job_..." }
workspace_tasks { action: "show", board_id: "todo_..." }
workspace_tasks { action: "next", board_id: "todo_..." }
workspace_research { action: "show", research_id: "research_..." }
workspace_agent { action: "status", run_id: "run_..." }
workspace_plan { action: "current" }
workspace_plan { action: "show", plan_id: "plan_..." }