@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.
- package/CHANGELOG.md +140 -1
- package/MANIFEST +7 -0
- package/README.md +6 -3
- package/bin/tezgah-decisions +6 -14
- package/bin/tezgah-design +21 -5
- package/bin/tezgah-docs +18 -16
- package/bin/tezgah-doctor +152 -0
- package/bin/tezgah-lessons +4 -1
- package/bin/tezgah-research +249 -17
- package/bin/tezgah-route +70 -8
- package/bin/tezgah-setup +26 -13
- package/bin/tezgah-task +877 -60
- package/bin/tezgah-taste +56 -15
- package/docs/architecture.md +28 -11
- package/docs/clarity-baseline.json +2 -2
- package/docs/contract.md +108 -24
- package/docs/environment.md +3 -1
- package/docs/evidence.md +209 -28
- package/docs/feature-audit.md +1 -1
- package/docs/gate.md +78 -23
- package/docs/glossary.md +4 -4
- package/docs/hosts.md +8 -8
- package/docs/index.json +11 -5
- package/docs/judge.md +9 -3
- package/docs/models.md +75 -14
- package/docs/operations.md +133 -3
- package/docs/research.md +349 -15
- package/docs/skills.md +1 -1
- package/docs/status-line.md +5 -5
- package/docs/testing.md +20 -13
- package/docs/vision.md +12 -4
- package/hooks/hooks.json +2 -2
- package/hooks/lang/en.json +323 -0
- package/hooks/lang/tr.json +344 -0
- package/hooks/projects-auto-init.py +29 -1
- package/hooks/projects-posttooluse.py +24 -5
- package/hooks/projects-pretooluse.py +9 -4
- package/hooks/projects-stop.py +28 -16
- package/hooks/tezgah_agents.py +53 -17
- package/hooks/tezgah_clarity.py +7 -3
- package/hooks/tezgah_context.py +489 -438
- package/hooks/tezgah_gate.py +996 -80
- package/hooks/tezgah_integrity.py +1547 -197
- package/hooks/tezgah_models.py +427 -45
- package/hooks/tezgah_paths.py +147 -16
- package/hooks/tezgah_policy.py +261 -129
- package/hooks/tezgah_rank.py +29 -27
- package/hooks/tezgah_replay.py +200 -30
- package/hooks/tezgah_research.py +1303 -14
- package/hooks/tezgah_stopspec.py +7 -0
- package/hooks/tezgah_store.py +74 -27
- package/hooks/tezgah_task.py +1201 -40
- package/hooks/tezgah_taste.py +8 -4
- package/hosts/codex/hook.py +32 -13
- package/hosts/cursor/hook.py +32 -14
- package/hosts/dsh/hooks.json +2 -2
- package/hosts/omp/hook.py +44 -23
- package/hosts/omp/tezgah-hook.ts.in +93 -7
- package/hosts/opencode/plugins/tezgah.js +273 -6
- package/output-styles/tezgah.md +76 -42
- package/package.json +1 -1
- package/skills/i-have-adhd/EVALS.md +22 -2
- package/skills/i-have-adhd/SKILL.md +12 -5
- package/skills/plan-add/SKILL.md +27 -11
- package/skills/plan-add/render_table.py +8 -3
- package/skills/plan-sync/SKILL.md +5 -3
- package/skills/ponytail/EVALS.md +21 -2
- package/skills/ponytail/SKILL.md +4 -4
- package/skills/research/SKILL.md +89 -1
- package/skills/tezgah-contract/EVALS.md +52 -7
- package/skills/tezgah-contract/SKILL.md +154 -59
package/hooks/tezgah_agents.py
CHANGED
|
@@ -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
|
|
225
|
-
"
|
|
226
|
-
"
|
|
227
|
-
"
|
|
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
|
|
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
|
|
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.
|
|
284
|
-
"
|
|
285
|
-
"
|
|
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.
|
|
423
|
-
"
|
|
424
|
-
"
|
|
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)
|
|
434
|
-
"
|
|
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 --
|
package/hooks/tezgah_clarity.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|