@r1z4x/tezgah 1.3.0 → 1.5.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 (53) hide show
  1. package/CHANGELOG.md +103 -1
  2. package/MANIFEST +3 -0
  3. package/agents/tezgah-reviewer.md +19 -10
  4. package/bin/tezgah-docs +3 -3
  5. package/bin/tezgah-doctor +75 -18
  6. package/bin/tezgah-route +5 -2
  7. package/bin/tezgah-setup +30 -18
  8. package/bin/tezgah-status +3 -1
  9. package/bin/tezgah-task +130 -37
  10. package/bin/tezgah-taste +74 -55
  11. package/bin/tezgah-triage +12 -7
  12. package/docs/architecture.md +4 -4
  13. package/docs/clarity-baseline.json +9 -9
  14. package/docs/contract.md +22 -12
  15. package/docs/environment.md +4 -1
  16. package/docs/evidence.md +71 -34
  17. package/docs/gate.md +21 -21
  18. package/docs/glossary.md +5 -5
  19. package/docs/hosts.md +8 -8
  20. package/docs/judge.md +93 -27
  21. package/docs/operations.md +69 -30
  22. package/docs/skills.md +2 -2
  23. package/docs/status-line.md +7 -7
  24. package/docs/vision.md +10 -5
  25. package/hooks/tezgah_agents.py +22 -11
  26. package/hooks/tezgah_attest.py +15 -22
  27. package/hooks/tezgah_context.py +84 -124
  28. package/hooks/tezgah_gate.py +26 -23
  29. package/hooks/tezgah_guard.py +9 -11
  30. package/hooks/tezgah_integrity.py +77 -178
  31. package/hooks/tezgah_judge.py +270 -122
  32. package/hooks/tezgah_lessons.py +18 -63
  33. package/hooks/tezgah_paths.py +183 -55
  34. package/hooks/tezgah_policy.py +35 -8
  35. package/hooks/tezgah_replay.py +57 -33
  36. package/hooks/tezgah_shapes.py +4 -4
  37. package/hooks/tezgah_skill_pick.py +6 -35
  38. package/hooks/tezgah_snapshot.py +25 -46
  39. package/hooks/tezgah_store.py +1268 -0
  40. package/hooks/tezgah_task.py +146 -40
  41. package/hooks/tezgah_taste.py +21 -18
  42. package/hooks/tezgah_taste_ledger.py +63 -88
  43. package/hooks/tezgah_update.py +6 -26
  44. package/hosts/codex/hook.py +5 -0
  45. package/hosts/cursor/hook.py +19 -31
  46. package/hosts/opencode/plugins/tezgah.js +309 -108
  47. package/package.json +1 -1
  48. package/skills/harness/SKILL.md +4 -0
  49. package/skills/plan-add/SKILL.md +23 -7
  50. package/skills/plan-add/render_table.py +3 -2
  51. package/skills/plan-status/SKILL.md +12 -4
  52. package/skills/plan-sync/SKILL.md +19 -9
  53. package/skills/tezgah-contract/SKILL.md +25 -12
@@ -37,8 +37,9 @@ def acceptance(strict):
37
37
  count = lambda state: sum(1 for i in report["items"] if i["state"] == state)
38
38
  print("plans: %d read, acceptance items: %d read; %d name no command, %d declared unverifiable"
39
39
  % (report["plans"], len(report["items"]), count("missing"), count("unverifiable")))
40
- open_missing = [i for i in report["items"]
41
- if i["state"] == "missing" and i["plan"].startswith(".tezgah/plans/open/")]
40
+ # the predicate the phase move refuses on (tezgah-task), so the two agree
41
+ open_missing = tt.unproven([i for i in report["items"]
42
+ if i["plan"].startswith(".tezgah/plans/open/")])
42
43
  if strict and open_missing:
43
44
  print("strict: %d item(s) under .tezgah/plans/open name no command and declare no "
44
45
  "unverifiable; a done plan is reported, never gated" % len(open_missing))
@@ -15,7 +15,12 @@ description: >
15
15
  1. Resolve the root: `ROOT=$(git rev-parse --show-toplevel)`. If it fails, stop and
16
16
  say plans need a git repo. If `$ROOT/.tezgah/plans/open` is missing, say so and stop.
17
17
  2. For each `.tezgah/plans/open/*.md`: read the frontmatter (id, title, status, branch, pr)
18
- and the first line of the `## Next` section.
18
+ and the first line of the `## Next` section. Then run
19
+ `~/.config/tezgah/bin/tezgah-task status`: per open plan it prints the
20
+ Acceptance boxes ticked, the plans its `after:` still waits on, and a
21
+ `parallel:` line naming the ready plans that share no `allowed_paths:`
22
+ prefix; a `FAIL` line (a status outside open|blocked, an `after:` id no plan
23
+ carries, a phase no reader accepts) goes into the report as it printed.
19
24
  3. If `pr:` is set, run
20
25
  `gh pr view <pr> --json state,mergedAt,reviewDecision,statusCheckRollup -q '[.state, .reviewDecision, ([.statusCheckRollup[]?.conclusion] | unique | join(","))] | map(select(. != null and . != "")) | join(" | ")'`
21
26
  and append the result to that row's `pr` cell, e.g. `#12 (OPEN | APPROVED | SUCCESS)`.
@@ -37,16 +42,19 @@ description: >
37
42
  no "Generated with" / "Made with", no robot emoji, no Claude/Anthropic/OpenAI/
38
43
  GPT/Codex/Gemini/Cursor/Copilot credit.
39
44
  8. Print the table, then one line per plan with `status: blocked` quoting its
40
- `BLOCKED: <reason>`, then any gh failures.
45
+ `BLOCKED: <reason>`, then one line per plan that waits on another (`waits on
46
+ NNN (open)`), then any gh failures and `FAIL` lines.
41
47
  9. End with exactly one recommendation: "Work on NNN <slug> next: <reason>". No menu.
42
48
  Prefer plans with an approved PR and green CI, then open plans with no blocker,
43
- oldest first.
49
+ oldest first; never a plan that still waits on another. When the `parallel:`
50
+ line names it with others, add one sentence: those plans can run at once, one
51
+ worktree each.
44
52
 
45
53
  ## Format
46
54
 
47
55
  Plan file `.tezgah/plans/open/NNN-slug.md` (status open|blocked) or `.tezgah/plans/done/NNN-slug.md`
48
56
  (status done|discarded). Frontmatter: id, title, status, branch (`plan/NNN-slug`),
49
- pr, created, updated, allowed_paths, plus phase/allowed_from/review when set. Sections: `## Goal`, `## Acceptance` (checkboxes), `## State`
57
+ pr, created, updated, allowed_paths, plus after/phase/allowed_from/checkpoint/review/review_round/reviewed_sha and the spike keys when set. Sections: `## Goal`, `## Acceptance` (checkboxes), `## State`
50
58
  (evidence), `## Next` (one action or `BLOCKED: <reason>`). README table lives between
51
59
  `<!-- status:start -->` and `<!-- status:end -->` with columns
52
60
  `| id | title | status | branch | pr | next |`.
@@ -28,16 +28,23 @@ description: >
28
28
  - gh returned `[]`: fallback `git branch -r --merged origin/main | grep -q "origin/<branch>"`.
29
29
  If it matches, treat as done and append `merged without PR`.
30
30
  - otherwise: leave the plan untouched.
31
- 5. For every plan marked done: if `## Acceptance` still has `- [ ]` boxes, still move
32
- it but append the line `acceptance boxes unchecked at sync` to `## State`.
31
+ 5. For every plan marked done: if `## Acceptance` still has `- [ ]` boxes (the
32
+ `acceptance N/M checked` count `~/.config/tezgah/bin/tezgah-task status` prints
33
+ per open plan), still move it but append the line
34
+ `acceptance boxes unchecked at sync (N/M checked)` to `## State`.
33
35
  6. Move each done or discarded plan with
34
36
  `~/.config/tezgah/bin/tezgah-task close NNN done|discarded`: it sets `status:` and
35
37
  `updated:` and moves the file to `.tezgah/plans/done/`. It refuses `done` unless the
36
- plan records `review: <reviewer> approve` - a fresh reviewer (the host's
37
- `tezgah-reviewer` subagent) read `git diff <base>..HEAD` and
38
- `tezgah-task review NNN <reviewer> approve` wrote the verdict - and it refuses
39
- the active task. A refused plan stays open: report it with the refusal, never
40
- move it by hand.
38
+ plan records `review: <reviewer> approve` - fresh reviewers (the host's
39
+ `tezgah-reviewer` subagent, one per dimension in one message for a large diff)
40
+ read `git diff <base>..HEAD` and `tezgah-task review NNN <reviewer> approve`
41
+ wrote the verdict - and it refuses the active task. A refused plan stays open:
42
+ report it with the refusal, never move it by hand, and never start a review
43
+ round from here. One review per plan, over its whole diff in the verification
44
+ phase; at most two rounds - only a confirmed critical or major finding opens
45
+ round two, a minor or suggestion one is recorded fix-later, and after round two
46
+ what is left goes to the user or is recorded fix-later, never a third round.
47
+ A plan refused with a spent budget is the user's decision.
41
48
  7. Rewrite the README status table: `~/.config/tezgah/bin/tezgah-render-table` (installed by `bin/tezgah-setup --install`; if it is missing, run that script)
42
49
  (one row per open plan, sorted by id; it prints the rows). No `--pr-info` here:
43
50
  the row's `pr` cell comes from the plan files, and review/check enrichment
@@ -55,14 +62,17 @@ description: >
55
62
  no "Generated with" / "Made with", no robot emoji, no Claude/Anthropic/OpenAI/
56
63
  GPT/Codex/Gemini/Cursor/Copilot credit.
57
64
  9. Report four lists: moved plans (with done/discarded and the evidence line),
58
- plans `close` refused (with its reason), still-open plans, and gh failures. Never delete branches, never edit code outside
65
+ plans `close` refused (with its reason), still-open plans - each with what
66
+ `tezgah-task status` says it waits on, so a plan whose `after:` names one just
67
+ discarded (`waits on NNN (discarded)`) is named for the user to re-plan - and
68
+ gh failures. Never delete branches, never edit code outside
59
69
  `.tezgah/plans/`.
60
70
 
61
71
  ## Format
62
72
 
63
73
  Plan file `.tezgah/plans/open/NNN-slug.md` (status open|blocked) or `.tezgah/plans/done/NNN-slug.md`
64
74
  (status done|discarded). Frontmatter: id, title, status, branch (`plan/NNN-slug`),
65
- pr, created, updated, allowed_paths, plus phase/allowed_from/review when set.
75
+ pr, created, updated, allowed_paths, plus after/phase/allowed_from/checkpoint/review/review_round/reviewed_sha and the spike keys when set.
66
76
  Sections: `## Goal`, `## Acceptance` (checkboxes), `## State`
67
77
  (evidence), `## Next` (one action or `BLOCKED: <reason>`). README table lives between
68
78
  `<!-- status:start -->` and `<!-- status:end -->` with columns
@@ -221,9 +221,11 @@ a list, several files or areas, todo entries that share nothing - go to one
221
221
  subagent each, and every writing slice gets its own branch and checkout (see
222
222
  below), never the main checkout. The
223
223
  orchestrator is the main thread itself: it does not wait idle on a slice while
224
- independent work remains. Fan out only when the subtasks share no mutable file and no interface: if two of them would edit the same file, or one's answer decides the other's, keep them in one context or sequence them. The shared artifact is the coordination channel, not chatter - naming a lead coordinates nothing by itself. If the work
225
- cannot be split - one file, one bounded change, a strictly serial chain - do it
226
- directly. Never spawn a subagent whose briefing is bigger than the work.
224
+ independent work remains. Fan out only when the subtasks share no mutable file and no interface: if two of them would edit the same file, or one's answer decides the other's, keep them in one context or sequence them. The shared artifact is the coordination channel, not chatter - naming a lead coordinates nothing by itself. Only a single item - one file, one
225
+ bounded change, a strictly serial chain - is done directly; a list of
226
+ independent items is never worked one by one on the main thread, however small
227
+ each item is, and that holds at every phase: a plan's tasks, its acceptance
228
+ commands and the sources of a survey fan out the same way.
227
229
  A slice that needs its own checkout: inside Orca (the session-start `Orca:`
228
230
  line) create it with `orca worktree create --name <slug> --parent-worktree
229
231
  active --json` and track it with `orca worktree ps --json` or `tezgah-status
@@ -272,7 +274,8 @@ guards against.
272
274
 
273
275
  ### The gate, for anything either tier produces
274
276
  Read the diff yourself. Then tests, lint and type check must pass, and anything
275
- non-trivial gets an independent review before it lands. A delegate's output is
277
+ non-trivial gets an independent review before it lands - once per plan, not
278
+ per task or commit. A delegate's output is
276
279
  a draft until the router has evidence; "the agent said it works" is not
277
280
  evidence.
278
281
 
@@ -519,12 +522,20 @@ rewrite it plainly.
519
522
  on a merge. Review first with a FRESH reviewer (never my own read of my own
520
523
  code), run the full suite, and if the review is clean and every test passes,
521
524
  merge, move the plan to `.tezgah/plans/done/`, and report the outcome. Bring it back
522
- to the user only on a critical or high-severity finding, or a failing test.
523
-
524
- **Review population: a change with an executable oracle.** The single FRESH
525
- reviewer above stays the rule for every change except one whose correctness can
525
+ to the user only on a critical or major finding left after round two, or a
526
+ failing test. One review per plan, over its whole diff in the verification
527
+ phase; at most two rounds - only a confirmed critical or major finding opens
528
+ round two, a minor or suggestion one is recorded fix-later, and after round two
529
+ what is left goes to the user or is recorded fix-later, never a third round.
530
+ A round spawns its reviewers in ONE message, one per dimension (correctness
531
+ and contract, security, tests and performance) or file group; a diff under 300
532
+ changed lines gets one reviewer. Per-task work gets tests, not a reviewer, and
533
+ `tezgah-task review` refuses a third round.
534
+
535
+ **Review population: a change with an executable oracle.** The fresh review
536
+ above stays the rule for every change except one whose correctness can
526
537
  be executed - a checker, a gate rule, a parser - where each claim can be built as
527
- a fixture. There the fresh-review step becomes a population:
538
+ a fixture. There round one becomes a population:
528
539
  1. One agent that has seen no known defect writes four failure directions from
529
540
  the code alone.
530
541
  2. Four reviewers, one direction each, run at once; every claim names an exact
@@ -534,9 +545,11 @@ a fixture. There the fresh-review step becomes a population:
534
545
  kind - a false accept and a false refusal alike. Only a confirmed claim counts.
535
546
  4. Confirmed claims are grouped by root mechanism, and each group gets a
536
547
  failing-first test.
537
- 5. A population round reviews one revision and does not replace re-review of
538
- the fix: every round that confirms a defect is followed by a round over that
539
- fix's delta, until a round confirms none.
548
+ 5. The population is round one and spends the same two-round budget: a fix
549
+ for a confirmed critical or major claim carries its failing-first test, and
550
+ round two reads that fix's delta, the round-one hunks and the direct callers
551
+ of what it touches. After round two what is left goes to the user or is
552
+ recorded fix-later, never a third round.
540
553
 
541
554
  Status: a tentative default, measured on two changes. E1
542
555
  (an internal prove-verify experiment): directed reviewers found 3 of 3 ground-truth defects,