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,116 @@
|
|
|
1
|
+
# Checklist format
|
|
2
|
+
|
|
3
|
+
Load this file only when writing `.checks/<feature>.md` — after the source is read, the refuse gate is passed, and the sweep is walked. Do not load it during the first pass of Extract.
|
|
4
|
+
|
|
5
|
+
Replace every placeholder with a concrete value, or omit the section. A heading with "N/A" under it does not appear.
|
|
6
|
+
|
|
7
|
+
## Template
|
|
8
|
+
|
|
9
|
+
Write `.checks/<feature>.md`:
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
# <Feature>
|
|
13
|
+
|
|
14
|
+
Sources:
|
|
15
|
+
|
|
16
|
+
- <ticket URL, document path, or "conversation"> - <what it settles>
|
|
17
|
+
- <design / screens> - **binding for the interface**: screens <ids>
|
|
18
|
+
|
|
19
|
+
## Out of scope
|
|
20
|
+
|
|
21
|
+
- <excluded capability> - <why>
|
|
22
|
+
|
|
23
|
+
## Landing
|
|
24
|
+
|
|
25
|
+
<Two or three lines: which modules this touches and what it reuses instead of duplicating.>
|
|
26
|
+
|
|
27
|
+
| One-way door | Literal shape | Alternative rejected |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `subscription.status` gains `Suspended` | enum value, not null, existing rows backfilled to `Active` | a boolean `is_suspended` - cannot express the next state |
|
|
30
|
+
| Provider status mapping becomes a module-level table | `map(providerStatus) -> localStatus`, total over the provider's 9 values | an inline switch per call site, the convention today - it drifts silently when the provider adds a status |
|
|
31
|
+
|
|
32
|
+
- Nothing else in this change is hard to reverse
|
|
33
|
+
|
|
34
|
+
## Checks
|
|
35
|
+
|
|
36
|
+
### S1 - Suspension on a failed charge · 4 files · 38 KB · ~10k
|
|
37
|
+
|
|
38
|
+
**C1** - A failed charge sets status to Suspended, never Cancelled
|
|
39
|
+
Proof: `pytest tests/billing/test_dunning.py::test_failed_charge_suspends`
|
|
40
|
+
|
|
41
|
+
**C2** - Every provider status maps to exactly one local status
|
|
42
|
+
Proof: `pytest tests/billing/test_status_map.py::test_every_provider_status_maps`
|
|
43
|
+
|
|
44
|
+
### S2 - Webhook ingest · 9 files · 140 KB · ~35k
|
|
45
|
+
|
|
46
|
+
**C3** - Retrying the same webhook delivery id changes nothing
|
|
47
|
+
Proof: `bun test -- -t "retry is idempotent"`
|
|
48
|
+
|
|
49
|
+
## Swept
|
|
50
|
+
|
|
51
|
+
- validation: C5
|
|
52
|
+
- failure modes: C1
|
|
53
|
+
- idempotency: C3
|
|
54
|
+
- authorization: existing auth guard already covers this route
|
|
55
|
+
- concurrency: C7 - second concurrent start returns 409
|
|
56
|
+
- data lifecycle: not in scope - nothing is retained
|
|
57
|
+
- dependency failure: C6
|
|
58
|
+
- state transitions: C1, C2
|
|
59
|
+
- observability: not in scope - no log requirement in V1
|
|
60
|
+
|
|
61
|
+
## Coverage
|
|
62
|
+
|
|
63
|
+
| Set (size) | Member -> proof | Unproven |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| provider status -> local (9) | C2, table-driven over all 9 | - |
|
|
66
|
+
| webhook event types (5) | `paused` C12 · `updated` C13 · `deleted` C14 · `trial_will_end` C15 · other C16 | - |
|
|
67
|
+
| `trialDays` bound (4 edges) | 0, 1, 30, 31 all in C5 | - |
|
|
68
|
+
| `Suspended` transitions (3) | into it C1 · out to `Active` C6 · out to `Cancelled` C7 | - |
|
|
69
|
+
| startup config: raw request body (2 assemblies) | app entry point C17 · test harness C3 | - |
|
|
70
|
+
|
|
71
|
+
- Claims naming a status code, route or response shape: C7, C12, C16 - each has a proof
|
|
72
|
+
that crosses the boundary
|
|
73
|
+
- No other check claims more than the single case its proof exercises
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Sources** is a list because what feeds this is a list. A task normalises several documents - a ticket, a PRD, a design, a branch - and a single-line field quietly keeps the ones that look like documents. Carry every source the upstream artifact names, each with what it settles, and mark the design as binding for the interface. Losing one here is a failure of Extract rather than a formatting preference: what does not cross into this file stops existing for whoever builds, and the design is the usual casualty, because it is the only source that is not prose.
|
|
77
|
+
|
|
78
|
+
`Landing` carries the doors this change closes and nothing else. A door is one-way when reversing it costs more than a refactor: a persisted schema, a contract someone else consumes, a new dependency, a data backfill - and a pattern the codebase does not have yet, because precedent stops being reversible once the next features have copied it. Each row shows the **literal shape** the next person will copy and what you rejected, named with the property that disqualified it: "cleaner" cannot be argued with, "cannot express the next state" can. Where the choice was forced rather than compared, name the constraint that forced it; where two options were live, give each one a row. For a pattern the rejected option is the convention already in the code. Decomposition inside a convention that already exists is not a door: it is reversible at the cost of a refactor, and writing it down produces exactly the design document that goes stale and then misleads. `None - <why nothing here is one-way>` is a complete answer, and the closing line is what makes the omission contestable.
|
|
79
|
+
|
|
80
|
+
That deferral is what keeps this skill from emitting a design document, and it presupposes something to defer to. Where there is no convention to read, both halves are empty at once - nothing written down and nothing to inherit - and the work belongs in a flow that does design before this one starts.
|
|
81
|
+
|
|
82
|
+
Where the repo already keeps a decision log or ADRs, append the rows that outlive this feature there once the checklist is approved - the checklist stops being read after the merge, and a choice with its rejected alternative keeps its value long after the code has moved. Do not start a log for this skill.
|
|
83
|
+
|
|
84
|
+
**Checks group under the slices they came from.** The upstream task already cuts the work into slices of one observable outcome each; flattening them into `C1..Cn` loses a structure the source had and that `## Handoff` later refers to by name. Keep the slice, keep its name, number the checks straight through.
|
|
85
|
+
|
|
86
|
+
Each slice heading carries its **size**, and the arithmetic is `wc -c` on the files that slice touches - the ones its checks land in, which `Landing` and your own walk already named - divided by four. That is a floor: it counts what you will read, not the iteration on top, which is the larger and less predictable half. It is still worth writing, because ranking slices by weight is the decision, and a floor ranks correctly even when it under-counts.
|
|
87
|
+
|
|
88
|
+
A check is **one** observable claim. If you need "and", split it. The proof must name a specific test, not a whole suite - a suite going green says nothing about *this* claim. Repeat `Proof:` when one test cannot settle the whole claim, and every proof listed must be green.
|
|
89
|
+
|
|
90
|
+
Read the code before choosing the proof, then check the claim against the input space behind it. A claim about nine provider statuses is not proven by a proof that exercises two - that gap needs a second proof, and it is a question about coverage rather than about test style.
|
|
91
|
+
|
|
92
|
+
The proof also has to be able to **reach the claim's subject**. A claim phrased as a response at a boundary is not settled by a test that never crosses it, and a claim about a decision table is not settled by one path through it. When the claim and the proof sit at different levels, either split the claim or name the second proof - never let the level slide to whichever one is cheaper to write.
|
|
93
|
+
|
|
94
|
+
**The level is the project's call, not this skill's** - but a proof settles the layer it asserts at, never the layers it passes through, so a claim proven at the boundary leaves the decision table behind it unproven. Follow what the repo declares - `AGENTS.md`, contributing docs, testing guidelines - and where its declaration does not say which code must be proven at which level and how deeply, derive that from the shape of the code, propose it with the checklist, and write the approved rows into the repo's own guidelines so the next run inherits them - under `standard` or `ui`, following [test-policy.md](references/test-policy.md); under `light` follow the repo and leave the gap unclosed, which is one of the things that profile buys you. Never impose a pyramid the codebase does not have, and never read a thin existing suite as the bar for logic it does not cover.
|
|
95
|
+
|
|
96
|
+
`Coverage` answers the sampling question in writing, while it is still cheap to act on. It is a **join, not a summary**: every set a proof must cover gets a row, and every member of that set is written as its own token beside the check that proves it. A set collapsed into a sentence - "dispatches over paused, updated, deleted and trial_will_end" - has no empty cell, so a member can go missing while the sentence still reads perfectly. That is how a branch named in your own evidence ships unproven. One proof that is table-driven over the whole set may stand for it, with the size stated, because there the enumeration lives in the test.
|
|
97
|
+
|
|
98
|
+
The rows are not a new inventory - they are the enumerations this artifact has already named somewhere: a door in `Landing`, a decision table in the test-policy evidence, the input space behind a claim. Anything you enumerated in prose owes a row here, which is the point: the two places have to agree, and only one of them can hide a member.
|
|
99
|
+
|
|
100
|
+
Walk it **from the sets, not from the checks**. Summarising the checks you just wrote can only find a check with nothing behind it; it cannot find a name with no check, which is the failure that costs. And state the gap as members rather than as an absence: `deleted` sitting in the `Unproven` column is contestable by anyone reading, while "nothing is missing" can only be checked by redoing the entire allocation, so nobody does. Never assert a negative here - write the count and its denominator, and let `-` be earned by the row beside it.
|
|
101
|
+
|
|
102
|
+
**Startup configuration is a set too, and its members are places.** A test suite assembles the application itself, so anything this change needs to be true before the first request arrives now lives in every assembly separately - and a proof can only ever assert the one it built. Each assembly is a member, including every app that mounts the module, so the size of the row is the number of assemblies rather than always two. The member is the place and never the value: the failure is not a wrong value, it is a value present in one assembly and absent from another, and a row whose member is the setting collapses into a single cell that cannot be empty.
|
|
103
|
+
|
|
104
|
+
Two resolutions count - a proof at each place, or one shared assembly both paths use. Prefer the second: it deletes the seam instead of testing it twice, and a row with two members is already the argument for collapsing them. When the setting already lives in exactly one place both paths share, no row is owed, and that is the better state rather than a loophole. A proof that passes only because the test assembles the system differently from production is **assembly substitution** - the same family as the level substitution in [test-policy.md](references/test-policy.md), and invisible to every coverage policy there is, because the branch *is* covered and only the assembly differs.
|
|
105
|
+
|
|
106
|
+
Under `profile: ui` the designed screens are a set too, with a row of their own - [screens.md](references/screens.md) has its shape.
|
|
107
|
+
|
|
108
|
+
The last two lines close the level gap the same way. List every check whose claim names a status code, a route or a response shape; each of them needs a proof that crosses the boundary. Writing the ids down is the whole mechanism: a check claiming a `400` while all its proofs sit below the boundary has to appear in that list, and the line is then false on its face.
|
|
109
|
+
|
|
110
|
+
Find the real commands first: read the package manifest, the task runner and the CI workflows. Prefer a command that already runs in CI. When nothing exists for what a check needs, ask - never invent a command, because a proof that cannot run is worse than none.
|
|
111
|
+
|
|
112
|
+
Then write the checklist and keep going into Build. Waiting for approval by default buys nothing when someone already decided the source and the checklist mostly restates it.
|
|
113
|
+
|
|
114
|
+
**What keeps it reviewable is the ordering, not a commit.** The artifact is complete before you touch code, so it reads as what you were building toward rather than a rationalisation of what you built. Where the project tracks `.checks/`, that ordering is worth a commit of its own before any code; where the project ignores it - which is common, and correct for a working artifact the skill says stops being read after the merge - the ordering still holds and nothing about it depends on git.
|
|
115
|
+
|
|
116
|
+
Stop only for what the user alone can settle: a `Landing` door with a live alternative - a forced choice needs no permission, a chosen one does; scope the sweep raised that would grow the work; anything the refuse-rather-than-guess door caught that asking did not resolve; and writing test-policy rows into the repo's guidelines, which you build under either way. Stop at the artifact when the request asked for the checklist alone.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Screens
|
|
2
|
+
|
|
3
|
+
**Read this only under `profile: ui`.** Under `light` or `standard` the interface is out of
|
|
4
|
+
scope for the checks, and loading this file costs a run that will not use it.
|
|
5
|
+
|
|
6
|
+
## The design decides, the check records
|
|
7
|
+
|
|
8
|
+
**On a screen the concrete values live in the design, so open it before writing the check.**
|
|
9
|
+
"Renders the intake" and "the body includes montando" pass under any interface at all - that is
|
|
10
|
+
"gracefully" wearing a string literal. Not fidelity, which no exit code settles, but the values
|
|
11
|
+
that are assertable and only the design carries: which elements exist, what the labels say, what
|
|
12
|
+
the step counter reads, whether a state is its own screen or a band on one that already exists.
|
|
13
|
+
Named, they are settled by the runner like every other check.
|
|
14
|
+
|
|
15
|
+
**A design is binding, not reference.** When a check and the design disagree, the check is wrong
|
|
16
|
+
until the user says otherwise. This is the failure worth naming, because it does not look like
|
|
17
|
+
one: a checklist that contradicts the design ships the contradiction with every proof green, and
|
|
18
|
+
the build is then correct against the artifact and wrong against the decision.
|
|
19
|
+
|
|
20
|
+
**It also outranks the screen that is already there.** Reuse is about components - the card, the
|
|
21
|
+
button, the container - never about a layout the design replaced. When the feature lands on an
|
|
22
|
+
existing screen and the design draws that screen differently, the old composition is the thing
|
|
23
|
+
the change is for; keeping it because it was already built is the most comfortable way to ship
|
|
24
|
+
the wrong screen with every check green.
|
|
25
|
+
|
|
26
|
+
## When the repo has a design system
|
|
27
|
+
|
|
28
|
+
Both are binding and they do not collide, because they decide different things. **The design
|
|
29
|
+
decides structure and hierarchy** - which regions exist, what contains what, which indicator, in
|
|
30
|
+
what order. **The system decides the values that realise it** - the colour token, the type scale,
|
|
31
|
+
the spacing scale, the component that already exists.
|
|
32
|
+
|
|
33
|
+
So never lift a hex or a font family out of a mock into a repo that has tokens: that breaks
|
|
34
|
+
theming, and the system is right. And never surrender the arrangement on the way there. "Use the
|
|
35
|
+
tokens" answers colour and answers nothing at all about whether the progress indicator is a ring
|
|
36
|
+
or a bar. Where a value in the mock has no token to land in, that is a finding for the user, not
|
|
37
|
+
a licence to redraw the screen around what the system already had.
|
|
38
|
+
|
|
39
|
+
## Open it, and say how
|
|
40
|
+
|
|
41
|
+
**Resolve it before writing a screen check, and do not assume you cannot.** Most designs are
|
|
42
|
+
reachable: an artifact URL opens with a fetch, a design file opens through its MCP where one is
|
|
43
|
+
connected, an attachment on a tracker issue comes down through that tracker's API, and an image
|
|
44
|
+
committed to the repo is a file to read. Work through whatever the environment actually offers,
|
|
45
|
+
then say which route worked - "the link was in the ticket" and "I opened the design" are
|
|
46
|
+
different claims, and only one of them is evidence.
|
|
47
|
+
|
|
48
|
+
**Opened means you saw the screens, not that a fetch returned bytes.** A design attachment often
|
|
49
|
+
arrives as something that is not an image: a JS bundle, an archive, a page whose markup is a
|
|
50
|
+
loader. Downloading that and recording the source as opened is the worst of the three outcomes,
|
|
51
|
+
worse than reporting it unreachable, because the checklist then claims an authority nobody
|
|
52
|
+
consulted and every later step trusts the claim. If you cannot see the arrangement, the design is
|
|
53
|
+
**unresolved** - say what came back, mark the screen checks as written without it, and let the
|
|
54
|
+
`Unproven` column carry the composition.
|
|
55
|
+
|
|
56
|
+
Falling back is allowed; doing it silently is not, and neither is falling back without trying -
|
|
57
|
+
a link reported as inaccessible on the strength of its domain is a fabricated fact, not caution.
|
|
58
|
+
When nothing resolves, record against the entry in `Sources` what you attempted and what came
|
|
59
|
+
back, build the screen checks from the values the task transcribed, and mark those checks as
|
|
60
|
+
written without the design. An unresolved design is a finding somebody can act on; an
|
|
61
|
+
unmentioned one is what produces the wrong screens.
|
|
62
|
+
|
|
63
|
+
## How far a screen check reaches
|
|
64
|
+
|
|
65
|
+
How far a screen check reaches is the same question as any other level and has the same answer:
|
|
66
|
+
whatever the repo already asserts. Where a suite drives a browser, a screen check can live there;
|
|
67
|
+
where only request tests exist, structural assertions are the ceiling. Never bring in a browser
|
|
68
|
+
stack to satisfy this - a proof that cannot run in the project's own setup is worse than none, and
|
|
69
|
+
this skill installs nothing.
|
|
70
|
+
|
|
71
|
+
What the ceiling leaves out is far narrower than it sounds, and overstating it turns this into an
|
|
72
|
+
amnesty. A selector reaches presence, absence, order, count, text **and containment**: that a
|
|
73
|
+
progress bar is in the markup, that no breadcrumb is, that the primary button comes before the
|
|
74
|
+
secondary, that the counter reads `1 de 3`, that `AGORA` sits inside the week band rather than
|
|
75
|
+
beside it. All of that is an ordinary check and none of it is exempt. What no selector reaches is
|
|
76
|
+
spacing, colour and type weight.
|
|
77
|
+
|
|
78
|
+
**Composition is assertable, so it is not exempt either.** Which regions the screen has, what
|
|
79
|
+
contains what, a bar where the design draws a bar and not a ring - those are presence,
|
|
80
|
+
containment and order wearing a visual name, and a list of the assertable that leaves them out
|
|
81
|
+
hands the arrangement back by accident. This is the failure this section has actually produced:
|
|
82
|
+
every label copied, every count correct, and a screen that reads as a different product. So write
|
|
83
|
+
the structural checks the design decides - one column or two, this indicator and not that one,
|
|
84
|
+
this block nested inside that one - and leave only the three properties above unproven.
|
|
85
|
+
|
|
86
|
+
So the exemption has to enumerate, under the same rule as every other negative in this skill.
|
|
87
|
+
"Visual fidelity is unproven" is a blanket that legitimises every mistake of form written after
|
|
88
|
+
it - including the ones a check would have caught - and a verifier reading it treats a real gap as
|
|
89
|
+
a limitation properly declared. Name the screen and the property: `03 overview - spacing and card
|
|
90
|
+
elevation unproven`. Then a person reviews three lines instead of being handed the whole surface
|
|
91
|
+
back.
|
|
92
|
+
|
|
93
|
+
## The Screens table needs a column for arrangement
|
|
94
|
+
|
|
95
|
+
Give the artifact a `## Screens (ui)` section with one row per screen and **three** columns, so
|
|
96
|
+
the omission shows up as an empty cell rather than as a shorter sentence:
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+
| Screen | Copy and elements (selector) | Arrangement (selector) | Visual unproven |
|
|
100
|
+
| --- | --- | --- | --- |
|
|
101
|
+
| 01 mid-cycle | kicker `CICLO DE {N} DIAS`, `dia K de N`, `ESTA SEMANA`, `AGORA`, Continuar, Deixar para depois, Regenerar | progress is a **bar**, not a ring · `AGORA` nested **inside** the week band, between last-opened and next · community in **two** columns · stages as numbered circles on a rail · footer: feedback left, Regenerar right | spacing, colour, type weight |
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The middle column is the one this whole file exists for. Without it a row reads as complete with
|
|
105
|
+
nothing but labels in it - which is how a screen ships with every string correct and a layout
|
|
106
|
+
nobody decided. Each item there is an ordinary check: presence, absence, containment, order,
|
|
107
|
+
count. What genuinely does not reach goes right, named, per screen.
|
|
108
|
+
|
|
109
|
+
## Screens are a Coverage set
|
|
110
|
+
|
|
111
|
+
**Designed screens are a set whose members are the screens.** The design already numbers them, so
|
|
112
|
+
the enumeration exists and owes a row like any other. The row is what forces the artifact open,
|
|
113
|
+
which is exactly where this fails: a screen nobody mapped is a screen nobody built, and it stays
|
|
114
|
+
invisible while every check is green. Map each screen to the check that renders it and leave the
|
|
115
|
+
rest in `Unproven`.
|
|
116
|
+
|
|
117
|
+
```markdown
|
|
118
|
+
| designed screens (6) | `01` intake C1 · `02` montando C5 · `03` overview C19 · `04` player C26 · `05` conclusão C20 | `06` |
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Where the design draws a state as a band on an existing screen and a check turned it into a
|
|
122
|
+
screen of its own, that is not a gap but a contradiction - say so in the row and settle it with
|
|
123
|
+
the user, because the check is the side that is wrong.
|
|
124
|
+
|
|
125
|
+
And mark the design in `Sources` as binding for the interface, naming the screens it covers:
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
- <design URL or path> - **binding for the interface**: screens 01-06
|
|
129
|
+
```
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Test policy
|
|
2
|
+
|
|
3
|
+
**Goal:** the repo, not this skill, decides which code must be proven at which level and how
|
|
4
|
+
deeply - and says so in writing, so the next agent and the next human inherit the decision
|
|
5
|
+
instead of re-deriving it.
|
|
6
|
+
|
|
7
|
+
## The failure this prevents
|
|
8
|
+
|
|
9
|
+
A test proves the layer where it **asserts**, not the layers it happens to **pass through**. An
|
|
10
|
+
end-to-end test that traverses a branch exercises one path through it; it says nothing about the
|
|
11
|
+
other paths, and it cannot fail when a second branch is wrong. Treating it as proof of the code
|
|
12
|
+
it traversed is **level substitution**, and it is the most common way a green suite ships a
|
|
13
|
+
broken branch table.
|
|
14
|
+
|
|
15
|
+
So obligations **add up rather than substitute**. When code that decides something is reached
|
|
16
|
+
across a boundary - a route, a queue, a scheduled job, a CLI entry point - two different claims
|
|
17
|
+
are in play and each needs its own asserted proof:
|
|
18
|
+
|
|
19
|
+
- the **entry point's contract**: it accepts what it should, rejects what it should, returns the
|
|
20
|
+
right shape, persists or emits what it promised. Proven where the boundary really is, with the
|
|
21
|
+
real transport.
|
|
22
|
+
- the **decision table inside**: every branch that changes the outcome, asserted case by case,
|
|
23
|
+
isolated from the transport so the cases can be enumerated at all.
|
|
24
|
+
|
|
25
|
+
The second one is what gets lost. It disappears whenever a requirement is phrased as an
|
|
26
|
+
observable outcome, because the observable outcome names the entry point and the decision hides
|
|
27
|
+
behind it.
|
|
28
|
+
|
|
29
|
+
## 1. Does the repo already answer this?
|
|
30
|
+
|
|
31
|
+
Do not judge whether the repo "has testing docs" - it almost always does, and that impression is
|
|
32
|
+
what makes this step never fire. Ask the two questions a policy has to answer, for each layer
|
|
33
|
+
this change touches:
|
|
34
|
+
|
|
35
|
+
1. **Which level proves this code?**
|
|
36
|
+
2. **How much of its input space must the proof assert to count?**
|
|
37
|
+
|
|
38
|
+
If the declaration answers both for every touched layer, follow it and skip the rest of this
|
|
39
|
+
file. If either is unanswered for code that decides something, derive the missing rows.
|
|
40
|
+
|
|
41
|
+
A statement answers neither question when it only says **where** tests live or how they are
|
|
42
|
+
named, **how** to run them, **how a test is built** (which dependencies are real and which are
|
|
43
|
+
doubled), or **that** testing matters. Those are all useful and none of them allocate: they
|
|
44
|
+
describe the tests, while a policy has to describe the code. Watch for the third one especially,
|
|
45
|
+
because it is the one that looks like an allocation rule: keying the level to whether a test
|
|
46
|
+
uses real dependencies decides *how* to write a test, and if you read it as deciding *what
|
|
47
|
+
deserves* one, every decision table that touches a real dependency gets routed away from its own
|
|
48
|
+
layer and is never enumerated.
|
|
49
|
+
|
|
50
|
+
## 2. Classify by the shape of the code, never by the name of the layer
|
|
51
|
+
|
|
52
|
+
Layer names lie. A file named like a service can be a pass-through, and a handler that looks like
|
|
53
|
+
plumbing can hold the densest decision table in the change. Classify each candidate on a signal
|
|
54
|
+
you can point at.
|
|
55
|
+
|
|
56
|
+
**Instrumentation** - the body forwards its arguments to one call, or maps one shape onto another
|
|
57
|
+
with no conditional deciding the result. Its correctness is its consumer's problem; a test over
|
|
58
|
+
it re-asserts the framework underneath.
|
|
59
|
+
|
|
60
|
+
**Decision** - anything that changes an outcome. A dispatch over a status, event type or code. A
|
|
61
|
+
boundary or validation check. A state transition. A payload assembled conditionally. A mapping
|
|
62
|
+
table with more than one row. A guard, a precedence rule, an ordering rule.
|
|
63
|
+
|
|
64
|
+
Count it and write the number down: decision points added or touched, per file. "Dispatches over
|
|
65
|
+
six event types, eleven branch points" is contestable. "Looks like business logic" is not.
|
|
66
|
+
|
|
67
|
+
Then **name the members, not only the count** - `paused`, `updated`, `deleted`, `trial_will_end`,
|
|
68
|
+
other. Those names are what `Coverage` joins each proof against, and a set that only ever exists
|
|
69
|
+
as a number cannot be joined at all: the member you left out of the sentence is the one that ends
|
|
70
|
+
up with no proof and is never missed.
|
|
71
|
+
|
|
72
|
+
**The level follows the branch, not the observation.** A requirement phrased as an outcome at the
|
|
73
|
+
boundary does not discharge the code behind it. Decide the level from where the branch lives.
|
|
74
|
+
|
|
75
|
+
## 3. Derive from the code, not from the current suite
|
|
76
|
+
|
|
77
|
+
The existing tests set style, location and commands - never the bar. A module with no tests at a
|
|
78
|
+
level is evidence about its history, not evidence that its logic needs none; deriving the policy
|
|
79
|
+
from the suite you found codifies the gap you were asked to look at.
|
|
80
|
+
|
|
81
|
+
**Judge the house pattern across the whole repo, not the folder you happen to be changing.** That
|
|
82
|
+
folder is the smallest and least reliable sample there is, and reading it as the standard is how
|
|
83
|
+
a local gap gets promoted to a rule. Search instead for the closest analogue **by code shape** -
|
|
84
|
+
the other state machine, the other dispatcher, the other validator - wherever it lives. When you
|
|
85
|
+
find one, cite it in the evidence: a proposal that points at a sibling proven at that level is
|
|
86
|
+
precedent, and one that does not is taste.
|
|
87
|
+
|
|
88
|
+
When the existing suite or an existing rule contradicts what you propose, say so in one line.
|
|
89
|
+
That contradiction is information for the user, not a reason to lower the proposal.
|
|
90
|
+
|
|
91
|
+
## 4. Propose
|
|
92
|
+
|
|
93
|
+
Present it with the checklist - one place, not two. It goes in the artifact as a
|
|
94
|
+
`## Test policy` section immediately before `## Checks`, because every proof below depends on the
|
|
95
|
+
rows above. Use the repo's own level names, locations and commands; invent none.
|
|
96
|
+
|
|
97
|
+
```markdown
|
|
98
|
+
## Test policy (proposed - the repo does not declare this)
|
|
99
|
+
|
|
100
|
+
| Code | Required proofs | Coverage expectation |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| Decides, and is 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 |
|
|
103
|
+
| Decides, not reached across a boundary | one at its own layer | one asserted case per row of the decision table |
|
|
104
|
+
| Entry point or adapter that decides nothing | one at the boundary | accepted input, each rejected input, each error path |
|
|
105
|
+
| Instrumentation, pass-throughs | none of its own | covered by its consumer's proof |
|
|
106
|
+
|
|
107
|
+
Evidence:
|
|
108
|
+
- <file>: dispatches over <n> cases, <n> branch points -> decides
|
|
109
|
+
- <file>: forwards a single call, no conditional -> instrumentation
|
|
110
|
+
- <existing declaration> decides <what it decides> and leaves the two questions open
|
|
111
|
+
- closest analogue in the repo: <file>, same shape, already proven at this level with <n> cases
|
|
112
|
+
- the module has <n> proofs at this level today, which the table deliberately does not match
|
|
113
|
+
|
|
114
|
+
Cost: <n> proofs at their own layer, across <n> files. Without these rows, <n> decision tables
|
|
115
|
+
are proven only by a path that happens to traverse them.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A floor, never a ceiling, and a target rather than a description of what exists today. State the
|
|
119
|
+
cost in the proposal - a row set nobody can price is a governance debate, and a row set with a
|
|
120
|
+
number next to it is a five-second decision.
|
|
121
|
+
|
|
122
|
+
## 5. Ask, then write
|
|
123
|
+
|
|
124
|
+
**One question, not a menu.** The rows you derived are the default you build under: state them
|
|
125
|
+
and keep going. Offering a choice between allocation philosophies hands back the analysis this
|
|
126
|
+
step exists to do, and the option that always looks like the conservative one - prove everything
|
|
127
|
+
at the boundary, the way the repo already does - is level substitution wearing a hat.
|
|
128
|
+
|
|
129
|
+
So the only explicit question is the narrow one: **do these rows go into the repo's guidelines?**
|
|
130
|
+
Building under them is reversible and needs no permission. Writing them is not: project
|
|
131
|
+
guidelines reach every future agent and every human in the repo, a wider blast radius than the
|
|
132
|
+
feature you were asked to build, so approved rows go in their own commit, before the build
|
|
133
|
+
starts, and never ride along in a feature commit.
|
|
134
|
+
|
|
135
|
+
Ask it in one line, with both outcomes stated, so silence is not ambiguous. Adapt the names, keep
|
|
136
|
+
the shape:
|
|
137
|
+
|
|
138
|
+
> These rows are the bar I build under - approving the checklist is enough for that. Writing them
|
|
139
|
+
> into `<guidelines file>` needs an explicit yes, and it lands as its own commit before the build.
|
|
140
|
+
> Without one I build under them and leave the file alone.
|
|
141
|
+
|
|
142
|
+
Then stop asking. The answer settles it for this feature, and rule 4 keeps the rows fixed from
|
|
143
|
+
that point on.
|
|
144
|
+
|
|
145
|
+
**Fix what misleads, do not just add to it.** If an existing line is being read as an allocation
|
|
146
|
+
rule and is not one, leaving it in place means the next run re-derives the same wrong answer and
|
|
147
|
+
the Verifier defers to it. Quote the line, say what it actually decides, and propose the edit that
|
|
148
|
+
scopes it - as part of the same approval, in the same commit as the new rows.
|
|
149
|
+
|
|
150
|
+
If the user does not answer, do not write. Carry the proposal inside the checklist as a stated
|
|
151
|
+
assumption, build under it, and leave the files alone - a policy nobody agreed to is worse than
|
|
152
|
+
no policy, for exactly the reason above.
|