@dezycro-ai/agent-plugin 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.claude-plugin/plugin.json +7 -0
  2. package/LICENSE +18 -0
  3. package/PERSONAS.md +309 -0
  4. package/README.md +125 -0
  5. package/bin/resolve-auth.js +112 -0
  6. package/dist/hooks/lib/authoring.d.ts +118 -0
  7. package/dist/hooks/lib/authoring.js +277 -0
  8. package/dist/hooks/lib/config.d.ts +28 -0
  9. package/dist/hooks/lib/config.js +175 -0
  10. package/dist/hooks/lib/controller-match.d.ts +16 -0
  11. package/dist/hooks/lib/controller-match.js +96 -0
  12. package/dist/hooks/lib/coverage.d.ts +17 -0
  13. package/dist/hooks/lib/coverage.js +66 -0
  14. package/dist/hooks/lib/hashing.d.ts +8 -0
  15. package/dist/hooks/lib/hashing.js +49 -0
  16. package/dist/hooks/lib/logging.d.ts +13 -0
  17. package/dist/hooks/lib/logging.js +72 -0
  18. package/dist/hooks/lib/publish-spec.d.ts +17 -0
  19. package/dist/hooks/lib/publish-spec.js +64 -0
  20. package/dist/hooks/lib/quality-gate.d.ts +67 -0
  21. package/dist/hooks/lib/quality-gate.js +187 -0
  22. package/dist/hooks/lib/router.d.ts +32 -0
  23. package/dist/hooks/lib/router.js +717 -0
  24. package/dist/hooks/lib/state.d.ts +34 -0
  25. package/dist/hooks/lib/state.js +238 -0
  26. package/dist/hooks/lib/undo.d.ts +11 -0
  27. package/dist/hooks/lib/undo.js +71 -0
  28. package/dist/hooks/lib/verify.d.ts +28 -0
  29. package/dist/hooks/lib/verify.js +94 -0
  30. package/dist/hooks/lib/workbook.d.ts +21 -0
  31. package/dist/hooks/lib/workbook.js +77 -0
  32. package/dist/hooks/types.d.ts +249 -0
  33. package/dist/hooks/types.js +14 -0
  34. package/hooks/companion-runner +108 -0
  35. package/hooks/hooks.json +74 -0
  36. package/install.js +84 -0
  37. package/package.json +50 -0
  38. package/prompts/existing-work-ranker.md +47 -0
  39. package/prompts/prd-drafter.md +53 -0
  40. package/prompts/prd-question.md +66 -0
  41. package/prompts/trd-context-gate.md +57 -0
  42. package/prompts/trd-discovery.md +71 -0
  43. package/prompts/trd-drafter.md +63 -0
  44. package/prompts/trd-question.md +61 -0
  45. package/prompts/trd-reviewer.md +74 -0
  46. package/prompts/workbook-sweep.md +89 -0
  47. package/setup.js +35 -0
  48. package/skills/author/SKILL.md +285 -0
  49. package/skills/import-features/SKILL.md +428 -0
  50. package/skills/init/SKILL.md +133 -0
  51. package/skills/publish-spec/SKILL.md +101 -0
  52. package/skills/status/SKILL.md +76 -0
  53. package/skills/sync/SKILL.md +76 -0
  54. package/skills/verify/SKILL.md +248 -0
  55. package/skills/work/SKILL.md +201 -0
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: status
3
+ description: Show a compact workbook summary for the active feature — journeys, tasks, issues, and latest verification results. Requires an active feature (run /dezycro:work first).
4
+ ---
5
+
6
+ # Dezycro Feature Status
7
+
8
+ You are displaying a compact workbook summary for the active Dezycro feature.
9
+
10
+ ## Step 1: Read Active Feature
11
+
12
+ Read `.dezycro/active-feature.json` using the Read tool. If the file does not exist, tell the user:
13
+
14
+ > No active feature. Run `/dezycro:work <feature-name>` first to select a feature.
15
+
16
+ Then stop.
17
+
18
+ Extract `featureId` and `featureName`.
19
+
20
+ ## Step 2: Read Config
21
+
22
+ Read `.dezycro/config.json` to get `workspaceId`.
23
+
24
+ ## Step 3: Fetch Workbook
25
+
26
+ Call `get_workbook(workspaceId, featureId)`.
27
+
28
+ ## Step 4: Fetch Coverage Report
29
+
30
+ Call `get_coverage_report(workspaceId, featureId)`. Treat a `null` `report` (no run yet) as gate-clear and skip the coverage line — otherwise compute:
31
+ - **bound**: `boundButNotExecutable.length + executableButNotObserved.length` (ops bound to a JEP but not yet observed)
32
+ - **inconclusive**: `observedButInconclusive.length`
33
+ - **failed**: `decisiveFailures.length`
34
+ - **scope**: `executionContexts.join(",")` (typically `API`)
35
+
36
+ ## Step 5: Render Summary
37
+
38
+ From the workbook response, compute:
39
+ - **Journeys**: count by status (PASSING, FAILING, PENDING, SKIPPED) — only count `enforced` journeys for the X/Y ratio
40
+ - **Tasks**: count by status (CONFIRMED, PUSHED, DONE, IN_PROGRESS, PENDING) — show confirmation progress: "X/Y confirmed"
41
+ - **Issues**: count OPEN issues, group by severity
42
+ - **Latest verify**: timestamp of most recent entry in `verifierRuns`, and its pass/total count
43
+
44
+ Display:
45
+
46
+ ```
47
+ Feature: <featureName> (<lifecycle status>)
48
+ Journeys: X/Y passing, Z failing, W pending
49
+ Tasks: N total — A confirmed, B pushed, C done, D in progress, E pending
50
+ Issues: M open (severities)
51
+ Verify: last run <relative time> — X/Y
52
+ Coverage: A bound · B inconclusive · C failed · scope=<scope>
53
+ ```
54
+
55
+ If the coverage report was null (no run processed yet), drop the `Coverage:` line entirely. If `lifecycleBlocking` is `true`, append ` ⛔ blocks VERIFIED` to the coverage line.
56
+
57
+ If there are **OPEN HIGH issues**, list each:
58
+ ```
59
+ HIGH issues:
60
+ - <summary>
61
+ ```
62
+
63
+ If there are **FAILING journeys**, list each:
64
+ ```
65
+ Failing journeys:
66
+ JOURNEY-X: <description>
67
+ JOURNEY-Y: <description>
68
+ ```
69
+
70
+ If there are **IN_PROGRESS tasks**, list each:
71
+ ```
72
+ In-progress tasks:
73
+ - <title>
74
+ ```
75
+
76
+ Keep the output compact. No extra explanations unless the user asks follow-up questions.
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: sync
3
+ description: Sync your current work to the Dezycro workbook — creates tasks, records decisions, links commits, and flags issues. Run periodically during development to keep the workbook current.
4
+ ---
5
+
6
+ # Sync Agent Context
7
+
8
+ You are reviewing what work has been done on the active feature and updating the Dezycro workbook to reflect it.
9
+
10
+ ## Step 1: Read Active Feature
11
+
12
+ Read `.dezycro/active-feature.json` and `.dezycro/config.json`. If no active feature, tell the user to run `/dezycro:work` first.
13
+
14
+ ## Step 2: Get Current Workbook State
15
+
16
+ Call `get_workbook(workspaceId, featureId)` to see what's already tracked.
17
+
18
+ ## Step 3: Review Recent Work
19
+
20
+ Look at what has happened since the feature was loaded:
21
+
22
+ 1. **Git commits**: Run `git log --oneline --since="<selectedAt from active-feature.json>"` to see commits made during this session.
23
+
24
+ 2. **Files changed**: Run `git diff --name-only HEAD~5` (or since the feature was loaded) to understand what areas were touched.
25
+
26
+ 3. **Current conversation context**: Review what you've been working on in this session — decisions made, problems encountered, assumptions relied on.
27
+
28
+ ## Step 4: Update Workbook
29
+
30
+ For each item identified, use the appropriate MCP tool:
31
+
32
+ ### Tasks
33
+ - For each distinct unit of work completed or in progress, check if a matching task exists in the workbook.
34
+ - If not, call `create_task(workspaceId, featureId, title, journeyRefs, intentRefs, notes)` to create it.
35
+ - If a task exists and its status changed (e.g., you finished implementing it), call `update_task(workspaceId, featureId, taskId, status)`.
36
+ - Link tasks to the required journeys they cover (`journeyRefs`).
37
+
38
+ ### Decisions
39
+ - For any architectural or design decision made during the session, call `add_decision(workspaceId, featureId, summary, reason, journeyRefs)`.
40
+ - Include the rationale — this is the audit trail for why code was written a certain way.
41
+
42
+ ### Issues
43
+ - For any issue that blocked progress or required a workaround, call `add_issue(workspaceId, featureId, summary, severity, intentRefs)`.
44
+ - Use HIGH for things that prevent journey completion, MEDIUM for workarounds, LOW for minor friction.
45
+
46
+ ### Assumptions
47
+ - For any assumption made that hasn't been validated, call `add_assumption(workspaceId, featureId, summary)`.
48
+
49
+ ### Artifacts
50
+ - For meaningful commits, call `link_artifact(workspaceId, featureId, artifactType="COMMIT", ref=<commit SHA>, linkedIds=<task IDs>)`.
51
+ - For PRs, call `link_artifact(workspaceId, featureId, artifactType="PR", ref=<PR URL>)`.
52
+
53
+ ## Step 5: Display Summary
54
+
55
+ Show what was synced:
56
+
57
+ ```
58
+ Workbook synced for "<featureName>"
59
+
60
+ Tasks: X created, Y updated
61
+ Decisions: N recorded
62
+ Issues: M flagged
63
+ Artifacts: P linked
64
+
65
+ Current state:
66
+ Journeys: A/B passing
67
+ Tasks: C done, D in progress, E pending
68
+ ```
69
+
70
+ ## Guidelines
71
+
72
+ - Don't create duplicate tasks — check existing tasks before creating new ones.
73
+ - Be specific in task titles — "Implement login endpoint" not "Work on feature".
74
+ - Always include `journeyRefs` when the work covers a specific required journey.
75
+ - Record decisions even if they seem obvious — the workbook is for humans reviewing later.
76
+ - Don't over-sync — only record meaningful work, not every small edit.
@@ -0,0 +1,248 @@
1
+ ---
2
+ name: verify
3
+ description: Pull the latest verifier binary, run it against the local (or remote) environment, and upload results to the workbook. Requires an active feature (run /dezycro:work first). Accepts optional --env argument to select environment.
4
+ ---
5
+
6
+ # Run Dezycro Verification
7
+
8
+ You are pulling the verifier binary for the active feature, running it against the configured environment, and uploading results.
9
+
10
+ ## Step 0: Check for Pending Spec Publish (Pillar 2)
11
+
12
+ Before running verify, check whether Companion's controller-edit tracker recorded any controller-path edits since the last spec publish. The PostToolUse hook flips `needsSpecPublish=true` whenever an Edit/Write/MultiEdit touches a file matching `companion.autoVerify.controllerPaths` (TRD §5.2).
13
+
14
+ Run:
15
+
16
+ ```bash
17
+ companion-runner state --get
18
+ ```
19
+
20
+ (If the binary isn't on PATH, fall back to `node ${CLAUDE_PLUGIN_ROOT}/hooks/companion-runner state --get`.)
21
+
22
+ Parse the JSON. If `needsSpecPublish === true` AND `controllerEditsSinceLastPublish` is non-empty:
23
+
24
+ 1. Print the announcement verbatim (replacing `<list>` with the paths from `controllerEditsSinceLastPublish[*].path`, comma-separated):
25
+
26
+ > Controllers changed since last published spec: \<list\>. Publishing spec before verify.
27
+
28
+ 2. Invoke `/dezycro:publish-spec` programmatically before continuing.
29
+
30
+ 3. Poll the feature's `verifyPending` flag every 5 seconds (call `get_workbook(workspaceId, featureId)` and read the feature record) until it clears or 5 minutes elapse — this matches the verifier compile SLA.
31
+
32
+ 4. After publish-spec returns control, clear the flags so the same edits don't re-trigger on the next verify:
33
+
34
+ ```bash
35
+ companion-runner state --patch='{"needsSpecPublish": false, "controllerEditsSinceLastPublish": []}'
36
+ ```
37
+
38
+ Note the `=` after `--patch` — the argv parser requires the `=` form (space-separated form is reserved for the `--route` flag).
39
+
40
+ 5. Continue to Step 1.
41
+
42
+ If `needsSpecPublish` is false (or `companion-state.json` is missing), continue to Step 1 immediately. If the `companion-runner` binary isn't installed (Companion V1 repos), skip Step 0 entirely.
43
+
44
+ ## Step 1: Read Active Feature
45
+
46
+ Read `.dezycro/active-feature.json` using the Read tool. If the file does not exist, tell the user:
47
+
48
+ > No active feature. Run `/dezycro:work <feature-name>` first to select a feature.
49
+
50
+ Then stop.
51
+
52
+ Extract `featureId` and `featureName`.
53
+
54
+ ## Step 2: Read Config
55
+
56
+ Read `.dezycro/config.json` using the Read tool. Extract `workspaceId` and `environments`.
57
+
58
+ Parse the command arguments (`$ARGUMENTS`) for `--env <name>`. If provided, use that environment. Otherwise, find the environment with `"default": true`. If no default, use the first environment.
59
+
60
+ Extract from the selected environment:
61
+ - `setup` (optional) — command to start the environment
62
+ - `apiUrl` (required) — base URL for the verifier
63
+ - `healthCheck` (optional) — command to check if environment is ready
64
+ - `teardown` (optional) — command to stop the environment
65
+
66
+ ## Step 3: Environment Setup
67
+
68
+ If the selected environment has a `setup` command:
69
+
70
+ 1. Run the setup command via Bash tool.
71
+ 2. If there's a `healthCheck` command, poll it:
72
+ - Run the health check command via Bash.
73
+ - If it fails (non-zero exit), wait 2 seconds and retry.
74
+ - Retry up to 15 times (30 seconds total).
75
+ - If still failing after 15 retries, tell the user:
76
+ > Environment health check failed after 30 seconds. Check your setup command and health check endpoint.
77
+ > Setup: `<setup command>`
78
+ > Health check: `<healthCheck command>`
79
+ - Then stop.
80
+
81
+ If no `setup` command, skip this step. If there's a `healthCheck` but no `setup`, still run the health check.
82
+
83
+ ## Step 4: Pull Verifier Binary
84
+
85
+ 1. Detect the platform by running via Bash:
86
+ ```bash
87
+ echo "$(uname -s | tr '[:upper:]' '[:lower:]')/$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')"
88
+ ```
89
+ This gives you the platform string like `darwin/arm64` or `linux/amd64`.
90
+
91
+ 2. Call `pull_verifier(featureId, platform)` via MCP (using the `pull_verifier` tool with `featureId` and `platform` parameters).
92
+
93
+ 3. If the tool returns an error indicating no binary exists:
94
+ - Check generation status by calling `generation_status(workspaceId, featureId)` via MCP.
95
+ - If generation is **in progress** (status is not IDLE/COMPLETE/FAILED):
96
+ - Tell the user: "JEP generation in progress — waiting for binary..."
97
+ - Poll `generation_status` every 15 seconds, up to 20 times (5 minutes).
98
+ - Show a brief status update every poll: "Still generating... (<status>)"
99
+ - Once status is COMPLETE, retry `pull_verifier`.
100
+ - If status is FAILED or timeout reached, tell the user:
101
+ > JEP generation failed or timed out. Check the generation logs or run `/dezycro:publish-spec` to retry.
102
+ - Then stop.
103
+ - If generation is **IDLE** (never started):
104
+ - Tell the user:
105
+ > No verifier binary available. The feature needs an API spec first.
106
+ > Run `/dezycro:publish-spec` to upload your spec and trigger JEP generation.
107
+ - Then stop.
108
+
109
+ 4. From the response, extract `downloadUrl`, `contentHash`, and any CLI usage hints.
110
+
111
+ 5. Check if the binary is already cached:
112
+ ```bash
113
+ ls .dezycro/bin/<contentHash>/dezycro-verify 2>/dev/null && echo "cached" || echo "not-cached"
114
+ ```
115
+
116
+ 6. If not cached, download and cache it:
117
+ ```bash
118
+ mkdir -p .dezycro/bin/<contentHash>
119
+ curl -fSL -o .dezycro/bin/<contentHash>/dezycro-verify "<downloadUrl>"
120
+ chmod +x .dezycro/bin/<contentHash>/dezycro-verify
121
+ ```
122
+
123
+ ## Step 5: Load Auth Personas (from `.dezycro/auth.local.json`)
124
+
125
+ The generated verifier expects each persona's auth config to be present as an environment variable whose name is declared in `.dezycro/auth.local.json` (`personas.<name>.envVar`, e.g. `AUTH_ADMIN1`). Without these, every authenticated request fails and the run looks broken for the wrong reason. Full schema in `PERSONAS.md` in the claude-plugin (`!file:` / `!env:` / `!cmd:` secret backends, `${VAR}` placeholders, auth types: `bearer`/`basic`/`header`/`http_endpoint`/`js`/`none`).
126
+
127
+ Use `dezycro-resolve-auth` — it reads `.dezycro/auth.local.json`, resolves secrets, substitutes `${…}` placeholders, and emits `export KEY='value'` lines that must be consumed via `eval` (so the shell strips the quotes before the binary sees the value — `env $(…)` does NOT work here and will produce `invalid character '\''` JSON parse errors):
128
+
129
+ ```bash
130
+ eval "$(dezycro-resolve-auth)"
131
+ ```
132
+
133
+ If the binary isn't on PATH (plugin not installed globally), fall back to invoking the script directly from the repo's claude-plugin dir:
134
+
135
+ ```bash
136
+ eval "$(node claude-plugin/bin/resolve-auth.js)"
137
+ ```
138
+
139
+ Do not hand-roll the exports from `.github/workflows/ci.yml` — `auth.local.json` is the source of truth and will drift if you do.
140
+
141
+ If `.dezycro/auth.local.json` does not exist, the script prints a stderr warning and emits nothing — `eval` of empty input is a no-op, which is the right behavior (dev/prod runs may inject credentials another way, or the user may have already exported them). Per-persona secret failures are stderr warnings only, so a missing `!file:` secret for one persona will NOT block unrelated personas.
142
+
143
+ ## Step 6: Run Verifier
144
+
145
+ Run the verifier binary via Bash, in the same shell invocation as the `eval` from Step 5 so the exports carry over:
146
+
147
+ ```bash
148
+ eval "$(dezycro-resolve-auth)"
149
+ .dezycro/bin/<contentHash>/dezycro-verify run --all --base-url <apiUrl> --json
150
+ ```
151
+
152
+ Capture the full stdout output. The verifier outputs JSON with path results.
153
+
154
+ If the binary fails to execute (non-zero exit with no JSON output), show stderr and suggest:
155
+ > Verifier binary failed to execute. Try:
156
+ > - `./dezycro-verify doctor` to check connectivity
157
+ > - Verify your API is running at `<apiUrl>`
158
+ > - Check that the binary matches your platform
159
+ > - Confirm the expected `AUTH_*` env vars from `.dezycro/auth.local.json` are set
160
+
161
+ ## Step 7: Upload Results
162
+
163
+ Take the JSON output from Step 6 and call `record_verifier_run` via MCP:
164
+ - `workspaceId`: from config
165
+ - `featureId`: from active feature
166
+ - `results`: the full JSON output as a string
167
+ - `specHash`, `flowVersion`, `jepVersion`: extract from the verifier JSON output's metadata section if present, otherwise omit
168
+
169
+ This automatically updates journey statuses in the workbook and may trigger lifecycle transitions (IN_PROGRESS -> VERIFIED if all enforced journeys pass and all journey-linked tasks are PUSHED).
170
+
171
+ ## Step 8: Display Results
172
+
173
+ Parse the JSON output and display a summary:
174
+
175
+ ```
176
+ Verification Results: X/Y passed
177
+
178
+ PASSING:
179
+ JOURNEY-1: <description>
180
+ JOURNEY-2: <description>
181
+
182
+ FAILING:
183
+ JOURNEY-3: <description>
184
+ -> <HTTP method> <endpoint> returned <actual status> (expected <expected status>)
185
+ -> Intent: "<intent reference>"
186
+
187
+ SKIPPED:
188
+ JOURNEY-8: <description> (not enforced)
189
+ ```
190
+
191
+ ## Step 9: Surface Coverage Gaps
192
+
193
+ The verifier run also feeds the coverage projection. Call `get_coverage_report(workspaceId, featureId)` once the upload from Step 7 has settled. If the response carries a `null` report, skip this step — the projection materializes asynchronously and may not be ready on the first call.
194
+
195
+ If the report is present, take the top 3 entries (in this priority order) from `decisiveFailures` first, then `observedButInconclusive` to fill the remaining slots, and surface them with action hints derived from `verdict`:
196
+
197
+ | Verdict | Action hint |
198
+ |--------------------------------------|--------------------------------------------------------------------------------------|
199
+ | `FAIL_DECISIVE_ROUTE_MISSING` | Endpoint not implemented — implement it or remove from the spec |
200
+ | `FAIL_DECISIVE_CONTRACT` | Response shape does not match the spec — fix the endpoint or update the spec |
201
+ | `FAIL_DECISIVE_PERSISTENCE` | State did not persist — investigate the write path |
202
+ | `INCONCLUSIVE_AUTH_REQUIRED` | Supply an auth fixture in `.dezycro/auth.local.json` for the persona that owns it |
203
+ | `INCONCLUSIVE_SETUP_REQUIRED` | Required setup state is missing — supply prerequisites (parent resource, fixture) |
204
+ | `INCONCLUSIVE_INPUT_CONSTRAINT` | Input did not satisfy a constraint — supply a valid fixture for the parameter |
205
+
206
+ Display:
207
+
208
+ ```
209
+ Coverage gaps (top 3):
210
+ - <operationId> [<verdict>] -> <action hint>
211
+ - <operationId> [<verdict>] -> <action hint>
212
+ - <operationId> [<verdict>] -> <action hint>
213
+ ```
214
+
215
+ If the report has zero entries in both buckets, print `Coverage: clear ✓` instead. If `lifecycleBlocking` is `true`, prepend a one-line note: `⛔ Coverage gate blocks VERIFIED until the entries below are addressed.`
216
+
217
+ ## Step 9b: Update Companion State (Pillar 4)
218
+
219
+ Tell Companion the verify completed and snapshot the coverage counts so the Stop-hook delta and pre-PUSH nudge can compare against the next run (TRD §5.4.1). Extract three counts from the `get_coverage_report` response from Step 9:
220
+
221
+ - `uncoveredPaths` — count of paths with no covering journey
222
+ - `endpointsNotInSpec` — count of observed endpoints absent from the spec
223
+ - `staleBaselines` — count of baselines older than `staleBaselineDays` (default 14)
224
+
225
+ If the report was null/missing, set all three to 0. Then run:
226
+
227
+ ```bash
228
+ companion-runner state --patch='{"lastVerifyCompletionTs":"<iso-8601-now>","coverageSnapshot":{"uncoveredPaths":<n>,"endpointsNotInSpec":<n>,"staleBaselines":<n>}}'
229
+ ```
230
+
231
+ (Fall back to `node ${CLAUDE_PLUGIN_ROOT}/hooks/companion-runner state --patch=…` if the binary isn't on PATH. Skip the entire step if the binary isn't installed — V1 repos.)
232
+
233
+ This is a fire-and-forget bookkeeping step. If the patch returns a lock-contention error, do not retry — the next verify will overwrite.
234
+
235
+ ## Step 10: Teardown (Optional)
236
+
237
+ If the selected environment has a `teardown` command, ask the user:
238
+
239
+ > Want to tear down the environment? (`<teardown command>`)
240
+
241
+ If yes, run it via Bash.
242
+
243
+ ## Next Steps
244
+
245
+ Based on results:
246
+ - **All journeys passing**: "All journeys passing! The feature may auto-transition to VERIFIED."
247
+ - **Some failures**: "Fix the failing journeys and run `/dezycro:verify` again. Focus on: <list top 2-3 failing journeys>."
248
+ - **No journeys passing**: "No journeys passing yet. Review the failing assertions and start implementing the feature endpoints."
@@ -0,0 +1,201 @@
1
+ ---
2
+ name: work
3
+ description: Start or resume working on a Dezycro feature — gates on PRD/TRD/graph approval, interactively helps pick a feature when none is given, and binds the session to the workbook as the source of truth. Use when starting a coding session. Accepts an optional feature name or UUID as argument.
4
+ ---
5
+
6
+ # Start/Resume Feature Work
7
+
8
+ You are loading a Dezycro feature's full context so the developer can start (or resume) working on it. **The workbook is the source of truth** — local files (`.dezycro/active-feature.json`) are only a session pointer; every meaningful state change goes through MCP workbook tools.
9
+
10
+ ## Hard Rules — Read Before Anything Else
11
+
12
+ 1. **No approved graph → no work.** A feature with `lifecycleStatus == "DRAFT"` has no approved flow graph, which means no journeys, no JEP, no agent context. **Refuse to start a coding session on it.** Walk the user to the webapp to approve the graph instead. (Lifecycle: `DRAFT` → `APPROVED` happens automatically when the flow graph is approved.)
13
+ 2. **No PRD or TRD → no work.** Even if the feature is `APPROVED`, both PRD and TRD documents must exist and be at `status == "COMPLETE"`. Without finalized docs, the agent context is incomplete and you will hallucinate.
14
+ 3. **Workbook is canonical.** Every issue you find, every decision you make, every task you complete during this session is persisted to the workbook via MCP tools (`add_issue`, `add_decision`, `add_assumption`, `update_task`, `update_issue`). **Do not** keep findings in scratch files or "I'll remember it" memory — it does not survive the session and the PM cannot see it.
15
+ 4. **Lifecycle states allowed for coding:** `APPROVED`, `IN_PROGRESS`, `VERIFIED`. Refuse: `DRAFT`, `SHIPPED`, `ABANDONED` (offer to reopen with the user's confirmation for `ABANDONED`/`SHIPPED`, but do not just dive in).
16
+
17
+ ## Step 1: Read Config
18
+
19
+ Read `.dezycro/config.json` from the repository root using the Read tool. If the file does not exist, tell the user:
20
+
21
+ > No `.dezycro/config.json` found. Run `/dezycro:init` first to set up this repository.
22
+
23
+ Then stop.
24
+
25
+ Extract `workspaceId` and `projectId` from the config.
26
+
27
+ ## Step 2: Resolve Feature
28
+
29
+ The user may provide a feature name or UUID as the command argument: `$ARGUMENTS`
30
+
31
+ ### 2a. If `$ARGUMENTS` is a UUID
32
+
33
+ (Matches pattern `[0-9a-f]{8}-[0-9a-f]{4}-...`.) Use it directly as `featureId`. You will need to fetch its full record later to read `lifecycleStatus`, `name`, and `breadcrumb` — do that by calling `search_features(workspaceId, projectId, query=<the UUID's first 8 chars>)` and matching by `id`, OR by skipping ahead to the lifecycle check via `get_workbook` and `list_feature_documents` and accepting that you'll surface the name from those.
34
+
35
+ ### 2b. If `$ARGUMENTS` is a non-empty string (feature name / substring)
36
+
37
+ Call `search_features(workspaceId, projectId, query=$ARGUMENTS)`.
38
+
39
+ - **Exactly one match**: use it.
40
+ - **Multiple matches**: use `AskUserQuestion` with up to 4 options. Label each `<featureName> — <breadcrumb path> · <lifecycleStatus>`. If more than 4 matches, show the 4 most recently updated and add a 5th catch-all "None of these — refine the search" option that re-prompts for a new query.
41
+ - **No matches**: tell the user "No features matched `<query>`. Run `/dezycro:work` with no argument to browse." Then stop.
42
+
43
+ ### 2c. If `$ARGUMENTS` is empty — interactive picker
44
+
45
+ This is the path most demos and resumed sessions hit. **Do not** dump a flat list of every feature — that's noisy. Help the user navigate.
46
+
47
+ 1. **Call `list_features(workspaceId, projectId)`** (omit `parentDirectoryId` to get the project root). The response has:
48
+ - `directories[]` with `id`, `name`, `namePath`, `updateTimestamp`
49
+ - `features[]` with `id`, `name`, `lifecycleStatus`, `updateTimestamp`, `breadcrumb`, `documentSummaries`
50
+
51
+ 2. **Sort `directories[]` by `updateTimestamp` descending** and take the top 5.
52
+
53
+ 3. **Sort root-level `features[]` by `updateTimestamp` descending** and take the top 3 — these are likely active work too.
54
+
55
+ 4. **Use `AskUserQuestion`** with a single question titled "Where do you want to work?" and options built from the sorted lists. Aim for ≤4 options total (the tool's max). Prioritize in this order:
56
+ - The 2 most recently updated directories (label: `📁 <namePath> — updated <relative time>`)
57
+ - The most recently updated root-level feature, if any (label: `📄 <name> · <lifecycleStatus>`)
58
+ - One "🔍 Search by name" option (description: "Type a feature name to search across the whole project")
59
+ - Always include "📂 Browse from root" as a fallback if you have to drop options to stay ≤4
60
+
61
+ The user can always pick "Other" to type a custom answer (e.g., a path like `Backend/Auth/Login` or a folder name).
62
+
63
+ 5. **Handle the response:**
64
+ - **Folder option** → call `list_features(workspaceId, projectId, parentDirectoryId=<folder.id>)`. Show its directories + features the same way (recently updated first). Recurse until the user picks a feature. Always include a "⬅ Go back" option once you're below the root.
65
+ - **Root feature option** → use that feature directly.
66
+ - **Search option** → ask the user for a query, then call `search_features` and resume at 2b.
67
+ - **"Other" / custom text** → treat as a search query (run `search_features`).
68
+
69
+ Store the resolved `featureId`, `featureName`, and `lifecycleStatus`.
70
+
71
+ ## Step 3: Lifecycle Gate (HARD STOP if ungated)
72
+
73
+ You now have a candidate feature. **Before loading anything else**, validate it's workable:
74
+
75
+ 1. If you don't yet have `lifecycleStatus` (e.g. user passed a raw UUID), call `get_workbook(workspaceId, featureId)` and read the feature's status via the parent lookup, OR call `search_features` with a fragment to recover it. The cheapest path: just call `list_feature_documents(workspaceId, featureId)` and `get_workbook(...)` next — both return enough metadata to fail-fast.
76
+
77
+ 2. **Check `lifecycleStatus`:**
78
+ - `DRAFT` → **REFUSE**. Print:
79
+ > ⛔ Feature **<name>** is in `DRAFT` — the flow graph hasn't been approved yet, so there's no agent context, no journeys, and no JEP. I won't start a coding session on it.
80
+ >
81
+ > **What to do:** open the feature in the webapp, review the flow graph, and approve it. Once approved, the workbook initializes automatically and `/dezycro:work` will load it.
82
+
83
+ Then stop. Do NOT write `.dezycro/active-feature.json`.
84
+ - `SHIPPED` → **REFUSE**. Print:
85
+ > ⛔ Feature **<name>** is `SHIPPED`. There's nothing to do here. If you need to extend it, create a new feature or ask the PM to reopen this one.
86
+
87
+ Then stop.
88
+ - `ABANDONED` → **REFUSE by default**. Print:
89
+ > ⛔ Feature **<name>** is `ABANDONED`. If this was a mistake, reopen it in the webapp first. I won't start a coding session on an abandoned feature without that step.
90
+
91
+ Then stop.
92
+ - `APPROVED`, `IN_PROGRESS`, `VERIFIED` → continue to step 4.
93
+
94
+ 3. **Check documents** — call `list_feature_documents(workspaceId, featureId)`. You need:
95
+ - At least one document with `type == "PRD"` and `status == "COMPLETE"`.
96
+ - At least one document with `type == "TRD"` and `status == "COMPLETE"`.
97
+
98
+ If either is missing or still `DRAFT` / `IN_PROGRESS`, **REFUSE**:
99
+ > ⛔ Feature **<name>** is `<lifecycleStatus>` but its documents aren't finalized:
100
+ > - PRD: <status or "missing">
101
+ > - TRD: <status or "missing">
102
+ >
103
+ > Without a finalized PRD and TRD, the agent context is incomplete and I will hallucinate. Finish the docs in the webapp first.
104
+
105
+ Then stop. Do NOT write `.dezycro/active-feature.json`.
106
+
107
+ ## Step 4: Load Workbook
108
+
109
+ Call `get_workbook(workspaceId, featureId)`.
110
+
111
+ From the response, extract:
112
+ - `status` — the workbook/feature lifecycle status (NOT_STARTED / ACTIVE / COMPLETE)
113
+ - `journeys` — list with `journeyId`, `description`, `status` (PENDING/PASSING/FAILING/SKIPPED), `enforced`
114
+ - `tasks` — list with `id`, `title`, `status` (PENDING/IN_PROGRESS/DONE/PUSHED/CONFIRMED)
115
+ - `issues` — list with `summary`, `severity`, `status` (OPEN/RESOLVED/PUSHED/CLOSED)
116
+ - `verifierRuns` — list, take the most recent one for timestamp and results
117
+
118
+ ## Step 5: Load Documents
119
+
120
+ Call `list_feature_documents(workspaceId, featureId)` to get document IDs (you already have the list from Step 3 — reuse it).
121
+
122
+ For each finalized document (PRD and TRD):
123
+ - Call `get_document(workspaceId, featureId, docId)`.
124
+ - Note the word count of the content.
125
+
126
+ Read both the PRD and TRD content — you will need this context to help the developer.
127
+
128
+ ## Step 6: Write Active Feature (session pointer only)
129
+
130
+ Write `.dezycro/active-feature.json` using the Write tool:
131
+
132
+ ```json
133
+ {
134
+ "featureId": "<resolved featureId>",
135
+ "featureName": "<resolved featureName>",
136
+ "selectedAt": "<current ISO 8601 timestamp>"
137
+ }
138
+ ```
139
+
140
+ Create the `.dezycro/` directory first if it doesn't exist: `mkdir -p .dezycro`
141
+
142
+ **This file is a pointer, not state.** It tells `/dezycro:status` and `/dezycro:verify` which feature is active. Any actual work — tasks, issues, decisions — lives in the workbook.
143
+
144
+ ## Step 7: Display Summary
145
+
146
+ Present the feature context to the user in this format:
147
+
148
+ ```
149
+ Feature: <featureName> (<lifecycleStatus>)
150
+ Path: <breadcrumb joined with " / ">
151
+
152
+ Journeys: X/Y passing, Z failing, W pending
153
+ Tasks: N total — A confirmed, B pushed, C done, D in progress, E pending
154
+ Issues: M open (list severities)
155
+ Verify: <timestamp or "never"> — X/Y journeys
156
+
157
+ PRD loaded (N words) | TRD loaded (M words)
158
+ ```
159
+
160
+ If there are **failing journeys**, list them:
161
+ ```
162
+ Failing journeys:
163
+ JOURNEY-X: <description> — FAILING
164
+ JOURNEY-Y: <description> — FAILING
165
+ ```
166
+
167
+ If there are **open HIGH issues**, list them:
168
+ ```
169
+ Open HIGH issues:
170
+ - <summary>
171
+ ```
172
+
173
+ If there are **in-progress tasks**, list them:
174
+ ```
175
+ In-progress tasks:
176
+ - <title>
177
+ ```
178
+
179
+ ## Step 8: Operating Rules (Show Once, Then Enforce)
180
+
181
+ After the summary, print this reminder verbatim so the developer sees what the agent will and won't do during the session:
182
+
183
+ > **Workbook is the source of truth for this session.**
184
+ > - I will record every issue I find via `add_issue` — not in chat-only or scratch files.
185
+ > - I will record every decision (e.g. "we chose JWT over session cookies") via `add_decision`.
186
+ > - I will record assumptions I'm making (e.g. "assuming all timestamps are UTC") via `add_assumption`.
187
+ > - I will update task status via `update_task` as I complete work — not local checkboxes.
188
+ > - When you tell me an issue is fixed, I will call `update_issue` to mark it RESOLVED.
189
+ > - Before declaring a journey done, I will run `/dezycro:verify` and let the verifier confirm.
190
+ >
191
+ > If you want me to skip the workbook for something quick (e.g. a one-off question), say so explicitly. Otherwise I will default to writing through.
192
+
193
+ ## Ready
194
+
195
+ The developer now has full context. Offer:
196
+
197
+ > Ready to work on "<featureName>". What would you like to do?
198
+ > - Pick a failing journey or open issue to tackle
199
+ > - Start implementing an in-progress task
200
+ > - Run `/dezycro:verify` to test current state
201
+ > - Run `/dezycro:status` for a quick status check