@gobing-ai/spur 0.4.8 → 0.4.10
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/pipeline-budgets.json +2 -2
- package/config/rules/README.md +1 -1
- package/config/rules/boundary/config-loading-ownership.yaml +1 -0
- package/config/rules/boundary/env-var-hygiene.yaml +0 -1
- package/config/rules/boundary/sp-plugin-standalone.yaml +1 -1
- package/config/rules/boundary/sp-script-placement.yaml +3 -3
- package/config/rules/docs/sourced-api-claims.yaml +29 -64
- package/config/rules/strict/runtime-boundaries.yaml +40 -1
- package/config/rules/structure/protected-files.yaml +1 -1
- package/config/rules/surface/check-cli-surface.yaml +33 -0
- package/config/rules/typescript/no-debugger.yaml +3 -0
- package/config/workflow-candidates.json +2 -2
- package/config/workflows/feature-verification.yaml +6 -19
- package/config/workflows/history-anatomy.yaml +14 -28
- package/config/workflows/idea-pipeline.yaml +6 -19
- package/config/workflows/pr-review.yaml +9 -16
- package/config/workflows/task-pipeline.yaml +18 -25
- package/config/workflows/wrapup-pipeline.yaml +21 -63
- package/package.json +3 -3
- package/plugins/sp/README.md +70 -37
- package/plugins/sp/agents/expert-spur.md +0 -1
- package/plugins/sp/agents/super-planner.md +5 -5
- package/plugins/sp/agents/super-reviewer.md +2 -2
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-daily.md +1 -1
- package/plugins/sp/commands/dev-pr-review.md +1 -1
- package/plugins/sp/commands/dev-review-session.md +1 -1
- package/plugins/sp/commands/dev-runall.md +4 -4
- package/plugins/sp/commands/dev-verify.md +4 -6
- package/plugins/sp/commands/dev-verifyall.md +4 -5
- package/plugins/sp/hooks/hooks.json +11 -1
- package/plugins/sp/lib/context-post-tool.ts +1 -1
- package/plugins/sp/lib/context-session-start.ts +1 -1
- package/plugins/sp/lib/context-session-stop.ts +1 -1
- package/plugins/sp/lib/destructive-policy.ts +65 -1
- package/plugins/sp/plugin.json +2 -5
- package/plugins/sp/{hooks → scripts/hooks}/agent-lifecycle.ts +1 -1
- package/plugins/sp/scripts/hooks/careful-guard.ts +94 -0
- package/plugins/sp/{hooks → scripts/hooks}/context-post-tool.ts +2 -2
- package/plugins/sp/{hooks → scripts/hooks}/context-session-start.ts +1 -1
- package/plugins/sp/{hooks → scripts/hooks}/context-session-stop.ts +1 -1
- package/plugins/sp/{hooks → scripts/hooks}/fleet-guest-stop.ts +6 -4
- package/plugins/sp/{hooks → scripts/hooks}/task-write-guard.ts +38 -21
- package/plugins/sp/skills/brainstorm/SKILL.md +12 -11
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +1 -1
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +0 -4
- package/plugins/sp/skills/brainstorm/metadata.openclaw +1 -1
- package/plugins/sp/skills/brainstorm/references/workflows.md +4 -14
- package/plugins/sp/skills/code-implementation/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/SKILL.md +8 -8
- package/plugins/sp/skills/code-verification/references/secu-review.md +4 -4
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +9 -1
- package/plugins/sp/skills/daily-summary/SKILL.md +4 -5
- package/plugins/sp/skills/dogfood-testing/SKILL.md +9 -9
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +1 -1
- package/plugins/sp/skills/history-anatomy/references/modes.md +2 -2
- package/plugins/sp/skills/history-anatomy/references/operations.md +3 -4
- package/plugins/sp/skills/history-anatomy/references/report-contract.md +2 -3
- package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/parallel-execution/SKILL.md +2 -2
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +9 -10
- package/plugins/sp/skills/pr-reviewing/SKILL.md +14 -15
- package/plugins/sp/skills/reverse-engineering/SKILL.md +4 -6
- package/plugins/sp/skills/session-review/SKILL.md +13 -29
- package/plugins/sp/skills/source-driven-development/SKILL.md +26 -27
- package/plugins/sp/skills/spur-check/SKILL.md +14 -13
- package/plugins/sp/skills/spur-cli/SKILL.md +1 -1
- package/plugins/sp/skills/spur-cli/references/agent.md +17 -2
- package/plugins/sp/skills/spur-cli/references/builder.md +27 -6
- package/plugins/sp/skills/spur-cli/references/features.md +6 -1
- package/plugins/sp/skills/spur-cli/references/history.md +3 -0
- package/plugins/sp/skills/spur-cli/references/self.md +5 -3
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +13 -3
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +36 -1
- package/plugins/sp/skills/spur-dev/SKILL.md +1 -1
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +1 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +12 -13
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +10 -11
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +16 -17
- package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +9 -12
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +6 -8
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +1 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +33 -40
- package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +24 -24
- package/plugins/sp/skills/spur-doctor/SKILL.md +5 -4
- package/spur.js +12726 -1456
- package/web/_astro/{BoardApp.CaNvQBD_.js → BoardApp.B5rTVNd_.js} +1 -1
- package/web/_astro/{BoardApp.C5jnkkKP.js → BoardApp.BMprmPRc.js} +141 -141
- package/web/_astro/{TaskDetail.DGKndhI8.js → TaskDetail.Ddsur8qd.js} +1 -1
- package/web/_astro/{arc.DHrwdg3G.js → arc.DLqVVBxP.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.pvKpK1s5.js → architectureDiagram-3BPJPVTR.C-Pk3uAi.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.BQmRcZsS.js → blockDiagram-GPEHLZMM.BRO1i_Nm.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.CCLjHeH1.js → c4Diagram-AAUBKEIU.BU_cWu6e.js} +1 -1
- package/web/_astro/channel.Bs3Illhy.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DL6Yuoma.js → chunk-2J33WTMH.D2VXiQ2t.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.CzlyEI7l.js → chunk-4BX2VUAB.BcHT772J.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.B60EWxp1.js → chunk-55IACEB6.DhDtICmo.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.c7v_fRLo.js → chunk-727SXJPM.BoKHp7gV.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.8BxLWdDc.js → chunk-AQP2D5EJ.Chu4JRpE.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DmKuxGFT.js → chunk-FMBD7UC4.wHdwKPlq.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.1Zwd4mqV.js → chunk-ND2GUHAM.ffN-M1JB.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BvYLu-A1.js → chunk-QZHKN3VN.FRubwg4S.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.CEqRt0WU.js → classDiagram-4FO5ZUOK.c22tQsc_.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.CEqRt0WU.js → classDiagram-v2-Q7XG4LA2.c22tQsc_.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.C7JiUdj2.js → cose-bilkent-S5V4N54A.B9c6fiSj.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.B6mZ-1be.js → cynefin-OW5HDTMX.DrZsrUHl.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.BuryfDy6.js → dagre-BM42HDAG.DG1U4b3y.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.dao39YQM.js → diagram-2AECGRRQ.CH15b-K3.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.lnGZe4At.js → diagram-5GNKFQAL.BH1j7twR.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.uWfhzEfT.js → diagram-KO2AKTUF.q2zCkbAj.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.ppq8-198.js → diagram-LMA3HP47.BLaaZnHV.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.CKSCqDt5.js → diagram-OG6HWLK6.BcpRdQwI.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.sFSf2yBN.js → erDiagram-TEJ5UH35.D7KBlqfM.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BJQjKLbz.js → flowDiagram-I6XJVG4X.D_gmuRqg.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DAHKNj2N.js → ganttDiagram-6RSMTGT7.DzgWYniD.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.BlmzcW_O.js → gitGraphDiagram-PVQCEYII.576i3hm3.js} +1 -1
- package/web/_astro/index.DiC1a6lh.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.DGhjaqsi.js → infoDiagram-5YYISTIA.DMCclBiz.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.gKIpgt6F.js → ishikawaDiagram-YF4QCWOH.9Kyca4SH.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.DG3tmP0R.js → journeyDiagram-JHISSGLW.chbdG-8q.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.CgHDSxkR.js → kanban-definition-UN3LZRKU.Bds54-e0.js} +1 -1
- package/web/_astro/{linear.BuGEpcuM.js → linear.D5ND9GN_.js} +1 -1
- package/web/_astro/{mermaid.core.DBVqkWBp.js → mermaid.core.D9N_PGbj.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.D-kOcji9.js → mindmap-definition-RKZ34NQL.t0xop5vp.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.BvGPwtZt.js → pieDiagram-4H26LBE5.DqgKh6hM.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.BKb_9FV6.js → quadrantDiagram-W4KKPZXB.DeuHVi2t.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.Cx0fvD8v.js → requirementDiagram-4Y6WPE33.BdYFSG4W.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.fatULi0W.js → sankeyDiagram-5OEKKPKP.k1LPPETJ.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.ChHyKqco.js → sequenceDiagram-3UESZ5HK.DdyfpzoG.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BdUpKWyj.js → stateDiagram-AJRCARHV.DSEI8il0.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.fmJxqIm5.js → stateDiagram-v2-BHNVJYJU.CoMnQRKo.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BayDn5-V.js → timeline-definition-PNZ67QCA.DM1AHNm-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Bm2Aggwa.js → vennDiagram-CIIHVFJN.C-cJmVtl.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DI75O-uG.js → wardleyDiagram-YWT4CUSO.D0xMzKPb.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DL90E7Q7.js → xychartDiagram-2RQKCTM6.BH5xJcEq.js} +1 -1
- package/web/index.html +2 -2
- package/config/plugin-scripts.json +0 -116
- package/config/script-placement-baseline.json +0 -33
- package/plugins/sp/hooks/careful-guard.ts +0 -74
- package/plugins/sp/hooks/pi/guard-extension.ts +0 -304
- package/plugins/sp/lib/dogfood-pipeline.ts +0 -265
- package/plugins/sp/lib/dogfood-report.ts +0 -278
- package/plugins/sp/lib/history-anatomy.generated.d.mts +0 -112
- package/plugins/sp/lib/history-anatomy.generated.mjs +0 -691
- package/plugins/sp/lib/idea-handoff.generated.d.mts +0 -17
- package/plugins/sp/lib/idea-handoff.generated.mjs +0 -1446
- package/plugins/sp/lib/inline-run-app.ts +0 -68
- package/plugins/sp/lib/inline-run.generated.d.mts +0 -37
- package/plugins/sp/lib/inline-run.generated.mjs +0 -3103
- package/plugins/sp/lib/plan-projection.generated.d.mts +0 -197
- package/plugins/sp/lib/plan-projection.generated.mjs +0 -982
- package/plugins/sp/lib/quality-gate.generated.d.mts +0 -139
- package/plugins/sp/lib/quality-gate.generated.mjs +0 -30510
- package/plugins/sp/lib/residual-scan.generated.d.mts +0 -93
- package/plugins/sp/lib/residual-scan.generated.mjs +0 -383
- package/plugins/sp/lib/run-summary-core.ts +0 -225
- package/plugins/sp/lib/spur-bin.ts +0 -36
- package/plugins/sp/lib/step-profile.generated.d.mts +0 -71
- package/plugins/sp/lib/step-profile.generated.mjs +0 -174
- package/plugins/sp/lib/transcript.ts +0 -112
- package/plugins/sp/scripts/batch-plan.mjs +0 -1096
- package/plugins/sp/scripts/batch-plan.ts +0 -145
- package/plugins/sp/scripts/batch-preflight.mjs +0 -423
- package/plugins/sp/scripts/batch-preflight.ts +0 -270
- package/plugins/sp/scripts/commit-guard.mjs +0 -226
- package/plugins/sp/scripts/commit-guard.ts +0 -248
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +0 -626
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +0 -855
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +0 -211
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +0 -110
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +0 -282
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +0 -98
- package/plugins/sp/scripts/feature-verification-steps.mjs +0 -82
- package/plugins/sp/scripts/feature-verification-steps.ts +0 -164
- package/plugins/sp/scripts/history-anatomy-cache.mjs +0 -931
- package/plugins/sp/scripts/history-anatomy-cache.ts +0 -247
- package/plugins/sp/scripts/idea-handoff.mjs +0 -32
- package/plugins/sp/scripts/idea-handoff.ts +0 -47
- package/plugins/sp/scripts/inline-run-dispatch.mjs +0 -131
- package/plugins/sp/scripts/inline-run-dispatch.ts +0 -115
- package/plugins/sp/scripts/inline-run-setup.mjs +0 -746
- package/plugins/sp/scripts/inline-run-setup.ts +0 -198
- package/plugins/sp/scripts/persist-out-check.mjs +0 -217
- package/plugins/sp/scripts/persist-out-check.ts +0 -249
- package/plugins/sp/scripts/pr-reviewing.mjs +0 -712
- package/plugins/sp/scripts/pr-reviewing.ts +0 -952
- package/plugins/sp/scripts/quality-gate.mjs +0 -30491
- package/plugins/sp/scripts/quality-gate.ts +0 -80
- package/plugins/sp/scripts/residual-scan.mjs +0 -634
- package/plugins/sp/scripts/residual-scan.ts +0 -248
- package/plugins/sp/scripts/run-summary.mjs +0 -758
- package/plugins/sp/scripts/run-summary.ts +0 -107
- package/plugins/sp/scripts/script-root.mjs +0 -129
- package/plugins/sp/scripts/script-root.ts +0 -199
- package/plugins/sp/scripts/session-timeline.mjs +0 -359
- package/plugins/sp/scripts/session-timeline.ts +0 -190
- package/plugins/sp/scripts/task-diffstat.mjs +0 -181
- package/plugins/sp/scripts/task-diffstat.ts +0 -219
- package/plugins/sp/scripts/workflow-step-profile.mjs +0 -338
- package/plugins/sp/scripts/workflow-step-profile.ts +0 -165
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +0 -190
- package/plugins/sp/scripts/wrapup-drift-probe.ts +0 -261
- package/plugins/sp/scripts/wrapup-steps.mjs +0 -627
- package/plugins/sp/scripts/wrapup-steps.ts +0 -891
- package/web/_astro/channel.C7wG9RxA.js +0 -1
- package/web/_astro/index.BCY1JJHd.css +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* careful-guard — PreToolUse guard for destructive shell commands (task 0215, R3).
|
|
5
|
+
*
|
|
6
|
+
* Warn (permission `ask`) before a `Bash` tool call runs a destructive command — `rm -rf`
|
|
7
|
+
* (any flag spelling, including the POSIX uppercase `-R`), `DROP TABLE`/`DROP DATABASE`/
|
|
8
|
+
* `TRUNCATE`, `git push --force`/`-f`/`+refspec`, `git reset --hard`, `git checkout .`/
|
|
9
|
+
* `git restore .`, `kubectl delete`, `docker system prune`. The operator can confirm to
|
|
10
|
+
* proceed. Pure pattern-match + decision, no domain logic (mirrors `task-write-guard`).
|
|
11
|
+
*
|
|
12
|
+
* Git global options between the executable and the subcommand are recognized — any run of them,
|
|
13
|
+
* not a fixed list: value-less flags (`--no-pager`, `--bare`, `-p`, …), glued long values
|
|
14
|
+
* (`--git-dir=<path>`), and value-taking options in separated form (`-C <path>`,
|
|
15
|
+
* `-c <name>=<value>`, `--git-dir|--work-tree|--namespace|--config-env|--attr-source <value>`).
|
|
16
|
+
* So `git -C . push --force` and `git --no-pager push --force` classify exactly like
|
|
17
|
+
* `git push --force`; the lexical pass only removes that option span and never executes git or
|
|
18
|
+
* expands a substitution. The run cannot cross a command boundary (`;`, `&`, `|`, newline).
|
|
19
|
+
*
|
|
20
|
+
* **Safe exceptions:** `rm -rf` of well-known build/dependency caches (`node_modules`, `dist`,
|
|
21
|
+
* `.next`, `coverage`, `build`, `.turbo`, `.cache`) passes without a warning — deleting a rebuildable
|
|
22
|
+
* cache is routine, not dangerous.
|
|
23
|
+
*
|
|
24
|
+
* **Output contract** (superskill ADR-039 `hook run`): allow prints **nothing** (exit 0). Ask prints
|
|
25
|
+
* Claude-native PreToolUse JSON with the reason in `permissionDecisionReason` (the confirm prompt) and
|
|
26
|
+
* `systemMessage` (Claude Code's user-facing warning, which the host-neutral `{decision,reason}` form
|
|
27
|
+
* cannot carry). Hosts that cannot confirm (Codex, omp, generic) receive a deny with the reason:
|
|
28
|
+
* superskill fails an unconfirmable ask closed. Pi confirms through its native host adapter.
|
|
29
|
+
*
|
|
30
|
+
* **Fail-open contract:** every error path — unparseable payload, non-Bash tool, empty command —
|
|
31
|
+
* allows (prints nothing). A broken guard must never wedge an agent tool call.
|
|
32
|
+
*
|
|
33
|
+
* **Escape hatch:** `SPUR_CAREFUL=off` short-circuits to allow.
|
|
34
|
+
*
|
|
35
|
+
* Classification itself lives in `lib/destructive-policy.ts` — one policy, every platform
|
|
36
|
+
* adapter runs this hook through superskill). This file owns the hook payload/decision shape only.
|
|
37
|
+
* Registered in `hooks/hooks.json` as `PreToolUse` / matcher `Bash` (task 0215 R3).
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { classifyCommand } from '../../lib/destructive-policy';
|
|
41
|
+
import { getEnvVar } from '../../lib/env';
|
|
42
|
+
|
|
43
|
+
interface ToolPayload {
|
|
44
|
+
tool_name?: string;
|
|
45
|
+
tool_input?: { command?: string };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Allow: print nothing and exit 0 (no objection; the host's own permission rules still apply). */
|
|
49
|
+
function allow(): never {
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Ask the operator to confirm, with the reason on the prompt and as a user-facing warning. */
|
|
54
|
+
function ask(reason: string): never {
|
|
55
|
+
process.stdout.write(
|
|
56
|
+
JSON.stringify({
|
|
57
|
+
hookSpecificOutput: {
|
|
58
|
+
hookEventName: 'PreToolUse',
|
|
59
|
+
permissionDecision: 'ask',
|
|
60
|
+
permissionDecisionReason: reason,
|
|
61
|
+
},
|
|
62
|
+
systemMessage: reason,
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function main(): Promise<void> {
|
|
69
|
+
if (getEnvVar('SPUR_CAREFUL') === 'off') allow();
|
|
70
|
+
|
|
71
|
+
const stdinText = await Bun.stdin.text();
|
|
72
|
+
let payload: ToolPayload;
|
|
73
|
+
try {
|
|
74
|
+
payload = JSON.parse(stdinText) as ToolPayload;
|
|
75
|
+
} catch {
|
|
76
|
+
allow(); // unparseable payload — fail open
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (payload.tool_name !== 'Bash') allow();
|
|
80
|
+
|
|
81
|
+
const command = payload.tool_input?.command ?? '';
|
|
82
|
+
if (command.trim() === '') allow();
|
|
83
|
+
|
|
84
|
+
const hit = classifyCommand(command);
|
|
85
|
+
if (hit !== null) {
|
|
86
|
+
ask(
|
|
87
|
+
`This command looks like ${hit} — a destructive operation. Confirm you intend to run it. ` +
|
|
88
|
+
'Set SPUR_CAREFUL=off to disable this guard.',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
allow();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (import.meta.main) void main();
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { join } from 'node:path';
|
|
13
|
-
import { recordToolUseEvent, type ToolPayload } from '
|
|
14
|
-
import { getEnvVar } from '
|
|
13
|
+
import { recordToolUseEvent, type ToolPayload } from '../../lib/context-post-tool';
|
|
14
|
+
import { getEnvVar } from '../../lib/env';
|
|
15
15
|
|
|
16
16
|
if (import.meta.main) {
|
|
17
17
|
void (async () => {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (legacy policy) and every error path exits 0 with no output.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { recordSessionStartFromPayloadText } from '
|
|
10
|
+
import { recordSessionStartFromPayloadText } from '../../lib/context-session-start';
|
|
11
11
|
|
|
12
12
|
if (import.meta.main) {
|
|
13
13
|
try {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* `agent.run`'s shutdown stays a no-op because the owner gate lives in the core, not here.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { recordSessionEndFromPayloadText } from '
|
|
10
|
+
import { recordSessionEndFromPayloadText } from '../../lib/context-session-stop';
|
|
11
11
|
|
|
12
12
|
if (import.meta.main) {
|
|
13
13
|
try {
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
* - **Bounded.** The pending check is `spur agent wait --inbox <id> --timeout 2000`, which also
|
|
16
16
|
* heartbeats the guest lease (R5), and the reason names at most the first few messages.
|
|
17
17
|
*
|
|
18
|
-
* Block contract
|
|
19
|
-
* `{"decision":"block","reason":"<non-empty>"}`.
|
|
20
|
-
* Codex
|
|
18
|
+
* Block contract: exit 0 with the host-neutral superskill result on stdout (ADR-039) —
|
|
19
|
+
* `{"decision":"block","reason":"<non-empty>"}`. `superskill hook run` renders it per host: Claude
|
|
20
|
+
* Code and Codex receive that same Stop JSON (Claude uses the reason as the stop reason; Codex turns
|
|
21
|
+
* it into the next user prompt), omp/Pi get exit 2 + the reason on stderr. No pending work prints
|
|
22
|
+
* nothing. Hosts that drop the Stop event (`codex exec` on
|
|
21
23
|
* 0.160.0 — see `docs/plans/2026-10-05-codex-guest-spike.md`) simply never call it.
|
|
22
24
|
*
|
|
23
25
|
* Self-contained by design: hooks are bundled standalone at install time, so this file imports
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
import { spawnSync } from 'node:child_process';
|
|
28
30
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
29
31
|
import { join } from 'node:path';
|
|
30
|
-
import { getEnvVar } from '
|
|
32
|
+
import { getEnvVar } from '../../lib/env';
|
|
31
33
|
|
|
32
34
|
/** Budget for the pending-work probe; the hook must never noticeably slow a turn. */
|
|
33
35
|
export const GUEST_STOP_PROBE_MS = 2000;
|
|
@@ -7,21 +7,28 @@
|
|
|
7
7
|
* hand. Pure delegation: ownership is decided by `spur task resolve --strict --json`'s exit code
|
|
8
8
|
* alone (exit 0 → owned, non-zero → unowned).
|
|
9
9
|
*
|
|
10
|
+
* **Output contract** (superskill ADR-039 `hook run`): allow prints **nothing** (exit 0) — a printed
|
|
11
|
+
* Claude `permissionDecision:"allow"` would auto-approve the call and bypass the user's permission
|
|
12
|
+
* rules. Deny prints Claude-native PreToolUse JSON carrying the reason twice: `permissionDecisionReason`
|
|
13
|
+
* (what Claude Code feeds back to the model, and what `hook run` turns into exit 2 + stderr on
|
|
14
|
+
* Codex/omp/generic hosts) and `systemMessage` (Claude Code's user-facing warning — the one field the
|
|
15
|
+
* host-neutral `{decision,reason}` form cannot carry, which is why this guard stays Claude-native).
|
|
16
|
+
*
|
|
10
17
|
* **Fail-open contract** (inherited from the pre-N3 shim and from superskill's runner): every error
|
|
11
18
|
* path — unparseable payload, non-Write/Edit tool, empty path, missing `spur` binary, spawn
|
|
12
|
-
* failure, timeout, `spur task resolve` non-zero exit, non-JSON stdout —
|
|
13
|
-
*
|
|
19
|
+
* failure, timeout, `spur task resolve` non-zero exit, non-JSON stdout — allows (prints nothing).
|
|
20
|
+
* A broken guard must never wedge an agent tool call.
|
|
14
21
|
*
|
|
15
22
|
* **Escape hatch:** `SPUR_WRITE_GUARD=off` short-circuits to allow.
|
|
16
23
|
*
|
|
17
|
-
* Self-contained by design (Wave E, task 0181, R3)
|
|
18
|
-
* `superskill hook run sp task-write-guard
|
|
19
|
-
*
|
|
24
|
+
* Self-contained by design (Wave E, task 0181, R3): `node:*` builtins and relative imports only.
|
|
25
|
+
* Installed hook configs invoke `superskill hook run sp task-write-guard`, which resolves this file
|
|
26
|
+
* as `scripts/hooks/task-write-guard.ts` under the native plugin root or the staged scripts root.
|
|
20
27
|
*/
|
|
21
28
|
|
|
22
29
|
import { spawnSync } from 'node:child_process';
|
|
23
|
-
import { getEnvVar } from '
|
|
24
|
-
import { couldBeTaskFile } from '
|
|
30
|
+
import { getEnvVar } from '../../lib/env';
|
|
31
|
+
import { couldBeTaskFile } from '../../lib/task-file-policy';
|
|
25
32
|
|
|
26
33
|
interface ToolPayload {
|
|
27
34
|
tool_name?: string;
|
|
@@ -30,12 +37,23 @@ interface ToolPayload {
|
|
|
30
37
|
|
|
31
38
|
type TaskOwnership = 'owned' | 'unowned' | 'unknown';
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
/** Allow: print nothing and exit 0 (no objection; the host's own permission rules still apply). */
|
|
41
|
+
function allow(): never {
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Deny with a reason the model (`permissionDecisionReason`) and the user (`systemMessage`) both see. */
|
|
46
|
+
function deny(reason: string): never {
|
|
47
|
+
process.stdout.write(
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
hookSpecificOutput: {
|
|
50
|
+
hookEventName: 'PreToolUse',
|
|
51
|
+
permissionDecision: 'deny',
|
|
52
|
+
permissionDecisionReason: reason,
|
|
53
|
+
},
|
|
54
|
+
systemMessage: reason,
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
39
57
|
process.exit(0);
|
|
40
58
|
}
|
|
41
59
|
|
|
@@ -55,35 +73,34 @@ function resolveSpurTaskOwnership(filePath: string, cwd: string): TaskOwnership
|
|
|
55
73
|
}
|
|
56
74
|
|
|
57
75
|
async function main(): Promise<void> {
|
|
58
|
-
if (getEnvVar('SPUR_WRITE_GUARD') === 'off')
|
|
76
|
+
if (getEnvVar('SPUR_WRITE_GUARD') === 'off') allow();
|
|
59
77
|
|
|
60
78
|
const stdinText = await Bun.stdin.text();
|
|
61
79
|
let payload: ToolPayload;
|
|
62
80
|
try {
|
|
63
81
|
payload = JSON.parse(stdinText) as ToolPayload;
|
|
64
82
|
} catch {
|
|
65
|
-
|
|
83
|
+
allow(); // unparseable payload — fail open
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
const toolName = payload.tool_name ?? '';
|
|
69
|
-
if (toolName !== 'Write' && toolName !== 'Edit')
|
|
87
|
+
if (toolName !== 'Write' && toolName !== 'Edit') allow();
|
|
70
88
|
|
|
71
89
|
const filePath = payload.tool_input?.file_path ?? '';
|
|
72
|
-
if (filePath === '')
|
|
90
|
+
if (filePath === '') allow();
|
|
73
91
|
// Skip the `spur task resolve` subprocess (~120ms) for paths whose basename
|
|
74
92
|
// cannot name a task file — that is every ordinary source edit.
|
|
75
|
-
if (!couldBeTaskFile(filePath))
|
|
93
|
+
if (!couldBeTaskFile(filePath)) allow();
|
|
76
94
|
|
|
77
95
|
const ownership = resolveSpurTaskOwnership(filePath, getEnvVar('CLAUDE_PROJECT_DIR') ?? process.cwd());
|
|
78
96
|
if (ownership === 'owned') {
|
|
79
|
-
|
|
80
|
-
'deny',
|
|
97
|
+
deny(
|
|
81
98
|
`${filePath} is a task file owned by the spur corpus. Edit it through the spur CLI ` +
|
|
82
99
|
'(e.g. `spur task update <wbs> --section <name> --from-file <file>`), not a raw ' +
|
|
83
100
|
'Write/Edit. Set SPUR_WRITE_GUARD=off to bypass.',
|
|
84
101
|
);
|
|
85
102
|
}
|
|
86
|
-
|
|
103
|
+
allow();
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
void main();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: brainstorm
|
|
3
|
-
description: "Structured ideation: generate solution options with trade-offs and
|
|
3
|
+
description: "Structured ideation: generate solution options with trade-offs and source citations, then delegate to research/task-creation skills. Triggers: \"brainstorm ideas\", \"explore solutions\", \"consider options\", \"research approaches\", \"what are my options\", \"how should I approach X\"."
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
created_at: 2026-03-25
|
|
@@ -30,7 +30,7 @@ see_also:
|
|
|
30
30
|
|
|
31
31
|
# sp:brainstorm — Structured Ideation Workflow
|
|
32
32
|
|
|
33
|
-
Generate solution options with trade-offs, recommendations, and
|
|
33
|
+
Generate solution options with trade-offs, recommendations, and source citations. Delegates research to specialized skills.
|
|
34
34
|
|
|
35
35
|
**Key distinction:**
|
|
36
36
|
- **`sp:brainstorm`** = Ideation: generate approaches with trade-offs
|
|
@@ -40,7 +40,7 @@ Generate solution options with trade-offs, recommendations, and confidence scori
|
|
|
40
40
|
|
|
41
41
|
## Overview
|
|
42
42
|
|
|
43
|
-
The `sp:brainstorm` skill generates multiple solution approaches with explicit trade-offs
|
|
43
|
+
The `sp:brainstorm` skill generates multiple solution approaches with explicit trade-offs and source citations. It follows a structured 3-phase workflow: Input parsing, Ideation with research delegation, and structured Output. Unlike pure research or bare task creation, brainstorm focuses on ideation—generating and comparing options before committing to a solution path.
|
|
44
44
|
|
|
45
45
|
## Quick Start
|
|
46
46
|
|
|
@@ -101,14 +101,15 @@ See the [inline-default contract](../spur-dev/references/cross-cutting.md#inline
|
|
|
101
101
|
|
|
102
102
|
### 3. Generate 2-3 Approaches
|
|
103
103
|
|
|
104
|
-
Always generate multiple options, each with description, trade-offs,
|
|
104
|
+
Always generate multiple options, each with description, trade-offs, and sources — full
|
|
105
105
|
per-approach template: [references/workflows.md](references/workflows.md#approach-generation).
|
|
106
106
|
|
|
107
|
-
### 4.
|
|
107
|
+
### 4. Source Citations
|
|
108
108
|
|
|
109
|
-
Every
|
|
110
|
-
source
|
|
111
|
-
|
|
109
|
+
Every external claim carries a dated source citation — format:
|
|
110
|
+
[references/workflows.md](references/workflows.md#source-citation-format). No HIGH/MEDIUM/LOW
|
|
111
|
+
confidence score (ADR-138): a self-assigned score is as easy to write as the claim; the citation and
|
|
112
|
+
the trade-offs are what the operator compares.
|
|
112
113
|
|
|
113
114
|
### 5. Task Delegation
|
|
114
115
|
|
|
@@ -224,13 +225,13 @@ still pauses unless the operator has encoded prior approval in the workflow vars
|
|
|
224
225
|
| "I understand the request — skip clarifying." | Ideating on a misread wastes the whole session. Validate input clarity and the two input modes before generating options. |
|
|
225
226
|
| "More options are always better." | Beyond ~3, options dilute focus and stall the decision. Cap at three and delegate deeper research instead. |
|
|
226
227
|
| "I'll design the architecture while I brainstorm." | Brainstorm generates and scores approaches; it does not lock the design. Route a chosen approach through the Design Approval Gate. |
|
|
227
|
-
| "
|
|
228
|
+
| "Sources are obvious — skip them." | An uncited option hides its risk. Cite sources and name the trade-offs so the operator compares on evidence, not vibes. |
|
|
228
229
|
|
|
229
230
|
## Red Flags
|
|
230
231
|
|
|
231
232
|
- Presenting a single approach with no alternatives or trade-offs.
|
|
232
233
|
- Starting ideation before the input is clarified.
|
|
233
|
-
- More than three approaches, or approaches with no
|
|
234
|
+
- More than three approaches, or approaches with no source.
|
|
234
235
|
- Skipping the task-delegation offer after the operator confirms a direction.
|
|
235
236
|
- Treating a brainstorm output as an approved design (bypassing the approval gate).
|
|
236
237
|
|
|
@@ -293,7 +294,7 @@ codebase-first rule, stop conditions, depth question budgets, smart positional d
|
|
|
293
294
|
The skill uses this tree to:
|
|
294
295
|
1. **Constrain the option space** — each approach must be compatible with resolved decisions
|
|
295
296
|
2. **Generate decision-trace annotations** — each approach lists which decisions it depends on
|
|
296
|
-
3. **
|
|
297
|
+
3. **Cite the evidence** — decisions resolved from codebase evidence cite the `path:line` they rest on
|
|
297
298
|
|
|
298
299
|
When `--skip-discovery` is used (no `--context`), the operation falls back to the standard
|
|
299
300
|
3-phase workflow with its own lightweight clarification step.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: brainstorm
|
|
2
2
|
description: "Structured ideation workflow for generating solution options with
|
|
3
|
-
trade-offs,
|
|
3
|
+
trade-offs, source citations, and delegation to research and task creation
|
|
4
4
|
skills. Triggers: brainstorm ideas, explore solutions, consider options,
|
|
5
5
|
research approaches, multiple solution options with trade-offs."
|
|
6
6
|
version: 1.0.0
|
|
@@ -80,7 +80,6 @@ async function authMiddleware(c: Context, next: Next) {
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
**Confidence:** HIGH
|
|
84
83
|
**Sources:**
|
|
85
84
|
- [jose Library Docs](https://github.com/panva/jose) | Verified: 2026-03-25
|
|
86
85
|
- [Hono Middleware Guide](https://hono.dev/docs/middleware/builtin/bearer-auth) | Verified: 2026-03-25
|
|
@@ -127,7 +126,6 @@ async function handleLogin(username: string, password: string) {
|
|
|
127
126
|
}
|
|
128
127
|
```
|
|
129
128
|
|
|
130
|
-
**Confidence:** MEDIUM
|
|
131
129
|
**Sources:**
|
|
132
130
|
- [Auth0 Node.js SDK v5](https://auth0.github.io/node-auth0/) | Verified: 2026-03-25
|
|
133
131
|
- [Firebase Admin Setup](https://firebase.google.com/docs/admin/setup) | Verified: 2026-03-15
|
|
@@ -172,7 +170,6 @@ async function apiKeyMiddleware(c: Context, next: Next) {
|
|
|
172
170
|
}
|
|
173
171
|
```
|
|
174
172
|
|
|
175
|
-
**Confidence:** MEDIUM
|
|
176
173
|
**Sources:**
|
|
177
174
|
- [Hono Bearer Auth Middleware](https://hono.dev/docs/middleware/builtin/bearer-auth) | Verified: 2026-03-25
|
|
178
175
|
|
|
@@ -206,4 +203,3 @@ async function apiKeyMiddleware(c: Context, next: Next) {
|
|
|
206
203
|
|
|
207
204
|
**Generated by:** sp:brainstorm
|
|
208
205
|
**Research delegation:** sp:source-driven-development, spur agent run
|
|
209
|
-
**Confidence:** HIGH (official jose/Hono documentation, 2026)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: brainstorm
|
|
2
2
|
description: "Structured ideation workflow for generating solution options with
|
|
3
|
-
trade-offs,
|
|
3
|
+
trade-offs, source citations, and delegation to research and task creation
|
|
4
4
|
skills. Triggers: brainstorm ideas, explore solutions, consider options,
|
|
5
5
|
research approaches, multiple solution options with trade-offs."
|
|
6
6
|
version: 1.0.0
|
|
@@ -85,7 +85,7 @@ DO NOT implement research directly. Delegate to specialized skills:
|
|
|
85
85
|
|
|
86
86
|
2. Delegate research + synthesis inline by default
|
|
87
87
|
- Run in the current session; escalate to `spur agent run` only on a subprocess trigger
|
|
88
|
-
- Request
|
|
88
|
+
- Request source citations
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
### Approach Generation
|
|
@@ -108,7 +108,6 @@ DO NOT implement research directly. Delegate to specialized skills:
|
|
|
108
108
|
- Key technical considerations
|
|
109
109
|
- Dependencies or prerequisites
|
|
110
110
|
|
|
111
|
-
**Confidence:** HIGH/MEDIUM/LOW
|
|
112
111
|
**Sources:** [Citations with dates]
|
|
113
112
|
```
|
|
114
113
|
|
|
@@ -120,14 +119,6 @@ DO NOT implement research directly. Delegate to specialized skills:
|
|
|
120
119
|
- [Title](URL) | **Verified**: YYYY-MM-DD
|
|
121
120
|
```
|
|
122
121
|
|
|
123
|
-
### Confidence Scoring
|
|
124
|
-
|
|
125
|
-
| Level | Range | Criteria |
|
|
126
|
-
|-------|-------|----------|
|
|
127
|
-
| **HIGH** | >90% | Direct quote from official docs (2025+) |
|
|
128
|
-
| **MEDIUM** | 70-90% | Synthesized from multiple sources |
|
|
129
|
-
| **LOW** | <70% | Uncertain, flag for review |
|
|
130
|
-
|
|
131
122
|
---
|
|
132
123
|
|
|
133
124
|
## Phase 3: Structured Output
|
|
@@ -144,7 +135,7 @@ DO NOT implement research directly. Delegate to specialized skills:
|
|
|
144
135
|
2. **Approaches** (200-300 words each)
|
|
145
136
|
- 2-3 options with trade-offs
|
|
146
137
|
- Implementation considerations
|
|
147
|
-
-
|
|
138
|
+
- Sources
|
|
148
139
|
|
|
149
140
|
3. **Recommendations** (100-150 words)
|
|
150
141
|
- Recommended approach with reasoning
|
|
@@ -197,7 +188,6 @@ run_id: <run id, omit when none>
|
|
|
197
188
|
**Implementation Notes:**
|
|
198
189
|
- [Technical considerations]
|
|
199
190
|
|
|
200
|
-
**Confidence:** HIGH/MEDIUM/LOW
|
|
201
191
|
**Sources:** [Citations]
|
|
202
192
|
|
|
203
193
|
### Approach 2: [Name]
|
|
@@ -255,7 +245,7 @@ Bash: spur task batch-create --file decomposition.json # bare JSON array (see
|
|
|
255
245
|
| File not found | Provide clear error with path |
|
|
256
246
|
| Invalid YAML | Report parsing error |
|
|
257
247
|
| Missing fields | List missing fields, ask if incomplete |
|
|
258
|
-
| Research unavailable | Continue,
|
|
248
|
+
| Research unavailable | Continue, mark the uncited claims |
|
|
259
249
|
| Save fails | Display output, suggest manual save |
|
|
260
250
|
|
|
261
251
|
---
|
|
@@ -265,6 +255,6 @@ Bash: spur task batch-create --file decomposition.json # bare JSON array (see
|
|
|
265
255
|
When tools unavailable:
|
|
266
256
|
|
|
267
257
|
1. **Continue** with available tools
|
|
268
|
-
2. **
|
|
258
|
+
2. **Mark** claims left uncited
|
|
269
259
|
3. **Suggest** manual fallback
|
|
270
260
|
4. **Save** intermediate state
|
|
@@ -169,7 +169,7 @@ that single full gate.
|
|
|
169
169
|
|
|
170
170
|
**Worker iteration check order (task 1142 R3):**
|
|
171
171
|
1. The **changed-path matrix** below (narrow behavior tests + affected consumers);
|
|
172
|
-
2.
|
|
172
|
+
2. `spur task gate <wbs> light` (biome on changed files, per-workspace typecheck, rule presets `rules:pre`/`rules:post`, related tests).
|
|
173
173
|
|
|
174
174
|
Neither step takes the full project gate. The full gate is named only for the pipeline's `test` and `test-recheck` hops.
|
|
175
175
|
|
|
@@ -284,9 +284,8 @@ the deterministic Testing writer `spur task record` (section authorship never ha
|
|
|
284
284
|
# write .spur/run/<wbs>-verdict.json (shape in references/verdict-schema.md), then:
|
|
285
285
|
spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json # renders ## Testing, flips proven boxes
|
|
286
286
|
# F96 residual sweep (observe-only): scan + fold AFTER record, under every --fix mode (0987).
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
node "$RESIDUAL" fold <wbs>
|
|
287
|
+
spur task residual <wbs> scan
|
|
288
|
+
spur task residual <wbs> fold
|
|
290
289
|
# Downgrade only: re-record so Testing carries the final (folded) verdict.
|
|
291
290
|
[ "$(jq -r .verdict .spur/run/<wbs>-verdict.json)" = PASS ] \
|
|
292
291
|
|| spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json
|
|
@@ -297,10 +296,9 @@ node "$RESIDUAL" fold <wbs>
|
|
|
297
296
|
> `residual-sweep` check in place (PASS → PARTIAL when a blocking residual exists), and the
|
|
298
297
|
> downgrade-only re-record transcribes it — a manual verify cannot certify what the pipeline would
|
|
299
298
|
> reject. The sweep runs after `record` (same order as the pipeline, 0983/0987): before it, a
|
|
300
|
-
> verdict-proven box is still unticked and a clean PASS would fold to PARTIAL.
|
|
301
|
-
>
|
|
302
|
-
> `
|
|
303
|
-
> through `--next`, run `residual-scan settle` (links follow-up tasks; best-effort).
|
|
299
|
+
> verdict-proven box is still unticked and a clean PASS would fold to PARTIAL. The sweep is the
|
|
300
|
+
> `spur task residual` verb (no plugin script to resolve). When the task reaches `done` through
|
|
301
|
+
> `--next`, run `spur task residual <wbs> settle` (files the follow-up task; best-effort).
|
|
304
302
|
|
|
305
303
|
> **Corrections: the answer file is the source of truth.** `spur task record` re-transcribes
|
|
306
304
|
> `## Testing` from the verdict artifact — direct `--section Testing` writes are futile. Fix
|
|
@@ -447,11 +445,13 @@ gate is **active**, evaluate feature AC satisfaction via the existing CLI.
|
|
|
447
445
|
|
|
448
446
|
```bash
|
|
449
447
|
SPUR_BIN="${SPUR_BIN:-$([ -f apps/cli/src/index.ts ] && echo 'bun apps/cli/src/index.ts' || echo spur)}"
|
|
450
|
-
$SPUR_BIN feature check <featureId> --json
|
|
448
|
+
$SPUR_BIN feature check <featureId> --as done --strict --json
|
|
451
449
|
$SPUR_BIN task list --feature <featureId> --json
|
|
452
450
|
```
|
|
453
451
|
|
|
454
452
|
3. Classify **Shippable: PASS** only if **all** of:
|
|
453
|
+
- Strict completion exits 0: PASS feature-verification receipts and required dogfood evidence.
|
|
454
|
+
Projection changes no status; active-state checks are insufficient.
|
|
455
455
|
- No finding whose code/message indicates **linked but unverified** scenarios
|
|
456
456
|
(`L4_SCENARIO_UNVERIFIED`).
|
|
457
457
|
- No **orphan / uncovered** feature scenarios (`L4_ORPHAN_SCENARIOS`,
|
|
@@ -83,16 +83,16 @@ verdict artifact so quality failures are not lost behind a requirements-only PAS
|
|
|
83
83
|
Before declaring a task `done`, run this lightweight checklist. It catches the most common oversights that survive the formal pipeline gates:
|
|
84
84
|
|
|
85
85
|
- [ ] Check receipt `.spur/run/<wbs>-check-receipt.json` reports `reuse: true` for the current
|
|
86
|
-
digest via `
|
|
86
|
+
digest via `spur task gate <wbs> status`; run `bun run spur-check` only when it reports stale or
|
|
87
87
|
missing (0940).
|
|
88
88
|
- [ ] No `TODO` or `FIXME` without a linked task WBS.
|
|
89
89
|
- [ ] `git status` shows only intentional changes (no debug artifacts, no temp files).
|
|
90
90
|
- [ ] No `console.log` / `console.error` in production code (use the project logger).
|
|
91
91
|
- [ ] No `--no-verify`, `--force`, or new suppression comments added to bypass gates.
|
|
92
92
|
- [ ] Solution section contains `file:line` citations for every changed file.
|
|
93
|
-
- [ ] API/library claims in changed docs carry a source citation (URL or `path:line`)
|
|
94
|
-
|
|
95
|
-
the `cited-version-strings` / `cited-api-claims`
|
|
93
|
+
- [ ] API/library claims in changed docs carry a source citation (URL or `path:line`) per
|
|
94
|
+
source-driven-development; no confidence label is required (ADR-138). The deterministic
|
|
95
|
+
advisory backstop is the `cited-version-strings` / `cited-api-claims` rules
|
|
96
96
|
(`.spur/rules/docs/sourced-api-claims.yaml`, run ad hoc — not wired into a preset).
|
|
97
97
|
- [ ] Review section has P1–P4 findings table (even if all rows are empty — the table itself proves review happened).
|
|
98
98
|
|
|
@@ -170,6 +170,14 @@ before the proof capture (task 1109), but it qualifies **unique** basenames only
|
|
|
170
170
|
basename (two tracked files share it) is reported and left untouched, and line drift and
|
|
171
171
|
`L4.anchor-subject-mismatch` are never repaired by that pass — those remain the author's rows.
|
|
172
172
|
|
|
173
|
+
A **workspace-relative** path fails the same way, and is the easier mistake to make because the
|
|
174
|
+
command it came from is real. `(cd apps/cli && bun test tests/commands/builder/pr.test.ts)` is the
|
|
175
|
+
right way to run the suite, but `tests/commands/builder/pr.test.ts` does not resolve from the repo
|
|
176
|
+
root, so the AC-coverage guard reports `missing: <AC> — <path>` and refuses `done` (observed
|
|
177
|
+
2026-10-16, task 1215 — the repair was a fresh verify pass over the whole answer). Cite both halves:
|
|
178
|
+
the workspace-rooted command you ran, then the repo-root-relative anchor of the file it names
|
|
179
|
+
(`apps/cli/tests/commands/builder/pr.test.ts`). One anchor per cited file per cell is enough.
|
|
180
|
+
|
|
173
181
|
## Source citations for external claims (task 1070)
|
|
174
182
|
|
|
175
183
|
A Requirement/AC evidence cell that asserts an external API/library claim must carry a verifiable
|
|
@@ -185,7 +193,7 @@ citation in the SAME cell, or lint rejects the row with `evidence-citation` (blo
|
|
|
185
193
|
presence-only — which citation proves which claim is not deterministically decidable.
|
|
186
194
|
- The same two predicates (`hasClaimMarker` / `hasCitationForm` in
|
|
187
195
|
`packages/app/src/services/verify-answer-lint.ts`) gate the review report's findings table through
|
|
188
|
-
`residual
|
|
196
|
+
`spur task residual <wbs> review-gate` as the blocking `review-contract` category — one definition of
|
|
189
197
|
"external claim" and one set of accepted citation forms for both paths.
|
|
190
198
|
|
|
191
199
|
## Hedged evidence is rejected on MET rows
|
|
@@ -52,13 +52,13 @@ The daily-summary skill:
|
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
54
|
# Generate summary for today
|
|
55
|
-
|
|
55
|
+
spur history summary
|
|
56
56
|
|
|
57
57
|
# Generate summary for a specific date
|
|
58
|
-
|
|
58
|
+
spur history summary --date 2026-04-17
|
|
59
59
|
|
|
60
60
|
# Show summary without writing file
|
|
61
|
-
|
|
61
|
+
spur history summary --dry-run
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
## Workflows
|
|
@@ -165,7 +165,6 @@ Read the skill file and follow the workflow manually.
|
|
|
165
165
|
|
|
166
166
|
## Additional Resources
|
|
167
167
|
|
|
168
|
-
- **
|
|
169
|
-
- **Tests:** [tests/daily-summary/daily-summary.test.ts](../../tests/daily-summary/daily-summary.test.ts) — unit coverage for parsing, date ranges, markdown output
|
|
168
|
+
- **CLI:** `spur history summary [--date d] [--dry-run] [--output p] [--no-git] [--no-ccusage]` — see `sp:spur-cli` (history reference)
|
|
170
169
|
- **Related skills:** `sp:dev-handover` (blocker handoff), `sp:dev-changelog` (commit-based changelog), `sp:spur-cli` (task management)
|
|
171
170
|
- **Upstream CLI:** [ccusage](https://github.com/ryoppippi/ccusage) — AI agent token usage reporter
|