@gobing-ai/spur 0.4.2 → 0.4.4

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 (168) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/decisions/maker-liveness.yaml +39 -0
  3. package/config/plugin-scripts.json +0 -4
  4. package/config/rules/README.md +1 -0
  5. package/config/rules/docs/sourced-api-claims.yaml +56 -12
  6. package/config/rules/docs/verdict-confidence.yaml +68 -0
  7. package/config/rules/quality/coverage-gate.yaml +13 -0
  8. package/config/rules/recommended-pre-check.yaml +6 -2
  9. package/config/rules/strict/runtime-boundaries.yaml +10 -0
  10. package/config/rules/surface/check-cli-surface.yaml +1 -3
  11. package/config/script-placement-baseline.json +1 -19
  12. package/config/templates/AGENTS.md +7 -0
  13. package/config/workflows/feature-lifecycle.yaml +46 -1
  14. package/config/workflows/feature-verification.yaml +20 -1
  15. package/config/workflows/task-lifecycle.yaml +50 -0
  16. package/config/workflows/task-pipeline.yaml +15 -9
  17. package/package.json +10 -10
  18. package/plugins/sp/README.md +22 -16
  19. package/plugins/sp/agents/super-reviewer.md +46 -0
  20. package/plugins/sp/bunfig.toml +8 -5
  21. package/plugins/sp/commands/dev-changelog.md +1 -1
  22. package/plugins/sp/commands/dev-gitmsg.md +6 -2
  23. package/plugins/sp/commands/dev-handover.md +1 -0
  24. package/plugins/sp/commands/dev-job-dump.md +2 -1
  25. package/plugins/sp/commands/dev-refine.md +14 -2
  26. package/plugins/sp/commands/dev-refineall.md +7 -1
  27. package/plugins/sp/commands/dev-review.md +1 -0
  28. package/plugins/sp/hooks/careful-guard.ts +1 -1
  29. package/plugins/sp/hooks/context-post-tool.ts +7 -427
  30. package/plugins/sp/hooks/context-session-start.ts +5 -213
  31. package/plugins/sp/hooks/context-session-stop.ts +5 -191
  32. package/plugins/sp/hooks/pi/guard-extension.ts +6 -5
  33. package/plugins/sp/hooks/task-write-guard.ts +1 -1
  34. package/plugins/sp/{hooks → lib}/agent-hint.ts +1 -1
  35. package/plugins/sp/lib/context-post-tool.ts +432 -0
  36. package/plugins/sp/lib/context-session-start.ts +214 -0
  37. package/plugins/sp/lib/context-session-stop.ts +196 -0
  38. package/plugins/sp/lib/dogfood-pipeline.ts +265 -0
  39. package/plugins/sp/lib/dogfood-report.ts +278 -0
  40. package/plugins/sp/lib/history-anatomy.generated.mjs +18 -18
  41. package/plugins/sp/lib/idea-handoff.generated.mjs +91 -91
  42. package/plugins/sp/lib/inline-run-app.ts +40 -0
  43. package/plugins/sp/lib/inline-run.generated.d.mts +3 -3
  44. package/plugins/sp/lib/inline-run.generated.mjs +1425 -212
  45. package/plugins/sp/lib/plan-projection.generated.d.mts +150 -0
  46. package/plugins/sp/lib/plan-projection.generated.mjs +623 -9
  47. package/plugins/sp/lib/quality-gate.generated.d.mts +1 -0
  48. package/plugins/sp/lib/quality-gate.generated.mjs +13809 -13969
  49. package/plugins/sp/lib/residual-scan.generated.d.mts +20 -1
  50. package/plugins/sp/lib/residual-scan.generated.mjs +120 -25
  51. package/plugins/sp/lib/run-summary-core.ts +34 -370
  52. package/plugins/sp/lib/step-profile.generated.mjs +8 -8
  53. package/plugins/sp/lib/transcript.ts +37 -228
  54. package/plugins/sp/plugin.json +1 -1
  55. package/plugins/sp/scripts/batch-plan.mjs +619 -11
  56. package/plugins/sp/scripts/batch-preflight.mjs +57 -13
  57. package/plugins/sp/scripts/batch-preflight.ts +35 -295
  58. package/plugins/sp/scripts/commit-guard.mjs +6 -6
  59. package/plugins/sp/scripts/daily-summary/daily-summary.mjs +127 -108
  60. package/plugins/sp/scripts/daily-summary/daily-summary.ts +111 -104
  61. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +13 -12
  62. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +7 -265
  63. package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +7 -4
  64. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +6 -272
  65. package/plugins/sp/scripts/feature-verification-steps.mjs +20 -125
  66. package/plugins/sp/scripts/feature-verification-steps.ts +57 -181
  67. package/plugins/sp/scripts/history-anatomy-cache.mjs +19 -19
  68. package/plugins/sp/scripts/idea-handoff.mjs +2 -2
  69. package/plugins/sp/scripts/inline-run-dispatch.mjs +25 -24
  70. package/plugins/sp/scripts/inline-run-dispatch.ts +1 -21
  71. package/plugins/sp/scripts/inline-run-setup.mjs +164 -137
  72. package/plugins/sp/scripts/inline-run-setup.ts +1 -21
  73. package/plugins/sp/scripts/persist-out-check.mjs +5 -5
  74. package/plugins/sp/scripts/pr-reviewing.mjs +13 -13
  75. package/plugins/sp/scripts/quality-gate.mjs +13730 -13887
  76. package/plugins/sp/scripts/residual-scan.mjs +129 -31
  77. package/plugins/sp/scripts/residual-scan.ts +16 -13
  78. package/plugins/sp/scripts/run-summary.mjs +166 -112
  79. package/plugins/sp/scripts/run-summary.ts +7 -5
  80. package/plugins/sp/scripts/script-root.mjs +6 -6
  81. package/plugins/sp/scripts/session-timeline.mjs +62 -35
  82. package/plugins/sp/scripts/task-diffstat.mjs +19 -9
  83. package/plugins/sp/scripts/task-diffstat.ts +8 -39
  84. package/plugins/sp/scripts/workflow-step-profile.mjs +12 -12
  85. package/plugins/sp/scripts/wrapup-drift-probe.mjs +9 -9
  86. package/plugins/sp/scripts/wrapup-steps.mjs +25 -25
  87. package/plugins/sp/skills/code-implementation/SKILL.md +7 -1
  88. package/plugins/sp/skills/code-verification/references/secu-review.md +2 -1
  89. package/plugins/sp/skills/code-verification/references/verdict-schema.md +4 -0
  90. package/plugins/sp/skills/dogfood-testing/SKILL.md +2 -2
  91. package/plugins/sp/skills/next-feature/SKILL.md +1 -1
  92. package/plugins/sp/skills/next-router/SKILL.md +3 -1
  93. package/plugins/sp/skills/next-router/references/routing-table.md +9 -3
  94. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
  95. package/plugins/sp/skills/source-driven-development/SKILL.md +7 -4
  96. package/plugins/sp/skills/spur-cli/references/builder.md +3 -2
  97. package/plugins/sp/skills/spur-cli/references/decision.md +32 -7
  98. package/plugins/sp/skills/spur-cli/references/features.md +46 -5
  99. package/plugins/sp/skills/spur-cli/references/tasks.md +24 -4
  100. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +8 -1
  101. package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -11
  102. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +1 -1
  103. package/plugins/sp/skills/spur-dev/references/execution-batch.md +19 -6
  104. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +22 -0
  105. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +14 -0
  106. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +4 -2
  107. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +49 -12
  108. package/schemas/section-matrix.schema.json +3 -2
  109. package/spur.js +66591 -73262
  110. package/web/_astro/{BoardApp.B3GQZvj8.js → BoardApp.Niubpe6z.js} +1 -1
  111. package/web/_astro/{BoardApp.BT7L2kSb.js → BoardApp.hF0RAIrg.js} +150 -150
  112. package/web/_astro/TaskDetail.DJpapt38.js +1 -0
  113. package/web/_astro/{arc.vaT7tPOB.js → arc.BgKcK0i8.js} +1 -1
  114. package/web/_astro/{architectureDiagram-3BPJPVTR.DRMmTjkN.js → architectureDiagram-3BPJPVTR.ChP-Ig0V.js} +1 -1
  115. package/web/_astro/{blockDiagram-GPEHLZMM.cla0LO_q.js → blockDiagram-GPEHLZMM.BVaCBoeN.js} +1 -1
  116. package/web/_astro/{c4Diagram-AAUBKEIU.D4YAIBKn.js → c4Diagram-AAUBKEIU.CHSDpEO5.js} +1 -1
  117. package/web/_astro/channel.DkpvN2tD.js +1 -0
  118. package/web/_astro/{chunk-2J33WTMH.BrSJbMRZ.js → chunk-2J33WTMH.MYRcYVRa.js} +1 -1
  119. package/web/_astro/{chunk-4BX2VUAB.CuLMgKF5.js → chunk-4BX2VUAB.S5j22Zqa.js} +1 -1
  120. package/web/_astro/{chunk-55IACEB6.zkvgu54F.js → chunk-55IACEB6.gciRPvmZ.js} +1 -1
  121. package/web/_astro/{chunk-727SXJPM.DxWkACh8.js → chunk-727SXJPM.CdqrSQkX.js} +1 -1
  122. package/web/_astro/{chunk-AQP2D5EJ.42XrmIlH.js → chunk-AQP2D5EJ.CyokdHT3.js} +1 -1
  123. package/web/_astro/{chunk-FMBD7UC4.Bao2wMK9.js → chunk-FMBD7UC4.Bg9KJhjW.js} +1 -1
  124. package/web/_astro/{chunk-ND2GUHAM.BhydojD1.js → chunk-ND2GUHAM.1gxxI-vD.js} +1 -1
  125. package/web/_astro/{chunk-QZHKN3VN.CmZ82g-H.js → chunk-QZHKN3VN.DDEYtCKU.js} +1 -1
  126. package/web/_astro/{classDiagram-4FO5ZUOK.Blr83Gt_.js → classDiagram-4FO5ZUOK.Ch3zi37T.js} +1 -1
  127. package/web/_astro/{classDiagram-v2-Q7XG4LA2.Blr83Gt_.js → classDiagram-v2-Q7XG4LA2.Ch3zi37T.js} +1 -1
  128. package/web/_astro/{cose-bilkent-S5V4N54A.qmfv0SPn.js → cose-bilkent-S5V4N54A.D2q5AINI.js} +1 -1
  129. package/web/_astro/{cynefin-OW5HDTMX.BtELhXPR.js → cynefin-OW5HDTMX.BA9kC2YT.js} +1 -1
  130. package/web/_astro/{dagre-BM42HDAG.AWmaAvXo.js → dagre-BM42HDAG.CHO08nRp.js} +1 -1
  131. package/web/_astro/{diagram-2AECGRRQ.DdH34KDi.js → diagram-2AECGRRQ.BfFQt0LW.js} +1 -1
  132. package/web/_astro/{diagram-5GNKFQAL.BmNPix1k.js → diagram-5GNKFQAL.CHMwMTe4.js} +1 -1
  133. package/web/_astro/{diagram-KO2AKTUF.BNQd_Ppo.js → diagram-KO2AKTUF.BJ-7gK-w.js} +1 -1
  134. package/web/_astro/{diagram-LMA3HP47.BAPgDi0e.js → diagram-LMA3HP47.C5xqcc0t.js} +1 -1
  135. package/web/_astro/{diagram-OG6HWLK6.DZ4zyLdC.js → diagram-OG6HWLK6.C2pQjfrC.js} +1 -1
  136. package/web/_astro/{erDiagram-TEJ5UH35.Q1TySMmw.js → erDiagram-TEJ5UH35._FoNyxgC.js} +1 -1
  137. package/web/_astro/{flowDiagram-I6XJVG4X.BXhFBicG.js → flowDiagram-I6XJVG4X.B_ENkT2I.js} +1 -1
  138. package/web/_astro/{ganttDiagram-6RSMTGT7.vHSgcuo2.js → ganttDiagram-6RSMTGT7.B3q8h77C.js} +1 -1
  139. package/web/_astro/{gitGraphDiagram-PVQCEYII.Bi1f73C7.js → gitGraphDiagram-PVQCEYII.QWZFDboZ.js} +1 -1
  140. package/web/_astro/index.BFyW13JJ.css +1 -0
  141. package/web/_astro/{infoDiagram-5YYISTIA.DPvXZEWm.js → infoDiagram-5YYISTIA.Cs6eEc92.js} +1 -1
  142. package/web/_astro/{ishikawaDiagram-YF4QCWOH.Cz829fsV.js → ishikawaDiagram-YF4QCWOH.BU9DJMHA.js} +1 -1
  143. package/web/_astro/{journeyDiagram-JHISSGLW.enRnB9Me.js → journeyDiagram-JHISSGLW.D35k6Jpe.js} +1 -1
  144. package/web/_astro/{kanban-definition-UN3LZRKU.DnTNk6d2.js → kanban-definition-UN3LZRKU.DBqcAT4m.js} +1 -1
  145. package/web/_astro/{linear.BzGnBwNL.js → linear.D-LSNK8W.js} +1 -1
  146. package/web/_astro/{mermaid.core.CSbTpIVz.js → mermaid.core.CSruWVOa.js} +4 -4
  147. package/web/_astro/{mindmap-definition-RKZ34NQL.DGJDy8zT.js → mindmap-definition-RKZ34NQL.BiFaUsfj.js} +1 -1
  148. package/web/_astro/{pieDiagram-4H26LBE5.HSPdi5_8.js → pieDiagram-4H26LBE5.D1KTKqb9.js} +1 -1
  149. package/web/_astro/{quadrantDiagram-W4KKPZXB.6Gv8mz2Y.js → quadrantDiagram-W4KKPZXB.DBHflsMG.js} +1 -1
  150. package/web/_astro/{requirementDiagram-4Y6WPE33.CnBCtFwa.js → requirementDiagram-4Y6WPE33.hwX9CNdk.js} +1 -1
  151. package/web/_astro/{sankeyDiagram-5OEKKPKP.5M8VWAu8.js → sankeyDiagram-5OEKKPKP.DkI8mJiE.js} +1 -1
  152. package/web/_astro/{sequenceDiagram-3UESZ5HK.DN41XN-U.js → sequenceDiagram-3UESZ5HK.DMz7jBDx.js} +1 -1
  153. package/web/_astro/{stateDiagram-AJRCARHV.ErOO3W8j.js → stateDiagram-AJRCARHV.B6Ef2xJ1.js} +1 -1
  154. package/web/_astro/{stateDiagram-v2-BHNVJYJU.B_ZHICM-.js → stateDiagram-v2-BHNVJYJU.CgoaufB9.js} +1 -1
  155. package/web/_astro/{timeline-definition-PNZ67QCA.CWdosr07.js → timeline-definition-PNZ67QCA.B3c8h1t-.js} +1 -1
  156. package/web/_astro/{vennDiagram-CIIHVFJN.BHzYjNV5.js → vennDiagram-CIIHVFJN.BdHPAxAb.js} +1 -1
  157. package/web/_astro/{wardleyDiagram-YWT4CUSO.h8x4IwPX.js → wardleyDiagram-YWT4CUSO.BrJXPPAj.js} +1 -1
  158. package/web/_astro/{xychartDiagram-2RQKCTM6.RTapW2X8.js → xychartDiagram-2RQKCTM6.CMH5yFsV.js} +1 -1
  159. package/web/index.html +2 -2
  160. package/web/spur_logo.svg +1 -1
  161. package/config/proportional-route-table.ts +0 -155
  162. package/plugins/sp/scripts/daily-summary/logger.ts +0 -28
  163. package/web/_astro/TaskDetail.Cxov1_N_.js +0 -1
  164. package/web/_astro/channel.D4nG9YLf.js +0 -1
  165. package/web/_astro/index.BhSwN8yY.css +0 -1
  166. /package/plugins/sp/{hooks → lib}/context-owner.ts +0 -0
  167. /package/plugins/sp/{hooks → lib}/destructive-policy.ts +0 -0
  168. /package/plugins/sp/{hooks → lib}/task-file-policy.ts +0 -0
@@ -441,9 +441,9 @@ Action semantics come from the YAML and the workflow action contract:
441
441
  recheck's `no-progress` guard honours it, so a cap-kill reads as a red gate the next time. Preserve
442
442
  the signal-induced receipt under a distinct name (`<wbs>-check-receipt.false-fail-<signal>.json`)
443
443
  and say so in the run log before re-running: never delete it silently, and never report a
444
- cap-killed attempt as a genuine gate failure. Measured this session: one foreground gate call
445
- (25.6 min host-wide lock wait + 7.4 min runtime) was SIGTERM-killed at the host cap and produced
446
- exactly that false FAIL receipt.
444
+ cap-killed attempt as a genuine gate failure. Measured 2026-10-10 (before the gate-lock removal):
445
+ one foreground gate call (25.6 min host-wide lock wait + 7.4 min runtime) was SIGTERM-killed at the
446
+ host cap and produced exactly that false FAIL receipt.
447
447
  - `note` — append the expanded message to the inline run log.
448
448
  - `doctor.probe` — run the declared Spur doctor once, persist its status file, and apply any
449
449
  `setVars` result (including a resolved executor) before the next action or state.
@@ -766,7 +766,7 @@ host-owned gate sat between the stages, or when the platform cannot address comp
766
766
  **Implement and test-fix workers never run the full gate (task 1142 R3).** Workers use the light tier as their iteration check (task 1142 R3) in exact order:
767
767
  1. the **changed-path matrix** (`code-implementation/SKILL.md` § Changed-path targeted checks) over the paths they touched;
768
768
  2. the resolved `quality-gate` script in `light` mode (source-repo probe, else the installed twin) (biome, per-workspace typecheck, rule presets, related tests).
769
- Neither step takes the full-gate lock. The pipeline's `test` and `test-recheck` hops remain the only full gate. Carry
769
+ Neither step takes the full gate. The pipeline's `test` and `test-recheck` hops remain the only full gate. Carry
770
770
  `--gate-log <path>` through to the child **verbatim**: never paraphrase it into "re-run the named
771
771
  gate command". That paraphrase is not cosmetic — it sent a worker into a full gate run instead of
772
772
  targeted iteration checks. The pipeline's next `test` (recheck)
@@ -835,6 +835,19 @@ The quality gate's `proofDigest` certifies a specific tree. Two rules protect it
835
835
  before a review dispatch is spent. The mismatch routes through the existing tripwire to `failed`;
836
836
  there is no new re-certify path.
837
837
 
838
+ **A host-driven pass that skips the `test` hop has no digest-bound receipt.** `proofDigest` is
839
+ captured by the `test` state's `proof.fingerprint` action, so hops driven out of band — an operator
840
+ implementing/verifying/recording by hand, or an audit of a task whose gate the host ran directly —
841
+ leave no `.spur/run/<wbs>-check-receipt.json`. The deciding artifacts are then
842
+ `.spur/run/<wbs>-test-gate.status` plus its gate log. Two consequences, in order of preference:
843
+
844
+ 1. **Drive the pipeline** for anything that must be certified: only a digest-bound full receipt
845
+ satisfies a review/verify/record boundary (`sp-spur-check`), and the `test` hop owns the capture.
846
+ 2. **When a host-driven pass is unavoidable, say so in the verdict** — name the status file and gate
847
+ log as the evidence and grade confidence `MEDIUM`. A `HIGH` claim needs re-runnable evidence from a
848
+ checked path (the `sp-code-verification` ladder); claiming a receipt that was never written is the
849
+ failure mode this note exists to prevent (observed across four A91 tasks, 2026-10-12).
850
+
838
851
  **A mismatch names the drifted paths (R5).** At gate entry the pipeline snapshots the non-corpus tree
839
852
  state (`git status --porcelain=v1 -uall` plus `git diff --name-only HEAD`, excluding
840
853
  `docs/tasks*` / `docs/features*`) into `.spur/run/<run-id>-gate-paths.txt`. On a mismatch the
@@ -909,21 +922,45 @@ verdict artifact exists (tasks 0617, 0619 — the clobbering spiral).
909
922
 
910
923
  ## Running the full gate (task 0872 / 1127 R7)
911
924
 
912
- The full gate serializes behind a host-wide lock and legitimately runs 10-25 minutes. Two rules keep
913
- it from becoming a hazard (both violated once on 2026-10-10, blocking every other session for ~11
914
- minutes and aborting the run's own verification):
925
+ The full gate legitimately runs minutes, not seconds — measured 1.8-3.1 min for `bun run spur-check`
926
+ on an idle 10-core host (2026-10-13), and far longer when other agents' suites run concurrently.
927
+ Five rules keep it from becoming a hazard (the first two
928
+ were both violated once on 2026-10-10, aborting the run's own verification):
915
929
 
916
930
  - **Never wrap it in an external `timeout`, and never treat its runtime as a hang.** An outer bound
917
- that fires mid-suite leaves the holder alive holding the lock while the caller believes it is gone.
918
- - **Run it detached and poll the log**, so losing the foreground call cannot lose the holder:
931
+ that fires mid-suite leaves a half-finished suite behind while the caller believes it is gone.
932
+ - **Run it detached and poll the log**, so losing the foreground call cannot lose the run:
919
933
 
920
934
  ```bash
921
935
  nohup bash -c 'bun run spur-check > /tmp/gate.log 2>&1; echo "EXIT=$?" >> /tmp/gate.log' &
922
936
  ```
923
937
 
924
- - **Never kill a gate holder whose pid is alive.** The waiter line `waiting for holder (… held Nms)`
925
- is printed only after `isProcessAlive(held.claim.pid)` succeeded, so a printed holder is a live one
926
- by construction; only the lock's own dead-pid reclaim is authorised to clear a claim.
938
+ - **Preserve a signal-induced receipt.** A cap-killed attempt leaves a red receipt that the next
939
+ recheck's `no-progress` guard honours, so it reads as a genuine failure unless the receipt is kept
940
+ under a distinct name and the run log says so.
941
+ - **Clear the killed attempt's process tree before re-running.** A cap-signalled gate leaves its
942
+ `bun test --test-worker` children alive: the parent dies, the workers keep burning ~100% CPU, and
943
+ each retry is slower than the last until the cap kills that one too and mints another leak.
944
+ Observed 2026-10-13: five leaked workers (ages 23 min, 37 min, 50 min, 2 h 17 m, 4 h 18 m) drove
945
+ consecutive attempts from the measured 1.8-3.1 min up to 13-40 min, and the real defect of the
946
+ session only became visible once they were cleared. Find them by age and cwd, then clear the tree
947
+ before the next run; leave a tree alone whose cwd is another session's live run:
948
+
949
+ ```bash
950
+ ps -Ao pid=,ppid=,etime=,%cpu=,command= | grep -E "run-tests\.ts|bun test --test-worker" | grep -v grep
951
+ kill -TERM <pid> <ppid>; sleep 4; kill -KILL <pid> <ppid> # escalate only if TERM is ignored
952
+ ```
953
+
954
+ - **One gate per tree.** Nothing serializes gate runs since task 1173 deleted the lock, so confirm
955
+ no live gate is already running in your tree before starting one: two suites in one tree contend
956
+ for CPU and for the shared fixtures, and the second one's result is uninterpretable. Measured
957
+ 2026-10-13: a duplicate gate launched into a tree already running another session's
958
+ `bun run spur-check` burned 40 min at the host cap and left an orphaned worker behind.
959
+
960
+ > Historical (task 1127, removed in task 1173): these rules were once stated in terms of a host-wide
961
+ > `full-gate.lock`. The lock mechanism was deleted (`refactor(gate): remove gate-lock mechanism and
962
+ > simplify quality-gate`), so nothing serializes gate runs today — the guidance above stands on its
963
+ > own without it.
927
964
 
928
965
  ## Runtime interface contracts (from run evidence)
929
966
 
@@ -53,7 +53,7 @@
53
53
  "variant": {
54
54
  "type": "object",
55
55
  "additionalProperties": false,
56
- "description": "A variant may declare any subset of the 7 canonical statuses (enumerated below); an unknown status key is rejected.",
56
+ "description": "A variant may declare any subset of the 8 canonical statuses (enumerated below); an unknown status key is rejected.",
57
57
  "properties": {
58
58
  "backlog": { "$ref": "#/$defs/entry" },
59
59
  "todo": { "$ref": "#/$defs/entry" },
@@ -61,7 +61,8 @@
61
61
  "testing": { "$ref": "#/$defs/entry" },
62
62
  "blocked": { "$ref": "#/$defs/entry" },
63
63
  "done": { "$ref": "#/$defs/entry" },
64
- "cancelled": { "$ref": "#/$defs/entry" }
64
+ "cancelled": { "$ref": "#/$defs/entry" },
65
+ "deprecated": { "$ref": "#/$defs/entry" }
65
66
  }
66
67
  }
67
68
  }