Companion (V2)¶
Companion is the background loop layer of the Dezycro CLI — five small hook handlers that fire on your agent's session events (tool calls, prompt submits, turn ends) and keep the work your agent does for you honest against the workbook. It runs identically in every supported agent: Claude Code, the Cursor app, and the Cursor CLI.
Design principle: Companion is silent unless something material happened. If you're mid-implementation and nothing is committed-decision-ish, Companion stays out of your way. When you finish a verify, when you mark a task DONE, when you say "save progress" — those are the moments it speaks up.
The pillars¶
1. Proactive verify gate¶
Blocks mcp__dezycro__update_task calls that try to mark a path-linked task as DONE or PUSHED when no recent passing verifier run is on file. The agent receives a structured deny with the specific paths and the exact /dezycro:verify --path <p> command to run.
Why: prevents the most common silent failure — your agent marking work "done" when the verifier would have failed it.
Override: set companion.autoVerify.preTaskDone: false in .dezycro/config.json.
2. Spec-publish nudge¶
Tracks every Edit / Write / MultiEdit against companion.autoVerify.controllerPaths (default: **/controllers/**, **/api/**). When a controller path is touched, Companion records the change and sets needsSpecPublish=true.
The next /dezycro:verify run reads that flag and chains /dezycro:publish-spec first, so you never run the verifier against a stale spec.
After 5 controller edits without a verify, Companion emits a one-line pulse nudge.
3. Workbook sweep — trigger-based, silent by default¶
When your agent finishes a turn, Companion does nothing by default. It fires the workbook-sweep directive only when one of these is true:
- The user said a wrap phrase on this turn:
save progress,log what we did,/dezycro:sync,wrap up,we're done,end of session, etc. /dezycro:verifyjust completed this turn (snapshot moment for committed decisions).
When it does fire, the directive asks the agent to scan the recent conversation for:
- Decisions (committed technical/product choices)
- Issues (current blockers/bugs)
- Assumptions (unverified beliefs)
- Task-status hints (a tracked task is now DONE/PUSHED)
…with confidence thresholds per the configured preset (default conservative: 0.85 / 0.80 / 0.90 / 0.90). The agent then calls the matching MCP workbook tool (add_decision, add_issue, add_assumption, update_task) and announces what it logged in plain English, with an 'undo that' if wrong suffix.
Caps: at most 2 entries per turn, 10 per session (configurable). Content-hash dedup against a 32-entry ring buffer prevents the same decision from being logged twice.
Undo: type undo that on the next user turn (within the immediate-next-turn window) and Companion emits a reversal directive that flips the entry to INVALIDATED / CANCELLED / restores the prior task status.
4. Coverage nudges¶
Two nudges, both deterministic — no LLM round-trip:
- Pre-PUSH: when you mark a task PUSHED and the verifier passed, Companion surfaces a one-liner of remaining coverage gaps via the system-message channel. Never blocks; informational only.
- Post-verify Stop: if a verify completed after the previous snapshot was last surfaced, Companion emits a coverage delta (e.g.
Coverage delta since last verify: -2 paths uncovered, -1 baseline stale).
The one-liner format pluralizes and omits zero-count segments:
5. /dezycro:author sanity check¶
When the agent calls change_document_status to mark a TRD COMPLETE, Companion runs a light deterministic sanity check against the most-recent draft sidecar — flags obvious placeholder tokens (TBD, TODO, FIXME) and warns on tiny drafts so a half-finished doc doesn't accidentally get marked as done.
There's no schema enforcement — TRDs don't have a required structure. The check exists as a "did you mean to do that?" guard, not as a content gate.
Configuration¶
All settings live in .dezycro/config.json under the companion key. Defaults (you can override any of these per-repo):
{
"companion": {
"safeMode": false,
"autoVerify": {
"preTaskDone": true,
"prePush": true,
"postEditPulse": { "enabled": true, "threshold": 5 },
"autoPublishSpecOnControllerChange": true,
"controllerPaths": ["**/controllers/**", "**/api/**"]
},
"autoWorkbookUpdates": {
"enabled": true,
"preset": "conservative",
"maxAutoLogsPerTurn": 2,
"maxAutoLogsPerSession": 10,
"thresholds": {
"decision": null,
"issue": null,
"assumption": null,
"taskStatus": null
}
},
"coverageNudges": {
"enabled": true,
"staleBaselineDays": 14
}
}
}
Confidence presets¶
| Preset | Decision | Issue | Assumption | Task-status |
|---|---|---|---|---|
conservative |
0.85 | 0.80 | 0.90 | 0.90 |
balanced |
0.75 | 0.70 | 0.80 | 0.85 |
aggressive |
0.60 | 0.55 | 0.70 | 0.75 |
Numeric thresholds.* overrides win over the preset (per-type).
Kill switch¶
Set companion.safeMode: true to disable all Companion behaviors except the deterministic Pillar 1/2 gates. Or disable individual pillars via the per-key enabled: false flags.
State and logs¶
Companion writes two files under .dezycro/:
companion-state.json— session counters, ring buffers, last verify timestamp, coverage snapshot. Safe to delete (regenerates).companion.log— JSON-lines log of every hook firing. Tail withtail -f .dezycro/companion.log | jqto debug.
Both files are gitignored by /dezycro:init.
Manual trigger¶
You can also drive Companion's workbook sweep directly:
Or say "save progress" — the next assistant turn-end will fire the sweep.