@zyaiting/keelson 0.4.0
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/LICENSE +21 -0
- package/README.md +101 -0
- package/README_CN.md +101 -0
- package/bin/keelson.js +15 -0
- package/hooks/codebuddy-session.mjs +67 -0
- package/hooks/opencode-session.mjs +65 -0
- package/hooks/prompt-state.mjs +66 -0
- package/hooks/session-start.mjs +94 -0
- package/package.json +64 -0
- package/registry/models.json +118 -0
- package/registry/platforms.json +92 -0
- package/skills/keelson/SKILL.md +44 -0
- package/skills/keelson/references/build.md +61 -0
- package/skills/keelson/references/context.md +34 -0
- package/skills/keelson/references/debug.md +46 -0
- package/skills/keelson/references/design-lenses.md +78 -0
- package/skills/keelson/references/discover.md +70 -0
- package/skills/keelson/references/engineer.md +110 -0
- package/skills/keelson/references/frontend-delivery.md +38 -0
- package/skills/keelson/references/frontend-interaction.md +31 -0
- package/skills/keelson/references/frontend-review.md +33 -0
- package/skills/keelson/references/frontend-visual.md +31 -0
- package/skills/keelson/references/frontend.md +33 -0
- package/skills/keelson/references/handoff.md +43 -0
- package/skills/keelson/references/harness.md +54 -0
- package/skills/keelson/references/interview.md +120 -0
- package/skills/keelson/references/land.md +47 -0
- package/skills/keelson/references/model.md +29 -0
- package/skills/keelson/references/plan.md +106 -0
- package/skills/keelson/references/reconcile.md +61 -0
- package/skills/keelson/references/shape.md +86 -0
- package/skills/keelson/references/verify.md +64 -0
- package/skills/keelson/templates/GLOSSARY.md +5 -0
- package/skills/keelson/templates/INTENT.md +22 -0
- package/skills/keelson/templates/NOW.md +9 -0
- package/skills/keelson/templates/README.md +60 -0
- package/skills/keelson/templates/ROADMAP.md +12 -0
- package/skills/keelson/templates/change-quick.md +16 -0
- package/skills/keelson/templates/change.md +32 -0
- package/skills/keelson/templates/delta-spec.md +12 -0
- package/skills/keelson/templates/handoff.md +27 -0
- package/skills/keelson/templates/ledger.md +3 -0
- package/skills/keelson/templates/resident-block.md +7 -0
- package/skills/keelson/templates/rules-general.md +10 -0
- package/skills/keelson/templates/rules-index.md +5 -0
- package/skills/keelson/templates/spec.md +14 -0
- package/skills/keelson/templates/tasks.md +9 -0
- package/skills/keelson/templates/workflow.md +18 -0
- package/skills/zh/keelson/SKILL.md +46 -0
- package/skills/zh/keelson/references/build.md +61 -0
- package/skills/zh/keelson/references/context.md +34 -0
- package/skills/zh/keelson/references/debug.md +46 -0
- package/skills/zh/keelson/references/design-lenses.md +78 -0
- package/skills/zh/keelson/references/discover.md +70 -0
- package/skills/zh/keelson/references/engineer.md +110 -0
- package/skills/zh/keelson/references/frontend-delivery.md +38 -0
- package/skills/zh/keelson/references/frontend-interaction.md +31 -0
- package/skills/zh/keelson/references/frontend-review.md +33 -0
- package/skills/zh/keelson/references/frontend-visual.md +31 -0
- package/skills/zh/keelson/references/frontend.md +33 -0
- package/skills/zh/keelson/references/handoff.md +43 -0
- package/skills/zh/keelson/references/harness.md +54 -0
- package/skills/zh/keelson/references/interview.md +120 -0
- package/skills/zh/keelson/references/land.md +47 -0
- package/skills/zh/keelson/references/model.md +29 -0
- package/skills/zh/keelson/references/plan.md +106 -0
- package/skills/zh/keelson/references/reconcile.md +61 -0
- package/skills/zh/keelson/references/shape.md +86 -0
- package/skills/zh/keelson/references/verify.md +64 -0
- package/skills/zh/keelson/templates/GLOSSARY.md +5 -0
- package/skills/zh/keelson/templates/INTENT.md +22 -0
- package/skills/zh/keelson/templates/NOW.md +9 -0
- package/skills/zh/keelson/templates/README.md +60 -0
- package/skills/zh/keelson/templates/ROADMAP.md +12 -0
- package/skills/zh/keelson/templates/change-quick.md +16 -0
- package/skills/zh/keelson/templates/change.md +32 -0
- package/skills/zh/keelson/templates/delta-spec.md +12 -0
- package/skills/zh/keelson/templates/handoff.md +27 -0
- package/skills/zh/keelson/templates/ledger.md +3 -0
- package/skills/zh/keelson/templates/resident-block.md +7 -0
- package/skills/zh/keelson/templates/rules-general.md +10 -0
- package/skills/zh/keelson/templates/rules-index.md +5 -0
- package/skills/zh/keelson/templates/spec.md +14 -0
- package/skills/zh/keelson/templates/tasks.md +9 -0
- package/skills/zh/keelson/templates/workflow.md +18 -0
- package/src/cli.js +87 -0
- package/src/commands/ablate.js +96 -0
- package/src/commands/ask.js +64 -0
- package/src/commands/attest.js +71 -0
- package/src/commands/check.js +127 -0
- package/src/commands/context.js +95 -0
- package/src/commands/design.js +63 -0
- package/src/commands/doctor.js +157 -0
- package/src/commands/focus.js +84 -0
- package/src/commands/guide.js +59 -0
- package/src/commands/handoff.js +41 -0
- package/src/commands/hook.js +23 -0
- package/src/commands/impact.js +58 -0
- package/src/commands/init.js +289 -0
- package/src/commands/land.js +258 -0
- package/src/commands/models.js +62 -0
- package/src/commands/new.js +70 -0
- package/src/commands/platforms.js +39 -0
- package/src/commands/retro.js +114 -0
- package/src/commands/status.js +115 -0
- package/src/commands/uninstall.js +30 -0
- package/src/commands/validate.js +117 -0
- package/src/lib/args.js +30 -0
- package/src/lib/changes.js +114 -0
- package/src/lib/check-activity.js +29 -0
- package/src/lib/config.js +102 -0
- package/src/lib/decisions.js +59 -0
- package/src/lib/evidence.js +127 -0
- package/src/lib/fs.js +126 -0
- package/src/lib/git.js +353 -0
- package/src/lib/glob.js +54 -0
- package/src/lib/health.js +113 -0
- package/src/lib/lifecycle.js +120 -0
- package/src/lib/maintenance.js +66 -0
- package/src/lib/markdown.js +438 -0
- package/src/lib/models.js +195 -0
- package/src/lib/out.js +13 -0
- package/src/lib/paths.js +82 -0
- package/src/lib/rules.js +27 -0
- package/src/lib/runtime-path.js +22 -0
- package/src/lib/session.js +100 -0
- package/src/lib/specs.js +345 -0
- package/src/lib/transaction.js +93 -0
- package/src/platforms/index.js +3 -0
- package/src/platforms/integration.js +384 -0
- package/src/platforms/registry.js +46 -0
- package/src/platforms/runtime.js +249 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"updated": "2026-09-19",
|
|
4
|
+
"note": "Tiers map to floating aliases, never to dated model IDs. Update this file only when a platform gains or retires a model family.",
|
|
5
|
+
"tiers": [
|
|
6
|
+
"light",
|
|
7
|
+
"standard",
|
|
8
|
+
"deep"
|
|
9
|
+
],
|
|
10
|
+
"platforms": {
|
|
11
|
+
"claude": {
|
|
12
|
+
"label": "Claude Code",
|
|
13
|
+
"rank": [
|
|
14
|
+
"haiku",
|
|
15
|
+
"sonnet",
|
|
16
|
+
"opus",
|
|
17
|
+
"fable"
|
|
18
|
+
],
|
|
19
|
+
"tiers": {
|
|
20
|
+
"light": "haiku",
|
|
21
|
+
"standard": "sonnet",
|
|
22
|
+
"deep": "opus"
|
|
23
|
+
},
|
|
24
|
+
"subagents": true,
|
|
25
|
+
"notes": "Agent tool accepts family aliases; each alias floats to the newest model of that family. `fable` is used for deep when the host exposes it."
|
|
26
|
+
},
|
|
27
|
+
"codex": {
|
|
28
|
+
"label": "Codex CLI",
|
|
29
|
+
"rank": [
|
|
30
|
+
"mini",
|
|
31
|
+
"default",
|
|
32
|
+
"high"
|
|
33
|
+
],
|
|
34
|
+
"tiers": {},
|
|
35
|
+
"subagents": false,
|
|
36
|
+
"notes": "Model names vary by release. Run `keelson models rank <name> <tier>` once, or `keelson models --refresh` with OPENAI_API_KEY to infer from the provider catalogue."
|
|
37
|
+
},
|
|
38
|
+
"opencode": {
|
|
39
|
+
"label": "OpenCode",
|
|
40
|
+
"rank": [],
|
|
41
|
+
"tiers": {},
|
|
42
|
+
"subagents": true,
|
|
43
|
+
"notes": "OpenCode provides built-in subagents; model identifiers are provider-qualified and project-specific, so Keelson does not guess a tier mapping."
|
|
44
|
+
},
|
|
45
|
+
"pi": {
|
|
46
|
+
"label": "Pi coding agent",
|
|
47
|
+
"rank": [],
|
|
48
|
+
"tiers": {},
|
|
49
|
+
"subagents": false,
|
|
50
|
+
"notes": "Pi model selection depends on the configured provider. Keep effort tiers semantic unless the user supplies aliases."
|
|
51
|
+
},
|
|
52
|
+
"gemini": {
|
|
53
|
+
"label": "Gemini CLI",
|
|
54
|
+
"rank": [
|
|
55
|
+
"flash-lite",
|
|
56
|
+
"flash",
|
|
57
|
+
"pro"
|
|
58
|
+
],
|
|
59
|
+
"tiers": {
|
|
60
|
+
"light": "flash-lite",
|
|
61
|
+
"standard": "flash",
|
|
62
|
+
"deep": "pro"
|
|
63
|
+
},
|
|
64
|
+
"subagents": false
|
|
65
|
+
},
|
|
66
|
+
"kiro": {
|
|
67
|
+
"label": "Kiro CLI",
|
|
68
|
+
"rank": [],
|
|
69
|
+
"tiers": {},
|
|
70
|
+
"subagents": true,
|
|
71
|
+
"notes": "Kiro CLI supports parallel subagents. Model availability can vary by account and release, so aliases are user-configured."
|
|
72
|
+
},
|
|
73
|
+
"codebuddy": {
|
|
74
|
+
"label": "CodeBuddy CLI",
|
|
75
|
+
"rank": [],
|
|
76
|
+
"tiers": {},
|
|
77
|
+
"subagents": true,
|
|
78
|
+
"notes": "CodeBuddy exposes an Agent subagent tool and host-specific model aliases. Keelson does not persist release-specific model IDs."
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"providers": {
|
|
82
|
+
"anthropic": {
|
|
83
|
+
"env": "ANTHROPIC_API_KEY",
|
|
84
|
+
"catalogue": "https://api.anthropic.com/v1/models",
|
|
85
|
+
"families": [
|
|
86
|
+
"haiku",
|
|
87
|
+
"sonnet",
|
|
88
|
+
"opus",
|
|
89
|
+
"fable"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"openai": {
|
|
93
|
+
"env": "OPENAI_API_KEY",
|
|
94
|
+
"catalogue": "https://api.openai.com/v1/models",
|
|
95
|
+
"families": [
|
|
96
|
+
"nano",
|
|
97
|
+
"mini",
|
|
98
|
+
"",
|
|
99
|
+
"pro"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"google": {
|
|
103
|
+
"env": "GEMINI_API_KEY",
|
|
104
|
+
"catalogue": null,
|
|
105
|
+
"families": [
|
|
106
|
+
"flash-lite",
|
|
107
|
+
"flash",
|
|
108
|
+
"pro"
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"dated_id_patterns": [
|
|
113
|
+
"claude-[a-z0-9.-]+-\\d{8}",
|
|
114
|
+
"gpt-[a-z0-9.-]+-\\d{4}-\\d{2}-\\d{2}",
|
|
115
|
+
"gemini-[a-z0-9.-]+-\\d{3,}",
|
|
116
|
+
"o[0-9]-[a-z-]+-\\d{4}-\\d{2}-\\d{2}"
|
|
117
|
+
]
|
|
118
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"updated": "2026-09-20",
|
|
4
|
+
"note": "Adapters describe generated discovery paths, not a promise of live end-to-end host parity. Codex session identity has been exercised locally. Other hosts have adapter contract tests; hooks are supported only where listed. Native session identity sources include CODEX_THREAD_ID, Claude hooks, Pi environment and explicit KEELSON_SESSION_ID. No source means an honest degraded state. Default installation is lightweight; --vendor explicitly copies package guidance.",
|
|
5
|
+
"platforms": {
|
|
6
|
+
"claude": {
|
|
7
|
+
"label": "Claude Code",
|
|
8
|
+
"bin": "claude",
|
|
9
|
+
"instructions": "CLAUDE.md",
|
|
10
|
+
"skillsDir": ".claude/skills",
|
|
11
|
+
"hooks": true,
|
|
12
|
+
"confidence": "documented",
|
|
13
|
+
"support": "first-class",
|
|
14
|
+
"sessionFocus": "native",
|
|
15
|
+
"sessionAdapter": "claude-hooks"
|
|
16
|
+
},
|
|
17
|
+
"codex": {
|
|
18
|
+
"label": "Codex CLI",
|
|
19
|
+
"bin": "codex",
|
|
20
|
+
"instructions": "AGENTS.md",
|
|
21
|
+
"skillsDir": ".agents/skills",
|
|
22
|
+
"hooks": false,
|
|
23
|
+
"confidence": "verified",
|
|
24
|
+
"support": "first-class",
|
|
25
|
+
"sessionFocus": "native",
|
|
26
|
+
"sessionAdapter": "codex-thread-env"
|
|
27
|
+
},
|
|
28
|
+
"opencode": {
|
|
29
|
+
"label": "OpenCode",
|
|
30
|
+
"bin": "opencode",
|
|
31
|
+
"instructions": "AGENTS.md",
|
|
32
|
+
"skillsDir": ".agents/skills",
|
|
33
|
+
"hooks": false,
|
|
34
|
+
"confidence": "documented",
|
|
35
|
+
"support": "first-class",
|
|
36
|
+
"sessionFocus": "degraded"
|
|
37
|
+
},
|
|
38
|
+
"pi": {
|
|
39
|
+
"label": "Pi coding agent",
|
|
40
|
+
"bin": "pi",
|
|
41
|
+
"instructions": "AGENTS.md",
|
|
42
|
+
"skillsDir": ".agents/skills",
|
|
43
|
+
"hooks": false,
|
|
44
|
+
"confidence": "documented",
|
|
45
|
+
"support": "first-class",
|
|
46
|
+
"sessionFocus": "native",
|
|
47
|
+
"sessionAdapter": "pi-env"
|
|
48
|
+
},
|
|
49
|
+
"gemini": {
|
|
50
|
+
"label": "Gemini CLI",
|
|
51
|
+
"bin": "gemini",
|
|
52
|
+
"instructions": "GEMINI.md",
|
|
53
|
+
"skillsDir": ".agents/skills",
|
|
54
|
+
"hooks": false,
|
|
55
|
+
"confidence": "documented",
|
|
56
|
+
"support": "first-class",
|
|
57
|
+
"sessionFocus": "degraded"
|
|
58
|
+
},
|
|
59
|
+
"kiro": {
|
|
60
|
+
"label": "Kiro CLI",
|
|
61
|
+
"bin": "kiro-cli",
|
|
62
|
+
"instructions": "AGENTS.md",
|
|
63
|
+
"skillsDir": ".kiro/skills",
|
|
64
|
+
"hooks": false,
|
|
65
|
+
"confidence": "documented",
|
|
66
|
+
"support": "first-class",
|
|
67
|
+
"sessionFocus": "degraded"
|
|
68
|
+
},
|
|
69
|
+
"codebuddy": {
|
|
70
|
+
"label": "CodeBuddy CLI",
|
|
71
|
+
"bin": "codebuddy",
|
|
72
|
+
"instructions": "CODEBUDDY.md",
|
|
73
|
+
"skillsDir": ".codebuddy/skills",
|
|
74
|
+
"hooks": false,
|
|
75
|
+
"confidence": "documented",
|
|
76
|
+
"support": "first-class",
|
|
77
|
+
"sessionFocus": "native",
|
|
78
|
+
"sessionAdapter": "codebuddy-hooks"
|
|
79
|
+
},
|
|
80
|
+
"agents": {
|
|
81
|
+
"label": "Portable AGENTS.md + Agent Skills",
|
|
82
|
+
"bin": null,
|
|
83
|
+
"instructions": "AGENTS.md",
|
|
84
|
+
"skillsDir": ".agents/skills",
|
|
85
|
+
"hooks": false,
|
|
86
|
+
"confidence": "documented",
|
|
87
|
+
"support": "portable",
|
|
88
|
+
"examples": "Any host that reads AGENTS.md and/or the open Agent Skills `.agents/skills/` convention",
|
|
89
|
+
"sessionFocus": "degraded"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keelson
|
|
3
|
+
description: Engineering control plane for coding work in repositories with a .keelson/ directory. Use for exploring an idea, changing code, fixing/debugging, frontend design and UX review, continuing prior work, or improving recurring engineering failures. Keeps conversation sessions separate from durable work items so users can keep asking questions without having to announce when a task starts or ends.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Keelson
|
|
7
|
+
|
|
8
|
+
Read the installed workflow with `keelson guide workflow`; load each named reference with `keelson guide <name>` (omit `.md`). Keelson constrains **state transitions and evidence**, not implementation taste. User and project instructions win.
|
|
9
|
+
|
|
10
|
+
## Classify the conversation, not the lifecycle
|
|
11
|
+
|
|
12
|
+
| Intent | Typical request | Start with |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **Explore** | compare, explain, “what should we do?”, “stress-test this” | `discover.md` + `interview.md`; read-only until a modification is requested |
|
|
15
|
+
| **Change** | build, add, refactor, migrate, “also change…” | `shape.md` → `context.md`; load `model.md` for boundary/language questions, `engineer.md` for non-obvious technical choices, `design-lenses.md` only for triggered risks; spec-sized work adds `plan.md` |
|
|
16
|
+
| **Fix** | bug, failing test, unexpected behavior | `debug.md`, then `verify.md` |
|
|
17
|
+
| **Resume** | continue, pick this back up | `keelson focus --auto` + current context; use `handoff.md` only when a real ownership/machine transfer exists |
|
|
18
|
+
| **Improve** | repeated mistake, harness/rule/process problem, retro | `harness.md` + `reconcile.md` |
|
|
19
|
+
|
|
20
|
+
Completion is **not** an intent and never depends on the user saying “done”. It is a state transition: when the focused change has satisfied acceptance, no blocking questions/assumptions, required rollout, and fresh verification on the current tree, it becomes `ready`. Run the Finish path (`verify.md` → `land.md` → `reconcile.md`) automatically before claiming completion.
|
|
21
|
+
|
|
22
|
+
- For interface design, review, interaction or responsive work, load `frontend.md`; use `keelson design` for focused action briefs. Keep browser observations distinct from code checks.
|
|
23
|
+
|
|
24
|
+
## Operating rules
|
|
25
|
+
|
|
26
|
+
- A conversation/session is only a focus pointer. Ending a window, going idle, or continuing to ask questions MUST NOT mark a change complete.
|
|
27
|
+
- `keelson new` binds the new change to the current session when session identity is available. Same-goal follow-ups stay on that change; an independent requested outcome gets a new change and focus moves.
|
|
28
|
+
- On Resume, use `keelson focus --auto`; branch match or a sole active change may be suggested. Never silently bind an ambiguous session.
|
|
29
|
+
- If `NOW.md` says “First contact”, infer and confirm `INTENT.md`; do not inventory the whole repository into specs/rules.
|
|
30
|
+
- Non-trivial modifying work starts from current context; shared modules get `keelson impact <files>`.
|
|
31
|
+
- Ask only at the decision frontier. Run the triggered blindspot pass, then use `interview.md`: up to three independent ready owner-owned decisions per round, skipping settled answers, concrete scenario/options, recommended default, and `not sure` as a valid route. Never ask what repo evidence, an experiment, or agent engineering judgment can settle.
|
|
32
|
+
- Route non-obvious mechanisms/architecture through `engineer.md`: reduce to facts, outcome, constraints, and invariants; state a falsifiable hypothesis; use the cheapest experiment/ablation that can discriminate; complexity must earn its keep with evidence.
|
|
33
|
+
- Size only the work: trivial = direct edit; quick = lightweight change; spec = acceptance + behavior delta + plan within existing user authorization; clarify only unresolved owner choices.
|
|
34
|
+
- Artifacts are information containers, not ceremony. Do not create empty roadmap/glossary/rule/task/ledger/handoff/spec files.
|
|
35
|
+
- `tasks.md` is an execution plan, not completion authority. Unchecked plan items never override satisfied acceptance + fresh evidence; reconcile or remove stale tasks when the implementation path changes.
|
|
36
|
+
- Knowledge maintenance is internal. During RECONCILE, automatically rewrite/split/dedupe pressured durable docs and let `land` auto-shard large specs; never ask the owner to maintain Keelson unless a product-semantic decision is required.
|
|
37
|
+
- Keep **code reality**, **confirmed truth**, and **planned change** distinct. Open questions block only dependent slices.
|
|
38
|
+
- Fresh structured `keelson check --record` evidence (review commands and use `--trust` on first execution) is required for completion claims. Never weaken acceptance to make a check pass.
|
|
39
|
+
- A `ready` change should be landed without waiting for a special user phrase. If landing still needs an owner decision, stop on that decision only.
|
|
40
|
+
- `handoff.md` is for real transfer across people/machines or deliberate ownership change; ordinary session continuity comes from durable change artifacts plus private per-machine session state.
|
|
41
|
+
- Repeated failures graduate to the narrowest durable control: spec → scoped rule → executable fitness check; remove redundant prose afterward.
|
|
42
|
+
- Use `light | standard | deep`; never persist dated model IDs.
|
|
43
|
+
|
|
44
|
+
Users normally need only `init`, `status`, `doctor`, `update`, and `uninstall`; the agent uses the rest.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Building
|
|
2
|
+
|
|
3
|
+
Execute `tasks.md` slice by slice. You choose how; these notes cover the parts that are easy to get wrong.
|
|
4
|
+
|
|
5
|
+
## Rulings, not stalls
|
|
6
|
+
<!-- keelson: id=build.rulings | without: agent parks the session on questions the plan already answers; or decides silently and the reasoning is lost | sunset: never -->
|
|
7
|
+
|
|
8
|
+
The plan is the argument; the specs and `INTENT.md` are the authority; your judgment settles what neither answers, within `INTENT.md → Authorizations`. When you hit ambiguity or a plan defect inside your authorization, decide, record it, and keep going:
|
|
9
|
+
|
|
10
|
+
```markdown
|
|
11
|
+
### Ruling: ack semantics
|
|
12
|
+
At-least-once with idempotent consumers. Exactly-once would need a broker feature we do not run. Cost if wrong: duplicate side effects in `notify`, bounded by the idempotency key.
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Outside your authorization, it is an open question: add it to `change.md → Open questions` with what it blocks, and build the slices it does not block. Four things stop you outright: an irreversible or destructive operation; a security-sensitive action; a side effect outside the working tree that convention says to ask about (merge, push to a shared branch, publish, external calls); a plan so broken every path forward is a guess.
|
|
16
|
+
|
|
17
|
+
## Subagents by effort tier
|
|
18
|
+
<!-- keelson: id=build.dispatch | without: one context does everything, quality drops as it fills, and cost is flat regardless of task difficulty | sunset: when the host has no subagent tool, this section is inert -->
|
|
19
|
+
|
|
20
|
+
When tasks are mostly independent and the host offers subagents, dispatch a fresh subagent per task with the model resolved from its effort tier: `keelson models --resolve <tier>` prints the alias for this platform (or map tiers onto the aliases your subagent tool exposes, in ascending capability order). Give the subagent the task text, the matched rules, the relevant spec, and the verification command. Never hand it your whole conversation.
|
|
21
|
+
|
|
22
|
+
More agents are not a linear throughput multiplier. When tasks share mutable state or the same contract, or need constant synchronization, coordination and merge cost can exceed the parallelism benefit; keep them sequential. Parallelize only when boundaries are clear, outputs are independently verifiable, and the merge contract is explicit. Do not try to rescue tightly coupled work by simply adding agents.
|
|
23
|
+
|
|
24
|
+
After each task, a reviewer subagent (tier ≥ `standard`, never below the implementer) checks the diff against the spec and the rules. Record both in the ledger:
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
### Dispatch: task 2 → standard (sonnet)
|
|
28
|
+
Result: pass
|
|
29
|
+
Implemented paged query; reviewer accepted. Verify `npm test -- orders.repo` exit 0.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The first line of a `Dispatch:` body is `Result: pass` or `Result: fail`; `keelson retro` counts only that line, never words in the prose.
|
|
33
|
+
|
|
34
|
+
If the task's verification fails twice at a tier, escalate one tier and re-dispatch; log it:
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
### Escalate: task 2 light → standard
|
|
38
|
+
Two failures on boundary handling; light-tier output ignored the empty-page case.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Escalation is for work that came back wrong. It is not for dispatches that never ran: a rate limit, a timeout, or a tool error is retried once at the same tier after a short pause, then the task is done inline by you and noted (`### Note: task 3 inline after two dispatch errors`). `deep` is the top tier; nothing escalates above it, and a `deep` verification failure stops and asks. Tightly coupled tasks, or no subagent tool: run inline yourself, still one task at a time, still ledgered.
|
|
42
|
+
|
|
43
|
+
## Parallel work
|
|
44
|
+
<!-- keelson: id=build.parallel | without: two writers on one branch overwrite each other, or two changes implement the same contract two ways | sunset: never -->
|
|
45
|
+
|
|
46
|
+
When more than one writer (person or agent) works at once, each change gets its own branch or worktree (`keelson new --worktree`). Shared interfaces are aligned before either side implements them: agree the contract in the delta spec, land or reference it, then build. `keelson status` warns when two active changes touch the same capability or the same declared paths; treat that as "talk first", not as a lock. A file on disk is not a distributed lock and a branch does not remove semantic conflicts; cross-machine claiming and merge control belong to the tracker, pull requests, and CI. After integrating someone else's change into yours, re-run verification; the old evidence is stale by definition.
|
|
47
|
+
|
|
48
|
+
When the other owner cannot be reached (an unattended run, a colleague offline), do not wait and do not pretend the overlap is absent: keep your delta to the shared requirement as small as the change allows, record the overlap as a `### Note:` in your ledger and a line in `NOW.md`, and say it in your write-back and completion report. `keelson land` names the overlapping changes when you land; their landing will stop at the drift gate until their owner re-reads the merged spec.
|
|
49
|
+
|
|
50
|
+
## Keep the artifacts true while you work
|
|
51
|
+
<!-- keelson: id=build.update-artifacts | without: tasks.md and change.md describe the plan, not what happened; the next session trusts stale text | sunset: never -->
|
|
52
|
+
|
|
53
|
+
Tick tasks as they are verified, not as they are written. Tick acceptance items when their check has run. When the design changes mid-build, edit `change.md` and, if behaviour changed, the delta spec. Nothing is locked; the only rule is that the files reflect reality at every commit. If you stop before the change is done, `keelson handoff <name>` and fill it in (see `handoff.md`).
|
|
54
|
+
|
|
55
|
+
<!-- guided -->
|
|
56
|
+
## Test-first when behaviour is specified
|
|
57
|
+
Where a scenario exists in the delta spec, write the failing test from the scenario first, watch it fail, implement, watch it pass. Where no scenario exists, judge whether a test is the cheapest evidence. Visual exploration and unknown APIs may start with a small prototype instead.
|
|
58
|
+
|
|
59
|
+
## Narration
|
|
60
|
+
Between tool calls, at most one short line. The ledger and tool output carry the record.
|
|
61
|
+
<!-- /guided -->
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Context and impact
|
|
2
|
+
|
|
3
|
+
Project material grows with the project; what you read per task must not grow with the whole history. Know where to look first, then open only what this change needs.
|
|
4
|
+
|
|
5
|
+
## Three layers
|
|
6
|
+
<!-- keelson: id=context.layers | without: every session reads everything or nothing; conventions are either flooded or missed | sunset: never -->
|
|
7
|
+
|
|
8
|
+
1. **Stable entry** — the resident block, `INTENT.md`, `ROADMAP.md → Now`, and the rules routed by `**`. Always read; kept short on purpose.
|
|
9
|
+
2. **Task material** — the active `change.md`, the specs of the capabilities it names, the rules matched by the paths you will touch, the tests that cover them, and any `refs` document the spec links to. `keelson context --paths <files>` prints most of this.
|
|
10
|
+
3. **On demand** — callers, other entry points, neighbouring modules, past changes in git history. Open when a question arises, not up front.
|
|
11
|
+
|
|
12
|
+
Never demote an always-on constraint because it is rarely relevant. Security and compatibility rules under `**` are read every time; that is the point of `**`.
|
|
13
|
+
|
|
14
|
+
## Impact is analysed, not looked up
|
|
15
|
+
<!-- keelson: id=context.impact | without: the agent treats the rules index and the diff as the whole blast radius and misses the caller outside the directory | sunset: never -->
|
|
16
|
+
|
|
17
|
+
`keelson impact <files>` lists importers by name, specs whose text or path matches, rules that apply, and active changes that declare the same paths or capabilities. That is navigation. Before you edit a shared module, answer by reading:
|
|
18
|
+
|
|
19
|
+
- Who calls this, including dynamic entry points the grep cannot see: CLI commands, jobs, routes, event handlers, templates?
|
|
20
|
+
- Is there another way in to the same behaviour (a download API next to the page, a batch job next to the request handler)?
|
|
21
|
+
- Which data constraints, permission rules, or compatibility promises depend on it? Check the spec's `Decisions`.
|
|
22
|
+
- Does an active change of someone else touch the same contract? `keelson status` shows shared contracts.
|
|
23
|
+
|
|
24
|
+
Write the answer into `change.md → Impact`. An Impact section that only lists the files in the diff is not an analysis.
|
|
25
|
+
|
|
26
|
+
## Budget
|
|
27
|
+
<!-- keelson: id=context.budget | without: when context runs short the agent silently drops constraints it already read, or guesses instead of reading | sunset: never -->
|
|
28
|
+
|
|
29
|
+
When the material for a change does not fit, do not summarise constraints into something looser. Narrow the slice, or keep reading on demand and say what you have not checked. `NOW.md → Blocked / uncertain` is the place for "not yet checked: …".
|
|
30
|
+
|
|
31
|
+
<!-- guided -->
|
|
32
|
+
## Reading order for a spec change
|
|
33
|
+
`INTENT.md` → `ROADMAP.md → Now` → `change.md` → the capability specs it names → matched rules → tests for those capabilities → `keelson impact` on the files you will touch → the callers it found → anything a spec links under `refs`.
|
|
34
|
+
<!-- /guided -->
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Debugging
|
|
2
|
+
|
|
3
|
+
A fix without a known cause is a guess that happened to pass. This reference exists so the cause is found, named, and fed back into the project.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
For interface work, load `frontend.md`; visual and interaction acceptance follow `frontend-review.md` and `frontend-delivery.md`.
|
|
7
|
+
|
|
8
|
+
## Reproduce, then locate, then fix
|
|
9
|
+
<!-- keelson: id=debug.reproduce-first | without: agent edits code on a hypothesis; symptom moves, cause stays, the bug returns under another name | sunset: when retro shows guessed-fix = 0 across the last 20 root-cause entries -->
|
|
10
|
+
|
|
11
|
+
1. Read the full error and stack. It usually names the line.
|
|
12
|
+
2. Reproduce deterministically: a failing test, a script, or exact steps. If you cannot reproduce it, you cannot know it is fixed.
|
|
13
|
+
3. Locate: where does observed behaviour first diverge from expected? Add logging or assertions at the boundaries rather than reading everything.
|
|
14
|
+
4. Form one hypothesis, test it with the smallest change, and only then write the fix.
|
|
15
|
+
5. Run the reproduction again; it must pass. Keep the negative check: with the fix reverted, the regression test fails. Then `keelson check --record`.
|
|
16
|
+
|
|
17
|
+
If three hypotheses in a row fail, stop and re-read the problem from the top; you are probably in the wrong layer.
|
|
18
|
+
|
|
19
|
+
## Name the root cause
|
|
20
|
+
<!-- keelson: id=debug.category | without: bugs are fixed one at a time and the pattern behind them is never seen | sunset: never -->
|
|
21
|
+
|
|
22
|
+
Append to the ledger of the active change (or create a quick change for the fix):
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
### Root cause: implicit-assumption
|
|
26
|
+
Callback handler assumed exactly one delivery; broker guarantees at-least-once.
|
|
27
|
+
Fix: idempotency key on `notify`. Prevention: rule in `rules/services.md`.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Categories, one per entry:
|
|
31
|
+
|
|
32
|
+
| category | meaning |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `missing-rule` | no convention said how to do this |
|
|
35
|
+
| `cross-layer` | the contract between two layers was unclear |
|
|
36
|
+
| `propagation` | one place changed, dependants were missed |
|
|
37
|
+
| `test-gap` | units passed, integration failed |
|
|
38
|
+
| `implicit-assumption` | code relied on something undocumented |
|
|
39
|
+
| `guessed-fix` | an earlier fix addressed the symptom, not the cause |
|
|
40
|
+
|
|
41
|
+
If the category is `missing-rule` or `cross-layer`, propose the rule or the spec requirement that would have prevented it, and add it while the context is fresh.
|
|
42
|
+
|
|
43
|
+
<!-- guided -->
|
|
44
|
+
## When the fix is not obvious
|
|
45
|
+
Ask what changed recently (`git log -p` on the failing area), what the data looked like, and whether the failure is in your code or in an assumption about a dependency. Each of these is a distinct layer; pick the layer before the line.
|
|
46
|
+
<!-- /guided -->
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Risk-triggered design lenses
|
|
2
|
+
|
|
3
|
+
These are **internal engineering lenses, not an architecture questionnaire**. Apply only the lenses triggered by the current change. Read the repository and existing contracts first; route what you find into defaults, experiments, acceptance, checks, or a single owner decision.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
For interface work, load `frontend.md`; visual and interaction acceptance follow `frontend-review.md` and `frontend-delivery.md`.
|
|
7
|
+
|
|
8
|
+
## Trigger, inspect, route
|
|
9
|
+
<!-- keelson: id=lenses.triggered | without: every feature gets a giant checklist, while important cross-domain risks still slip through because the list is treated mechanically | sunset: never -->
|
|
10
|
+
|
|
11
|
+
| Lens | Trigger examples | Inspect before asking | Prefer to produce |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| User + domain | new workflow, ambiguous nouns, multiple actors | actor/job, current workflow, vocabulary, ownership boundary | scenario/non-goal; glossary only if load-bearing |
|
|
14
|
+
| Data + integrity | persisted state, schema, import/export, delete, money | source of truth, invariants, lifecycle, retention, migration, audit/reconciliation | requirement + migration/rollback/reconciliation evidence |
|
|
15
|
+
| Security + privacy | auth, permissions, secrets, PII, uploads, untrusted input/tools | assets, trust boundaries, least privilege, abuse paths, validation | negative acceptance + security check |
|
|
16
|
+
| Concurrency + async | queues, webhooks, workers, realtime, multi-writer | duplicates, ordering, idempotency, retry, timeout, cancellation, partial failure | duplicate/out-of-order/retry/failure tests |
|
|
17
|
+
| API + compatibility | public API, event/schema/config/storage format | consumers, versioning, breaking definition, deprecation, rollout/rollback | compatibility contract + rollout evidence |
|
|
18
|
+
| Reliability + operations | error handling, cleanup/resource lifetime, critical path, background process, external dependency | full failure path, recovery, observer-visible state, observability, safe degradation | adversarial regression + recovery check; operational pointer when relevant |
|
|
19
|
+
| Performance + cost | explicit latency/throughput/volume/cost target, measured hot path | workload, SLO, baseline, growth assumption, resource ceiling | measurement/load/cost check; no speculative cache |
|
|
20
|
+
| Interface + accessibility | UI, form, navigation, interactive workflow | primary task, error/recovery, keyboard/focus, comprehension, destructive action | usability/accessibility acceptance |
|
|
21
|
+
| AI + nondeterminism | LLM, agent, RAG, model/tool call | eval cases, fallback, data boundary, prompt/tool injection, authorization, reproducibility | eval set + safety/fallback acceptance |
|
|
22
|
+
|
|
23
|
+
A trigger means “inspect this dimension”, **not** “ask every question in this row”.
|
|
24
|
+
|
|
25
|
+
## Make failure contracts executable before the fix
|
|
26
|
+
<!-- keelson: id=lenses.failure-contract | without: an error-handling fix covers the first failure but a later finalizer or observer still discards errors or exposes corrupted state | sunset: never -->
|
|
27
|
+
|
|
28
|
+
For error-handling or resource-lifetime changes, trace the entire call path before editing, including nested cleanup, finalizers, notifications, and the final caller. In the existing plan or test notes, briefly map each phase to: what can fail, what must still run, what state observers must see, and which errors must reach the caller. Derive these obligations from the request and existing contracts; distinguish an explicit requirement from an additional robustness probe.
|
|
29
|
+
|
|
30
|
+
Turn the highest-risk combination into a failing regression **before** the implementation: inject distinct errors into multiple phases of one execution, including the last applicable observer, and exercise a nested or already-active resource when supported. Assert the required final state and the propagated errors' identities, multiplicity, and order when contractual; assert observer-visible state at the time the observer runs. A passing single-error test does not establish the combined-failure contract. Keep this focused on the affected lifetime rather than inventing a generic framework or an exhaustive fault matrix.
|
|
31
|
+
|
|
32
|
+
## Prefer simple, reversible architecture
|
|
33
|
+
<!-- keelson: id=lenses.simplicity | without: the agent designs for hypothetical scale, introduces abstractions before pressure exists, or treats every future possibility as a current requirement | sunset: never -->
|
|
34
|
+
|
|
35
|
+
Use the simplest design that satisfies the current contract and leaves a credible path to change. Before adding a new service, queue, cache, abstraction layer, database, framework, or protocol, name the concrete pressure that requires it now.
|
|
36
|
+
|
|
37
|
+
Treat speculative future scale/features as a hypothesis, not a requirement. If the pressure is cheap to test, run a spike/measurement. If the design can be changed locally later, prefer the reversible choice and keep moving. Deep modules and narrow interfaces are preferred over many shallow wrappers that merely mirror implementation.
|
|
38
|
+
|
|
39
|
+
## Turn risk into evidence, not prose
|
|
40
|
+
<!-- keelson: id=lenses.evidence | without: design review produces impressive documentation but important properties are not protected when the code changes | sunset: never -->
|
|
41
|
+
|
|
42
|
+
Each triggered lens must end as one or more of:
|
|
43
|
+
|
|
44
|
+
- **already guaranteed** by an existing spec/rule/test → reuse it;
|
|
45
|
+
- **owner-owned decision** → ask at the decision frontier;
|
|
46
|
+
- **engineering default** → decide and record only if future work needs the rationale;
|
|
47
|
+
- **cheap uncertainty** → spike, prototype, measurement, or inspect telemetry;
|
|
48
|
+
- **stable invariant** → scoped rule, preferably an executable fitness/check;
|
|
49
|
+
- **acceptance/evidence obligation** → add the failure/compatibility/security/performance/migration/accessibility case;
|
|
50
|
+
- **explicitly out of scope** → name it once when omission would otherwise look accidental.
|
|
51
|
+
|
|
52
|
+
Do not create a generic NFR document or architecture checklist artifact.
|
|
53
|
+
|
|
54
|
+
## Protect architecture with fitness functions
|
|
55
|
+
<!-- keelson: id=lenses.fitness | without: architecture quality depends on reviewers remembering prose rules and gradually decays as the project evolves | sunset: never -->
|
|
56
|
+
|
|
57
|
+
When a durable architecture characteristic can be measured mechanically, convert it into `config.yaml → check` instead of repeatedly explaining it:
|
|
58
|
+
|
|
59
|
+
- forbidden dependency direction;
|
|
60
|
+
- public schema/API compatibility;
|
|
61
|
+
- latency or bundle-size ceiling;
|
|
62
|
+
- migration reversibility check;
|
|
63
|
+
- security/static-analysis policy;
|
|
64
|
+
- accessibility test;
|
|
65
|
+
- deterministic contract/eval suite.
|
|
66
|
+
|
|
67
|
+
Keep only enough prose to explain **why** the guard exists and where it applies. Repeated review comments are evidence that a fitness check or narrower rule should replace prose.
|
|
68
|
+
|
|
69
|
+
## Prioritize irreversible risk
|
|
70
|
+
<!-- keelson: id=lenses.priority | without: reversible taste gets debated while data loss, permissions, compatibility, migrations, or failure semantics are silently guessed | sunset: never -->
|
|
71
|
+
|
|
72
|
+
Resolve roughly in this order:
|
|
73
|
+
|
|
74
|
+
**irreversible data/security/production effects → public compatibility/migration/expensive commitments → failure/concurrency correctness → user-visible behavior/accessibility → measured reliability/performance/cost → reversible implementation taste**
|
|
75
|
+
|
|
76
|
+
For security use a compact loop internally: **what are we protecting → what can go wrong → what control prevents/detects it → what evidence proves the control works?**
|
|
77
|
+
|
|
78
|
+
For performance and scale, measure before adding machinery. For distributed work, assume retries and partial failure exist unless the transport contract proves otherwise. For destructive behavior, make recovery/rollback explicit.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Discovering what is wanted
|
|
2
|
+
|
|
3
|
+
The user often cannot describe the whole requirement in the first sentence, and they should not need to know which engineering choice matters. Discovery finds the problem behind the request before anyone picks a database. Use `interview.md` for owner-owned uncertainty; load `design-lenses.md` only when the work triggers a real cross-domain risk.
|
|
4
|
+
|
|
5
|
+
## Scenario before technology
|
|
6
|
+
<!-- keelson: id=discover.scenario-first | without: the first question is a technology choice the owner cannot answer, and the product is shaped by whatever they guessed | sunset: never -->
|
|
7
|
+
|
|
8
|
+
When a request is a product idea ("a team knowledge base", "add collaboration"), do not ask about storage, frameworks, or schemas. Ask which use is at the centre, with concrete alternatives that differ in what the user would do:
|
|
9
|
+
|
|
10
|
+
> Which of these is closest to the first thing people will do with it?
|
|
11
|
+
> A. Several people edit the same documents.
|
|
12
|
+
> B. Company material is collected and searched.
|
|
13
|
+
> C. Material is handed to an assistant that answers questions.
|
|
14
|
+
> D. All of them eventually; a first version should pick one.
|
|
15
|
+
> For a first version I suggest picking one: permissions, search, assistant, and co-editing each add their own complexity, and together they stall the project.
|
|
16
|
+
|
|
17
|
+
Keep each question small: one concrete decision, enough scenario to understand it, and a recommended default with the one trade-off that matters. Options are a tool, not a required format. When the owner says "I don't know", route through `interview.md`: investigate, choose a reversible default, or make the consequence visible with a tiny example/experiment. Never repeat the term louder.
|
|
18
|
+
|
|
19
|
+
## Which unknowns to raise
|
|
20
|
+
<!-- keelson: id=discover.frontier | without: either every unknown becomes a question and nothing starts, or the agent settles product questions by itself | sunset: never -->
|
|
21
|
+
|
|
22
|
+
Sort each unknown before asking:
|
|
23
|
+
|
|
24
|
+
| Unknown | Handling |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Answerable from the code, tests, or docs | Read it; never ask |
|
|
27
|
+
| The project already has a convention | Follow it; mention it in the write-back |
|
|
28
|
+
| Low risk and easy to reverse | Decide, record it as confirmed under your authorization |
|
|
29
|
+
| Technical, and the owner has no reason to care | Pick a sensible default; say so in one line |
|
|
30
|
+
| Changes what the product does for its users | Ask, with a recommendation |
|
|
31
|
+
| Changes long-term architecture, cost, or a public commitment | Explain, then confirm |
|
|
32
|
+
| Destroys data, widens permissions, touches production | Confirm explicitly, always |
|
|
33
|
+
|
|
34
|
+
Only questions whose answer would change the result reach the owner. Everything else is a default or a `(assumed)` decision that surfaces before landing.
|
|
35
|
+
|
|
36
|
+
## Ask at the decision frontier
|
|
37
|
+
<!-- keelson: id=discover.decision-frontier | without: the agent either interrupts for facts it could investigate, invents user-owned intent, or asks low-value questions whose answers do not change the work | sunset: never -->
|
|
38
|
+
|
|
39
|
+
Before asking, classify the gap by who can resolve it:
|
|
40
|
+
|
|
41
|
+
| Gap | Action |
|
|
42
|
+
|---|---|
|
|
43
|
+
| Already established in repository/context | Use it; cite the source in the write-back |
|
|
44
|
+
| Reality-owned (code behaviour, API contract, measurement, dependency capability) | Investigate or run a small experiment |
|
|
45
|
+
| User-owned and load-bearing (goal, scope, acceptance, risk tolerance, public commitment) | Ask one question |
|
|
46
|
+
| Non-load-bearing or cheap to reverse | Decide under authorization, or leave unresolved for a later slice |
|
|
47
|
+
| Evidence exhausted | Mark it UNKNOWN; do not convert uncertainty into a user belief |
|
|
48
|
+
|
|
49
|
+
Choose the gap with the highest practical value of information: the answer most likely to change the next slice, weighted by the cost of being wrong. Before asking, apply the `interview.md` question protocol. After the answer, update the write-back and reassess the frontier. "Exactly one question" is a bottleneck for **blocking uncertainty**, not a ritual: when no user-owned load-bearing gap exists, ask nothing and proceed.
|
|
50
|
+
|
|
51
|
+
## Scope guard
|
|
52
|
+
<!-- keelson: id=discover.scope-guard | without: a first request asks for five independent domains at once, and integration risk, debugging cost, and requirement churn compound | sunset: never -->
|
|
53
|
+
|
|
54
|
+
When a request bundles several domains (identity, payments, real-time collaboration, an assistant, plugins, mobile), name them as separate domains and propose an order: the domain that the others depend on first, the rest as later milestones in `ROADMAP.md → Next`. The reason is not that the code cannot be written; it is that each added domain multiplies the ways the first ones can be wrong, and nothing has been verified yet. Say that in plain words.
|
|
55
|
+
|
|
56
|
+
## Explore before committing
|
|
57
|
+
<!-- keelson: id=discover.explore | without: an abstract decision is forced when a cheap experiment would settle it with evidence | sunset: never -->
|
|
58
|
+
|
|
59
|
+
When a choice is reversible and the owner is unsure, do not press for a decision. Offer a spike, a prototype, a mock, or a measurement, sized to answer one question: two small UI variants to pick between; a measurement before adding a cache; a spike before adopting a library. Record the result as evidence in the ledger (`### Note:`) and the decision it produced under `## Decisions`.
|
|
60
|
+
|
|
61
|
+
## Guided mode adds teaching, not usability
|
|
62
|
+
<!-- keelson: id=discover.guided | without: accessible questioning is incorrectly gated behind a beginner setting, or teaching content becomes permanent project ceremony | sunset: never -->
|
|
63
|
+
|
|
64
|
+
Scenario-first language, sensible defaults, and understandable questions are always on. `guide: true` adds only pedagogy:
|
|
65
|
+
|
|
66
|
+
- briefly name the engineering idea after the plain-language decision is understood;
|
|
67
|
+
- explain why a rule/constraint exists when applying it;
|
|
68
|
+
- after a spec change lands, add a short teaching note: key decision, why, the engineering idea, and when to revisit it.
|
|
69
|
+
|
|
70
|
+
The teaching note stays in conversation. Guided mode never changes artifacts, gates, or who owns a decision.
|