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
package/bin/wtk.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createInterface } from 'node:readline/promises';
|
|
6
|
+
import { runInstallWizard } from '../scripts/installer/terminal.js';
|
|
7
|
+
|
|
8
|
+
export const HELP = `Usage: wtk <command>\n\nCommands:\n install Install or update Workflow Toolkit modules in the current directory\n\nCanonical invocation: wtk install\nModules: core, quality, extras\nTarget: current working directory\nBackups: existing files are verified under .my-workflow/backups/ before replacement\nRuntime: Node.js 18 or newer`;
|
|
9
|
+
const CANCELLATION = 'Installation cancelled. No files changed.';
|
|
10
|
+
const isReadlineCancellation = (error) => error?.code === 'ABORT_ERR' && error?.name === 'AbortError';
|
|
11
|
+
|
|
12
|
+
export async function main(argv = process.argv.slice(2), runtime = {}) {
|
|
13
|
+
const stdin = runtime.stdin || process.stdin; const stdout = runtime.stdout || process.stdout; const stderr = runtime.stderr || process.stderr;
|
|
14
|
+
if (argv.includes('--help') || argv.includes('-h')) { stdout.write(`${HELP}\n`); return 0; }
|
|
15
|
+
if (!argv.length || argv[0] !== 'install' || argv.length !== 1) { stderr.write(`${HELP}\n`); return 2; }
|
|
16
|
+
if (!stdin.isTTY || !stdout.isTTY) { stderr.write('Interactive terminal required; run this command in a TTY.\n'); return 2; }
|
|
17
|
+
const readlineOutput = process.env.NO_COLOR === undefined ? stdout : new Proxy(stdout, { get(target, property, receiver) { return property === 'write' ? () => true : Reflect.get(target, property, receiver); } });
|
|
18
|
+
const readline = runtime.readline || createInterface({ input: stdin, output: readlineOutput, terminal: true });
|
|
19
|
+
try {
|
|
20
|
+
const result = await runInstallWizard({ targetRoot: runtime.targetRoot || process.cwd(), sourceRoot: runtime.sourceRoot, input: () => readline.question(''), write: (value) => stdout.write(`${value}\n`), width: runtime.width, color: process.env.NO_COLOR === undefined, requireGit: runtime.requireGit ?? true, transaction: runtime.transaction });
|
|
21
|
+
return result.code ?? 0;
|
|
22
|
+
} catch (error) { if (isReadlineCancellation(error)) { stdout.write(`${CANCELLATION}\n`); return 0; } stderr.write(`${error.message}\n`); return 1; } finally { if (!runtime.readline) readline.close(); }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) main().then((code) => { process.exitCode = code; });
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Workflow tour
|
|
2
|
+
|
|
3
|
+
Human-facing. Agents run [`AGENTS.md`](../../AGENTS.md) and load a guideline only when its
|
|
4
|
+
condition fires. This folder is the **why**: what each stage is for, what each guideline
|
|
5
|
+
protects, and which trade-off it encodes.
|
|
6
|
+
|
|
7
|
+
These pages do not restate the rules. The guidelines remain the source of truth for behaviour.
|
|
8
|
+
|
|
9
|
+
Cross-provider session continuation is owned by the host. Repository files, Git state, feature
|
|
10
|
+
artifacts, and explicit handoff prompts remain the durable semantic context.
|
|
11
|
+
|
|
12
|
+
## Walk this in order
|
|
13
|
+
|
|
14
|
+
1. [Purpose — delivery and reliability](purpose.md)
|
|
15
|
+
2. [The loop — stages from spec to merge](loop.md)
|
|
16
|
+
3. [Reviews — three questions, hard caps](reviews.md)
|
|
17
|
+
4. [Decisions — two namespaces, halt vs decide](decisions.md)
|
|
18
|
+
5. [Guidelines — why each file exists](guidelines.md)
|
|
19
|
+
6. [Skills, knowledge, adopt](pack.md)
|
|
20
|
+
7. [Repository intelligence](repository-intelligence.md)
|
|
21
|
+
|
|
22
|
+
## Map
|
|
23
|
+
|
|
24
|
+
| You want | Read |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| The thesis | [purpose.md](purpose.md) |
|
|
27
|
+
| Specify → slice → gate → PR | [loop.md](loop.md) |
|
|
28
|
+
| Verifier, QA, wtk-deep-review, filed issues | [reviews.md](reviews.md) |
|
|
29
|
+
| `AD-NNN` vs architecture invariants | [decisions.md](decisions.md) |
|
|
30
|
+
| One paragraph per guideline | [guidelines.md](guidelines.md) |
|
|
31
|
+
| What is vendored and what is not | [pack.md](pack.md) |
|
|
32
|
+
| Graphify/Graft routing, setup, freshness, and benchmark | [repository-intelligence.md](repository-intelligence.md) |
|
|
33
|
+
| Shared execution contracts | [`wtk/references/`](../../.agents/skills/wtk/references/) |
|
|
34
|
+
| Surface-specific rules | [`docs/toolkit/guidelines/`](guidelines/) |
|
|
35
|
+
| What agents load every turn | [`AGENTS.md`](../../AGENTS.md) |
|
|
36
|
+
|
|
37
|
+
## The loop at a glance
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
per slice implement → scoped gate → atomic commit
|
|
41
|
+
feature one fresh Technical Verifier over the complete feature range
|
|
42
|
+
resolved wtk-deep-review groups from wtk-config, before QA
|
|
43
|
+
|
|
44
|
+
feature selected QA session (no product code)
|
|
45
|
+
then selected full/scoped gate → pull request
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Public hierarchy: `Feature -> Slice -> Check`. Read
|
|
49
|
+
`.agents/skills/wtk-config/SKILL.md` before dispatch; it resolves cadence and delegated providers.
|
|
50
|
+
|
|
51
|
+
Repeated review blockers use the immutable fingerprint and independent counter in
|
|
52
|
+
[`REVIEW-ROUNDS.md`](guidelines/REVIEW-ROUNDS.md); this guide does not duplicate that protocol.
|
|
53
|
+
|
|
54
|
+
A filed issue skips the ceremony: `implement → scoped gate → one commit`.
|
|
55
|
+
Credential-free declarative agent-tool configuration uses the local light path in
|
|
56
|
+
[`validation.md`](../../.agents/skills/wtk/references/validation.md).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Decisions
|
|
2
|
+
|
|
3
|
+
Two namespaces, on purpose. Mixing them is how an architecture invariant becomes a reversible
|
|
4
|
+
project call, or a one-feature choice becomes “the way the system is”.
|
|
5
|
+
|
|
6
|
+
## Where a choice lives
|
|
7
|
+
|
|
8
|
+
| Kind | Id | Home | Lifetime |
|
|
9
|
+
| --- | --- | --- | --- |
|
|
10
|
+
| **Project decision** | `AD-NNN` (three digits) | `.specs/STATE.md`, append-only | The project. Supersede, never delete, never reuse an id |
|
|
11
|
+
| **Architecture invariant** | Whatever the consuming project uses | `docs/architecture/` | Holds regardless of feature. This pack does not invent those ids |
|
|
12
|
+
| **Feature-local** | Table in `decisions.md` | `.specs/features/<slug>/decisions.md` | Versioned with the feature; promote if it must outlive it |
|
|
13
|
+
|
|
14
|
+
Always cite **the file** with the label. The same letters in two files are not the same object.
|
|
15
|
+
|
|
16
|
+
Promote before the pull request, per [artifacts.md](../../.agents/skills/wtk/references/artifacts.md):
|
|
17
|
+
|
|
18
|
+
- Must outlive the feature as a project call → `AD-NNN`
|
|
19
|
+
- Must outlive it as a product promise → `docs/qa/scenarios/`
|
|
20
|
+
- Must outlive it as an invariant → the architecture docs
|
|
21
|
+
- Must outlive it as an agent rule → `docs/toolkit/guidelines/`
|
|
22
|
+
|
|
23
|
+
Feature workflow state (`plan.md`, `checks.md`, and `verification.md`) stays under the versioned
|
|
24
|
+
`.specs/features/<slug>/` tree. Workflow memory remains disposable local state.
|
|
25
|
+
|
|
26
|
+
## Halt vs decide
|
|
27
|
+
|
|
28
|
+
An unattended run (`wtk-ship`) must **settle or stop** before building:
|
|
29
|
+
|
|
30
|
+
- If the documents already answer it, proceed.
|
|
31
|
+
- If evidence in the repo is enough, decide, record `AD-NNN` with reasoning, move on.
|
|
32
|
+
- If the remaining choice would **change what gets built**, halt. Write the report. Merge nothing.
|
|
33
|
+
|
|
34
|
+
A decision recorded with its reasoning is reversible in the morning. A decision made silently
|
|
35
|
+
inside an implementation is found months later.
|
|
36
|
+
|
|
37
|
+
Ambiguity that does **not** change what gets built is not a halt. Record it in `decisions.md` and
|
|
38
|
+
continue. A phase boundary is not a checkpoint.
|
|
39
|
+
|
|
40
|
+
## What a recorded decision must carry
|
|
41
|
+
|
|
42
|
+
For anything an unattended run chose while nobody was watching:
|
|
43
|
+
|
|
44
|
+
- what was chosen
|
|
45
|
+
- why
|
|
46
|
+
- alternatives rejected, and why
|
|
47
|
+
- cost to change now
|
|
48
|
+
- cost to the user today
|
|
49
|
+
|
|
50
|
+
Separate the human’s calls from the run’s. A reviewer in the morning needs to know whose they are.
|
|
51
|
+
|
|
52
|
+
Accepting a security risk is the same shape: explicit approval plus an append-only `AD-NNN`.
|
|
53
|
+
Silence is not acceptance.
|
|
54
|
+
|
|
55
|
+
## Knowledge
|
|
56
|
+
|
|
57
|
+
When two source documents disagree, the **source wins** and the wiki concept is wrong. The bundle
|
|
58
|
+
holds the graph and the contradiction; it does not override `docs/` or `.specs/STATE.md`.
|
|
59
|
+
|
|
60
|
+
Offer to record durable knowledge when it surfaces in conversation. Never write to `knowledge/`
|
|
61
|
+
without a yes. Never skip the offer.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Context Budget
|
|
2
|
+
|
|
3
|
+
**Read when:** editing `AGENTS.md`, `CLAUDE.md`, or any file in this directory.
|
|
4
|
+
|
|
5
|
+
**Why this exists:** Instruction files compete with the work for the same window. A previous
|
|
6
|
+
arrangement loaded more than a thousand mandatory lines before any task, most of it irrelevant.
|
|
7
|
+
Dispatch by condition; growing a file with restated prose is a defect.
|
|
8
|
+
|
|
9
|
+
`AGENTS.md` loads into every Cursor and Codex prompt. `CLAUDE.md` is `@AGENTS.md` — Claude Code
|
|
10
|
+
imports it; Cursor does not expand `@`, so a symlink that duplicates the contract is a defect.
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
1. **Growing an instruction file with restated or redundant prose is a defect.** Adding a rule means
|
|
15
|
+
finding the one it replaces, or justifying why both must exist.
|
|
16
|
+
2. **`AGENTS.md` carries conditions and dispatch, not content.** If a rule applies only sometimes, it
|
|
17
|
+
belongs in a guideline behind a trigger. `CLAUDE.md` stays one import line.
|
|
18
|
+
3. **One home per fact.** A guideline references `docs/` — it never copies from it. Two copies of a
|
|
19
|
+
rule disagree eventually, and the disagreement is discovered by an agent following the wrong one.
|
|
20
|
+
4. **Each guideline states its trigger in its first line.** An agent must be able to decide whether to
|
|
21
|
+
read it from the title and one sentence.
|
|
22
|
+
5. **Rules are stated once, in the imperative.** No "remember to", no restating the rule as a warning
|
|
23
|
+
later in the same file, no summary section repeating what the sections said.
|
|
24
|
+
6. **Delete on sight.** A rule that no longer describes how the project works is worse than no rule,
|
|
25
|
+
because agents follow it.
|
|
26
|
+
|
|
27
|
+
## Size targets
|
|
28
|
+
|
|
29
|
+
| File | Target |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `AGENTS.md` | Under 200 lines |
|
|
32
|
+
| A rule guideline | Under 120 lines |
|
|
33
|
+
| A reference guideline — one carrying a schema, a surface list, or a protocol | Under 160 lines |
|
|
34
|
+
| All guidelines together | Under 1,500 lines, of which a typical task reads two or three |
|
|
35
|
+
|
|
36
|
+
A rule guideline states what must be true and can nearly always be shortened. A reference guideline
|
|
37
|
+
carries content that is irreducible — `SECURITY.md` owns the surface list, `QA-SCENARIOS.md` owns a
|
|
38
|
+
field schema, `KNOWLEDGE-WIKI.md` owns four operations. Cutting those does not save context, it just
|
|
39
|
+
moves the lookup somewhere else and costs a round trip.
|
|
40
|
+
|
|
41
|
+
These are targets, not gates. A file at its limit because nobody pruned it is the problem this
|
|
42
|
+
addresses; a file at its limit because the content is that size is fine.
|
|
43
|
+
|
|
44
|
+
## The test before adding anything
|
|
45
|
+
|
|
46
|
+
Ask, in order:
|
|
47
|
+
|
|
48
|
+
1. **Does a rule already cover this?** Then extend that rule rather than adding a second one.
|
|
49
|
+
2. **Will an agent behave differently because of this line?** If not, it is commentary. Cut it.
|
|
50
|
+
3. **Is this a condition or a rule?** Conditions go in the `AGENTS.md` dispatch table; rules go in the
|
|
51
|
+
guideline the condition points at.
|
|
52
|
+
4. **Is this durable or is it about right now?** Anything about the current state of the work belongs
|
|
53
|
+
in workflow memory or the pull request, never in an instruction file.
|
|
54
|
+
|
|
55
|
+
## What does not belong here
|
|
56
|
+
|
|
57
|
+
- Status, progress, or plans — those are branch and pull-request concerns
|
|
58
|
+
- History or rationale, except the one sentence needed to stop a rule being undone
|
|
59
|
+
- Anything the repository already states: file structure, available commands, code conventions the
|
|
60
|
+
linter enforces
|
|
61
|
+
- Speculative rules for problems that have not happened
|
|
62
|
+
|
|
63
|
+
A rule earns its lines by preventing a defect that occurred, or by resolving an ambiguity an agent
|
|
64
|
+
actually hit.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Public Surface Contract
|
|
2
|
+
|
|
3
|
+
**Read when:** the feature adds or changes a public surface — an HTTP route, a config key, a CLI verb,
|
|
4
|
+
a package export.
|
|
5
|
+
|
|
6
|
+
**Why this exists:** A surface designed after its internals inherits the internals' shape instead of
|
|
7
|
+
the caller's needs. Writing the contract first — as if it already shipped, failures enumerated —
|
|
8
|
+
surfaces ergonomic problems while they are still free to fix. Internals-only features skip this.
|
|
9
|
+
|
|
10
|
+
## The artifact
|
|
11
|
+
|
|
12
|
+
`.specs/features/<feature>/dx.md`, written in Design, before internal design.
|
|
13
|
+
|
|
14
|
+
```markdown
|
|
15
|
+
# <Feature> Surface Contract
|
|
16
|
+
|
|
17
|
+
## Routes
|
|
18
|
+
|
|
19
|
+
### `POST /api/records`
|
|
20
|
+
- **Auth:** none
|
|
21
|
+
- **Request:** `{ name, email, region }`
|
|
22
|
+
- **Success:** `201 { id, createdAt }`
|
|
23
|
+
- **Failures:** `422` validation, field-level detail · `429` rate limited · `500` no detail
|
|
24
|
+
- **Idempotency:** none — duplicate submissions create duplicate rows by design
|
|
25
|
+
|
|
26
|
+
## Config
|
|
27
|
+
|
|
28
|
+
| Key | Type | Default | Effect |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| `PUBLIC_RATE_LIMIT_PER_MINUTE` | integer | 10 | Requests per IP before 429 |
|
|
31
|
+
|
|
32
|
+
## Exports
|
|
33
|
+
|
|
34
|
+
What this feature adds to a package's public interface, and what now depends on it.
|
|
35
|
+
|
|
36
|
+
## Removals
|
|
37
|
+
|
|
38
|
+
What this feature deletes. Hard cuts, no aliases, no dual fields.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
1. **Write it as if it shipped.** Present tense, no hedging, no "we could". A surface described in
|
|
44
|
+
conditionals has not been decided.
|
|
45
|
+
2. **Every failure is enumerated with its status and its body shape.** An unlisted failure ships as a
|
|
46
|
+
500.
|
|
47
|
+
3. **Error copy is part of the surface.** What the caller reads on failure is designed here, not
|
|
48
|
+
improvised in a catch block.
|
|
49
|
+
4. **The surface freezes before internals.** Internals are designed to serve it. Reopening it later is
|
|
50
|
+
an explicit decision, not a quiet adaptation.
|
|
51
|
+
5. **Removals are listed.** This workflow does not preserve backward compatibility — so a change that
|
|
52
|
+
removes something states exactly what goes, and the same change updates every caller.
|
|
53
|
+
6. **It respects the project's boundary.** The consuming project's architecture docs name the product
|
|
54
|
+
boundary. A surface that would violate that boundary is wrong at design time, not at build time.
|
|
55
|
+
7. **Write all versioned or published text in English.**
|
|
56
|
+
|
|
57
|
+
## What to grill before freezing
|
|
58
|
+
|
|
59
|
+
The questions worth asking about a surface, once the draft exists:
|
|
60
|
+
|
|
61
|
+
- Does the name say what it does to someone who has not read the spec?
|
|
62
|
+
- Is the failure a caller is most likely to hit the one with the clearest message?
|
|
63
|
+
- What happens on the second call with the same input?
|
|
64
|
+
- What does this look like from a client that cannot retry?
|
|
65
|
+
- Which field will someone want that is not here, and is leaving it out deliberate?
|
|
66
|
+
|
|
67
|
+
The draft is the question. Rework it between rounds rather than discussing it in the abstract.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Front-End Engineering
|
|
2
|
+
|
|
3
|
+
**Read when:** writing or reorganizing front-end application code, or working on a mockup under
|
|
4
|
+
`docs/design/`.
|
|
5
|
+
|
|
6
|
+
**Why this exists:** Feature-specific policy dumped into shared UI, and routes that draw their own
|
|
7
|
+
layout, produce a front-end that cannot tell capability from reuse. Feature folders own capability;
|
|
8
|
+
shared folders own reuse. Appearance still belongs in the project's design docs.
|
|
9
|
+
|
|
10
|
+
This document owns front-end *code organization*. It does not own appearance or behaviour. The
|
|
11
|
+
consuming project's design docs win on appearance and behaviour. Link to those instead of restating
|
|
12
|
+
them here.
|
|
13
|
+
|
|
14
|
+
## Feature folders vs shared UI
|
|
15
|
+
|
|
16
|
+
Routes compose. A route selects a shell, loads route state and composes feature and shared
|
|
17
|
+
components. It does not own reusable layout and does not draw raw landmarks (`header`, `nav`,
|
|
18
|
+
`main`) that a shell already owns.
|
|
19
|
+
|
|
20
|
+
Feature-specific browser and transport logic lives in a feature folder named for the capability:
|
|
21
|
+
|
|
22
|
+
- a client adapter for the browser-facing surface;
|
|
23
|
+
- a server-side forwarder only when this app is not itself the product boundary;
|
|
24
|
+
- an explicit marker (suffix, package, or bundler boundary) for modules that must not enter the
|
|
25
|
+
browser bundle.
|
|
26
|
+
|
|
27
|
+
Shared folders have narrower roles: generic primitives, compositions used by more than one route,
|
|
28
|
+
feature-neutral helpers. Do not move feature-specific policy into a shared folder to avoid creating
|
|
29
|
+
a feature folder.
|
|
30
|
+
|
|
31
|
+
Tests stay grouped by execution layer, not by feature folder, unless the consuming project already
|
|
32
|
+
colocate them.
|
|
33
|
+
|
|
34
|
+
## Component script
|
|
35
|
+
|
|
36
|
+
Follow this order before writing any application UI:
|
|
37
|
+
|
|
38
|
+
1. Identify the shell. Exactly one component owns each shell. Select it; do not improvise an
|
|
39
|
+
equivalent header, navigation or main layout in the route.
|
|
40
|
+
2. If the needed primitive exists, use it without a wrapper whose only purpose is spacing or styling.
|
|
41
|
+
3. If a shared composition exists, use it.
|
|
42
|
+
4. If a generic primitive is missing, add it at the project's primitive layer — follow that layer's
|
|
43
|
+
generation rules; do not hand-edit generated files.
|
|
44
|
+
5. Express a primitive variation as a variant of that primitive. Do not copy or fork it.
|
|
45
|
+
6. If a product composition is missing, add it with closed props. Use a free slot only when the
|
|
46
|
+
surface genuinely varies. Consistency-critical content belongs in named, constrained props.
|
|
47
|
+
7. Never add a stylesheet outside the project's canonical style root.
|
|
48
|
+
|
|
49
|
+
## Mockups
|
|
50
|
+
|
|
51
|
+
Standalone mockups are implementation references when the project treats them that way, not
|
|
52
|
+
disposable sketches. Reuse the same shell family, component treatment and state vocabulary the
|
|
53
|
+
implementation will use. If the existing pattern cannot express the surface, change the shared
|
|
54
|
+
reference deliberately and extend its conformity test in the same task.
|
|
55
|
+
|
|
56
|
+
## Browser permanence
|
|
57
|
+
|
|
58
|
+
Use the cheapest layer that discriminates the outcome. Keep an application e2e permanently only for a
|
|
59
|
+
browser-only or real-stack property, a session/cookie/origin/authorization/checkout boundary, a named
|
|
60
|
+
minimum smoke capability, or a regression that lower layers demonstrably miss. Permanent scenarios
|
|
61
|
+
carry stable `@feature:<slug>` and `@journey:<slug>` tags, own every account/IP/session/resource they
|
|
62
|
+
create, and clean exact resources in `finally` with zero-residue assertions. Temporary probes are
|
|
63
|
+
removed before commit.
|
|
64
|
+
|
|
65
|
+
Durable regression is a deterministic spec with no model call. Exploratory scripts and agent sessions
|
|
66
|
+
are disposable. Neither their transcript nor a successful session is evidence.
|
|
67
|
+
|
|
68
|
+
## Vendored skill scope
|
|
69
|
+
|
|
70
|
+
Vendored skills are advisory. Canonical project documents, installed source and installed dependency
|
|
71
|
+
declarations win when guidance conflicts. Do not edit a vendored skill to record a project exception:
|
|
72
|
+
that changes its lockfile hash and the next upstream refresh can overwrite the edit. Record the
|
|
73
|
+
exception in the consuming project's front-end guideline.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Knowledge Wiki
|
|
2
|
+
|
|
3
|
+
**Read when:** discussing a product rule, domain term, or architecture invariant stated in more than
|
|
4
|
+
one document — which is most of planning — or when durable knowledge surfaces in conversation and
|
|
5
|
+
needs recording.
|
|
6
|
+
|
|
7
|
+
**Why this exists:** Source documents cannot see each other. The wiki holds the graph and the
|
|
8
|
+
contradictions; it is not a summary of `docs/`. When bundle and source disagree, the source wins.
|
|
9
|
+
Silence when durable knowledge surfaces leaves an existing concept confidently wrong.
|
|
10
|
+
|
|
11
|
+
`knowledge/wiki/` is an Open Knowledge Format bundle holding what no single source document can: the
|
|
12
|
+
graph between them, and the contradictions no document resolves.
|
|
13
|
+
|
|
14
|
+
It is not a summary of `docs/`. Its pages synthesize several sources into one answer and cite each
|
|
15
|
+
claim back. A concept that reconciles four product files into a single table and names the failure
|
|
16
|
+
mode in both directions is doing work no source document could, because none of them can see the
|
|
17
|
+
other three.
|
|
18
|
+
|
|
19
|
+
This pack ships the machinery empty. The consuming project fills concepts as they are earned.
|
|
20
|
+
|
|
21
|
+
## Reading is automatic and cheap
|
|
22
|
+
|
|
23
|
+
No permission needed, no schema to load first.
|
|
24
|
+
|
|
25
|
+
1. Read `knowledge/wiki/index.md` — it is the router, and it lists what exists before you open
|
|
26
|
+
anything.
|
|
27
|
+
2. Follow the subdirectory index, then the concept.
|
|
28
|
+
3. Answer with its citations, and follow them to the source when the answer must be exact.
|
|
29
|
+
|
|
30
|
+
Read it when the conversation is about:
|
|
31
|
+
|
|
32
|
+
- A product rule stated in several places
|
|
33
|
+
- A domain term whose meaning might differ between documents
|
|
34
|
+
- An architecture invariant and what it constrains
|
|
35
|
+
- Why a past decision went the way it did, including the reversals
|
|
36
|
+
|
|
37
|
+
**Planning a feature that touches those areas is exactly when to read it**, not a reason to skip it.
|
|
38
|
+
|
|
39
|
+
**The source always wins.** When bundle and source disagree, the source is right and the concept is
|
|
40
|
+
wrong. Say so and note it — never quietly follow the concept.
|
|
41
|
+
|
|
42
|
+
## Writing: never silently, but never miss it either
|
|
43
|
+
|
|
44
|
+
Two write paths, and they have different rules because the knowledge comes from different places.
|
|
45
|
+
|
|
46
|
+
### From the human, in conversation — offer it, every time
|
|
47
|
+
|
|
48
|
+
When something durable surfaces while talking, **say so and offer to record it**. The schema requires
|
|
49
|
+
this: *"a useful query should leave the bundle better than it found it, not evaporate into the
|
|
50
|
+
transcript."*
|
|
51
|
+
|
|
52
|
+
The stakes are asymmetric. An observation that contradicts a founding assumption does not merely leave
|
|
53
|
+
the bundle incomplete — it leaves an existing concept confidently wrong. Silence is the expensive
|
|
54
|
+
option.
|
|
55
|
+
|
|
56
|
+
Offer when any of these appear:
|
|
57
|
+
|
|
58
|
+
- An observation about real user behaviour that differs from a documented assumption
|
|
59
|
+
- A decision made in conversation that changes a documented rule
|
|
60
|
+
- A contradiction between two sources that the human points out
|
|
61
|
+
- An outside constraint learned from the market, a competitor, or a platform
|
|
62
|
+
- An answer derived at real cost that would cost the same to derive again
|
|
63
|
+
|
|
64
|
+
Do not offer for: anything a source document already states, implementation detail, or transient
|
|
65
|
+
status.
|
|
66
|
+
|
|
67
|
+
The offer names the target and waits:
|
|
68
|
+
|
|
69
|
+
> Users treating the catalogue as a directory rather than a search tool contradicts
|
|
70
|
+
> `product/<concept>.md`, which assumes intent-driven reads. I would write
|
|
71
|
+
> `raw/YYYY-MM-DD-<slug>.md` with the observation, then amend that concept to cite it. Record it?
|
|
72
|
+
|
|
73
|
+
Then INGEST as the schema defines it: the observation lands in `knowledge/raw/` as
|
|
74
|
+
`YYYY-MM-DD-<slug>` and is **never modified afterwards** — a correction belongs in the concepts citing
|
|
75
|
+
it. Concepts cite sources, so an observation with no `raw/` entry is a claim with no provenance.
|
|
76
|
+
|
|
77
|
+
**The human always decides. Never write without a yes, and never skip the offer because a feature is
|
|
78
|
+
in progress.**
|
|
79
|
+
|
|
80
|
+
### From shipped artifacts — explicit request only
|
|
81
|
+
|
|
82
|
+
HARVEST reads the project's own `.specs/`, commits and docs. Never run it as part of a feature: an
|
|
83
|
+
agent harvesting what it just wrote produces restatements, and the schema bans exactly that — a
|
|
84
|
+
harvested concept must not restate its source.
|
|
85
|
+
|
|
86
|
+
**At the granularity of a finished feature, never a finished task.** Most tasks produce nothing
|
|
87
|
+
durable. Never harvest `tasks.md` (runner state) or `LESSONS.md` / `lessons.json` (machine-owned).
|
|
88
|
+
|
|
89
|
+
### Either path loads the schema first
|
|
90
|
+
|
|
91
|
+
Writing means reading `knowledge/AGENTS.md` in full — it owns frontmatter, citation shape, index and
|
|
92
|
+
log rules. That load is justified for writing and wasted for reading.
|
|
93
|
+
|
|
94
|
+
## Verifying happens with the write, not with the ship
|
|
95
|
+
|
|
96
|
+
The knowledge checker (`bun run knowledge` in this pack) runs as the **first step of a harvest**, not
|
|
97
|
+
as part of the consuming project's full gate.
|
|
98
|
+
|
|
99
|
+
Its conformance, gap and drift reports are useful input when you are about to write to the bundle.
|
|
100
|
+
They are noise when you are trying to merge a bug fix — and the drift check is file-granular against
|
|
101
|
+
entry-granular sources, so an unrelated append to `.specs/STATE.md` restales every concept citing that
|
|
102
|
+
file. Gating a feature on that is gating on bookkeeping.
|
|
103
|
+
|
|
104
|
+
LINT is the judgment half no script performs — contradictions between concepts, claims superseded by a
|
|
105
|
+
newer source, orphan pages, missing index entries. It runs with the harvest, periodically, and always
|
|
106
|
+
before a large ingest.
|
|
107
|
+
|
|
108
|
+
## No overlap with the QA tree
|
|
109
|
+
|
|
110
|
+
Sometimes confused. They ask unrelated questions:
|
|
111
|
+
|
|
112
|
+
| | Asks | Built from |
|
|
113
|
+
| --- | --- | --- |
|
|
114
|
+
| `knowledge/wiki/` | How do these documents connect, and where do they contradict? | Reading documents |
|
|
115
|
+
| `docs/qa/scenarios/` | What does the product promise users, and what state is each promise in? | Walking the product |
|
|
116
|
+
|
|
117
|
+
Neither substitutes for the other.
|
|
118
|
+
|
|
119
|
+
## Summary
|
|
120
|
+
|
|
121
|
+
| Operation | Trigger | Who decides | Loads |
|
|
122
|
+
| --- | --- | --- | --- |
|
|
123
|
+
| **Read** (QUERY) | Automatic, whenever the topic spans documents | Agent | `index.md` + the concept |
|
|
124
|
+
| **Offer** (INGEST) | Automatic, whenever durable knowledge surfaces in conversation | **Human approves, agent writes** | `AGENTS.md` after the yes |
|
|
125
|
+
| **Harvest** (HARVEST) | Explicit request only, per finished feature | Human | `AGENTS.md` in full |
|
|
126
|
+
| **Verify** (knowledge checker + LINT) | With any write | Agent | — |
|
|
127
|
+
|
|
128
|
+
Reading and offering are the agent's job without being asked. Deciding is always the human's.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Domain and Architecture Modeling
|
|
2
|
+
|
|
3
|
+
**Read when:** a change creates or alters a bounded context, module boundary or dependency direction;
|
|
4
|
+
introduces, replaces or decouples an external provider; changes a port, adapter, queue or inter-module
|
|
5
|
+
message; or models an Entity, Value Object, Aggregate, Domain Service or Domain Event. Simple CRUD,
|
|
6
|
+
local bug fixes and boundary-preserving refactors do not.
|
|
7
|
+
|
|
8
|
+
**Why this exists:** A domain that imports the web, API, or persistence framework cannot outlive
|
|
9
|
+
those frameworks. Invariants that live only in SQL cannot be exercised without the database. This
|
|
10
|
+
file is how the model is written, not what the product means.
|
|
11
|
+
|
|
12
|
+
This document owns how the domain is expressed in code. It does not own product language, domain
|
|
13
|
+
rules or architecture decisions. `docs/product/` owns the domain; the consuming project's architecture
|
|
14
|
+
docs own architecture invariants; `.specs/STATE.md` owns project decisions. Those sources win
|
|
15
|
+
whenever skill guidance conflicts.
|
|
16
|
+
|
|
17
|
+
## Design sequence
|
|
18
|
+
|
|
19
|
+
1. Ground the change in the canonical product and architecture sources. Use `knowledge/wiki/` only
|
|
20
|
+
to follow connections or find contradictions; return to the cited source for the rule.
|
|
21
|
+
2. For boundaries, integrations or evolution, record ownership, public contract, port/adapter
|
|
22
|
+
boundary, consistency model, failure semantics and evolution trigger in the feature design.
|
|
23
|
+
3. When a dependency crosses module or context boundaries, record its strength, distance and
|
|
24
|
+
volatility, then decide whether to accept, relocate or decouple it.
|
|
25
|
+
4. For behaviour inside one bounded context, apply *Domain expression* below. Record the chosen
|
|
26
|
+
building blocks, invariants, transaction boundary and domain events in the feature design without
|
|
27
|
+
restating the product model.
|
|
28
|
+
5. When architectural and tactical modeling both apply, establish the bounded context and its
|
|
29
|
+
contracts first, then model its internals.
|
|
30
|
+
6. Record a new lasting choice in the correct namespace: project decisions are `AD-NNN` entries in
|
|
31
|
+
`.specs/STATE.md`; architecture invariants live in the consuming project's architecture docs.
|
|
32
|
+
|
|
33
|
+
For an auto-sized change without `design.md`, keep the same result in the inline design note.
|
|
34
|
+
|
|
35
|
+
## Domain expression
|
|
36
|
+
|
|
37
|
+
These rules fix how the model is written. A rule needing a concrete entity name to be understood
|
|
38
|
+
belongs in `docs/product/` instead.
|
|
39
|
+
|
|
40
|
+
### One aggregate, one module
|
|
41
|
+
|
|
42
|
+
An aggregate owns one folder, named for the aggregate. The folder holds the aggregate's behaviour,
|
|
43
|
+
its repository port and every adapter implementing that port, plus whatever else is specific to it.
|
|
44
|
+
Two aggregates in one folder is a folder that must split; one aggregate spread across two folders is
|
|
45
|
+
a boundary error.
|
|
46
|
+
|
|
47
|
+
Folders carrying no aggregate keep their own names: the HTTP surface, shared technical modules.
|
|
48
|
+
|
|
49
|
+
### One repository per aggregate root
|
|
50
|
+
|
|
51
|
+
Only an aggregate root gets a repository. Everything inside the aggregate is loaded and saved through
|
|
52
|
+
that root. The port takes and returns domain values. A persistence row never crosses it.
|
|
53
|
+
|
|
54
|
+
### Value Object or primitive field
|
|
55
|
+
|
|
56
|
+
A value becomes a Value Object when a rule must hold everywhere the value appears — a format, a range,
|
|
57
|
+
a normalization, a unit, or two fields only meaningful together. It stays a primitive when its only
|
|
58
|
+
rule is shape already enforced at the trust boundary.
|
|
59
|
+
|
|
60
|
+
The discriminator is where the value can enter from. A value that reaches the domain only through a
|
|
61
|
+
validated request needs no second guard. A value the domain derives itself, reads back from storage,
|
|
62
|
+
or receives from a job or a provider callback bypasses that boundary, so its rule has to travel with
|
|
63
|
+
it.
|
|
64
|
+
|
|
65
|
+
Identifiers stay opaque strings unless the project has decided otherwise.
|
|
66
|
+
|
|
67
|
+
### Where invariants are enforced
|
|
68
|
+
|
|
69
|
+
An invariant over one aggregate's own state is enforced inside that aggregate, in the method that
|
|
70
|
+
performs the transition, before the state changes. The method is named for the transition in the
|
|
71
|
+
product's language and refuses an illegal one rather than reporting it.
|
|
72
|
+
|
|
73
|
+
| Layer | Its job |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| HTTP / command boundary | Rejects malformed input and resolves authority before the command |
|
|
76
|
+
| Aggregate | Decides whether the transition is legal, then performs it |
|
|
77
|
+
| Repository adapter | Persists a decided outcome |
|
|
78
|
+
| Database constraint | Backstop proving the invariant held |
|
|
79
|
+
|
|
80
|
+
Authority is not an aggregate invariant. The command boundary resolves who may act; an aggregate
|
|
81
|
+
re-deriving it duplicates a rule whose inputs it cannot see.
|
|
82
|
+
|
|
83
|
+
A database constraint is never a rule's only statement. A rule living solely in SQL cannot be
|
|
84
|
+
exercised without the database and cannot explain its own refusal.
|
|
85
|
+
|
|
86
|
+
### Transaction boundary
|
|
87
|
+
|
|
88
|
+
One command mutates one aggregate in one transaction. The application layer opens the transaction and
|
|
89
|
+
the adapter runs inside it. An aggregate receives no handle to the transaction; it computes the next
|
|
90
|
+
state and returns it.
|
|
91
|
+
|
|
92
|
+
A rule spanning two aggregates resolves through events or jobs, never through a second aggregate
|
|
93
|
+
mutation in the same transaction, unless the architecture docs explicitly allow it.
|
|
94
|
+
|
|
95
|
+
### What the domain may import
|
|
96
|
+
|
|
97
|
+
A domain module imports the language standard library and other modules of the same aggregate.
|
|
98
|
+
|
|
99
|
+
**It does not import the web framework, the API framework, the persistence framework, a provider SDK,
|
|
100
|
+
or the public wire-contract package.** Each is a boundary the domain is meant to outlive. A domain
|
|
101
|
+
type matching a DTO field for field is still declared separately, because a wire contract and an
|
|
102
|
+
internal model change for different reasons.
|
|
103
|
+
|
|
104
|
+
The consuming project's boundary gate, if it has one, enumerates those module names. Moving business
|
|
105
|
+
rules out of persistence adapters is done as part of the next feature that touches a repository, not
|
|
106
|
+
as a migration of its own.
|
|
107
|
+
|
|
108
|
+
### Ports and adapters
|
|
109
|
+
|
|
110
|
+
The domain declares the port and names it for what the domain needs. The adapter conforms. A port
|
|
111
|
+
mirroring a library's API instead of the domain's need has the direction backwards.
|
|
112
|
+
|
|
113
|
+
A port earns its place when it isolates something the domain must outlive, or when it lets the domain
|
|
114
|
+
be exercised without infrastructure. A collaborator that is neither needs no port.
|
|
115
|
+
|
|
116
|
+
### Proportional intensity
|
|
117
|
+
|
|
118
|
+
Match the machinery to the rules a module actually has:
|
|
119
|
+
|
|
120
|
+
| What the module has | What it gets |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| Shape rules only | A contract schema, a repository and route handlers |
|
|
123
|
+
| One rule holding on every write | That rule, in one named function in the module |
|
|
124
|
+
| States with legal and illegal transitions, or fields that must agree | An aggregate owning those transitions |
|
|
125
|
+
| A rule spanning aggregates | A domain service, or the architecture doc's event path |
|
|
126
|
+
|
|
127
|
+
Model behaviour where a rule exists. Before adding an aggregate, name the invariant it protects; when
|
|
128
|
+
no name comes, the module has shape rules and the first row applies.
|
|
129
|
+
|
|
130
|
+
## Vendored skill scope
|
|
131
|
+
|
|
132
|
+
Vendored modeling skills are advisory. Their defaults do not become project rules merely because the
|
|
133
|
+
skill is installed. Do not edit a vendored skill to record a project exception. Record conventions
|
|
134
|
+
here after they are adopted.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# QA Execution
|
|
2
|
+
|
|
3
|
+
**Read when:** a feature reaches its closing QA session.
|
|
4
|
+
|
|
5
|
+
`wtk-qa-plan` and `wtk-qa-execute` own the procedures. This guideline only decides whether QA runs, dispatches
|
|
6
|
+
the existing Verifier, and points to the authorities that keep the contract stable.
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
QA runs once per feature, at feature close over the integrated tree; no slice runs QA. Run it when
|
|
11
|
+
the feature diff changes an observable UI, API, CLI, mobile surface, public configuration,
|
|
12
|
+
adoption flow, docs-as-interface, or user-facing copy, unless the proportional classifier in
|
|
13
|
+
`.agents/skills/wtk/references/validation.md` selects a narrower route. A behavior-preserving `direct correction` or `UI-only correction`
|
|
14
|
+
is the exception: its targeted integration validation covers the consuming project and it receives no QA Plan/Execute cycle,
|
|
15
|
+
even when the rendered component changes. A browser-only invariant explicitly
|
|
16
|
+
changed by that correction may use one existing targeted scenario. Purely internal refactors receive
|
|
17
|
+
technical verification only. Record `no user-visible change` when no public promise changed.
|
|
18
|
+
|
|
19
|
+
## Dispatch
|
|
20
|
+
|
|
21
|
+
After the final implementation wtk-deep-review group, use the provider's existing `verifier` with one
|
|
22
|
+
phase per packet:
|
|
23
|
+
|
|
24
|
+
1. Send a fresh `phase: wtk-qa-plan` packet to invoke `wtk-qa-plan`, create or refresh durable journeys and
|
|
25
|
+
scenarios, and create a new dated charter for this cycle. Never edit an existing charter.
|
|
26
|
+
2. Send a distinct fresh `phase: wtk-qa-execute` packet to invoke `wtk-qa-execute` and walk those journeys.
|
|
27
|
+
|
|
28
|
+
The QA Plan session ends before the product starts. The QA Execute session does not write product
|
|
29
|
+
code. A defect returns to an Implementer; after the fix, a fresh Verifier applies incremental impact
|
|
30
|
+
selection, reruns invalidated technical proofs, retests the affected journey, and resumes the cycle.
|
|
31
|
+
|
|
32
|
+
## Authorities and adapters
|
|
33
|
+
|
|
34
|
+
- `docs/toolkit/guidelines/QA-SCENARIOS.md` owns scenario fields, ids, statuses, and flag/reset rules.
|
|
35
|
+
- `docs/qa/README.md` owns the consuming project's public interfaces, existing adapter, setup,
|
|
36
|
+
authentication, fixtures, cleanup, and limitations.
|
|
37
|
+
- `wtk-qa-execute` selects the declared browser, API, CLI, mobile, or manual adapter. It records the
|
|
38
|
+
exact path, evidence, and limitation. It does not install tooling or invent commands.
|
|
39
|
+
- Each checkout owns its runtime and raw evidence. Keep durable reports and statuses in `docs/qa/`
|
|
40
|
+
and keep generated evidence in the consuming project's disposable evidence path.
|
|
41
|
+
- When a selected QA scope carries a visual AC, follow `UI-UX.md#verifying-the-built-screen`, point the
|
|
42
|
+
report at its feature `uiux.md` row, and record the paired-capture output fields. A manual comparison
|
|
43
|
+
is evidence, not an automated test; keep behavioral assertions intact.
|
|
44
|
+
|
|
45
|
+
Read the two skills and `QA-SCENARIOS.md` for the active branch; this bridge deliberately carries no
|
|
46
|
+
duplicate scenario schema or live-walk protocol.
|