diff --git a/.uf/dewey/learnings/openspec-workflow-20260815T191635-jay-flowers.md b/.uf/dewey/learnings/openspec-workflow-20260815T191635-jay-flowers.md new file mode 100644 index 0000000..00a94e4 --- /dev/null +++ b/.uf/dewey/learnings/openspec-workflow-20260815T191635-jay-flowers.md @@ -0,0 +1,10 @@ +--- +tag: openspec-workflow +author: jay-flowers +category: gotcha +created_at: 2026-08-15T19:16:35Z +identity: openspec-workflow-20260815T191635-jay-flowers +tier: draft +--- + +The OpenSpec workflow for content-only changes (no Go code, no tests) follows a streamlined path: propose creates all artifacts, spec review validates the design, implementation is direct file edits, and code review confirms tag placement and JSON validity. The key gotcha is that review markers (`` and ``) must be written to tasks.md immediately after reviews pass -- if the session ends before markers are written, the unleash pipeline cannot detect completion on resume and must re-run reviews. Always write filesystem markers before proceeding to the next step. diff --git a/.uf/dewey/learnings/protect-tags-slash-commands-20260815T191631-jay-flowers.md b/.uf/dewey/learnings/protect-tags-slash-commands-20260815T191631-jay-flowers.md new file mode 100644 index 0000000..b306bf1 --- /dev/null +++ b/.uf/dewey/learnings/protect-tags-slash-commands-20260815T191631-jay-flowers.md @@ -0,0 +1,10 @@ +--- +tag: protect-tags-slash-commands +author: jay-flowers +category: pattern +created_at: 2026-08-15T19:16:31Z +identity: protect-tags-slash-commands-20260815T191631-jay-flowers +tier: draft +--- + +When implementing protect-tags-slash-commands (issue #74), the change was purely additive markup -- only `` and `` tags added to 5 embedded markdown files plus a single `"protectTags": true` line in opencode.json. No Go code, no tests, no MCP protocol changes. The key design decision was section-level granularity (one protect block per logical section, not per line), with a clear taxonomy: protect guardrails/MUST rules, workflows with numbered steps, and session procedures; leave explanatory/advisory content (examples, interpretations, usage patterns) unprotected so DCP can still compress them. The 5 reviewers in spec review and 3 in code review all returned APPROVE with zero blocking findings. The recurring review feedback was that the exact JSON path for `protectTags` in opencode.json should be documented with a concrete snippet -- this was addressed at implementation time by placing it at the top level after `$schema`. For content-only changes like this, the verification tasks (tag count grep, JSON validation, make build, git diff --stat for constitution alignment) are lightweight and effective. diff --git a/internal/agentkit/content/commands/forge-status.md b/internal/agentkit/content/commands/forge-status.md index 54146d4..31ead33 100644 --- a/internal/agentkit/content/commands/forge-status.md +++ b/internal/agentkit/content/commands/forge-status.md @@ -2,6 +2,7 @@ description: Check forge coordination status - workers, messages, cells --- + # /forge:status Show active forge state. @@ -22,3 +23,4 @@ Show active forge state. Run all three tools to get a complete picture of forge state. If any workers are blocked, read their messages and respond. + diff --git a/internal/agentkit/content/commands/forge.md b/internal/agentkit/content/commands/forge.md index 727958a..bfd7b78 100644 --- a/internal/agentkit/content/commands/forge.md +++ b/internal/agentkit/content/commands/forge.md @@ -2,6 +2,7 @@ description: Decompose task into subtasks and coordinate parallel agents --- + # /forge Decompose a task and spawn parallel workers. @@ -48,3 +49,4 @@ $ARGUMENTS - Workers reserve their own files via `comms_reserve` - Check inbox regularly for blocked workers - Store learnings after completion + diff --git a/internal/agentkit/content/commands/handoff.md b/internal/agentkit/content/commands/handoff.md index 9f1ce29..77ea04a 100644 --- a/internal/agentkit/content/commands/handoff.md +++ b/internal/agentkit/content/commands/handoff.md @@ -2,6 +2,7 @@ description: End a session cleanly - release reservations, sync state, generate handoff note --- + # /handoff Wrap up a session cleanly. @@ -50,3 +51,4 @@ or parallelize. - Next Steps: What the next agent should do first - Gotchas: Any surprises or edge cases discovered ``` + diff --git a/internal/agentkit/content/commands/inbox.md b/internal/agentkit/content/commands/inbox.md index 3a9ca90..fcea793 100644 --- a/internal/agentkit/content/commands/inbox.md +++ b/internal/agentkit/content/commands/inbox.md @@ -2,6 +2,7 @@ description: Check comms inbox for messages from other agents --- + # /inbox Check your message inbox. @@ -24,3 +25,4 @@ To send a message to another agent: ``` comms_send(to=["worker-1"], subject="...", body="...", importance="normal") ``` + diff --git a/internal/agentkit/content/commands/org.md b/internal/agentkit/content/commands/org.md index 072ea07..af1ca91 100644 --- a/internal/agentkit/content/commands/org.md +++ b/internal/agentkit/content/commands/org.md @@ -2,6 +2,7 @@ description: Query and manage work items (cells) --- + # /org Manage cells with `org_*` tools. @@ -34,3 +35,4 @@ org_create_epic(epic_title="...", subtasks=[{title: "...", files: [...]}]) - `org_session_start()` — begin a work session, get previous handoff notes - `org_session_end(handoff_notes="...")` — end session with context for next agent + diff --git a/opencode.json b/opencode.json index 6e57884..9507ac1 100644 --- a/opencode.json +++ b/opencode.json @@ -1,5 +1,6 @@ { "$schema": "https://opencode.ai/config.json", + "protectTags": true, "mcp": { "dewey": { "type": "local", diff --git a/openspec/changes/protect-tags-slash-commands/.openspec.yaml b/openspec/changes/protect-tags-slash-commands/.openspec.yaml new file mode 100644 index 0000000..c0bf8c7 --- /dev/null +++ b/openspec/changes/protect-tags-slash-commands/.openspec.yaml @@ -0,0 +1,2 @@ +schema: unbound-force +created: 2026-08-15 diff --git a/openspec/changes/protect-tags-slash-commands/design.md b/openspec/changes/protect-tags-slash-commands/design.md new file mode 100644 index 0000000..3f6a5c1 --- /dev/null +++ b/openspec/changes/protect-tags-slash-commands/design.md @@ -0,0 +1,120 @@ +## Context + +Five slash command files in `internal/agentkit/content/commands/` deliver +workflow instructions to agents as user messages. DCP can compress these +during long sessions, losing critical steps. The proposal identifies +adding `` tags as the mechanism to prevent this, complementing +prior structural hardening work. + +The proposal's constitution alignment confirms this change is PASS on +Autonomous Collaboration (strengthens agent instruction delivery), +Composability First (tags are inert without DCP), and Testability (no +external services needed). Observable Quality is N/A (no tool output +changes). + +## Goals / Non-Goals + +### Goals +- Wrap safety-critical content (invariants, review gates, ordered + workflows, exit conditions) in `` tags across all five + command files. +- Enable `protectTags: true` in `opencode.json` so the DCP engine + recognizes the tags. +- Keep unprotected content available for DCP compression to maintain + context budget efficiency. + +### Non-Goals +- Restructuring command file content (already done in prior DCP + hardening changes). +- Adding `` tags to skill files (skills are delivered as + `tool_use` pairs and protected by `protectedTools`). +- Modifying replicator Go source code or MCP tool behavior. +- Adding tests for tag presence (the tags are consumed by OpenCode's DCP + engine, not by replicator). + +## Decisions + +### D1: What to protect vs. leave unprotected + +**Decision**: Protect content whose loss causes behavioral failure. +Leave explanatory/contextual content unprotected. + +**Protected categories** (from issue #74): +1. **Guardrails / safety rules** -- invariant sections, MUST/NEVER + constraints, review gate requirements. +2. **Execution checklists / step definitions** -- numbered workflow + steps, tool call sequences. +3. **Exit conditions / resume instructions** -- session end procedures, + handoff note structure. + +**Unprotected categories**: +- Section headings (redundant with protected content). +- Descriptive text explaining *why* a step exists (the step itself is + protected). +- Examples and code blocks that illustrate usage patterns (agents can + reconstruct these from tool schemas). +- "Interpreting Results" guidance in forge-status.md (advisory, not + behavioral). + +**Rationale**: Over-protecting defeats the purpose of DCP compression. +The goal is surgical protection of content that, if lost, causes agents +to skip steps, violate ordering, or bypass gates. + +### D2: Protect tag granularity + +**Decision**: Use one `` block per logical section, not per +line. + +For example, in forge.md: +- One `` block wrapping the entire Critical Invariants section. +- One `` block wrapping the entire Workflow section (steps 1-8). +- One `` block wrapping the Rules section. + +**Rationale**: Per-line tagging adds noise and makes files harder to +maintain. Section-level tagging aligns with how DCP processes content +(it compresses by sections, not by lines). A single block per logical +unit keeps the markup clean. + +### D3: File-by-file protect coverage + +| File | Protected sections | Unprotected sections | +|------|-------------------|---------------------| +| forge.md | Critical Invariants, Workflow (1-8), Rules | Title, description, `$ARGUMENTS` placeholder | +| handoff.md | Workflow (steps 0-5 with ordering constraint and handoff note structure) | Title, description | +| inbox.md | Workflow (3 steps) | Title, description, Filtering, Sending | +| forge-status.md | Workflow (3 steps) | Title, description, Interpreting Results, Quick Health Check | +| org.md | Common Actions, Sessions | Title, description, Usage, Epics | + +### D4: DCP configuration + +**Decision**: Add `"protectTags": true` to the top level of +`opencode.json`. + +**Rationale**: This is the toggle that tells OpenCode's DCP engine to +recognize `` tags. Without it, the tags are ignored. The +setting belongs in the project config so it applies to all agents using +this repository. + +## Risks / Trade-offs + +### R1: Over-protection reduces DCP effectiveness + +If too much content is protected, DCP cannot compress enough and the +conversation may hit context limits sooner. **Mitigation**: The design +limits protection to behavioral content only -- roughly 60-70% of +forge.md and handoff.md, 30-40% of the smaller files. + +### R2: Tag maintenance burden + +Future edits to command files must maintain `` tag placement. +**Mitigation**: The tag pattern is simple (`` / ``) +and the files are small (24-52 lines each). The tags are visually +obvious during editing. + +### R3: Tags visible in non-DCP contexts + +Agents reading command files outside OpenCode's DCP engine will see the +`` tags as literal text. **Mitigation**: The tags are inert +HTML-style markup. They do not interfere with markdown rendering or +agent comprehension. This aligns with the Composability First principle. + diff --git a/openspec/changes/protect-tags-slash-commands/proposal.md b/openspec/changes/protect-tags-slash-commands/proposal.md new file mode 100644 index 0000000..0590b23 --- /dev/null +++ b/openspec/changes/protect-tags-slash-commands/proposal.md @@ -0,0 +1,114 @@ +## Why + +OpenCode's Dynamic Context Protocol (DCP) compresses user-message content +during long conversations to stay within context limits. Slash command +files (`internal/agentkit/content/commands/*.md`) are delivered as user +messages, making them eligible for compression. When DCP compresses these +files, critical instructions -- execution order, safety invariants, +mandatory review gates -- can be lost or summarized, causing agents to +skip steps or violate workflow constraints. + +DCP supports `` tags that mark content as compression-resistant. +Content inside `` blocks is preserved verbatim during +compression. This change adds `` tags to the five slash command +files, targeting the content whose loss would cause behavioral failures. + +Prior work (forge-dcp-hardening, harden-forge-skill-compression, +harden-skill-compression) restructured content for better DCP survival +through positioning and constraint language. This change uses `` +tags -- a complementary mechanism that explicitly marks content as +non-compressible. + +Resolves: unbound-force/replicator#74 + +## What Changes + +Add `` tags to five slash command files in +`internal/agentkit/content/commands/`: + +1. **forge.md** -- Protect the Critical Invariants section (review gate + rules) and the ordered Workflow steps (1-8). The Rules section + reiterates invariants and should also be protected. +2. **handoff.md** -- Protect the sequential workflow steps (0-5) and the + ordering constraint ("Steps MUST execute in this exact order"). +3. **inbox.md** -- Protect the 3-step Workflow section. +4. **forge-status.md** -- Protect the 3-step Workflow section. +5. **org.md** -- Protect the Common Actions tool reference and the + Sessions section (session start/end is critical for handoff + continuity). + +Additionally, enable `protectTags: true` in the DCP configuration +(`opencode.json`) so that the tags are recognized by the compression +engine. + +## Capabilities + +### New Capabilities +- `dcp-protect-tags`: Slash command guardrails, workflows, and safety + rules survive DCP compression intact via `` tag markup. + +### Modified Capabilities +- `forge-command`: Critical invariants and workflow steps are now + compression-resistant. +- `handoff-command`: Sequential workflow steps are now + compression-resistant. +- `inbox-command`: Workflow steps are now compression-resistant. +- `forge-status-command`: Workflow steps are now compression-resistant. +- `org-command`: Tool reference and session instructions are now + compression-resistant. + +### Removed Capabilities +- None. + +## Impact + +- **Files modified**: 5 command markdown files under + `internal/agentkit/content/commands/`, plus `opencode.json` for DCP + config. +- **No Go code changes**: The `` tags are consumed by + OpenCode's DCP engine, not by replicator's Go code. The agentkit + embeds these files as-is. +- **No test changes**: The embedded content is delivered verbatim. Tags + do not affect tool registration or MCP protocol behavior. +- **Risk**: Low. `` tags are inert markup when DCP is not + active or when `protectTags` is disabled. The tags have no effect on + agents that read the content directly. + +## Constitution Alignment + +Assessed against the Unbound Force org constitution. + +### I. Autonomous Collaboration + +**Assessment**: PASS + +This change strengthens autonomous collaboration by ensuring that +workflow instructions agents rely on survive context compression. Agents +following slash command workflows (forge coordination, handoff sequences) +will receive the complete instructions regardless of conversation length. +No runtime coupling is introduced. + +### II. Composability First + +**Assessment**: PASS + +The `` tags are inert when DCP is not active. The replicator +binary remains independently installable and usable without OpenCode's +DCP engine. The tags degrade gracefully -- they appear as no-op markup +in non-DCP contexts. + +### III. Observable Quality + +**Assessment**: N/A + +This change modifies embedded markdown content, not tool outputs or +machine-parseable artifacts. No observable output formats are affected. + +### IV. Testability + +**Assessment**: PASS + +The change is purely additive markup in embedded files. No test isolation +requirements are affected. The embedded files can be verified by +inspecting their content directly. No external services are required. + diff --git a/openspec/changes/protect-tags-slash-commands/specs/protect-tags.md b/openspec/changes/protect-tags-slash-commands/specs/protect-tags.md new file mode 100644 index 0000000..189129e --- /dev/null +++ b/openspec/changes/protect-tags-slash-commands/specs/protect-tags.md @@ -0,0 +1,102 @@ +## ADDED Requirements + +### Requirement: Protect tags on slash command guardrails + +All safety rules, invariant sections, and MUST/NEVER constraints in +slash command files MUST be wrapped in `` / `` tags. + +#### Scenario: forge.md Critical Invariants survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** a long conversation triggers DCP compression on forge.md content +- **THEN** the Critical Invariants section (review gate rules, mandatory forge creation, coordinator/worker separation) MUST be preserved verbatim + +#### Scenario: forge.md Rules survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses forge.md content +- **THEN** the Rules section MUST be preserved verbatim + +### Requirement: Protect tags on slash command workflows + +All numbered workflow step sequences in slash command files MUST be +wrapped in `` / `` tags. + +#### Scenario: forge.md Workflow steps survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses forge.md content +- **THEN** all 8 workflow steps (initialize through complete) MUST be preserved verbatim with step ordering intact + +#### Scenario: handoff.md ordered workflow survives compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses handoff.md content +- **THEN** the ordering constraint ("Steps MUST execute in this exact order") and all 6 steps (0-5) with their dependency explanations MUST be preserved verbatim + +#### Scenario: inbox.md workflow survives compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses inbox.md content +- **THEN** the 3-step workflow (inbox, read, ack) MUST be preserved verbatim + +#### Scenario: forge-status.md workflow survives compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses forge-status.md content +- **THEN** the 3-step workflow (forge_status, comms_inbox, org_cells) MUST be preserved verbatim + +### Requirement: Protect tags on exit conditions and resume instructions + +Session end procedures and handoff note structures MUST be wrapped in +`` / `` tags. + +#### Scenario: handoff.md session end and handoff structure survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses handoff.md content +- **THEN** step 5 (org_session_end with handoff note structure) MUST be preserved verbatim + +### Requirement: Protect tags on org tool reference and session instructions + +The Common Actions tool reference and Sessions section in org.md MUST be +wrapped in `` / `` tags. + +#### Scenario: org.md Common Actions survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses org.md content +- **THEN** the Common Actions tool reference (org_ready, org_cells, org_create, org_update, org_close, org_start) MUST be preserved verbatim + +#### Scenario: org.md Sessions survive compression +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP compresses org.md content +- **THEN** the Sessions section (org_session_start, org_session_end) MUST be preserved verbatim + +### Requirement: DCP protectTags configuration + +The project configuration (`opencode.json`) MUST include +`"protectTags": true` at the top level to enable DCP recognition of +`` tags. + +#### Scenario: protectTags enabled in project config +- **GIVEN** the opencode.json configuration file +- **WHEN** OpenCode loads the project configuration +- **THEN** `protectTags` MUST be set to `true` + +### Requirement: Unprotected content remains compressible + +Descriptive text, examples, section headings, and advisory guidance +SHOULD NOT be wrapped in `` tags to preserve DCP compression +effectiveness. + +#### Scenario: forge-status.md Interpreting Results remains compressible +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP evaluates forge-status.md for compression +- **THEN** the Interpreting Results and Quick Health Check sections SHOULD be available for compression + +#### Scenario: org.md Usage and Epics remain compressible +- **GIVEN** DCP is active with `protectTags: true` +- **WHEN** DCP evaluates org.md for compression +- **THEN** the Usage and Epics sections SHOULD be available for compression + +## MODIFIED Requirements + +None. + +## REMOVED Requirements + +None. + diff --git a/openspec/changes/protect-tags-slash-commands/tasks.md b/openspec/changes/protect-tags-slash-commands/tasks.md new file mode 100644 index 0000000..68a943e --- /dev/null +++ b/openspec/changes/protect-tags-slash-commands/tasks.md @@ -0,0 +1,36 @@ + + +## 1. Add protect tags to command files + +Each file is independent -- all five tasks touch different files and can +run in parallel. + +- [x] 1.1 [P] Add `` tags to `internal/agentkit/content/commands/forge.md` — wrap Critical Invariants section, Workflow section (steps 1-8), and Rules section. Leave title, description, and `$ARGUMENTS` placeholder unprotected. +- [x] 1.2 [P] Add `` tags to `internal/agentkit/content/commands/handoff.md` — wrap the entire Workflow section including the ordering constraint, steps 0-5, dependency explanations, and handoff note structure. Leave title and description unprotected. +- [x] 1.3 [P] Add `` tags to `internal/agentkit/content/commands/inbox.md` — wrap the Workflow section (3 steps). Leave title, description, Filtering, and Sending sections unprotected. +- [x] 1.4 [P] Add `` tags to `internal/agentkit/content/commands/forge-status.md` — wrap the Workflow section (3 steps). Leave title, description, Interpreting Results, and Quick Health Check sections unprotected. +- [x] 1.5 [P] Add `` tags to `internal/agentkit/content/commands/org.md` — wrap Common Actions section and Sessions section. Leave title, description, Usage, and Epics sections unprotected. + +## 2. Enable DCP configuration + +- [x] 2.1 Add `"protectTags": true` to `opencode.json` at the top level + +## 3. Verification + +- [x] 3.1 Verify each command file has correctly placed `` / `` tags with no nesting errors +- [x] 3.2 Verify `opencode.json` is valid JSON after modification +- [x] 3.3 Run `make build` to confirm embedded files compile without issues +- [x] 3.4 Verify constitution alignment: confirm no Go code changes, no test changes, no MCP protocol changes (Autonomous Collaboration PASS, Composability First PASS, Testability PASS) + + +