tldr-experts 0.3.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +913 -0
  2. package/LICENSE +21 -0
  3. package/README.md +174 -0
  4. package/dist/hooks/answer-capture.js +174 -0
  5. package/dist/hooks/budget-gate.js +173 -0
  6. package/dist/hooks/chunk-0bt6yb2q.js +88 -0
  7. package/dist/hooks/chunk-1zwcxd3f.js +66 -0
  8. package/dist/hooks/chunk-9gb21660.js +66 -0
  9. package/dist/hooks/chunk-a8p2rc94.js +20 -0
  10. package/dist/hooks/chunk-ae6bkfs5.js +0 -0
  11. package/dist/hooks/chunk-azctppjh.js +198 -0
  12. package/dist/hooks/chunk-g395gk7e.js +503 -0
  13. package/dist/hooks/chunk-j234zf0t.js +339 -0
  14. package/dist/hooks/chunk-kw4tffzf.js +139 -0
  15. package/dist/hooks/chunk-p274ckxv.js +7435 -0
  16. package/dist/hooks/chunk-sdjnnmzz.js +497 -0
  17. package/dist/hooks/chunk-t56k6146.js +14 -0
  18. package/dist/hooks/chunk-t8tdv11p.js +35 -0
  19. package/dist/hooks/chunk-x98qs959.js +302 -0
  20. package/dist/hooks/chunk-y0jdr3et.js +627 -0
  21. package/dist/hooks/claim-sources.js +72 -0
  22. package/dist/hooks/dod-gate.js +198 -0
  23. package/dist/hooks/no-reask.js +67 -0
  24. package/dist/hooks/session-start.js +1348 -0
  25. package/dist/hooks/statusline.js +116 -0
  26. package/dist/tldrx.js +34219 -0
  27. package/env.yml +79 -0
  28. package/package.json +60 -0
  29. package/plugin/.claude-plugin/plugin.json +9 -0
  30. package/plugin/README.md +113 -0
  31. package/plugin/agents/README.md +22 -0
  32. package/plugin/hooks/hooks.json +107 -0
  33. package/plugin/skills/tldrx/SKILL.md +170 -0
  34. package/stages/build/stage.md +70 -0
  35. package/stages/build/stage.yml +54 -0
  36. package/stages/how/stage.md +89 -0
  37. package/stages/how/stage.yml +53 -0
  38. package/stages/plan/stage.md +89 -0
  39. package/stages/plan/stage.yml +48 -0
  40. package/stages/watch/stage.md +85 -0
  41. package/stages/watch/stage.yml +61 -0
  42. package/stages/what/stage.md +89 -0
  43. package/stages/what/stage.yml +61 -0
  44. package/templates/budget.yml +17 -0
  45. package/templates/competencies.yml +14 -0
  46. package/templates/env.yml +19 -0
  47. package/templates/epic.md +38 -0
  48. package/templates/expert.md +51 -0
  49. package/templates/experts/architect.md +77 -0
  50. package/templates/experts/delivery.md +76 -0
  51. package/templates/experts/developer.md +78 -0
  52. package/templates/experts/operations.md +74 -0
  53. package/templates/experts/product.md +78 -0
  54. package/templates/facts.yml +18 -0
  55. package/templates/handoff.md +63 -0
  56. package/templates/process.yml +33 -0
  57. package/templates/questions.md +63 -0
  58. package/templates/run.yml +24 -0
  59. package/templates/story.md +55 -0
  60. package/templates/watcher.md +68 -0
  61. package/templates/waves.yml +17 -0
  62. package/templates/workspace.yml +30 -0
  63. package/workflows/bugfix.yml +26 -0
  64. package/workflows/docs.yml +23 -0
  65. package/workflows/feature.yml +22 -0
  66. package/workflows/hotfix.yml +24 -0
  67. package/workflows/integration.yml +24 -0
  68. package/workflows/migration.yml +24 -0
  69. package/workflows/performance.yml +23 -0
  70. package/workflows/prototype.yml +24 -0
  71. package/workflows/refactor.yml +24 -0
  72. package/workflows/retro.yml +20 -0
  73. package/workflows/security-patch.yml +23 -0
  74. package/workflows/spike.yml +23 -0
  75. package/workflows/upgrade.yml +23 -0
@@ -0,0 +1,54 @@
1
+ # schema: draft
2
+ # Phase 4 of the loop. Concept §3 and §9; spec §5 "Build executor".
3
+ #
4
+ # This stage is NOT run by the default one-stage-one-agent path. `04-build` selects
5
+ # the wave executor (src/core/facilitator/executors/build.ts), which reads
6
+ # 03-plan/{waves.yml,stories/*.md,epics/*.md} and, story by story in wave order,
7
+ # cuts the branch, opens the worktree, spawns ONE developer sub-agent in it, re-runs
8
+ # the story's ```dod block, commits, merges into the epic branch, and spawns a
9
+ # read-only reviewer. A story is `done` only when the DoD exited 0 and the reviewer
10
+ # approved; its evidence is written back into the story's own front matter.
11
+ #
12
+ # `budget_usd` below is the WHOLE phase: the executor splits it by story count and
13
+ # caps each share at budget.yml's `per_agent_max_usd`.
14
+ name: build
15
+ title: Build
16
+ phase: 4
17
+ model: sonnet
18
+ # --effort for this stage's sub-agent (spec §2.3). The cost lever
19
+ # `--max-budget-usd` is not: the budget flag only STOPS a turn already in flight.
20
+ # `[assumption]` — Build writes code that a DoD and a reviewer will judge. A cheap
21
+ # turn here is not a saving: it is a `changes` verdict and a second, paid attempt.
22
+ effort: high
23
+ budget_usd: 9
24
+ timeout_s: 1800
25
+ # Branches and commits are not revertible by a flag, so a dry run is refused
26
+ # rather than half-honoured (spec §5, Build executor).
27
+ dry_run_allowed: false
28
+
29
+ inputs:
30
+ - "03-plan/waves.yml"
31
+ - ".tldrx/conventions/shared.md"
32
+ - ".tldrx/memory/facts.yml"
33
+
34
+ # The handoff is written by the executor, deterministically, from exit codes and
35
+ # merge results it holds — no sub-agent is asked to summarise what it already knows.
36
+ # `04-build/log/<story-id>.md` is written per story and cited by every Finding.
37
+ outputs:
38
+ - {path: "04-build/handoff.md", sections: [Findings, Decisions, Unknowns, "Evidence ledger"]}
39
+
40
+ experts:
41
+ - developer
42
+
43
+ # `requires:` used to list five acceptance criteria here. Nothing read them:
44
+ # `normaliseGate` (src/core/run/workflowPreset.ts:216-231) reads only `.type`,
45
+ # `validateStage` (src/core/schemas/stage.ts:72-76) checks only `gate.type`, the
46
+ # prompt ships `stage.md` and never this file (src/core/facilitator/prompt.ts:101),
47
+ # and no other file in the repo touches the key. Criteria no gate enforces and no
48
+ # reader ever sees are worse than none — the enforcement that IS real is the
49
+ # `checks:` list below.
50
+ gate:
51
+ type: human-approval
52
+
53
+ checks:
54
+ - claim-sources
@@ -0,0 +1,89 @@
1
+ <!-- schema: draft -->
2
+ <!-- Stage template: how (phase 2). Rendered into <record>/02-how/handoff.md. -->
3
+
4
+ # How — handoff
5
+
6
+ **Run:** `<run-id>` · **Stage:** `how` · **Expert(s):** `<from stage.yml>` · **Model:** `<from stage.yml>`
7
+ **Spent:** `$<n>` of `$<budget_usd>`
8
+
9
+ > Place the design on real files and modules from the code map. A component that does not cite an existing path is a wish, not a design.
10
+
11
+ ---
12
+
13
+ ## Findings
14
+
15
+ > What Investigate actually established. **Every bullet ends with a source.**
16
+ > `[src: path/to/file.ts:42]` · `[src: https://…]` · `[src: Q7]`
17
+ > A bullet you cannot source does not belong here — move it to Unknowns.
18
+
19
+ - The change lands in <module>, which today does <…>. `[src: …]`
20
+ - The external API behaves as <…> per its official docs, fetched this run. `[src: …]`
21
+
22
+ ## Decisions
23
+
24
+ > What was decided, and on the strength of what. Same rule: every bullet is sourced.
25
+ > Label each one **measured** (it was run), **inferred** (mechanism plus evidence,
26
+ > could be wrong) or **assumed** (nobody knows yet).
27
+
28
+ - Approach <A> over <B>, because <…>. `[src: …]`
29
+
30
+ ## Unknowns
31
+
32
+ > Only these become questions. Before writing one, grep `.tldrx/memory/facts.yml`:
33
+ > re-asking a recorded fact is a framework test failure, not a style choice.
34
+ > Each unknown states who or what could answer it.
35
+
36
+ - Whether <…> is load-bearing for <…> — no test covers it. — *could be answered by:* `<person | file | command | doc>`
37
+
38
+ ## Evidence ledger
39
+
40
+ > Every source cited above, once, with what it proved. This is what the next stage
41
+ > and the reviewer read instead of re-deriving the work. **List items, not a table**
42
+ > — this section is checked exactly like the other three, and a table holds no
43
+ > list items for the gate to check.
44
+
45
+ - … what this file establishes … `[src: <repo>:<path>:<line>]`
46
+ - … what this command proved … `[src: $ <command> → exit 0]`
47
+
48
+ ## Outputs written
49
+
50
+ - `design.md`
51
+ - `contracts.md` (APIs / DTOs / events)
52
+ - `risks.md`
53
+ - `test-strategy.md`
54
+
55
+ ## Gate
56
+
57
+ Blocked on: **<human approval | checks green>** — `stage.yml`'s `gate.type`. What is
58
+ actually enforced is that file's `checks:` list, which `tldrx approve` re-runs against what
59
+ is on disk before it will advance anything. Nothing advances until this is recorded in
60
+ `run.yml` and `events.jsonl`.
61
+
62
+ ## Rules
63
+
64
+ - Every bullet under Findings / Decisions / Unknowns / Evidence ledger is ONE line and ENDS with a source token. A bullet without one is refused by the `claim-sources` gate and the whole stage fails.
65
+ - Each of Findings / Decisions / Unknowns / Evidence ledger must hold at least ONE list item; a section that is genuinely empty is written as `- none [src: absent:<what you looked at>]`, and a prose-only section is refused by the `claim-sources` gate.
66
+ - Source token grammar (exact): `[src: <one or more sources separated by "; ">]` where a source is ONE of:
67
+ - `<repo>:<path>:<line>` or `<repo>:<path>:<start>-<end>` — a file with ONE line or ONE range. Never a whole file, never a comma list (`file.md:7,21` is invalid: write two sources or a range).
68
+ - `F<n>` — a fact id from `.tldrx/memory/facts.yml` (cite the id, never the file).
69
+ - `Q<n>` — a question from this run's questions.md.
70
+ - `https://…` — an external document (https only).
71
+ - `aidlc:<file>:<line>` / `aidlc:<file>#Q<n>` — an imported source, exactly as it already appears in intent.md/scope.md.
72
+ - `$ <command> → exit <n>` — only under Evidence ledger, only for commands listed in `.tldrx/workspace.yml`.
73
+ - `absent:<path>` — you looked there and found nothing.
74
+ - Do not cite templates, expert files or directories (`.tldrx/experts/*` is not evidence).
75
+ - Questions go in `questions.md`, and its shape is a PARSER's, not a style. One regex reads a block — `^## (Q\d+) · (.+)$` — and a heading that misses it is not half-read, it is read as ABSENT: the gate then records "0 open questions" and signs itself over questions nobody answered. Write each one EXACTLY like this, `·` being U+00B7 MIDDLE DOT:
76
+ ```
77
+ ## Q1 · Where does leaderboard state live?
78
+ <!-- id: Q1 | status: open | area: data-model | asked_by: architect | asked_at: 2026-08-29T14:02:11Z -->
79
+ Why asked: no ranking store exists in the map [src: absent:.tldrx/map/api/domains.md]
80
+
81
+ - A) New Postgres table, recomputed on hunt completion
82
+ - B) Redis sorted set
83
+ - C) other — write it below
84
+
85
+ [Answer]:
86
+ ```
87
+ All five metadata keys are required; `Why asked:` must END with a `[src: …]` token; 2–5 options lettered A–E in order; exactly one empty `[Answer]:` slot. Ids ascend. Never write `### Qn — …`, `**Answer:**`, or the answered footer — the hook writes that. `tldrx questions lint` checks the file; `--fix` converts a file already written the wrong way.
88
+ - Before asking a question, grep `.tldrx/memory/facts.yml`; if the answer is there, cite `F<n>` instead of asking.
89
+ - Write only the declared outputs; do not add sections beyond the ones listed under Produce.
@@ -0,0 +1,53 @@
1
+ # schema: draft
2
+ # Phase 2 of the loop. Concept §3.
3
+ # Design must be placed on REAL files and modules from the code map — not on
4
+ # hypothetical components.
5
+ name: how
6
+ title: How
7
+ phase: 2
8
+ model: opus
9
+ # --effort for this stage's sub-agent (spec §2.3). The cost lever
10
+ # `--max-budget-usd` is not: the budget flag only STOPS a turn already in flight.
11
+ # `[assumption]` — How is where the thinking is. Every component must land on a
12
+ # real path and every contract must survive contact with the code, so this is the
13
+ # one stage where effort is bought deliberately rather than saved.
14
+ effort: high
15
+ budget_usd: 6
16
+
17
+ inputs:
18
+ - "01-what/intent.md"
19
+ - "01-what/scope.md"
20
+ - "01-what/success-metrics.md"
21
+ - ".tldrx/map/architecture.md"
22
+ - ".tldrx/map/conventions.md"
23
+ - ".tldrx/memory/facts.yml"
24
+
25
+ outputs:
26
+ - "design.md"
27
+ - "contracts.md"
28
+ - "risks.md"
29
+ - "test-strategy.md"
30
+ - "handoff.md"
31
+ - "questions.md"
32
+
33
+ # `domain` and `stack` used to be listed here. They were never expert NAMES:
34
+ # `stack_experts: true` above already loads `<lang>-stack` for the run's repos,
35
+ # and a `kind: domain` expert is picked by the paths this run actually cites
36
+ # (spec §2.3, rules 2 and 3). A name nothing can create is a permanent
37
+ # "NOT LOADED" line, so the rules are left to do their own work.
38
+ experts:
39
+ - architect
40
+
41
+ # `requires:` used to list three acceptance criteria here. Nothing read them:
42
+ # `normaliseGate` (src/core/run/workflowPreset.ts:216-231) reads only `.type`,
43
+ # `validateStage` (src/core/schemas/stage.ts:72-76) checks only `gate.type`, and
44
+ # no other file in the repo touches the key. Three sentences a reviewer would
45
+ # have to open this file to find, that no gate ever enforced, are worse than
46
+ # none — the enforcement that IS real is the `checks:` list below.
47
+ gate:
48
+ type: human-approval
49
+
50
+ checks:
51
+ - claim-sources
52
+ - no-reask
53
+ - budget-gate
@@ -0,0 +1,89 @@
1
+ <!-- schema: draft -->
2
+ <!-- Stage template: plan (phase 3). Rendered into <record>/03-plan/handoff.md. -->
3
+
4
+ # Plan — handoff
5
+
6
+ **Run:** `<run-id>` · **Stage:** `plan` · **Expert(s):** `<from stage.yml>` · **Model:** `<from stage.yml>`
7
+ **Spent:** `$<n>` of `$<budget_usd>`
8
+
9
+ > Cut the design into stories somebody could pick up cold, ordered by dependency, priced against the budget, and shaped the way this team actually works.
10
+
11
+ ---
12
+
13
+ ## Findings
14
+
15
+ > What Investigate actually established. **Every bullet ends with a source.**
16
+ > `[src: path/to/file.ts:42]` · `[src: https://…]` · `[src: Q7]`
17
+ > A bullet you cannot source does not belong here — move it to Unknowns.
18
+
19
+ - Story <id> touches <files>, and its acceptance criteria are testable by <…>. `[src: …]`
20
+ - Stories <a> and <b> are independent and can run in the same wave. `[src: …]`
21
+
22
+ ## Decisions
23
+
24
+ > What was decided, and on the strength of what. Same rule: every bullet is sourced.
25
+ > Label each one **measured** (it was run), **inferred** (mechanism plus evidence,
26
+ > could be wrong) or **assumed** (nobody knows yet).
27
+
28
+ - Wave ordering is <…>, because <b> needs <a>'s contract. `[src: …]`
29
+
30
+ ## Unknowns
31
+
32
+ > Only these become questions. Before writing one, grep `.tldrx/memory/facts.yml`:
33
+ > re-asking a recorded fact is a framework test failure, not a style choice.
34
+ > Each unknown states who or what could answer it.
35
+
36
+ - Whether <…> can ship behind a flag or needs a migration first. — *could be answered by:* `<person | file | command | doc>`
37
+
38
+ ## Evidence ledger
39
+
40
+ > Every source cited above, once, with what it proved. This is what the next stage
41
+ > and the reviewer read instead of re-deriving the work. **List items, not a table**
42
+ > — this section is checked exactly like the other three, and a table holds no
43
+ > list items for the gate to check.
44
+
45
+ - … what this file establishes … `[src: <repo>:<path>:<line>]`
46
+ - … what this command proved … `[src: $ <command> → exit 0]`
47
+
48
+ ## Outputs written
49
+
50
+ - `epics/<epic>.md`
51
+ - `stories/<id>.md` (AC + test plan + touched files + repo)
52
+ - `waves.yml`
53
+ - `budget.yml`
54
+
55
+ ## Gate
56
+
57
+ Blocked on: **<human approval | checks green>** — `stage.yml`'s `gate.type`. What is
58
+ actually enforced is that file's `checks:` list, which `tldrx approve` re-runs against what
59
+ is on disk before it will advance anything. Nothing advances until this is recorded in
60
+ `run.yml` and `events.jsonl`.
61
+
62
+ ## Rules
63
+
64
+ - Every bullet under Findings / Decisions / Unknowns / Evidence ledger is ONE line and ENDS with a source token. A bullet without one is refused by the `claim-sources` gate and the whole stage fails.
65
+ - Each of Findings / Decisions / Unknowns / Evidence ledger must hold at least ONE list item; a section that is genuinely empty is written as `- none [src: absent:<what you looked at>]`, and a prose-only section is refused by the `claim-sources` gate.
66
+ - Source token grammar (exact): `[src: <one or more sources separated by "; ">]` where a source is ONE of:
67
+ - `<repo>:<path>:<line>` or `<repo>:<path>:<start>-<end>` — a file with ONE line or ONE range. Never a whole file, never a comma list (`file.md:7,21` is invalid: write two sources or a range).
68
+ - `F<n>` — a fact id from `.tldrx/memory/facts.yml` (cite the id, never the file).
69
+ - `Q<n>` — a question from this run's questions.md.
70
+ - `https://…` — an external document (https only).
71
+ - `aidlc:<file>:<line>` / `aidlc:<file>#Q<n>` — an imported source, exactly as it already appears in intent.md/scope.md.
72
+ - `$ <command> → exit <n>` — only under Evidence ledger, only for commands listed in `.tldrx/workspace.yml`.
73
+ - `absent:<path>` — you looked there and found nothing.
74
+ - Do not cite templates, expert files or directories (`.tldrx/experts/*` is not evidence).
75
+ - Questions go in `questions.md`, and its shape is a PARSER's, not a style. One regex reads a block — `^## (Q\d+) · (.+)$` — and a heading that misses it is not half-read, it is read as ABSENT: the gate then records "0 open questions" and signs itself over questions nobody answered. Write each one EXACTLY like this, `·` being U+00B7 MIDDLE DOT:
76
+ ```
77
+ ## Q1 · Where does leaderboard state live?
78
+ <!-- id: Q1 | status: open | area: data-model | asked_by: architect | asked_at: 2026-08-29T14:02:11Z -->
79
+ Why asked: no ranking store exists in the map [src: absent:.tldrx/map/api/domains.md]
80
+
81
+ - A) New Postgres table, recomputed on hunt completion
82
+ - B) Redis sorted set
83
+ - C) other — write it below
84
+
85
+ [Answer]:
86
+ ```
87
+ All five metadata keys are required; `Why asked:` must END with a `[src: …]` token; 2–5 options lettered A–E in order; exactly one empty `[Answer]:` slot. Ids ascend. Never write `### Qn — …`, `**Answer:**`, or the answered footer — the hook writes that. `tldrx questions lint` checks the file; `--fix` converts a file already written the wrong way.
88
+ - Before asking a question, grep `.tldrx/memory/facts.yml`; if the answer is there, cite `F<n>` instead of asking.
89
+ - Write only the declared outputs; do not add sections beyond the ones listed under Produce.
@@ -0,0 +1,48 @@
1
+ # schema: draft
2
+ # Phase 3 of the loop. Concept §3 and §9.
3
+ # Renders into the team's shape: sprints for scrum, a WIP-limited flow board for
4
+ # kanban, a plain ordered list for none. Read .tldrx/process.yml, never assume.
5
+ name: plan
6
+ title: Plan
7
+ phase: 3
8
+ model: sonnet
9
+ # --effort for this stage's sub-agent (spec §2.3). The cost lever
10
+ # `--max-budget-usd` is not: the budget flag only STOPS a turn already in flight.
11
+ # `[assumption]` — Plan is decomposition against a design that already exists:
12
+ # split, order, size, cite. Medium; the hard judgement was made upstream in How.
13
+ effort: medium
14
+ budget_usd: 4
15
+
16
+ inputs:
17
+ - "02-how/design.md"
18
+ - "02-how/contracts.md"
19
+ - "02-how/test-strategy.md"
20
+ - ".tldrx/process.yml"
21
+ - ".tldrx/map/workspace.md"
22
+
23
+ outputs:
24
+ - "epics/<epic>.md"
25
+ - "stories/<id>.md"
26
+ - "waves.yml"
27
+ - "budget.yml"
28
+ - "handoff.md"
29
+ - "questions.md"
30
+
31
+ experts:
32
+ - delivery
33
+ - architect
34
+
35
+ # `requires:` used to list four acceptance criteria here. Nothing read them:
36
+ # `normaliseGate` (src/core/run/workflowPreset.ts:216-231) reads only `.type`,
37
+ # `validateStage` (src/core/schemas/stage.ts:72-76) checks only `gate.type`, the
38
+ # prompt ships `stage.md` and never this file (src/core/facilitator/prompt.ts:101),
39
+ # and no other file in the repo touches the key. Criteria no gate enforces and no
40
+ # reader ever sees are worse than none — the enforcement that IS real is the
41
+ # `checks:` list below.
42
+ gate:
43
+ type: human-approval
44
+
45
+ checks:
46
+ - claim-sources
47
+ - plan
48
+ - budget-gate
@@ -0,0 +1,85 @@
1
+ <!-- Stage template: watch (phase 5). One sub-agent per shipped feature. -->
2
+
3
+ # Watch — `{{run}}`
4
+
5
+ ## Role
6
+
7
+ You are the operations expert for run `{{run}}`, repos `{{repos}}`. You have been
8
+ on call. You know the difference between a dashboard someone built and a dashboard
9
+ someone trusts, and you have been paged at 3am by an alert on a metric that was
10
+ never emitted.
11
+
12
+ ## Objective
13
+
14
+ Write ONE watcher card for ONE shipped feature, so that six months from now a
15
+ person who has never seen this code can answer: **is it still working?**
16
+
17
+ Done when the card exists, every item in its four checked sections carries a
18
+ `[src: …]` token, and its Query block would run as pasted.
19
+
20
+ ## Feature
21
+
22
+ (replaced by the facilitator)
23
+
24
+ ## Inputs
25
+
26
+ (replaced by the facilitator)
27
+
28
+ ## Investigate
29
+
30
+ 1. Read the diff first. It is what actually landed; a story's `touches:` list was
31
+ written before the code existed and is an intention, not evidence.
32
+ 2. Find what the feature EMITS — a log line, a metric, a counter, an event, a row
33
+ written somewhere queryable. Cite it at `<repo>:<path>:<line>`.
34
+ 3. If it emits nothing, stop looking for a way to phrase it as though it does.
35
+ Write `absent:<what you looked at>` and say what to instrument. That is a
36
+ correct, useful answer and it is the answer this stage exists to be able to give.
37
+ 4. Take the baseline from the evidence you have — a number in the diff, a number in
38
+ a fact, a number a command printed. If nobody has measured it, say so under
39
+ **Looks broken when** as an assumption rather than inventing one under
40
+ **Healthy baseline**.
41
+ 5. Check the gotchas for this repo before writing the Query: a query that ignores a
42
+ known trap is a query that will mislead someone at 3am.
43
+
44
+ ## Produce
45
+
46
+ The single file named under **Feature**, with the front matter given there and
47
+ these H2 sections, in order:
48
+
49
+ - `## Signal` — the log line / metric / event that proves it works.
50
+ - `## Where` — the dashboard, log stream, table or console it is read in.
51
+ - `## Healthy baseline` — a measured number, and when it was measured.
52
+ - `## Looks broken when` — what the same signal looks like on the bad day.
53
+ - `## Query` — one fenced block, copy-pasteable.
54
+ - `## Sources` — each citation above, once, with what it establishes.
55
+
56
+ ## Rules
57
+
58
+ - Every list item under Signal / Where / Healthy baseline / Looks broken when is ONE
59
+ line and ENDS with a `[src: …]` token. An item without one is refused.
60
+ - Source grammar (exact): `[src: <one or more sources separated by "; ">]`, a source being
61
+ `<repo>:<path>:<line>` (or `:<start>-<end>`) · `F<n>` · `https://…` ·
62
+ `$ <command> → exit <n>` · `absent:<path>`. Never a whole file, never a comma list.
63
+ - A section with genuinely nothing in it is written as `- none [src: absent:<what you looked at>]`,
64
+ never as prose.
65
+ - Do not cite a file you were not given. If it is not inlined above, you have not read it.
66
+ - Do not describe a signal you would add. The card records what the code emits today.
67
+
68
+ Facts on record:
69
+
70
+ {{facts}}
71
+
72
+ Conventions:
73
+
74
+ {{conventions}}
75
+
76
+ ## Questions
77
+
78
+ None. This stage asks nothing: everything it needs is inlined above, and what is
79
+ not there is an `absent:` source rather than a question. If the code emits nothing,
80
+ the card saying so IS the finding.
81
+
82
+ ## Stop
83
+
84
+ Write the one file. Do not write the handoff — the framework writes that from your
85
+ card. Do not touch any other file. Budget: `${{budget_usd}}`.
@@ -0,0 +1,61 @@
1
+ # schema: draft
2
+ # Phase 5 of the loop. Concept §3 and §10; the card's schema is spec §2.16.
3
+ #
4
+ # Generated from what Build actually instrumented. If nothing was instrumented,
5
+ # the watcher says so — an aspirational watcher is worse than no watcher.
6
+ #
7
+ # This stage is run by the WATCH EXECUTOR (src/core/facilitator/executors/watch.ts),
8
+ # not by the default one-agent path: it spawns one sub-agent per shipped feature,
9
+ # and how many features there are is a fact about the run rather than about the
10
+ # stage. That is also why `watchers/<feature>.md` is NOT listed under `outputs:` —
11
+ # a declared output is re-read from disk BY NAME (spec §5), and these have no name
12
+ # until the pre-pass has grouped the done stories by epic. The executor validates
13
+ # every card itself, with the same parser `claim-sources` uses, and stamps its
14
+ # status: `verified` only when nothing under `## Signal` cites `absent:`.
15
+ name: watch
16
+ title: Watch
17
+ phase: 5
18
+ model: haiku
19
+ # --effort for this stage's sub-agent (spec §2.3). The cost lever
20
+ # `--max-budget-usd` is not: the budget flag only STOPS a turn already in flight.
21
+ # `[assumption]` — Watch renders a card per shipped feature from evidence the
22
+ # executor has already grouped and handed over. Low: it is a transcription job
23
+ # with a validator behind it, not an analysis.
24
+ effort: low
25
+ budget_usd: 2
26
+ timeout_s: 900
27
+
28
+ # Read PER FEATURE by the executor rather than inlined wholesale: the done stories
29
+ # of ONE epic, that epic's file, the read-only diff of its branch against the
30
+ # repo's default branch, the `observability`/`deploy` facts, and the gotchas of the
31
+ # repos it touched. One sub-agent never sees another feature's evidence.
32
+ #
33
+ # The draft array form on purpose (as in stages/what/stage.yml): the v0 skeleton
34
+ # validator requires `inputs` to be an array, and a bare list is read as all
35
+ # OPTIONAL — which is right here, since a run whose Plan produced nothing still has
36
+ # a Watch stage to complete. `[assumption]`
37
+ inputs:
38
+ - "03-plan/stories"
39
+ - "03-plan/epics"
40
+ - ".tldrx/map/{repo}/gotchas.md"
41
+ - ".tldrx/memory/facts.yml"
42
+
43
+ outputs:
44
+ - {path: "handoff.md", sections: [Findings, Decisions, Unknowns, "Evidence ledger"]}
45
+
46
+ experts:
47
+ - operations
48
+
49
+ # `requires:` used to list four acceptance criteria here. Nothing read them:
50
+ # `normaliseGate` (src/core/run/workflowPreset.ts:216-231) reads only `.type`,
51
+ # `validateStage` (src/core/schemas/stage.ts:72-76) checks only `gate.type`, the
52
+ # prompt ships `stage.md` and never this file (src/core/facilitator/prompt.ts:101),
53
+ # and no other file in the repo touches the key. Criteria no gate enforces and no
54
+ # reader ever sees are worse than none — the enforcement that IS real is the
55
+ # `checks:` list below.
56
+ gate:
57
+ type: human-approval
58
+
59
+ checks:
60
+ - claim-sources
61
+ - budget-gate
@@ -0,0 +1,89 @@
1
+ <!-- schema: draft -->
2
+ <!-- Stage template: what (phase 1). Rendered into <record>/01-what/handoff.md. -->
3
+
4
+ # What — handoff
5
+
6
+ **Run:** `<run-id>` · **Stage:** `what` · **Expert(s):** `<from stage.yml>` · **Model:** `<from stage.yml>`
7
+ **Spent:** `$<n>` of `$<budget_usd>`
8
+
9
+ > Turn a phrase, a document or a ticket into a scope somebody can disagree with. Accepts a document as input: read it, extract the claims it actually makes, and ask only about the gaps.
10
+
11
+ ---
12
+
13
+ ## Findings
14
+
15
+ > What Investigate actually established. **Every bullet ends with a source.**
16
+ > `[src: path/to/file.ts:42]` · `[src: https://…]` · `[src: Q7]`
17
+ > A bullet you cannot source does not belong here — move it to Unknowns.
18
+
19
+ - The request is <…>, stated as <…> in the source document. `[src: …]`
20
+ - The system today does <…> in this area. `[src: …]`
21
+
22
+ ## Decisions
23
+
24
+ > What was decided, and on the strength of what. Same rule: every bullet is sourced.
25
+ > Label each one **measured** (it was run), **inferred** (mechanism plus evidence,
26
+ > could be wrong) or **assumed** (nobody knows yet).
27
+
28
+ - In scope: <…>. Out of scope: <…>, because <…>. `[src: …]`
29
+
30
+ ## Unknowns
31
+
32
+ > Only these become questions. Before writing one, grep `.tldrx/memory/facts.yml`:
33
+ > re-asking a recorded fact is a framework test failure, not a style choice.
34
+ > Each unknown states who or what could answer it.
35
+
36
+ - Who owns <…>, and what happens today when <…>? — *could be answered by:* `<person | file | command | doc>`
37
+
38
+ ## Evidence ledger
39
+
40
+ > Every source cited above, once, with what it proved. This is what the next stage
41
+ > and the reviewer read instead of re-deriving the work. **List items, not a table**
42
+ > — this section is checked exactly like the other three, and a table holds no
43
+ > list items for the gate to check.
44
+
45
+ - … what this file establishes … `[src: <repo>:<path>:<line>]`
46
+ - … what this command proved … `[src: $ <command> → exit 0]`
47
+
48
+ ## Outputs written
49
+
50
+ - `intent.md`
51
+ - `scope.md` (in / out, MoSCoW)
52
+ - `success-metrics.md`
53
+ - `open-questions.md`
54
+
55
+ ## Gate
56
+
57
+ Blocked on: **<human approval | checks green>** — `stage.yml`'s `gate.type`. What is
58
+ actually enforced is that file's `checks:` list, which `tldrx approve` re-runs against what
59
+ is on disk before it will advance anything. Nothing advances until this is recorded in
60
+ `run.yml` and `events.jsonl`.
61
+
62
+ ## Rules
63
+
64
+ - Every bullet under Findings / Decisions / Unknowns / Evidence ledger is ONE line and ENDS with a source token. A bullet without one is refused by the `claim-sources` gate and the whole stage fails.
65
+ - Each of Findings / Decisions / Unknowns / Evidence ledger must hold at least ONE list item; a section that is genuinely empty is written as `- none [src: absent:<what you looked at>]`, and a prose-only section is refused by the `claim-sources` gate.
66
+ - Source token grammar (exact): `[src: <one or more sources separated by "; ">]` where a source is ONE of:
67
+ - `<repo>:<path>:<line>` or `<repo>:<path>:<start>-<end>` — a file with ONE line or ONE range. Never a whole file, never a comma list (`file.md:7,21` is invalid: write two sources or a range).
68
+ - `F<n>` — a fact id from `.tldrx/memory/facts.yml` (cite the id, never the file).
69
+ - `Q<n>` — a question from this run's questions.md.
70
+ - `https://…` — an external document (https only).
71
+ - `aidlc:<file>:<line>` / `aidlc:<file>#Q<n>` — an imported source, exactly as it already appears in intent.md/scope.md.
72
+ - `$ <command> → exit <n>` — only under Evidence ledger, only for commands listed in `.tldrx/workspace.yml`.
73
+ - `absent:<path>` — you looked there and found nothing.
74
+ - Do not cite templates, expert files or directories (`.tldrx/experts/*` is not evidence).
75
+ - Questions go in `questions.md`, and its shape is a PARSER's, not a style. One regex reads a block — `^## (Q\d+) · (.+)$` — and a heading that misses it is not half-read, it is read as ABSENT: the gate then records "0 open questions" and signs itself over questions nobody answered. Write each one EXACTLY like this, `·` being U+00B7 MIDDLE DOT:
76
+ ```
77
+ ## Q1 · Where does leaderboard state live?
78
+ <!-- id: Q1 | status: open | area: data-model | asked_by: architect | asked_at: 2026-08-29T14:02:11Z -->
79
+ Why asked: no ranking store exists in the map [src: absent:.tldrx/map/api/domains.md]
80
+
81
+ - A) New Postgres table, recomputed on hunt completion
82
+ - B) Redis sorted set
83
+ - C) other — write it below
84
+
85
+ [Answer]:
86
+ ```
87
+ All five metadata keys are required; `Why asked:` must END with a `[src: …]` token; 2–5 options lettered A–E in order; exactly one empty `[Answer]:` slot. Ids ascend. Never write `### Qn — …`, `**Answer:**`, or the answered footer — the hook writes that. `tldrx questions lint` checks the file; `--fix` converts a file already written the wrong way.
88
+ - Before asking a question, grep `.tldrx/memory/facts.yml`; if the answer is there, cite `F<n>` instead of asking.
89
+ - Write only the declared outputs; do not add sections beyond the ones listed under Produce.
@@ -0,0 +1,61 @@
1
+ # schema: draft
2
+ # Phase 1 of the loop. Concept §3.
3
+ # Accepts a phrase OR a document: Investigate reads the doc, extracts claims plus
4
+ # gaps, and Interview asks about the gaps only.
5
+ name: what
6
+ title: What
7
+ phase: 1
8
+ model: sonnet
9
+ # --effort for this stage's sub-agent (spec §2.3). The cost lever
10
+ # `--max-budget-usd` is not: the budget flag only STOPS a turn already in flight.
11
+ # `[assumption]` — What is elicitation over a small, capped input set: read
12
+ # the seeds, name what is in and out. Medium is the level that reads carefully
13
+ # without paying to reason about a design it has not been asked for.
14
+ effort: medium
15
+ budget_usd: 4
16
+
17
+ # `seed: true` — this stage ALSO receives the run's seed documents: the files
18
+ # `tldrx run new --seed <file|dir>` recorded in `run.yml` for it (spec §2.3). They
19
+ # cannot be named here because they differ per run; the stage opts in, the run
20
+ # says what the seed was, and an unseeded run simply has none. This replaces the
21
+ # old `"<free text, a PRD, any document, or a Jira epic>"` placeholder, which was
22
+ # prose no code could act on — the facilitator inlined zero documents for it.
23
+ #
24
+ # The §2.3 spelling is `inputs: {seed: true, required: [...], optional: [...]}`
25
+ # and the loader accepts it; the shipped file uses the draft array form plus this
26
+ # top-level key because the v0 skeleton validator still requires `inputs` to be an
27
+ # array (`src/core/schemas/stage.ts`). `[assumption]`
28
+ seed: true
29
+ inputs:
30
+ - ".tldrx/memory/facts.yml"
31
+ - ".tldrx/map/{repo}/domains.md"
32
+
33
+ outputs:
34
+ - "intent.md"
35
+ - "scope.md"
36
+ - "success-metrics.md"
37
+ - "open-questions.md"
38
+ - "handoff.md"
39
+ - "questions.md"
40
+
41
+ # `domain` used to be listed here and was never an expert NAME — a `kind: domain`
42
+ # expert is picked by the paths this run cites (spec §2.3, rule 3), which a stage
43
+ # file written once for every workspace cannot know. Rules 2 and 3 still apply to
44
+ # this stage; only the placeholder is gone.
45
+ experts:
46
+ - product
47
+
48
+ # `requires:` used to list three acceptance criteria here. Nothing read them:
49
+ # `normaliseGate` (src/core/run/workflowPreset.ts:216-231) reads only `.type`,
50
+ # `validateStage` (src/core/schemas/stage.ts:72-76) checks only `gate.type`, the
51
+ # prompt ships `stage.md` and never this file (src/core/facilitator/prompt.ts:101),
52
+ # and no other file in the repo touches the key. Criteria no gate enforces and no
53
+ # reader ever sees are worse than none — the enforcement that IS real is the
54
+ # `checks:` list below.
55
+ gate:
56
+ type: human-approval
57
+
58
+ checks:
59
+ - claim-sources
60
+ - no-reask
61
+ - budget-gate
@@ -0,0 +1,17 @@
1
+ # schema: draft
2
+ # Written to tldrx-work/<run>/budget.yml. Concept §11.
3
+ #
4
+ # ceiling_usd is a refusal, not a warning: a stage whose estimate exceeds what
5
+ # remains does not start. spent_usd is rolled up from events.jsonl — never typed
6
+ # by hand, never estimated by an agent.
7
+ version: 1
8
+ run: "260828-example-slug"
9
+ ceiling_usd: 25
10
+ spent_usd: 0
11
+
12
+ per_phase_usd:
13
+ what: 4
14
+ how: 6
15
+ plan: 4
16
+ build: 9
17
+ watch: 2
@@ -0,0 +1,14 @@
1
+ # schema: draft
2
+ # Written to .tldrx/experts/<name>/competencies.yml. Concept §6.
3
+ #
4
+ # `level` is COMPUTED from evidence count and recency. It is never self-declared
5
+ # and an expert may not edit its own. The star chart in the dashboard is this file
6
+ # rendered — nothing more.
7
+ version: 1
8
+ expert: example-expert
9
+
10
+ areas:
11
+ - area: "oauth"
12
+ level: 0 # 0-5, computed
13
+ evidence: [] # each entry cites a file:line, a doc URL, or a run id
14
+ last_trained: null