workflow-toolkit 1.0.1
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/.agents/skills/ponytail/SKILL.md +111 -0
- package/.agents/skills/ponytail-audit/SKILL.md +37 -0
- package/.agents/skills/ponytail-debt/SKILL.md +41 -0
- package/.agents/skills/ponytail-gain/SKILL.md +47 -0
- package/.agents/skills/ponytail-help/SKILL.md +70 -0
- package/.agents/skills/ponytail-review/SKILL.md +52 -0
- package/.agents/skills/prompt-review/SKILL.md +60 -0
- package/.agents/skills/wtk/SKILL.md +64 -0
- package/.agents/skills/wtk/references/artifacts.md +82 -0
- package/.agents/skills/wtk/references/evidence.md +68 -0
- package/.agents/skills/wtk/references/git.md +75 -0
- package/.agents/skills/wtk/references/test-contract.md +76 -0
- package/.agents/skills/wtk/references/validation.md +127 -0
- package/.agents/skills/wtk-config/SKILL.md +102 -0
- package/.agents/skills/wtk-config/assets/agents/claude/deep-reviewer.md +40 -0
- package/.agents/skills/wtk-config/assets/agents/claude/designer.md +57 -0
- package/.agents/skills/wtk-config/assets/agents/claude/explorer.md +41 -0
- package/.agents/skills/wtk-config/assets/agents/claude/implementer.md +57 -0
- package/.agents/skills/wtk-config/assets/agents/claude/planner.md +68 -0
- package/.agents/skills/wtk-config/assets/agents/claude/verifier.md +80 -0
- package/.agents/skills/wtk-config/assets/agents/codex/deep-reviewer.toml +41 -0
- package/.agents/skills/wtk-config/assets/agents/codex/designer.toml +55 -0
- package/.agents/skills/wtk-config/assets/agents/codex/explorer.toml +35 -0
- package/.agents/skills/wtk-config/assets/agents/codex/implementer.toml +52 -0
- package/.agents/skills/wtk-config/assets/agents/codex/planner.toml +66 -0
- package/.agents/skills/wtk-config/assets/agents/codex/verifier.toml +78 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/deep-reviewer.md +38 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/designer.md +55 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/explorer.md +39 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/implementer.md +55 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/planner.md +66 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/verifier.md +79 -0
- package/.agents/skills/wtk-config/scripts/ad-index.py +123 -0
- package/.agents/skills/wtk-config/scripts/repository_intelligence.py +671 -0
- package/.agents/skills/wtk-config/scripts/workflow_config.py +972 -0
- package/.agents/skills/wtk-deep-review/SKILL.md +164 -0
- package/.agents/skills/wtk-deep-review/assets/PROMPT.md +56 -0
- package/.agents/skills/wtk-deep-review/assets/REVIEW_UI.html +1340 -0
- package/.agents/skills/wtk-deep-review/assets/findings.schema.json +113 -0
- package/.agents/skills/wtk-deep-review/references/context-pack.md +88 -0
- package/.agents/skills/wtk-deep-review/references/orchestration.md +164 -0
- package/.agents/skills/wtk-deep-review/references/output-contracts.md +149 -0
- package/.agents/skills/wtk-deep-review/references/publish-github.md +83 -0
- package/.agents/skills/wtk-deep-review/references/state-and-learnings.md +64 -0
- package/.agents/skills/wtk-deep-review/references/subagent-runtimes.md +33 -0
- package/.agents/skills/wtk-deep-review/references/taxonomy.md +70 -0
- package/.agents/skills/wtk-deep-review/scripts/_common.py +371 -0
- package/.agents/skills/wtk-deep-review/scripts/build_jobs.py +561 -0
- package/.agents/skills/wtk-deep-review/scripts/build_knowledge.py +349 -0
- package/.agents/skills/wtk-deep-review/scripts/build_manifest.py +479 -0
- package/.agents/skills/wtk-deep-review/scripts/graft_context.py +160 -0
- package/.agents/skills/wtk-deep-review/scripts/graphify_context.py +75 -0
- package/.agents/skills/wtk-deep-review/scripts/merge_findings.py +313 -0
- package/.agents/skills/wtk-deep-review/scripts/render_html.py +240 -0
- package/.agents/skills/wtk-deep-review/scripts/render_review.py +282 -0
- package/.agents/skills/wtk-deep-review/scripts/run_jobs.py +436 -0
- package/.agents/skills/wtk-deep-review/scripts/token_metrics.py +369 -0
- package/.agents/skills/wtk-discover/SKILL.md +270 -0
- package/.agents/skills/wtk-discover/references/document-format.md +149 -0
- package/.agents/skills/wtk-implement/SKILL.md +95 -0
- package/.agents/skills/wtk-implement/references/checklist-format.md +116 -0
- package/.agents/skills/wtk-implement/references/screens.md +129 -0
- package/.agents/skills/wtk-implement/references/test-policy.md +152 -0
- package/.agents/skills/wtk-implement/references/verify.md +297 -0
- package/.agents/skills/wtk-knowledge-check/SKILL.md +16 -0
- package/.agents/skills/wtk-knowledge-check/scripts/check.ts +502 -0
- package/.agents/skills/wtk-knowledge-check/scripts/cli.ts +32 -0
- package/.agents/skills/wtk-knowledge-check/scripts/frontmatter.ts +44 -0
- package/.agents/skills/wtk-lean/.skill-meta.json +6 -0
- package/.agents/skills/wtk-lean/NOTICE.md +18 -0
- package/.agents/skills/wtk-lean/SKILL.md +137 -0
- package/.agents/skills/wtk-lean/references/build.md +168 -0
- package/.agents/skills/wtk-lean/references/checks.md +253 -0
- package/.agents/skills/wtk-lean/references/memory.md +156 -0
- package/.agents/skills/wtk-lean/references/plan.md +514 -0
- package/.agents/skills/wtk-lean/references/verify.md +336 -0
- package/.agents/skills/wtk-lean/scripts/check_commit.py +121 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/checks.md +98 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/plan.md +119 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/verification.md +41 -0
- package/.agents/skills/wtk-lean/scripts/lessons.py +412 -0
- package/.agents/skills/wtk-lean/scripts/selftest.py +401 -0
- package/.agents/skills/wtk-lean/scripts/validate_checks.py +417 -0
- package/.agents/skills/wtk-lean/scripts/validate_plan.py +580 -0
- package/.agents/skills/wtk-lean/scripts/validate_verification.py +357 -0
- package/.agents/skills/wtk-plan/SKILL.md +102 -0
- package/.agents/skills/wtk-plan/references/document-format.md +222 -0
- package/.agents/skills/wtk-qa/SKILL.md +14 -0
- package/.agents/skills/wtk-qa-execute/SKILL.md +115 -0
- package/.agents/skills/wtk-qa-execute/references/fix-loop.md +23 -0
- package/.agents/skills/wtk-qa-execute/references/session-protocol.md +25 -0
- package/.agents/skills/wtk-qa-plan/SKILL.md +111 -0
- package/.agents/skills/wtk-qa-plan/references/profile.md +35 -0
- package/.agents/skills/wtk-ship/SKILL.md +49 -0
- package/.agents/skills/wtk-ship/remediation.py +170 -0
- package/.agents/skills/wtk-ship/scripts/close_feature.py +83 -0
- package/.agents/skills/wtk-ship/scripts/review_convergence.py +373 -0
- package/.wtk.toml.example +93 -0
- package/AGENTS.md +129 -0
- package/NOTICE.md +12 -0
- package/README.md +440 -0
- package/bin/wtk.js +25 -0
- package/docs/toolkit/README.md +56 -0
- package/docs/toolkit/decisions.md +61 -0
- package/docs/toolkit/guidelines/CONTEXT-BUDGET.md +64 -0
- package/docs/toolkit/guidelines/DX.md +67 -0
- package/docs/toolkit/guidelines/FRONTEND.md +73 -0
- package/docs/toolkit/guidelines/KNOWLEDGE-WIKI.md +128 -0
- package/docs/toolkit/guidelines/MODELING.md +134 -0
- package/docs/toolkit/guidelines/QA-EXECUTION.md +46 -0
- package/docs/toolkit/guidelines/QA-SCENARIOS.md +165 -0
- package/docs/toolkit/guidelines/REVIEW-ROUNDS.md +160 -0
- package/docs/toolkit/guidelines/SECURITY.md +160 -0
- package/docs/toolkit/guidelines/UI-UX.md +117 -0
- package/docs/toolkit/guidelines/WORKFLOW-MEMORY.md +73 -0
- package/docs/toolkit/guidelines.md +50 -0
- package/docs/toolkit/loop.md +77 -0
- package/docs/toolkit/purpose.md +51 -0
- package/docs/toolkit/repository-intelligence.md +53 -0
- package/docs/toolkit/reviews.md +77 -0
- package/knowledge/AGENTS.md +316 -0
- package/knowledge/raw/README.md +17 -0
- package/package.json +74 -0
- package/scripts/install_security_skills.py +816 -0
- package/scripts/installer/engine.js +254 -0
- package/scripts/installer/knowledge.js +28 -0
- package/scripts/installer/packets.js +77 -0
- package/scripts/installer/terminal.js +98 -0
- package/scripts/installer/transaction.js +75 -0
- package/skills-lock.json +92 -0
- package/templates/adoption/agents/core.md +23 -0
- package/templates/adoption/agents/quality.md +3 -0
- package/templates/adoption/knowledge/wiki/architecture/index.md +3 -0
- package/templates/adoption/knowledge/wiki/decisions/index.md +3 -0
- package/templates/adoption/knowledge/wiki/design/index.md +3 -0
- package/templates/adoption/knowledge/wiki/domain/index.md +3 -0
- package/templates/adoption/knowledge/wiki/index.md +3 -0
- package/templates/adoption/knowledge/wiki/log.md +3 -0
- package/templates/adoption/knowledge/wiki/open-questions/index.md +3 -0
- package/templates/adoption/knowledge/wiki/product/index.md +3 -0
- package/templates/adoption/knowledge/wiki/research/index.md +3 -0
- package/templates/adoption/product/AGENT-CONTEXT.md +25 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wtk-lean
|
|
3
|
+
description: 'Run spec-driven feature work through a reviewed plan, proof-backed checks, build, and independent verification. Use for `.specs/features/` work; not modular task lists or standalone design.'
|
|
4
|
+
license: CC-BY-4.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: Tech Leads Club - github.com/tech-leads-club
|
|
7
|
+
version: '1.0.0'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Tech Lead's Club - Spec, Lean
|
|
11
|
+
|
|
12
|
+
Run a decided feature through four moves: `PLAN → CHECKS → BUILD → VERIFY`. A human reviews the
|
|
13
|
+
feature shape before checks freeze its obligations; builders choose reversible implementation detail;
|
|
14
|
+
one fresh Verifier proves the complete feature. There is no task breakdown or component catalogue.
|
|
15
|
+
|
|
16
|
+
## Core contract
|
|
17
|
+
|
|
18
|
+
1. Every check is one observable claim with a concrete value and a proof whose exit code settles it.
|
|
19
|
+
2. Tests come from the approved checks, never from the implementation. Do not weaken, skip, or
|
|
20
|
+
delete a test to pass a gate; a wrong or impossible check stops for user renegotiation.
|
|
21
|
+
3. Approved `checks.md` and `Test policy` rows are fixed. New `Landing`, `Relations`, and `Surface`
|
|
22
|
+
rows may be added when building discovers a door, entity, or route; approved rows are never
|
|
23
|
+
rewritten. Keep `Flow` and `Impact` current when the path changes.
|
|
24
|
+
4. The coordinator dispatches one fresh Verifier over `<feature base>..HEAD` with every check after
|
|
25
|
+
the last slice. The builder reports and stops; verification is never optional or self-authored.
|
|
26
|
+
5. The declared profile is a floor. Its report names the profile and `validate_verification.py` must
|
|
27
|
+
exit 0. An approved spec authorizes local edits and commits only; push, deploy, and production
|
|
28
|
+
data changes require explicit authorization.
|
|
29
|
+
|
|
30
|
+
## Profile
|
|
31
|
+
|
|
32
|
+
`AGENTS.md` or the feature snapshot declares the profile. The resolver defaults to `standard`;
|
|
33
|
+
`light`, `standard`, and `ui` remain valid upstream levels. The profile is a floor, not a preference,
|
|
34
|
+
and `checks.md` plus the verification report must name the same value.
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
## wtk-lean
|
|
38
|
+
|
|
39
|
+
profile: standard
|
|
40
|
+
budget: 150k
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Profile | Proof obligations |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `light` | proofs at `HEAD`, named tests exist and ran, one located assertion per check, level/sampling gaps, and `Swept existing` re-read |
|
|
46
|
+
| `standard` | light plus recomputed `Coverage`, `Test policy` verdicts, and one fault per assertion surface |
|
|
47
|
+
| `ui` | standard plus binding-source comparison and per-screen copy and arrangement enumeration |
|
|
48
|
+
|
|
49
|
+
An empty input costs a recorded line, not a skipped step. `validate_verification.py` rejects a
|
|
50
|
+
profile mismatch and missing sections required by `standard` or `ui`. If the declared floor is too
|
|
51
|
+
thin, ask the user to raise it rather than silently changing the profile.
|
|
52
|
+
|
|
53
|
+
## Artifacts
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
.specs/
|
|
57
|
+
├── STATE.md # Decisions log (AD-NNN) + Handoff snapshot
|
|
58
|
+
├── LESSONS.md # rendered by scripts/lessons.py - never hand-edit
|
|
59
|
+
├── lessons.json # machine-owned
|
|
60
|
+
└── features/<feature>/
|
|
61
|
+
├── plan.md # problem, EARS criteria, surfaces walked, then flow, relations, surface, landing, impact
|
|
62
|
+
├── checks.md # claims + proofs, the coverage join, test policy, swept
|
|
63
|
+
└── verification.md # the Verifier's report
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Create each file when its phase produces content. For a change under roughly three files with no
|
|
67
|
+
one-way door, write only `checks.md` with an `## Intent` paragraph and skip `plan.md` - one
|
|
68
|
+
bounded escape, not a sizing matrix.
|
|
69
|
+
|
|
70
|
+
The plan is the human review boundary: write criteria before shape, then record the shape that
|
|
71
|
+
implements them. Its fixed sections are `Problem`, `Out of scope`, `Assumptions`, `Criteria`,
|
|
72
|
+
`Traceability`, `Observable`, `Flow`, `Relations`, `Surface`, `Landing`, and `Impact`. `Flow` is
|
|
73
|
+
the path, `Relations` the entities and one-way constraints, `Surface` the route/signature/statuses,
|
|
74
|
+
`Landing` the literal irreversible choices and rejected alternatives, and `Impact` what existing
|
|
75
|
+
terms or data change. Placement and reversible implementation detail stay in the diff.
|
|
76
|
+
|
|
77
|
+
`checks.md` derives proof-backed checks from the plan and joins every enumerated route, entity,
|
|
78
|
+
status, and door to a check. `plan.md`, `checks.md`, and `verification.md` therefore stay
|
|
79
|
+
distinct: the first freezes reviewed shape, the second freezes obligations, and the third is the
|
|
80
|
+
independent evidence. An unresolved architecture choice needs its own ADR/RFC/spike before it can
|
|
81
|
+
be recorded as a `Landing` decision.
|
|
82
|
+
|
|
83
|
+
## Phase references
|
|
84
|
+
|
|
85
|
+
- **Plan:** human review of EARS criteria, boundary, surfaces, nine implicit dimensions, and the
|
|
86
|
+
five shape sections. Ask only genuine decisions; use `n/a - <reason>` where a dimension does not
|
|
87
|
+
apply. Full procedure and closure gate: [plan.md](references/plan.md).
|
|
88
|
+
- **Checks:** derive proof-backed claims, join every enumerated set member, and record swept
|
|
89
|
+
landings: [checks.md](references/checks.md).
|
|
90
|
+
- **Build:** tests come from checks; implementation decomposition is yours. Keep new `Landing`,
|
|
91
|
+
`Relations`, and `Surface` rows additive before closing code, then use the scope guardrail and
|
|
92
|
+
handoff procedure: [build.md](references/build.md).
|
|
93
|
+
- **Verify:** after the feature's last slice, the coordinator sends one fresh Verifier over the
|
|
94
|
+
full range with every check; procedure and report schema: [verify.md](references/verify.md).
|
|
95
|
+
- **Memory:** decisions, handoff, and lessons live in [memory.md](references/memory.md).
|
|
96
|
+
|
|
97
|
+
## Scripts
|
|
98
|
+
|
|
99
|
+
Resolve `<skill-dir>` as the directory containing this `SKILL.md` and invoke
|
|
100
|
+
`python3 <skill-dir>/scripts/<name>.py`. Project data under `.specs/` stays relative to the
|
|
101
|
+
project root; pass `--root` when cwd differs. A non-zero exit stops the phase.
|
|
102
|
+
|
|
103
|
+
| When | Command |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| Before presenting the plan | `validate_plan.py <feature>` |
|
|
106
|
+
| Before starting to build | `validate_checks.py <feature>` |
|
|
107
|
+
| Before each commit | `check_commit.py --message "<msg>"` |
|
|
108
|
+
| Before declaring done | `validate_verification.py <feature>` |
|
|
109
|
+
| At distillation | `lessons.py add ...` |
|
|
110
|
+
| After editing a validator or template | `selftest.py` |
|
|
111
|
+
|
|
112
|
+
The validators own structural detail: `validate_plan.py` closes the human-reviewed shape,
|
|
113
|
+
`validate_checks.py` catches missing proofs, coverage, swept rows, and profile, and
|
|
114
|
+
`validate_verification.py` requires evidence, no surviving mutant, no `Unproven` member, and a
|
|
115
|
+
non-author Verifier. Run `selftest.py` only after changing a validator or template. If execution is
|
|
116
|
+
unavailable, perform the same checks by inspection and report the degraded path.
|
|
117
|
+
|
|
118
|
+
## Sub-agents and handoff
|
|
119
|
+
|
|
120
|
+
One builder owns whole slices sequentially. Before code, record the intended split and budget
|
|
121
|
+
arithmetic under `## Handoff`; if reading exceeds the declared budget (default 150k tokens), hand off
|
|
122
|
+
only between slices. Before handoff, the outgoing builder records closed checks, user decisions, and
|
|
123
|
+
abandoned approaches, and continues only after every proof in the batch is green. The next builder
|
|
124
|
+
reads the artifact and landed diff, not a narrative. Never split a slice or create a task DAG. The
|
|
125
|
+
coordinator owns checkpoint synchronization and the final full-range Verifier; builders report and
|
|
126
|
+
stop.
|
|
127
|
+
|
|
128
|
+
## Knowledge chain
|
|
129
|
+
|
|
130
|
+
Use existing code and conventions, project docs, library docs (Context7 where available), then web
|
|
131
|
+
search; mark anything still uncertain. Never invent an API, flag, command, or behaviour.
|
|
132
|
+
|
|
133
|
+
## Output
|
|
134
|
+
|
|
135
|
+
Produce the artifact, lead with the verdict, and keep schema headings and identifiers unchanged.
|
|
136
|
+
For a concrete feature path, `.specs/features/lockfile-v2/plan.md` is reviewed before its checks;
|
|
137
|
+
the route then validates checks, builds, and dispatches the fresh full-range Verifier.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Build
|
|
2
|
+
|
|
3
|
+
**Goal:** satisfy the checks. How is yours.
|
|
4
|
+
|
|
5
|
+
No task list, no phase plan, no per-task review tables, no `Files to touch` declaration before
|
|
6
|
+
each edit. The checks are the bar; the route is your call. If you find yourself writing a plan
|
|
7
|
+
for the model to obey, you are rebuilding the thing this skill removed.
|
|
8
|
+
|
|
9
|
+
## What is fixed and what is not
|
|
10
|
+
|
|
11
|
+
Fixed: the checks, the `Test policy` rows, and the proofs each check names. Lowering either is
|
|
12
|
+
renegotiation with the user, visible in the diff.
|
|
13
|
+
|
|
14
|
+
Yours: order, decomposition, how many commits, where files go, naming, error shapes, which
|
|
15
|
+
helper gets extracted. The repo's conventions answer most of it and the rest is reversible and
|
|
16
|
+
reviewed in the diff.
|
|
17
|
+
|
|
18
|
+
The plan's shape sections have a rule each, and the split matters because it is what keeps one
|
|
19
|
+
file both approved and current.
|
|
20
|
+
|
|
21
|
+
Additive: `Landing`, `Relations`, `Surface`. A door you discover while building gets a row - never
|
|
22
|
+
a deletion, and never a rewrite of a row the user approved. `Relations` and `Surface` grow the
|
|
23
|
+
same way, because both were reviewed: an entity or a route appearing mid-build is new information,
|
|
24
|
+
one that quietly changes shape is a renegotiation.
|
|
25
|
+
|
|
26
|
+
**Kept true: `Flow` and `Impact`.** They are a map, not an obligation, so changing them is not
|
|
27
|
+
renegotiation - but a map that no longer matches the road is worse than none, because the next
|
|
28
|
+
reader trusts it. Take a different path and the hop changes, in the commit that takes it. The rule
|
|
29
|
+
is the same as `Landing`'s and for the same reason: written afterwards it describes what you
|
|
30
|
+
happened to do, which is the failure mode of every architecture document that ever went stale.
|
|
31
|
+
|
|
32
|
+
A hop you *add* is worth a second look before you write it. Reaching a fifth module in a feature
|
|
33
|
+
scoped to two is not a `Flow` edit, it is evidence the boundary was wrong - say so rather than
|
|
34
|
+
quietly extending the path.
|
|
35
|
+
|
|
36
|
+
## Tests come from the checks
|
|
37
|
+
|
|
38
|
+
Write the test from the check's claim and its concrete value. Never write a test by reading the
|
|
39
|
+
implementation and asserting what it currently does: that produces a test that passes under the
|
|
40
|
+
bug it was supposed to catch.
|
|
41
|
+
|
|
42
|
+
**Hard constraints, no exceptions:**
|
|
43
|
+
|
|
44
|
+
- Do not weaken an assertion to make it pass.
|
|
45
|
+
- Do not delete a test, and do not use the framework's skip / disable / pending mechanism to
|
|
46
|
+
bypass a failing one.
|
|
47
|
+
- Do not modify a check's test afterwards to make the implementation pass.
|
|
48
|
+
|
|
49
|
+
A red proof is a stop, not a note. If a check turns out to be wrong or impossible, stop and
|
|
50
|
+
renegotiate with the user. The same holds for a `Landing` row the user approved that the build
|
|
51
|
+
proves unbuildable - they approved that shape specifically.
|
|
52
|
+
|
|
53
|
+
Extra tests beyond the proofs are welcome and there is no quota. A guard clause, a log line, a
|
|
54
|
+
clear error message at an edge the checks did not name: that is the work, not scope creep.
|
|
55
|
+
|
|
56
|
+
## Landing rows go in before the code
|
|
57
|
+
|
|
58
|
+
A door found mid-build did not exist when the design was confirmed, so it lands the same way that
|
|
59
|
+
file's rows did. Decide it yourself - stopping to ask on every one defeats the point of getting out
|
|
60
|
+
of your way. Then record it in `plan.md`: append the row with its literal shape and the
|
|
61
|
+
alternative you rejected **before the code that closes it is written**, and in that code's commit.
|
|
62
|
+
|
|
63
|
+
The timing is the mechanism. An alternative is only knowable while you are still choosing between
|
|
64
|
+
them; written at the end it becomes a justification of what you already wrote, which is the stale
|
|
65
|
+
design document `Landing` exists to avoid. Stating what the other option would have done is also
|
|
66
|
+
the one thing that can expose a bad decision with nobody else in the loop.
|
|
67
|
+
|
|
68
|
+
A new door that contradicts nothing already approved never stops the build.
|
|
69
|
+
|
|
70
|
+
## Commit
|
|
71
|
+
|
|
72
|
+
One coherent piece per commit, [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/):
|
|
73
|
+
`<type>(<scope>): <description>`, types `feat` `fix` `refactor` `docs` `test` `style` `perf`
|
|
74
|
+
`build` `ci` `chore`. Imperative mood, lowercase, no trailing period. A `!` marker requires a
|
|
75
|
+
`BREAKING CHANGE:` footer.
|
|
76
|
+
|
|
77
|
+
Validate before committing:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
python3 <skill-dir>/scripts/check_commit.py --message "feat(billing): suspend on failed charge"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Optional git-level guard, independent of any agent:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
ln -sf <skill-dir>/scripts/check_commit.py .git/hooks/commit-msg && chmod +x .git/hooks/commit-msg
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Skip the hook if the project manages hooks its own way. Mark the check complete in `checks.md`
|
|
90
|
+
before the commit that satisfies it, and include that update in the same commit - a crash between
|
|
91
|
+
those two steps is how a resume redoes finished work.
|
|
92
|
+
|
|
93
|
+
Never add Co-Authored-By, Made-with, or any agent attribution trailer.
|
|
94
|
+
|
|
95
|
+
## How to write the code
|
|
96
|
+
|
|
97
|
+
Behavioural bias, not a checklist:
|
|
98
|
+
|
|
99
|
+
**Simplicity.** No features beyond what was asked. No abstraction for single-use code. No
|
|
100
|
+
"flexibility" nobody requested. No error handling for impossible scenarios. Two hundred lines
|
|
101
|
+
that could be fifty: rewrite them.
|
|
102
|
+
|
|
103
|
+
**Surgical changes.** Do not improve adjacent code, comments or formatting. Do not refactor what
|
|
104
|
+
is not broken. Match existing style even where you would do it differently. Remove only the
|
|
105
|
+
imports and variables your own change orphaned; pre-existing dead code gets mentioned, not
|
|
106
|
+
deleted.
|
|
107
|
+
|
|
108
|
+
**Push back.** Multiple interpretations exist: present them, do not pick silently. A simpler
|
|
109
|
+
approach exists: say so. The user's approach looks wrong: disagree honestly.
|
|
110
|
+
|
|
111
|
+
After each change, ask whether a senior engineer would call it overcomplicated. If yes, simplify
|
|
112
|
+
before proceeding.
|
|
113
|
+
|
|
114
|
+
## Scope guardrail
|
|
115
|
+
|
|
116
|
+
You will notice things that could be improved. Do not act on them. A bug gets surfaced to the
|
|
117
|
+
user; an improvement gets noted in chat or as a follow-up. The heuristic: is this in a check? If
|
|
118
|
+
no, do not touch it.
|
|
119
|
+
|
|
120
|
+
**Blast radius.** An approved spec authorizes local edits and local commits. `git push`,
|
|
121
|
+
force-push, deploy, production DB changes and any other remote or destructive operation need an
|
|
122
|
+
explicit go-ahead for that action, even mid-build.
|
|
123
|
+
|
|
124
|
+
## Running out of context
|
|
125
|
+
|
|
126
|
+
Two ways through it, and they are not equivalent. Automatic compaction summarises the
|
|
127
|
+
*conversation* and chooses for you what to drop. A handoff to a fresh builder carries the
|
|
128
|
+
*artifact*, at a boundary you chose. This skill is built for the second - that is why `Landing`
|
|
129
|
+
rows are appended before the code that closes them rather than at the end.
|
|
130
|
+
|
|
131
|
+
**Handing off.** Only on green, with every proof in the batch passing. The next builder reads
|
|
132
|
+
`checks.md` and the **diff of what already landed** - never a narrative summary. The diff is the
|
|
133
|
+
state, and it carries the hundred reversible choices that sit below the `Landing` bar: naming,
|
|
134
|
+
error shape, where the helper went. Those are exactly what drifts between builders and exactly
|
|
135
|
+
what no document records.
|
|
136
|
+
|
|
137
|
+
Then append the three `## Handoff` lines - boundary, what the user settled mid-build, what was
|
|
138
|
+
abandoned. They go in the artifact rather than in the next builder's prompt: a briefing written
|
|
139
|
+
into a prompt survives exactly one boundary, and the third builder needs the first one's.
|
|
140
|
+
|
|
141
|
+
**When compaction happens anyway,** re-read `checks.md` and the diff before continuing. You
|
|
142
|
+
cannot see the limit approaching, but you can see that a compaction occurred - so build the
|
|
143
|
+
recovery on the signal that exists.
|
|
144
|
+
|
|
145
|
+
## Then stop
|
|
146
|
+
|
|
147
|
+
When the last check of **your batch** is committed, report and stop: checks closed, commit
|
|
148
|
+
hashes, proof results, deviations. Do not dispatch the Verifier - that is the orchestrator's
|
|
149
|
+
step, after the last batch of the whole feature, over the full check set. A Verifier briefed by
|
|
150
|
+
the builder that just closed the final batch inherits that builder's scope even though it
|
|
151
|
+
inherits none of its tokens, and reports a pass over four checks that reads exactly like a pass
|
|
152
|
+
over forty. See [verify.md](verify.md).
|
|
153
|
+
|
|
154
|
+
## What was deliberately removed
|
|
155
|
+
|
|
156
|
+
If you are used to a per-task cycle, these are gone on purpose:
|
|
157
|
+
|
|
158
|
+
| Removed | Why |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| Granular task breakdown with `Where` / `Tools` / `Depends on` | buys ordering, not correctness, and competes with the checks for attention |
|
|
161
|
+
| Per-task test adequacy review with evidence tables | author self-review reproduces the author's own blind spot; the Verifier does it once, better |
|
|
162
|
+
| Pre-implementation assumption declaration per task | the assumptions that matter are in the spec, closed by its gate |
|
|
163
|
+
| The component catalogue in a design doc - `Purpose` / `Location` / `Interfaces` / `Dependencies` per class | reversible detail that goes stale with the authority of a document; the plan keeps the path, the entities, the signature and the doors, and nothing per-component |
|
|
164
|
+
| The `graph TD` architecture diagram, as the default rendering of the path | a picture of five boxes carries less than five lines that each say what enters, what crosses and what is handed on, and it rots silently while `Flow` is kept true through the build; a mermaid `flowchart` stays available for the case a list genuinely cannot express - a fan-out, a fork, an async hand-off |
|
|
165
|
+
| The `Code Reuse Analysis` table - `Component` / `Location` / `How to Use` | the inventory is already distributed through `Flow`, where each hop marks whether its module exists; what a table adds beyond that is the catalogue again, so only the decision survives, as the sentence opening `Flow` on what is reused instead of duplicated |
|
|
166
|
+
| The pace question (`Quick` / `Guided` / `Detailed`) and a `context.md` of its own | a meta-question spends a turn deciding how to spend turns; the elicitation rules apply always, and their output lands in the plan's `Assumptions` |
|
|
167
|
+
| A quota of gray areas to generate per feature | a quota manufactures questions; the surface rubric in `## Observable` is a fixed enumeration with an `n/a` escape instead, which finds items without inventing them |
|
|
168
|
+
| An offer to spawn sub-agents | logistics the user cannot decide better than you |
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Checks
|
|
2
|
+
|
|
3
|
+
**Goal:** one small, frozen, external obligation set. Every claim carries the proof that
|
|
4
|
+
settles it, and every enumerated set is joined member by member, so an omission leaves an empty
|
|
5
|
+
cell instead of a confident sentence.
|
|
6
|
+
|
|
7
|
+
This is the artifact everything downstream refers to by check number: a proof, a review
|
|
8
|
+
comment, a question, a fault. It replaces a task breakdown - it says what must be true, never
|
|
9
|
+
how to work.
|
|
10
|
+
|
|
11
|
+
**It is derived, not decided.** [plan.md](plan.md) settled what must be true and what is being
|
|
12
|
+
built; this turns both into obligations with proofs.
|
|
13
|
+
So the shape - the path, the entities, the interface, the doors - is not written here and not
|
|
14
|
+
re-argued here. What *is* this file's job is the derivation, and it is where omissions surface:
|
|
15
|
+
every route's statuses in `Surface`, every door in `Landing`, every entity in `Relations` owes a
|
|
16
|
+
set row in `Coverage` or a check. A shape section with nothing pointing back at it from here is
|
|
17
|
+
either dead or unproven, and both are findings.
|
|
18
|
+
|
|
19
|
+
## Find the real commands first
|
|
20
|
+
|
|
21
|
+
Read the package manifest, the task runner and the CI workflows. Prefer a command that already
|
|
22
|
+
runs in CI. Where nothing exists for what a check needs, ask - never invent a command, because
|
|
23
|
+
a proof that cannot run is worse than none.
|
|
24
|
+
|
|
25
|
+
A proof must name a **specific test**, not a whole suite. A suite going green settles no
|
|
26
|
+
individual claim. Repeat `Proof:` when one test cannot settle the whole claim; every proof
|
|
27
|
+
listed must be green.
|
|
28
|
+
|
|
29
|
+
## What makes a check writable
|
|
30
|
+
|
|
31
|
+
Four things must be true before you write one:
|
|
32
|
+
|
|
33
|
+
- someone could **observe** the outcome - if you cannot say what would be seen, it is too vague
|
|
34
|
+
- it carries a **concrete value** - a status code, a field, a bound
|
|
35
|
+
- **one run settles it** - a single execution either satisfies it or does not
|
|
36
|
+
- you can name the **proof** - the test or command whose exit code decides
|
|
37
|
+
|
|
38
|
+
Missing one is normal and asking is cheap. Proceeding on a guess is not: a vague check becomes a
|
|
39
|
+
vague assertion that passes, which is the failure this whole artifact exists to prevent.
|
|
40
|
+
|
|
41
|
+
## The proof has to reach the claim
|
|
42
|
+
|
|
43
|
+
Read the code before choosing the proof, then check the claim against the input space behind it.
|
|
44
|
+
|
|
45
|
+
A claim about nine provider statuses is not proven by a test that exercises two - that gap needs
|
|
46
|
+
a second proof, and it is a question about coverage rather than about test style. A claim phrased
|
|
47
|
+
as a response at a boundary is not settled by a test that never crosses it. A claim about a
|
|
48
|
+
decision table is not settled by one path through it. When the claim and the proof sit at
|
|
49
|
+
different levels, either split the claim or name the second proof - never let the level slide to
|
|
50
|
+
whichever is cheaper to write.
|
|
51
|
+
|
|
52
|
+
**Obligations add up rather than substitute.** A test proves the layer where it *asserts*, not
|
|
53
|
+
the layers it happens to *pass through*. An end-to-end test that traverses a branch exercises one
|
|
54
|
+
path through it and cannot fail when a second branch is wrong. Treating it as proof of the code
|
|
55
|
+
it traversed is level substitution, and it is the most common way a green suite ships a broken
|
|
56
|
+
branch table.
|
|
57
|
+
|
|
58
|
+
## Coverage - the join
|
|
59
|
+
|
|
60
|
+
Every set a proof must cover gets a row, and **every member is written as its own token** beside
|
|
61
|
+
the check that proves it.
|
|
62
|
+
|
|
63
|
+
A set collapsed into a sentence - "dispatches over paused, updated, deleted and trial_will_end" -
|
|
64
|
+
has no empty cell, so a member can go missing while the sentence still reads perfectly. That is
|
|
65
|
+
how a branch named in your own evidence ships unproven. One proof that is table-driven over the
|
|
66
|
+
whole set may stand for it, with the size stated, because there the enumeration lives in the test.
|
|
67
|
+
|
|
68
|
+
Walk it **from the sets, not from the checks.** Summarising the checks you just wrote can only
|
|
69
|
+
find a check with nothing behind it; it cannot find a name with no check, which is the failure
|
|
70
|
+
that costs. The rows are not a new inventory - they are the enumerations already named somewhere:
|
|
71
|
+
a door in the plan's `Landing`, a decision table in the level evidence, the input space behind
|
|
72
|
+
a claim. Anything enumerated in prose owes a row here.
|
|
73
|
+
|
|
74
|
+
**Every route in the plan's `Surface` owes a row, and its members are the statuses.** That row
|
|
75
|
+
is the only thing that turns the signature you reviewed into an obligation; without it a status
|
|
76
|
+
listed in the plan can ship with nothing behind it, and the artifact that named it looks like
|
|
77
|
+
evidence that it was covered.
|
|
78
|
+
|
|
79
|
+
Never assert a negative. Write the count and its denominator and let `-` in the `Unproven`
|
|
80
|
+
column be earned by the row beside it.
|
|
81
|
+
|
|
82
|
+
**Startup configuration is a set too, and its members are places.** A test suite assembles the
|
|
83
|
+
application itself, so anything this change needs to be true before the first request arrives now
|
|
84
|
+
lives in every assembly separately - and a proof can only ever assert the one it built. Each
|
|
85
|
+
assembly is a member, including every app that mounts the module. The member is the place, never
|
|
86
|
+
the value: the failure is not a wrong value, it is a value present in one assembly and absent from
|
|
87
|
+
another. Two resolutions count - a proof at each place, or one shared assembly both paths use.
|
|
88
|
+
Prefer the second; a row with two members is already the argument for collapsing them.
|
|
89
|
+
|
|
90
|
+
## Test policy (`standard`, `ui`)
|
|
91
|
+
|
|
92
|
+
Only when the repo does not already answer two questions for every layer this change touches:
|
|
93
|
+
**which level proves this code**, and **how much of its input space must the proof assert to
|
|
94
|
+
count**. Do not judge whether the repo "has testing docs" - it almost always does, and that
|
|
95
|
+
impression is what makes this step never fire.
|
|
96
|
+
|
|
97
|
+
A statement answers neither question when it only says where tests live, how they are named, how
|
|
98
|
+
to run them, or how a test is built (which dependencies are real and which are doubled). Watch
|
|
99
|
+
for the last one especially: keying the level to whether a test uses real dependencies decides
|
|
100
|
+
*how* to write a test, and read as deciding *what deserves* one, every decision table that
|
|
101
|
+
touches a real dependency gets routed away from its own layer and is never enumerated.
|
|
102
|
+
|
|
103
|
+
Classify by the **shape of the code**, never by the name of the layer. Layer names lie.
|
|
104
|
+
|
|
105
|
+
- **Instrumentation** - the body forwards its arguments to one call, or maps one shape onto
|
|
106
|
+
another with no conditional deciding the result. A test over it re-asserts the framework.
|
|
107
|
+
- **Decision** - anything that changes an outcome. A dispatch over a status or event type. A
|
|
108
|
+
boundary or validation check. A state transition. A conditionally assembled payload. A mapping
|
|
109
|
+
table with more than one row. A guard, a precedence rule, an ordering rule.
|
|
110
|
+
|
|
111
|
+
Count the decision points per file and write the number down: "dispatches over six event types,
|
|
112
|
+
eleven branch points" is contestable, "looks like business logic" is not. Then **name the
|
|
113
|
+
members**, because those names are what `Coverage` joins against.
|
|
114
|
+
|
|
115
|
+
Derive from the code, not from the current suite - a module with no tests at a level is evidence
|
|
116
|
+
about its history, not that its logic needs none. Judge the house pattern across the whole repo,
|
|
117
|
+
not the folder you happen to be changing: search for the closest analogue by code shape - the
|
|
118
|
+
other state machine, the other dispatcher - and cite it. A proposal pointing at a sibling proven
|
|
119
|
+
at that level is precedent; one that does not is taste.
|
|
120
|
+
|
|
121
|
+
State the cost. Then ask **one** narrow question: do these rows go into the repo's guidelines?
|
|
122
|
+
Building under them is reversible and needs no permission; writing them reaches every future
|
|
123
|
+
agent, so approved rows land in their own commit before the build. If the user does not answer,
|
|
124
|
+
build under them and leave the files alone.
|
|
125
|
+
|
|
126
|
+
## Template: `.specs/features/<feature>/checks.md`
|
|
127
|
+
|
|
128
|
+
````markdown
|
|
129
|
+
# <Feature> checks
|
|
130
|
+
|
|
131
|
+
Profile: light
|
|
132
|
+
Plan: `.specs/features/<feature>/plan.md`
|
|
133
|
+
|
|
134
|
+
## Intent
|
|
135
|
+
|
|
136
|
+
<Only when there is no plan.md - a change under three files with no one-way door: the problem in
|
|
137
|
+
the present tense, then what is different for a user when this ships.>
|
|
138
|
+
|
|
139
|
+
<N checks in M slices · K one-way doors · Q open, of which B block>
|
|
140
|
+
|
|
141
|
+
## Checks
|
|
142
|
+
|
|
143
|
+
Grouped by the spec's slices; numbering runs across the whole feature.
|
|
144
|
+
|
|
145
|
+
### S1 - <slice> · 4 files · 38 KB · ~10k
|
|
146
|
+
|
|
147
|
+
**C1** - A failed charge sets status to Suspended, never Cancelled (FEAT-01, AC 1)
|
|
148
|
+
Proof: `bin/rails test test/billing/dunning_test.rb -n "/failed_charge_suspends/"`
|
|
149
|
+
|
|
150
|
+
**C2** - Every provider status maps to exactly one local status (FEAT-01, AC 4)
|
|
151
|
+
Proof: `bin/rails test test/billing/status_map_test.rb -n "/every_provider_status/"`
|
|
152
|
+
|
|
153
|
+
### S2 - <slice> · 9 files · 140 KB · ~35k
|
|
154
|
+
|
|
155
|
+
**C3** - Retrying the same webhook delivery id changes nothing (FEAT-02, AC 5)
|
|
156
|
+
Proof: `bin/rails test test/webhooks/ingest_test.rb -n "/retry_is_idempotent/"`
|
|
157
|
+
|
|
158
|
+
## Coverage
|
|
159
|
+
|
|
160
|
+
| Set (size) | Member -> proof | Unproven |
|
|
161
|
+
| --- | --- | --- |
|
|
162
|
+
| provider status -> local (9) | C2, table-driven over all 9 | - |
|
|
163
|
+
| webhook event types (5) | `paused` C12 · `updated` C13 · `deleted` C14 · `trial_will_end` C15 · other C16 | - |
|
|
164
|
+
| `trial_days` bound (4 edges) | 0 C5 · 1 C5 · 30 C5 · 31 C5 | - |
|
|
165
|
+
| `Suspended` transitions (3) | into it C1 · out to `Active` C6 · out to `Cancelled` C7 | - |
|
|
166
|
+
| `POST /webhooks/provider` statuses (3) | 200 C3 · 409 C7 · 422 C16 | - |
|
|
167
|
+
| startup config: raw request body (2 assemblies) | app entry point C17 · test harness C3 | - |
|
|
168
|
+
|
|
169
|
+
- Claims naming a status code, route or response shape: C7, C12, C16 - each has a proof that
|
|
170
|
+
crosses the boundary
|
|
171
|
+
- No other check claims more than the single case its proof exercises
|
|
172
|
+
|
|
173
|
+
## Test policy
|
|
174
|
+
|
|
175
|
+
<Only at `standard` / `ui`, and only when the repo leaves the two questions open. Omit the
|
|
176
|
+
section entirely otherwise.>
|
|
177
|
+
|
|
178
|
+
| Code | Required proofs | Coverage expectation |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| Decides, reached across a boundary | one at the boundary **and** one at its own layer | the contract at the boundary; one asserted case per row of the decision table at its own layer |
|
|
181
|
+
| Decides, not reached across a boundary | one at its own layer | one asserted case per row of the decision table |
|
|
182
|
+
| Entry point that decides nothing | one at the boundary | accepted input, each rejected input, each error path |
|
|
183
|
+
| Instrumentation, pass-throughs | none of its own | covered by its consumer's proof |
|
|
184
|
+
|
|
185
|
+
Evidence:
|
|
186
|
+
|
|
187
|
+
- `<file>`: dispatches over <n> cases, <n> branch points -> decides
|
|
188
|
+
- `<file>`: forwards a single call, no conditional -> instrumentation
|
|
189
|
+
- closest analogue in the repo: `<file>`, same shape, already proven at this level with <n> cases
|
|
190
|
+
|
|
191
|
+
Cost: <n> proofs at their own layer across <n> files. Without these rows, <n> decision tables are
|
|
192
|
+
proven only by a path that happens to traverse them.
|
|
193
|
+
|
|
194
|
+
## Swept
|
|
195
|
+
|
|
196
|
+
Where each unwritten requirement landed. All nine, one line each, every time.
|
|
197
|
+
|
|
198
|
+
- validation: C5
|
|
199
|
+
- failure modes: C1
|
|
200
|
+
- idempotency: C3
|
|
201
|
+
- authorization: existing - <the guard or policy that already covers this>
|
|
202
|
+
- concurrency: C7
|
|
203
|
+
- data lifecycle: n/a - <why it does not apply>
|
|
204
|
+
- dependency failure: C6
|
|
205
|
+
- state transitions: C1, C2
|
|
206
|
+
- observability: n/a - no logging requirement in this slice
|
|
207
|
+
|
|
208
|
+
## Out of scope
|
|
209
|
+
|
|
210
|
+
- <excluded capability> - <why>
|
|
211
|
+
|
|
212
|
+
## Handoff
|
|
213
|
+
|
|
214
|
+
Intended split, with the arithmetic, written before any code:
|
|
215
|
+
|
|
216
|
+
- S1-S3 = 118k, all in Billing; S4 enters Webhooks at 140k -> hand off after S3
|
|
217
|
+
|
|
218
|
+
<Appended by each builder as it finishes, three lines each:>
|
|
219
|
+
|
|
220
|
+
- **Boundary:** C1-C7 closed at `<sha>`
|
|
221
|
+
- **Settled mid-build:** <every clarification the user gave that did not become a Landing row or an edited check>
|
|
222
|
+
- **Abandoned:** <tried, discarded, and why>
|
|
223
|
+
````
|
|
224
|
+
|
|
225
|
+
`Out of scope` is only needed when there is no plan, which already carries it - along with
|
|
226
|
+
everything about the requirements and the solution's shape: [plan.md](plan.md).
|
|
227
|
+
|
|
228
|
+
## Gate before building
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
python3 <skill-dir>/scripts/validate_checks.py <feature>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
It fails a check with no `Proof:`, a duplicate check id, a coverage row whose declared size
|
|
235
|
+
exceeds the members actually assigned, a coverage row with an empty member cell, a missing swept
|
|
236
|
+
dimension, a swept landing left blank, and a missing `Profile:` line. It warns on a proof that
|
|
237
|
+
names no test selector, on a claim carrying a vague word, and - the derivation check - on a route
|
|
238
|
+
the plan's `Surface` names that nothing here mentions.
|
|
239
|
+
|
|
240
|
+
A non-zero exit means fix before writing code. The script checks structure; the judgment - is the
|
|
241
|
+
proof the right one, does the level match the claim - stays yours.
|
|
242
|
+
|
|
243
|
+
## Then keep going
|
|
244
|
+
|
|
245
|
+
Write the artifact and continue into [build.md](build.md). Waiting for approval by default buys
|
|
246
|
+
nothing when the plan was already confirmed and the checks derive from it. Stop only for: scope
|
|
247
|
+
the sweep raised that would grow the work, a derivation that contradicts the approved plan -
|
|
248
|
+
which sends you back to that file, not around it - anything the writability gate caught that
|
|
249
|
+
asking did not resolve, and writing test-policy rows into the repo's guidelines.
|
|
250
|
+
|
|
251
|
+
What keeps this reviewable is the ordering, not a commit: the artifact is complete before you
|
|
252
|
+
touch code, so it reads as what you were building toward rather than a rationalisation of what
|
|
253
|
+
you built.
|