@r1z4x/tezgah 1.6.0 → 1.8.2

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 (71) hide show
  1. package/CHANGELOG.md +140 -1
  2. package/MANIFEST +7 -0
  3. package/README.md +6 -3
  4. package/bin/tezgah-decisions +6 -14
  5. package/bin/tezgah-design +21 -5
  6. package/bin/tezgah-docs +18 -16
  7. package/bin/tezgah-doctor +152 -0
  8. package/bin/tezgah-lessons +4 -1
  9. package/bin/tezgah-research +249 -17
  10. package/bin/tezgah-route +70 -8
  11. package/bin/tezgah-setup +26 -13
  12. package/bin/tezgah-task +877 -60
  13. package/bin/tezgah-taste +56 -15
  14. package/docs/architecture.md +28 -11
  15. package/docs/clarity-baseline.json +2 -2
  16. package/docs/contract.md +108 -24
  17. package/docs/environment.md +3 -1
  18. package/docs/evidence.md +209 -28
  19. package/docs/feature-audit.md +1 -1
  20. package/docs/gate.md +78 -23
  21. package/docs/glossary.md +4 -4
  22. package/docs/hosts.md +8 -8
  23. package/docs/index.json +11 -5
  24. package/docs/judge.md +9 -3
  25. package/docs/models.md +75 -14
  26. package/docs/operations.md +133 -3
  27. package/docs/research.md +349 -15
  28. package/docs/skills.md +1 -1
  29. package/docs/status-line.md +5 -5
  30. package/docs/testing.md +20 -13
  31. package/docs/vision.md +12 -4
  32. package/hooks/hooks.json +2 -2
  33. package/hooks/lang/en.json +323 -0
  34. package/hooks/lang/tr.json +344 -0
  35. package/hooks/projects-auto-init.py +29 -1
  36. package/hooks/projects-posttooluse.py +24 -5
  37. package/hooks/projects-pretooluse.py +9 -4
  38. package/hooks/projects-stop.py +28 -16
  39. package/hooks/tezgah_agents.py +53 -17
  40. package/hooks/tezgah_clarity.py +7 -3
  41. package/hooks/tezgah_context.py +489 -438
  42. package/hooks/tezgah_gate.py +996 -80
  43. package/hooks/tezgah_integrity.py +1547 -197
  44. package/hooks/tezgah_models.py +427 -45
  45. package/hooks/tezgah_paths.py +147 -16
  46. package/hooks/tezgah_policy.py +261 -129
  47. package/hooks/tezgah_rank.py +29 -27
  48. package/hooks/tezgah_replay.py +200 -30
  49. package/hooks/tezgah_research.py +1303 -14
  50. package/hooks/tezgah_stopspec.py +7 -0
  51. package/hooks/tezgah_store.py +74 -27
  52. package/hooks/tezgah_task.py +1201 -40
  53. package/hooks/tezgah_taste.py +8 -4
  54. package/hosts/codex/hook.py +32 -13
  55. package/hosts/cursor/hook.py +32 -14
  56. package/hosts/dsh/hooks.json +2 -2
  57. package/hosts/omp/hook.py +44 -23
  58. package/hosts/omp/tezgah-hook.ts.in +93 -7
  59. package/hosts/opencode/plugins/tezgah.js +273 -6
  60. package/output-styles/tezgah.md +76 -42
  61. package/package.json +1 -1
  62. package/skills/i-have-adhd/EVALS.md +22 -2
  63. package/skills/i-have-adhd/SKILL.md +12 -5
  64. package/skills/plan-add/SKILL.md +27 -11
  65. package/skills/plan-add/render_table.py +8 -3
  66. package/skills/plan-sync/SKILL.md +5 -3
  67. package/skills/ponytail/EVALS.md +21 -2
  68. package/skills/ponytail/SKILL.md +4 -4
  69. package/skills/research/SKILL.md +89 -1
  70. package/skills/tezgah-contract/EVALS.md +52 -7
  71. package/skills/tezgah-contract/SKILL.md +154 -59
@@ -37,7 +37,7 @@ import subprocess
37
37
 
38
38
  import tezgah_models as tm
39
39
  from tezgah_paths import (CONFIG_DIR, HOME, codegraph_bin, host_installed, off,
40
- root_for)
40
+ root_for, say)
41
41
  from tezgah_paths import HOST_DIRS as HOST_HOMES
42
42
 
43
43
  MARKER = "# tezgah: managed by tezgah-agents; do not edit"
@@ -186,6 +186,7 @@ def detect_infra(root):
186
186
  # ------------------------------------------------------------------ roles ----
187
187
 
188
188
  def _reviewer_body(host):
189
+ decision = say()["decision"]
189
190
  return (
190
191
  "You are tezgah-reviewer, an adversarial code reviewer. Review a change,\n"
191
192
  "not the whole repo, with the code graph as below.\n\n"
@@ -221,10 +222,11 @@ def _reviewer_body(host):
221
222
  "provisional. Disclose the order you read the files in.\n\n"
222
223
  "Scope and budget. One review per plan, over its whole diff in the\n"
223
224
  "verification phase; at most two rounds - only a confirmed critical or\n"
224
- "major finding opens round two, a minor or suggestion one is recorded\n"
225
- "fix-later, and after round two what is left is fixed by the session\n"
226
- "and closed with `--resolved`, or recorded fix-later, never a third\n"
227
- "round. A round may be a fan-out of\n"
225
+ "major finding opens round two; a minor or suggestion one is fixed in the\n"
226
+ "session without a new round, or recorded fix-later only when it waits\n"
227
+ "on a user decision (%s); after round two what is left is fixed by\n"
228
+ "the session and closed with `--resolved`, or recorded fix-later only\n"
229
+ "with %s, never a third round. A round may be a fan-out of\n"
228
230
  "reviewers spawned at once, one per dimension (correctness and contract,\n"
229
231
  "security, tests and performance) or per file group: when your brief\n"
230
232
  "names a dimension or files, review only those - a sibling owns the rest.\n"
@@ -237,7 +239,7 @@ def _reviewer_body(host):
237
239
  "specific accusation needs it. The same defect family confirmed in both\n"
238
240
  "rounds is a sign the design needs a pivot, not another patch.\n\n"
239
241
  "%s" % (_graph_howto(host), _blast_radius(host), EMPTY_IS_NOT_PROOF,
240
- _may_use(host)))
242
+ decision, decision, _may_use(host)))
241
243
 
242
244
 
243
245
  def _worker_body(tier):
@@ -250,17 +252,29 @@ def _worker_body(tier):
250
252
  scope = ("If the work needs a judgement above this tier - a design choice,\n"
251
253
  "a stored-data or ordering invariant, security-sensitive code, or\n"
252
254
  "a failure whose cause you cannot find - stop editing and answer\n"
253
- "`ESCALATE: <why>`; the router restarts it on tezgah-frontier.")
255
+ "`ESCALATE: <why>`.")
254
256
  return ("You are tezgah-%s, a worker on the %s model tier. Do exactly the\n"
255
257
  "brief: stay inside the files it names, run the checks it names, and\n"
256
258
  "report what changed and what each check printed, verbatim. Report\n"
257
259
  "progress, but never redefine the work. Never widen or narrow the brief's\n"
258
260
  "scope, budget or question. If the brief cannot be met as written, say\n"
259
261
  "so and stop rather than answering a different question.\n%s\n"
260
- "Never spawn subagents." % (tier, tier, scope))
262
+ "Never spawn subagents.\n%s" % (tier, tier, scope, WORKER_OUTPUT))
261
263
  return body
262
264
 
263
265
 
266
+ # The report a consumer reads: the orchestrator re-briefs a report missing one
267
+ # of these fields (_orch_body), so only a role with a reader gets them. One
268
+ # text on every host, since a worker body ignores its host.
269
+ WORKER_OUTPUT = ("End the report, after any other shape asked for, with `Output to\n"
270
+ "orchestrator`, every field, `none` when empty:\n"
271
+ "- changed: the files you changed\n"
272
+ "- commit: the sha\n"
273
+ "- checks: each command, its exit code and the last lines of its\n"
274
+ " output file, verbatim\n"
275
+ "- escalate: the `ESCALATE:` reason (always `none` on tezgah-frontier)")
276
+
277
+
264
278
  # The specialists beside the tier workers: name -> (what it does, the skills it
265
279
  # loads first, its tools, the role text). The tier is not here: it is
266
280
  # tezgah_models.AGENT_SLOT, the row every host's model line is rendered from, so
@@ -280,9 +294,11 @@ SPECIALISTS = {
280
294
  "import the changed modules. Keep each check last on its line with its\n"
281
295
  "output in a file, then read the file in a separate call: never pipe a\n"
282
296
  "check into tail or grep, never `|| true`, never `--no-verify`, never a\n"
283
- "new skip. Set the shell timeout above 300 s for a long run. Report each\n"
284
- "check as passed or failed with its counts and the exact failure text.\n"
285
- "Never edit source or test files; a fix belongs to the caller."),
297
+ "new skip. Set the shell timeout above 300 s for a long run. Never edit\n"
298
+ "source or test files; a fix belongs to the caller.\n"
299
+ "End the report, after any other shape asked for, with `Output to\n"
300
+ "orchestrator`, per check: its command, the pass/fail/skip counts and\n"
301
+ "the first failure verbatim (`none` when it passed)."),
286
302
  "tezgah-docs": (
287
303
  "Writes and repairs docs pages and their `path:line` / `path::symbol` "
288
304
  "citations after a code change, under the repo's own docs checks.",
@@ -419,9 +435,26 @@ def _orch_body(names):
419
435
  "--name <slug> --parent-worktree active --json` when the session runs\n"
420
436
  "inside Orca, else `git worktree add -b <branch> <absolute path>` - and\n"
421
437
  "brief it with absolute paths under that checkout only, never the main\n"
422
- "checkout. Serialize only a real\n"
423
- "dependency, and never wait idle while independent work remains; you\n"
424
- "integrate the branches and run the checks once on the merged tree.\n\n"
438
+ "checkout. Every writing brief names its `Owns:` globs (the files only\n"
439
+ "that slice writes; the gate holds its siblings to them) and declares\n"
440
+ "its checkout on a `Worktree: <abs path>` line, and siblings\n"
441
+ "message each other only on an interface or ownership change - status\n"
442
+ "goes to you. Serialize only a real\n"
443
+ "dependency. Your todo list is the step queue: each open item is ready\n"
444
+ "or blocked on something named (a slice id, %s).\n"
445
+ "After every spawn and every landed slice, dispatch every ready\n"
446
+ "item at once, before any `wait`, and mark each dispatched item blocked\n"
447
+ "on its slice id. Never `wait` while a ready step exists. Once every\n"
448
+ "open item is blocked on a running slice, `wait` or end the turn - the\n"
449
+ "host wakes you on the result. You integrate the branches in the order\n"
450
+ "`tezgah-task slice merge-plan` prints, and own CHANGELOG.md, MANIFEST\n"
451
+ "and the citation baseline. The per-turn\n"
452
+ "checks of what changed still run in the turn, in the background; only\n"
453
+ "the heavy tier (full suite, neuter, e2e) is joined at merge.\n"
454
+ "A slice commits `wip: <step>` after each step. A stopped slice is\n"
455
+ "resumed (`tezgah-task slice resume <id>`) or re-dispatched, never\n"
456
+ "silently absorbed inline; run `tezgah-task slice reconcile --prune`\n"
457
+ "before the turn that merged slices ends.\n\n"
425
458
  "Route reviews to tezgah-reviewer, with the changed files and symbols in\n"
426
459
  "the brief: where it has no shell it cannot run `git diff` itself. Checks\n"
427
460
  "go to tezgah-tester, docs and citations to tezgah-docs, a security review\n"
@@ -430,10 +463,13 @@ def _orch_body(names):
430
463
  "codegraph tools; a second opinion (`consult`) stays with the main\n"
431
464
  "thread. Other work goes to the tier worker\n"
432
465
  "`tezgah-route \"<brief>\"` names (tezgah-cheap, tezgah-standard,\n"
433
- "tezgah-frontier); an ESCALATE answer is restarted on tezgah-frontier with\n"
434
- "the same brief. Never delegate a task a specialist is not\n"
466
+ "tezgah-frontier). A report missing an `Output to orchestrator` field,\n"
467
+ "or an ESCALATE, gets one narrower re-brief of the same role naming the\n"
468
+ "missing field or the escalated judgement; only a second miss is\n"
469
+ "restarted on tezgah-frontier with the original brief, never continued.\n"
470
+ "Never delegate a task a specialist is not\n"
435
471
  "listed for, and never let a subagent spawn its own subagents. Verify each\n"
436
- "returned claim against the code before acting." % listed)
472
+ "returned claim against the code before acting." % (listed, say()["blocker_tokens"]))
437
473
 
438
474
 
439
475
  # ---------------------------------------------------------------- renderers --
@@ -4,7 +4,8 @@ Four rules are counted per file over docs/*.md and CHANGELOG.md: sentences over
4
4
  25 words, semicolons, a short list of words with a plainer replacement, and
5
5
  passive voice. Only English prose written for people is read: fenced code,
6
6
  code spans (including one broken across lines), link targets, HTML comments,
7
- tables, headings and any line holding a Turkish letter are blanked first, with
7
+ tables, headings and any line holding another language's marker letter (a
8
+ language pack's `markers.letters`, hooks/lang/) are blanked first, with
8
9
  their newlines kept so a hit still names its line.
9
10
 
10
11
  The counts are a ratchet, not a style gate: `docs/clarity-baseline.json` holds
@@ -19,6 +20,8 @@ import json
19
20
  import os
20
21
  import re
21
22
 
23
+ from tezgah_paths import packs
24
+
22
25
  RULES = ("long_sentences", "semicolons", "replace_words", "passive")
23
26
  LONG = 25
24
27
  REPLACE = ("commence", "initiate", "utilize", "prior to", "in order to", "ensure",
@@ -33,7 +36,8 @@ FENCE = re.compile(r"^\s*(```|~~~)")
33
36
  SPAN = re.compile(r"(?<!`)(`+)(?!`)(.+?)(?<!`)\1(?!`)", re.S)
34
37
  COMMENT = re.compile(r"<!--.*?-->", re.S)
35
38
  LINK_TARGET = re.compile(r"\]\([^)]*\)|\]\[[^\]]*\]|<https?://[^>]*>|https?://\S+")
36
- TURKISH = re.compile(r"[ğĞışŞçÇöÖüÜİ]")
39
+ OTHER_LANGUAGE = re.compile("[%s]" % "".join(
40
+ c for p in packs().values() for c in p["markers"]["letters"]))
37
41
  SKIP_LINE = re.compile(r"^\s*(?:#|\||\[[^\]]+\]:\s)")
38
42
  ITEM = re.compile(r"^\s*(?:[-*+]|\d+[.)])\s+")
39
43
  BASELINE = os.path.join("docs", "clarity-baseline.json")
@@ -58,7 +62,7 @@ def prose(text):
58
62
  out.append(SPAN.sub(lambda m: _blank(m, " CODE "), para))
59
63
  text = LINK_TARGET.sub(lambda m: "]" if m.group(0)[0] == "]" else "",
60
64
  COMMENT.sub(_blank, "".join(out)))
61
- return "\n".join("" if SKIP_LINE.match(line) or TURKISH.search(line) else line
65
+ return "\n".join("" if SKIP_LINE.match(line) or OTHER_LANGUAGE.search(line) else line
62
66
  for line in text.split("\n"))
63
67
 
64
68