superdev-cli 0.1.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 (182) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +21 -0
  3. package/.codex-plugin/plugin.json +27 -0
  4. package/CODE_OF_CONDUCT.md +109 -0
  5. package/CONTRIBUTING.md +205 -0
  6. package/LICENSE +202 -0
  7. package/NOTICE +11 -0
  8. package/README.md +1051 -0
  9. package/SECURITY.md +135 -0
  10. package/THIRD-PARTY-NOTICES.md +253 -0
  11. package/hooks/hooks.json +61 -0
  12. package/hooks/run.mjs +88 -0
  13. package/package.json +65 -0
  14. package/references/confidentiality.md +48 -0
  15. package/references/evidence-and-risk.md +73 -0
  16. package/references/operating-model.md +105 -0
  17. package/references/platform-capabilities.md +51 -0
  18. package/references/project-record.md +91 -0
  19. package/references/provider-contracts.md +102 -0
  20. package/scripts/doctor/doctor.mjs +539 -0
  21. package/scripts/privacy/scan-history.mjs +163 -0
  22. package/scripts/privacy/scan.mjs +368 -0
  23. package/scripts/validate/README.md +94 -0
  24. package/scripts/validate/common.mjs +149 -0
  25. package/scripts/validate/data-model.mjs +225 -0
  26. package/scripts/validate/dependencies.mjs +69 -0
  27. package/scripts/validate/docs-templates.mjs +99 -0
  28. package/scripts/validate/footprint.mjs +78 -0
  29. package/scripts/validate/imports.mjs +61 -0
  30. package/scripts/validate/manifests.mjs +173 -0
  31. package/scripts/validate/markdown.mjs +123 -0
  32. package/scripts/validate/migrations.mjs +187 -0
  33. package/scripts/validate/no-tests.mjs +136 -0
  34. package/scripts/validate/privacy.mjs +115 -0
  35. package/scripts/validate/record-links.mjs +127 -0
  36. package/scripts/validate/skill-commands.mjs +190 -0
  37. package/scripts/validate/skills.mjs +112 -0
  38. package/scripts/validate/specification.mjs +88 -0
  39. package/scripts/validate/style.mjs +78 -0
  40. package/scripts/validate/validate-all.mjs +175 -0
  41. package/skills/debug/SKILL.md +68 -0
  42. package/skills/decision/SKILL.md +99 -0
  43. package/skills/docs/SKILL.md +86 -0
  44. package/skills/docs/assets/fragments/api/events.md +14 -0
  45. package/skills/docs/assets/fragments/api/graphql.md +14 -0
  46. package/skills/docs/assets/fragments/api/local-only.md +13 -0
  47. package/skills/docs/assets/fragments/api/rest.md +13 -0
  48. package/skills/docs/assets/fragments/api/rpc.md +13 -0
  49. package/skills/docs/assets/fragments/async/event-bus.md +13 -0
  50. package/skills/docs/assets/fragments/async/none.md +11 -0
  51. package/skills/docs/assets/fragments/async/platform-jobs.md +13 -0
  52. package/skills/docs/assets/fragments/async/queue.md +13 -0
  53. package/skills/docs/assets/fragments/async/scheduler.md +13 -0
  54. package/skills/docs/assets/fragments/auth/detected-provider.md +15 -0
  55. package/skills/docs/assets/fragments/auth/neutral-base.md +14 -0
  56. package/skills/docs/assets/fragments/data/document.md +13 -0
  57. package/skills/docs/assets/fragments/data/external-saas.md +13 -0
  58. package/skills/docs/assets/fragments/data/key-value.md +13 -0
  59. package/skills/docs/assets/fragments/data/none.md +12 -0
  60. package/skills/docs/assets/fragments/data/sql-orm.md +13 -0
  61. package/skills/docs/assets/fragments/data/sql-plain.md +13 -0
  62. package/skills/docs/assets/fragments/env/conventional.md +13 -0
  63. package/skills/docs/assets/fragments/env/envx.md +13 -0
  64. package/skills/docs/assets/fragments/env/managed-platform.md +13 -0
  65. package/skills/docs/assets/fragments/env/none.md +11 -0
  66. package/skills/docs/assets/fragments/ui/api-only.md +13 -0
  67. package/skills/docs/assets/fragments/ui/cli.md +14 -0
  68. package/skills/docs/assets/fragments/ui/desktop.md +14 -0
  69. package/skills/docs/assets/fragments/ui/mobile.md +14 -0
  70. package/skills/docs/assets/fragments/ui/web.md +14 -0
  71. package/skills/docs/assets/templates/adr.md +62 -0
  72. package/skills/docs/assets/templates/api.md +30 -0
  73. package/skills/docs/assets/templates/architecture.md +52 -0
  74. package/skills/docs/assets/templates/change-impact-drift-report.md +29 -0
  75. package/skills/docs/assets/templates/compliance.md +29 -0
  76. package/skills/docs/assets/templates/data-schema.md +43 -0
  77. package/skills/docs/assets/templates/feature.md +43 -0
  78. package/skills/docs/assets/templates/foundations.md +55 -0
  79. package/skills/docs/assets/templates/jobs-webhooks.md +36 -0
  80. package/skills/docs/assets/templates/module-inventory.md +19 -0
  81. package/skills/docs/assets/templates/module.md +50 -0
  82. package/skills/docs/assets/templates/nfr.md +22 -0
  83. package/skills/docs/assets/templates/observability.md +28 -0
  84. package/skills/docs/assets/templates/pages-ui-actions.md +47 -0
  85. package/skills/docs/assets/templates/project-summary.md +44 -0
  86. package/skills/docs/assets/templates/roles-permissions.md +26 -0
  87. package/skills/docs/assets/templates/test-plan.md +23 -0
  88. package/skills/docs/assets/templates/workflow-state-machine.md +43 -0
  89. package/skills/docs/references/adr-authoring.md +24 -0
  90. package/skills/docs/references/apis-and-data.md +23 -0
  91. package/skills/docs/references/capability-fragments.md +25 -0
  92. package/skills/docs/references/change-tracking.md +62 -0
  93. package/skills/docs/references/diagrams.md +31 -0
  94. package/skills/docs/references/discovery.md +59 -0
  95. package/skills/docs/references/edge-cases.md +45 -0
  96. package/skills/docs/references/foundations-modules.md +18 -0
  97. package/skills/docs/references/ingestion.md +52 -0
  98. package/skills/docs/references/initialize-adopt.md +25 -0
  99. package/skills/docs/references/module-decomposition.md +38 -0
  100. package/skills/docs/references/profiles.md +60 -0
  101. package/skills/docs/references/quality-attributes.md +27 -0
  102. package/skills/docs/references/reverse-engineer.md +21 -0
  103. package/skills/docs/references/spec-depths.md +31 -0
  104. package/skills/docs/references/summarize.md +18 -0
  105. package/skills/docs/references/surfaces-and-actions.md +24 -0
  106. package/skills/docs/references/validation.md +47 -0
  107. package/skills/docs/references/workflows-and-jobs.md +25 -0
  108. package/skills/docs/scripts/ingest.mjs +984 -0
  109. package/skills/docs/scripts/profile-detect.mjs +299 -0
  110. package/skills/docs/scripts/screen.mjs +96 -0
  111. package/skills/docs/scripts/template-lint.mjs +143 -0
  112. package/skills/docs/scripts/validate-docs.mjs +363 -0
  113. package/skills/doctor/SKILL.md +167 -0
  114. package/skills/feature/SKILL.md +132 -0
  115. package/skills/init/SKILL.md +137 -0
  116. package/skills/project/SKILL.md +261 -0
  117. package/skills/project/references/commands.md +213 -0
  118. package/skills/resume/SKILL.md +79 -0
  119. package/skills/review/SKILL.md +91 -0
  120. package/skills/status/SKILL.md +85 -0
  121. package/skills/task/SKILL.md +183 -0
  122. package/src/cli/product-map.mjs +468 -0
  123. package/src/cli/render.mjs +544 -0
  124. package/src/cli.mjs +2774 -0
  125. package/src/cloud/crypto.mjs +118 -0
  126. package/src/cloud/merge.mjs +186 -0
  127. package/src/cloud/policy.mjs +115 -0
  128. package/src/cloud/sync.mjs +512 -0
  129. package/src/cloud/transport.mjs +116 -0
  130. package/src/db/connect.mjs +189 -0
  131. package/src/db/maintenance.mjs +419 -0
  132. package/src/db/migrate.mjs +188 -0
  133. package/src/db/migrations/001_initial.sql +1024 -0
  134. package/src/db/migrations/002_docs_coverage.sql +126 -0
  135. package/src/db/migrations/003_memory_retrieval_and_integrity.sql +168 -0
  136. package/src/db/migrations/004_task_categories.sql +59 -0
  137. package/src/db/migrations/005_executable_evidence.sql +32 -0
  138. package/src/db/migrations/006_module_and_feature_boundaries.sql +27 -0
  139. package/src/db/migrations/007_drop_redundant_module_users.sql +13 -0
  140. package/src/db/migrations/008_changes_assumptions_test_plans_api_services.sql +166 -0
  141. package/src/db/migrations/009_retired_documents.sql +54 -0
  142. package/src/db/migrations/010_test_plan_evidence.sql +20 -0
  143. package/src/db/migrations/011_criterion_waiver.sql +13 -0
  144. package/src/db/migrations/012_synchronization.sql +56 -0
  145. package/src/db/store.mjs +327 -0
  146. package/src/decisions/record.mjs +167 -0
  147. package/src/docs/proposals.mjs +871 -0
  148. package/src/docs/render.mjs +1424 -0
  149. package/src/docs/templates.mjs +1281 -0
  150. package/src/features/acceptance.mjs +315 -0
  151. package/src/features/specify.mjs +248 -0
  152. package/src/init/discovery.mjs +901 -0
  153. package/src/init/index.mjs +784 -0
  154. package/src/init/questions.mjs +562 -0
  155. package/src/memory/benchmark.mjs +171 -0
  156. package/src/memory/capture.mjs +135 -0
  157. package/src/memory/consolidate.mjs +255 -0
  158. package/src/memory/index.mjs +810 -0
  159. package/src/model/ids.mjs +185 -0
  160. package/src/model/screening.mjs +150 -0
  161. package/src/model/toolkit.mjs +258 -0
  162. package/src/model/vocabulary.mjs +190 -0
  163. package/src/product/assumptions.mjs +120 -0
  164. package/src/product/changes.mjs +180 -0
  165. package/src/product/test-plans.mjs +183 -0
  166. package/src/progress/index.mjs +1364 -0
  167. package/src/runtime/harness.mjs +264 -0
  168. package/src/runtime/hooks.mjs +1021 -0
  169. package/src/runtime/identity.mjs +305 -0
  170. package/src/runtime/resume.mjs +343 -0
  171. package/src/runtime/session.mjs +679 -0
  172. package/src/runtime/version.mjs +315 -0
  173. package/src/service/assets/control-center.html +206 -0
  174. package/src/service/assets/control-center.manifest.json +7 -0
  175. package/src/service/manage.mjs +542 -0
  176. package/src/service/mutations.mjs +860 -0
  177. package/src/service/read-model.mjs +1557 -0
  178. package/src/service/server.mjs +783 -0
  179. package/src/tasks/categories.mjs +154 -0
  180. package/src/tasks/derive.mjs +977 -0
  181. package/src/tasks/lifecycle.mjs +830 -0
  182. package/src/verify/index.mjs +236 -0
@@ -0,0 +1,264 @@
1
+ // What a lifecycle hook can actually drive, per harness, and what to run when it
2
+ // cannot. Brief section 12.6.
3
+ //
4
+ // This file exists because the failure it prevents is silent. A harness that
5
+ // looks like it is tracking work and is not leaves a project whose records stop
6
+ // matching reality without anyone being told. So every entry below states what
7
+ // was verified rather than what would be convenient, and every lifecycle point
8
+ // names the explicit command that achieves the same outcome with no hook at all.
9
+ //
10
+ // The governing rule: correctness never depends on a hook firing. A hook is an
11
+ // accelerator. The command is the contract.
12
+
13
+ /**
14
+ * Events Superdev wires in hooks/hooks.json. Kept here so the matrix and the
15
+ * wiring cannot drift apart: anything claimed as hook-driven below must appear
16
+ * in this list.
17
+ */
18
+ export const WIRED_EVENTS = [
19
+ "SessionStart", "UserPromptSubmit", "PostToolUse", "PreCompact", "SessionEnd",
20
+ ];
21
+
22
+ /**
23
+ * Named in Claude Code's own event registry but deliberately not wired.
24
+ * PreToolUse is omitted because Superdev never blocks a tool call: hooks here
25
+ * are development automation, never a permission boundary, and paying a process
26
+ * launch before every tool call buys nothing.
27
+ */
28
+ export const AVAILABLE_BUT_UNWIRED = [
29
+ { event: "PreToolUse", why: "Superdev never blocks or rewrites a tool call, so there is nothing for it to do." },
30
+ { event: "Stop", why: "A completion nag is not verification. Completion runs through superdev task complete, which checks evidence." },
31
+ { event: "SubagentStop", why: "Same as Stop, and a subagent shares the parent session's records." },
32
+ { event: "Notification", why: "Nothing in the lifecycle depends on a notification." },
33
+ ];
34
+
35
+ /**
36
+ * Events referenced by earlier Superdev versions with no first-party source.
37
+ * `PostToolBatch` was Superdev's only canonical-write path for a while, which
38
+ * means that path may never have fired. Nothing may depend on it again.
39
+ */
40
+ export const UNVERIFIED_EVENTS = [
41
+ {
42
+ event: "PostToolBatch",
43
+ finding: "Not in Claude Code's documented event list (re-verified 2026-07-27, CLI 2.1.220). Found only in Superdev's own files and one third-party plugin.",
44
+ consequence: "src/runtime/hooks.mjs still answers post-tool-batch so that a harness which does emit it behaves correctly, but hooks.json does not wire it and no lifecycle point is credited to it.",
45
+ },
46
+ ];
47
+
48
+ const HARNESSES = [
49
+ {
50
+ harness: "claude-code",
51
+ mechanism: "hooks/hooks.json in the plugin, per-hook timeout field, loaded without further approval",
52
+ hooks: "supported",
53
+ note: "Lifecycle hooks fire. Superdev still verifies state from the database rather than trusting that a hook ran.",
54
+ },
55
+ {
56
+ harness: "codex",
57
+ mechanism: "hooks/hooks.json in a plugin is discovered, but each hook needs per-hook hash trust before it runs",
58
+ hooks: "partial",
59
+ note: "Only PreToolUse for shell commands has been verified to fire. No session-lifecycle event has been observed, and a freshly installed Superdev has no trusted hooks at all, so every lifecycle point below is treated as command-driven on Codex until a first-party source says otherwise.",
60
+ },
61
+ {
62
+ harness: "skills-sh",
63
+ mechanism: "none",
64
+ hooks: "none",
65
+ note: "skills.sh has no hook mechanism at all. There is nothing to install a hook into, so a Superdev skill installed there gets no session context, no dirty marking and no handoff persistence. Every lifecycle point is driven by an explicit command run by the orchestrator.",
66
+ },
67
+ ];
68
+
69
+ /**
70
+ * Coverage states, strongest first.
71
+ *
72
+ * `hook` the hook performs the work and the record is written without a person.
73
+ * `prompt` a hook can inject the requirement into context, but the work is a
74
+ * judgement call and the command still has to run. Reminding is not doing.
75
+ * `command` no hook contributes anything. The command is the only path.
76
+ */
77
+ const HOOK = (event, note) => ({ state: "hook", event, note });
78
+ const PROMPT = (event, note) => ({ state: "prompt", event, note });
79
+ const COMMAND = (note) => ({ state: "command", event: null, note });
80
+
81
+ const CODEX_UNTRUSTED =
82
+ "Untrusted or unverified on Codex. Run the command.";
83
+ const SKILLS_NONE =
84
+ "No hook mechanism exists here. Run the command.";
85
+
86
+ const codex = () => COMMAND(CODEX_UNTRUSTED);
87
+ const skills = () => COMMAND(SKILLS_NONE);
88
+
89
+ /** The sixteen points a tracked unit of work passes through. Brief 12.1 to 12.5. */
90
+ const LIFECYCLE = [
91
+ {
92
+ id: "session-start",
93
+ point: "Session start",
94
+ what: "Detect the root, verify the schema revision, identify developer, agent, branch and worktree, find any active assignment, and inject the context report.",
95
+ command: "superdev resume",
96
+ detail: "Prints the same report the hook injects and starts or rejoins the work session.",
97
+ claudeCode: HOOK("SessionStart", "Runs on startup, resume, clear and compact."),
98
+ },
99
+ {
100
+ id: "task-lookup",
101
+ point: "Task lookup or creation",
102
+ what: "Find an existing task for the requested work, or open a draft one.",
103
+ command: "superdev task create",
104
+ detail: "Search first with superdev status; create only when nothing matches.",
105
+ claudeCode: PROMPT("UserPromptSubmit", "The hook can state the requirement, but matching a request to a task is judgement. No hook can do it."),
106
+ },
107
+ {
108
+ id: "contract-mapping",
109
+ point: "Feature and contract mapping",
110
+ what: "Link the task to a feature and to a workflow step or contract, or mark it enabling against a named feature.",
111
+ command: "superdev task update",
112
+ detail: "A task with no contract link is refused at claim time with E_TASK_WITHOUT_CONTRACT, so this cannot be skipped quietly.",
113
+ claudeCode: PROMPT("UserPromptSubmit", "The hook injects the rule. The link is a modelling decision and stays with the command."),
114
+ },
115
+ {
116
+ id: "decision-check",
117
+ point: "Decision check",
118
+ what: "Read the accepted and time-boxed decisions that constrain this work before writing code.",
119
+ command: "superdev resume",
120
+ detail: "Governing decisions are part of the resume context; superdev status shows them project wide.",
121
+ claudeCode: PROMPT("SessionStart", "Session start injects the decisions in force. Applying one to the work at hand is not hookable."),
122
+ },
123
+ {
124
+ id: "claim",
125
+ point: "Claim",
126
+ what: "Take the task for this developer, agent, branch and session.",
127
+ command: "superdev task claim",
128
+ detail: "A partial unique index makes a second active claim impossible, hook or no hook.",
129
+ claudeCode: COMMAND("No Claude Code event corresponds to taking ownership of work."),
130
+ },
131
+ {
132
+ id: "start",
133
+ point: "Start",
134
+ what: "Move the claimed task to in progress and stamp started_at.",
135
+ command: "superdev task update",
136
+ detail: "Set the status to in_progress. The transition is written to status_history either way.",
137
+ claudeCode: COMMAND("No event marks the moment implementation begins."),
138
+ },
139
+ {
140
+ id: "activity",
141
+ point: "Activity update",
142
+ what: "Record meaningful progress at natural boundaries, and refresh branch HEAD and dirty state.",
143
+ command: "superdev task update",
144
+ detail: "Records one activity event with a summary a human would want to read.",
145
+ claudeCode: HOOK("PostToolUse", "Fires after Write, Edit and NotebookEdit. It accumulates touched paths and appends at most one activity event per interval, never one per file."),
146
+ },
147
+ {
148
+ id: "scope-change",
149
+ point: "Scope-change correction",
150
+ what: "When the work outgrows the accepted scope, update the specification first, then regenerate the task delta.",
151
+ command: "superdev plan",
152
+ detail: "Edit the feature, run superdev plan for the delta, then superdev task update to accept it. Never widen a task silently.",
153
+ claudeCode: COMMAND("Detecting that work has left its accepted scope needs the specification, not a tool call."),
154
+ },
155
+ {
156
+ id: "block",
157
+ point: "Block and unblock",
158
+ what: "Record a blocker the moment it appears, with a reason, and clear it when it is gone.",
159
+ command: "superdev task block",
160
+ detail: "Blocking needs a reason. Unblock with superdev task update by setting the status back to ready or in_progress.",
161
+ claudeCode: COMMAND("A failing command is not a blocker. Only the agent knows which is which."),
162
+ },
163
+ {
164
+ id: "verification",
165
+ point: "Verification",
166
+ what: "Run the product's required verification and attach the evidence to the task.",
167
+ command: "superdev task update",
168
+ detail: "Attach the evidence type, summary, reference and result. Completion reads this, so an unverified task cannot be completed.",
169
+ claudeCode: COMMAND("A Stop hook could nag, which is not the same as verifying. It is deliberately not wired."),
170
+ },
171
+ {
172
+ id: "completion",
173
+ point: "Completion",
174
+ what: "Complete the task, check acceptance criteria, mark changed contracts and recalculate parent progress.",
175
+ command: "superdev task complete",
176
+ detail: "Refuses on open subtasks (E_OPEN_SUBTASKS) or missing evidence, hook or no hook.",
177
+ claudeCode: COMMAND("No event means done. Done is a claim that has to be checked against evidence."),
178
+ },
179
+ {
180
+ id: "release",
181
+ point: "Release",
182
+ what: "Give up the claim so the task is available again.",
183
+ command: "superdev task release",
184
+ detail: "Needed mid-session. At session end the claim is released automatically by the session-end path.",
185
+ claudeCode: HOOK("SessionEnd", "Only covers release at the end of a session. A mid-session release is command-only."),
186
+ },
187
+ {
188
+ id: "compaction",
189
+ point: "Compaction",
190
+ what: "Persist objective, active task and feature, last verified result, branch and HEAD, decisions, blockers, scope changes, pending documentation and the exact next action before context is discarded.",
191
+ command: "superdev task update",
192
+ detail: "The command surface in brief 14.1 has no session-boundary verb. Record the outcome and next action on the active task, then call compactSession in src/runtime/session.mjs directly.",
193
+ claudeCode: HOOK("PreCompact", "Writes the whole 12.5 packet to the database before the transcript is compacted."),
194
+ },
195
+ {
196
+ id: "handoff",
197
+ point: "Handoff",
198
+ what: "Close the session with a note for whoever picks the work up, and release what it held.",
199
+ command: "superdev task release",
200
+ detail: "Release the claim and record the next action on the task. handoffSession in src/runtime/session.mjs writes the full packet when a named handoff is wanted.",
201
+ claudeCode: HOOK("SessionEnd", "Persists the packet and releases the claim. A handoff addressed to a named person still needs the explicit call."),
202
+ },
203
+ {
204
+ id: "resume",
205
+ point: "Resume",
206
+ what: "Rebuild working context for a new agent from records rather than from conversation.",
207
+ command: "superdev resume",
208
+ detail: "Reads everything from the database. It never needs a previous transcript.",
209
+ claudeCode: HOOK("SessionStart", "Also fires with source compact, so context returns immediately after compaction."),
210
+ },
211
+ {
212
+ id: "session-end",
213
+ point: "Session end",
214
+ what: "Close the session, write its outcome and next action, release assignments and mark the agent ended.",
215
+ command: "superdev task release",
216
+ detail: "Releases the claim. endSession in src/runtime/session.mjs closes the session record itself.",
217
+ claudeCode: HOOK("SessionEnd", "Fires on clear, logout and normal exit. It is not guaranteed on a killed process, which is why nothing depends on it alone."),
218
+ },
219
+ ];
220
+
221
+ /**
222
+ * The honest coverage matrix.
223
+ *
224
+ * Read it as: for this lifecycle point, on this harness, does a hook do the work
225
+ * (`hook`), does a hook only remind (`prompt`), or is the command the only path
226
+ * (`command`)? Every row carries a command, including the rows a hook covers,
227
+ * because a hook that did not fire has to be indistinguishable from one that
228
+ * never existed.
229
+ */
230
+ export function harnessMatrix() {
231
+ const lifecycle = LIFECYCLE.map((entry) => ({
232
+ id: entry.id,
233
+ point: entry.point,
234
+ what: entry.what,
235
+ fallback: { command: entry.command, detail: entry.detail },
236
+ coverage: {
237
+ "claude-code": entry.claudeCode,
238
+ codex: codex(),
239
+ "skills-sh": skills(),
240
+ },
241
+ }));
242
+
243
+ return {
244
+ rule: "Correctness must not depend solely on a hook firing. Every lifecycle point below names the explicit command that achieves the same thing when no hook is available, and the database is the authority in both cases.",
245
+ harnesses: HARNESSES.map((h) => ({
246
+ ...h,
247
+ // Counted rather than asserted, so the headline can never claim more
248
+ // coverage than the rows underneath it actually carry.
249
+ hookDriven: lifecycle.filter((l) => l.coverage[h.harness].state === "hook").length,
250
+ promptOnly: lifecycle.filter((l) => l.coverage[h.harness].state === "prompt").length,
251
+ commandOnly: lifecycle.filter((l) => l.coverage[h.harness].state === "command").length,
252
+ of: lifecycle.length,
253
+ })),
254
+ lifecycle,
255
+ wiredEvents: WIRED_EVENTS,
256
+ availableButUnwired: AVAILABLE_BUT_UNWIRED,
257
+ unverifiedEvents: UNVERIFIED_EVENTS,
258
+ gaps: [
259
+ "Brief 14.1 lists no session-boundary command. Compaction, handoff and session end are hook-driven on Claude Code and are otherwise called directly through compactSession, handoffSession and endSession in src/runtime/session.mjs. Naming that here is better than implying a command that does not exist.",
260
+ "Claim, start, verification and completion have no corresponding event on any harness. They are decisions, not observable side effects, so no hook could drive them honestly.",
261
+ "Codex hook trust is per-hook and hash-based, so a Superdev upgrade invalidates it. Assume no Codex hook is running until the doctor reports otherwise.",
262
+ ],
263
+ };
264
+ }