refactor(tooling): T-1286 — generate, pr and dev become reach domains
Twelve scripts retired, three domains registered. `reach` now covers nine. generate: `generate-brands` and `generate-corporations` were the second and third copies of the same 24-line build-if-missing-then-exec bash `tooling/atlas` carried, so they collapsed into `core.process.cargo_binary` rather than being ported. `import_economics` shelled out to the first of those, so it now calls that helper — `generated_brands.toml` comes back byte-identical, and the stamp registry swaps the retired wrapper for `core/process.py`. pr: `watchlist-diff` derives its watched set from `generator_sources.py` instead of restating it, so it cannot drift from the stamp check. dev: the environment scripts split decision from performing, per D-263's guarded-exec rule. `godot_plan()` and `worktree_plan()` decide what would happen; `install_godot()`, `install_rust()` and `setup_worktree()` do it. `tooling/test_environment.py` pins the version pin, both override precedences, the already-current skip, the platform refusal and both worktree refusals — none of them performed. `make setup` now installs reach first, since the targets that install rust and godot are reach verbs. Two live bugs found while porting: - The clerk read its decision index from `decisions/README.md`, a path that stopped existing when the DQR tree moved to `governance/`. Every clerk agent has been grepping blind; its prompt pointed at the same dead directory. - The conformance exec-check matched any `x.system()` regardless of receiver, so `platform.system()` read as `os.system()`. Narrowed and re-proved against a real mutant. `process.run` gains `input=`, `timeout=` and a `ProcessTimeout` subclass so a killed run stays distinguishable from a verdict. The pre-push hook no longer merges the clerk's stderr into its stdout — under streaming the last merged line is a JSONL event, which would read as an unrecognised verdict and block. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,3 +66,57 @@ ALSO CAUGHT: update_field now checks rowcount and fails when no row matched. The
|
||||
|
||||
THE THREE PYTHON SCRIPTS moved with the usual treatment: prints to console events, argparse mains replaced by typed functions the router calls, __file__-relative roots to config.repo_root(). No root bug this time — checked before moving rather than after, which is the third domain running.', NULL, '2026-09-02 12:36:36', '2026-09-02 12:36:36.194', '2026-09-02 12:36:36.194', NULL, 'd804c766e461d4aaf6cdf4d8d1157125', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G642RKW8PNW7AP9BY9203SPG', 'status', 'in_progress', 'done', NULL, '2026-09-02 12:36:36', '2026-09-02 12:36:36.208', '2026-09-02 12:36:36.208', NULL, '8aa91d6e9cacaaa410b20ef6cf9703b9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'description', 'Twelve small files, three domains, no ladder entanglement — deliberately batched to clear the tail before the two large ports (atlas planet, ledger). GENERATE: generate-brands (bash 23, wraps the Rust generate_brands binary), generate-corporations (bash 23), generate-character-manifest (py 111), generate_corp_stubs.py (py 413). PR: tea-comment (bash 41), pr-watchlist-diff (bash 37), pql-board-html (py). DEV, joining the existing selftest verb: install-rust (bash 33), install-godot (bash 108), worktree-setup (bash 49), perf-baseline (py), clerk-review (py). Standard port acceptance as on T-1281. SEVEN OF THE TWELVE ARE BASH so those are rewrites. THE THREE ENVIRONMENT SCRIPTS need the D-263 guarded-exec treatment specifically: install-godot downloads and unzips a pinned Godot build, install-rust drives rustup, worktree-setup manipulates git worktrees — port the DECISION logic (which version is wanted, is it already present, what does the tree look like) into a testable service and keep the irreducible external calls behind core/process.run. The test of a correct port is whether the decisions can be exercised WITHOUT performing them; a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. WATCH tea-comment: .claude/rules/tea-cli.md says tea prompts crash in Claude Code with no TTY and that tooling/tea-comment exists specifically to avoid subshells breaking permission matching — preserve both properties, and pass --no-input through.', 'Twelve small files, three domains, no ladder entanglement — deliberately batched to clear the tail before the two large ports (atlas planet, ledger). GENERATE: generate-brands (bash 23, wraps the Rust generate_brands binary), generate-corporations (bash 23), generate-character-manifest (py 111), generate_corp_stubs.py (py 413). PR: tea-comment (bash 41), pr-watchlist-diff (bash 37), pql-board-html (py). DEV, joining the existing selftest verb: install-rust (bash 33), install-godot (bash 108), worktree-setup (bash 49), perf-baseline (py), clerk-review (py). Standard port acceptance as on T-1281. SEVEN OF THE TWELVE ARE BASH so those are rewrites. THE THREE ENVIRONMENT SCRIPTS need the D-263 guarded-exec treatment specifically: install-godot downloads and unzips a pinned Godot build, install-rust drives rustup, worktree-setup manipulates git worktrees — port the DECISION logic (which version is wanted, is it already present, what does the tree look like) into a testable service and keep the irreducible external calls behind core/process.run. The test of a correct port is whether the decisions can be exercised WITHOUT performing them; a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. WATCH tea-comment: .claude/rules/tea-cli.md says tea prompts crash in Claude Code with no TTY and that tooling/tea-comment exists specifically to avoid subshells breaking permission matching — preserve both properties, and pass --no-input through.
|
||||
|
||||
Ported. `generate`, `pr` and `dev` are registered; 12 scripts retired.
|
||||
|
||||
**generate** — `generate-brands` and `generate-corporations` were the *third*
|
||||
and second copies of the same 24-line build-if-missing-then-exec bash that
|
||||
`tooling/atlas` carried, so both collapsed into `core.process.cargo_binary`
|
||||
rather than being ported. `generate-character-manifest` and
|
||||
`generate_corp_stubs.py` moved as modules; both had `__file__`-relative roots
|
||||
that break on move (the fourth and fifth instances of that trap this epic) and
|
||||
now use `config.repo_root()`.
|
||||
|
||||
**pr** — `watchlist-diff` now derives its watched set from
|
||||
`generator_sources.GENERATOR_SOURCES` instead of restating it, so it cannot
|
||||
drift from the stamp check (185 registered paths + 5 non-stamped extras).
|
||||
Verified with a positive control: silent on a commit touching only a test file,
|
||||
reports `economy_import/atlas.py` + `import_economics.py` on 8da9670e0.
|
||||
|
||||
**dev** — the risky third. Split per the ticket''s own test: `godot_plan()` and
|
||||
`worktree_plan()` are pure and decide *what would happen*; `install_godot()`,
|
||||
`install_rust()` and `setup_worktree()` perform it. `tooling/test_environment.py`
|
||||
pins the version pin, the `--version` and `GODOT_VERSION` precedence, the
|
||||
already-current skip decision, the unsupported-platform refusal, and both
|
||||
worktree refusals — none of them performed. Every assertion was mutation-checked.
|
||||
|
||||
## Found while porting
|
||||
|
||||
1. **`make regen-db` was about to break.** `import_economics` shells out to
|
||||
`tooling/generate-brands`, which this ticket deleted. Rerouted through
|
||||
`cargo_binary`; `generated_brands.toml` came back byte-identical, and the
|
||||
stamp registry swapped the retired wrapper for `core/process.py`. Regen run,
|
||||
stamp fresh.
|
||||
2. **The clerk has been grepping a directory that does not exist.** `load_index()`
|
||||
read `decisions/README.md`; the DQR tree moved to `governance/` long ago, so
|
||||
every clerk agent got "(not found)" as its domain index. The prompt told it to
|
||||
grep `decisions/*.md` too. Both fixed. (Clerk is disabled by default per #965,
|
||||
so this cost nothing yet — but it would have been invisible on re-enable.)
|
||||
3. **The conformance exec-check fired on the wrong receiver.** It matched any
|
||||
`x.system()`, so `platform.system()` read as `os.system()`. Narrowed to an
|
||||
`os` receiver and re-proved against a real `os.system` mutant.
|
||||
4. **The committed character manifest was stale** — it predates the 24-garment
|
||||
wardrobe. Confirmed the port is not the cause: the original script, run from
|
||||
its own directory, produces the identical new output. Regenerated.
|
||||
5. **`make setup` had a bootstrap-order problem** once `setup-rust`/`setup-godot`
|
||||
became reach verbs — they ran before `install-reach`. `install-reach` needs
|
||||
only `uv`, so it now leads the chain.
|
||||
6. `process.run` gained `input=` and `timeout=` (the clerk needs both) plus a
|
||||
`ProcessTimeout` subclass, so a killed run is distinguishable from a verdict.
|
||||
The pre-push hook''s clerk capture no longer merges stderr into stdout — under
|
||||
streaming the last merged line is a JSONL event, which would have read as an
|
||||
unrecognised verdict and blocked the push.
|
||||
|
||||
Gate: `ruff check tooling/` clean, `make test-tooling` PASS (12 checks).', NULL, '2026-09-02 14:54:35', '2026-09-02 14:54:35.578', '2026-09-02 14:54:35.578', NULL, 'e0bd8f1d16b2dc7c7d1b8b1511633cc3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'status', 'backlog', 'done', NULL, '2026-09-02 14:54:37', '2026-09-02 14:54:37.762', '2026-09-02 14:54:37.762', NULL, '5f9240c61aa2bf03924e4edaf4dd6f7c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G63FEA51J4JKE3A7473D3QZ0', 'T-1284', '2026-09-02 10:50:23.145', '2026-09-02 10:50:23.145', NULL, '74113524e3a280bd06875305a547349a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G642RKW8PNW7AP9BY9203SPG', 'T-1285', '2026-09-02 12:14:48.290', '2026-09-02 12:14:48.290', NULL, '020f491d1ae8fbde83d2aae0f8325011', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'T-1286', '2026-09-02 12:49:55.434', '2026-09-02 12:49:55.434', NULL, '7c65442cc261176c9c472fdbd635cc91', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
|
||||
@@ -122,3 +122,110 @@ UPDATE-FIELD ported with the asset-pipeline distinction in its help, per the pre
|
||||
ALSO CAUGHT: update_field now checks rowcount and fails when no row matched. The original''s SQL would succeed silently against a system_id that does not exist — a no-op reported as success, which is the exact shape of failure this initiative keeps finding.
|
||||
|
||||
THE THREE PYTHON SCRIPTS moved with the usual treatment: prints to console events, argparse mains replaced by typed functions the router calls, __file__-relative roots to config.repo_root(). No root bug this time — checked before moving rather than after, which is the third domain running.', 'done', 'high', NULL, NULL, 'D-263', '2026-09-02 12:14:48.290', '2026-09-02 12:36:36.208', NULL, '6eff7972f7304c334f347ae8598bdf6b', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Port generate, pr, and the rest of dev', 'Twelve small files, three domains, no ladder entanglement — deliberately batched to clear the tail before the two large ports (atlas planet, ledger). GENERATE: generate-brands (bash 23, wraps the Rust generate_brands binary), generate-corporations (bash 23), generate-character-manifest (py 111), generate_corp_stubs.py (py 413). PR: tea-comment (bash 41), pr-watchlist-diff (bash 37), pql-board-html (py). DEV, joining the existing selftest verb: install-rust (bash 33), install-godot (bash 108), worktree-setup (bash 49), perf-baseline (py), clerk-review (py). Standard port acceptance as on T-1281. SEVEN OF THE TWELVE ARE BASH so those are rewrites. THE THREE ENVIRONMENT SCRIPTS need the D-263 guarded-exec treatment specifically: install-godot downloads and unzips a pinned Godot build, install-rust drives rustup, worktree-setup manipulates git worktrees — port the DECISION logic (which version is wanted, is it already present, what does the tree look like) into a testable service and keep the irreducible external calls behind core/process.run. The test of a correct port is whether the decisions can be exercised WITHOUT performing them; a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. WATCH tea-comment: .claude/rules/tea-cli.md says tea prompts crash in Claude Code with no TTY and that tooling/tea-comment exists specifically to avoid subshells breaking permission matching — preserve both properties, and pass --no-input through.', 'backlog', 'medium', NULL, NULL, 'D-263', '2026-09-02 12:49:55.434', '2026-09-02 12:49:55.434', NULL, '5676581f3cae08432c174d73b39a8cd5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Port generate, pr, and the rest of dev', 'Twelve small files, three domains, no ladder entanglement — deliberately batched to clear the tail before the two large ports (atlas planet, ledger). GENERATE: generate-brands (bash 23, wraps the Rust generate_brands binary), generate-corporations (bash 23), generate-character-manifest (py 111), generate_corp_stubs.py (py 413). PR: tea-comment (bash 41), pr-watchlist-diff (bash 37), pql-board-html (py). DEV, joining the existing selftest verb: install-rust (bash 33), install-godot (bash 108), worktree-setup (bash 49), perf-baseline (py), clerk-review (py). Standard port acceptance as on T-1281. SEVEN OF THE TWELVE ARE BASH so those are rewrites. THE THREE ENVIRONMENT SCRIPTS need the D-263 guarded-exec treatment specifically: install-godot downloads and unzips a pinned Godot build, install-rust drives rustup, worktree-setup manipulates git worktrees — port the DECISION logic (which version is wanted, is it already present, what does the tree look like) into a testable service and keep the irreducible external calls behind core/process.run. The test of a correct port is whether the decisions can be exercised WITHOUT performing them; a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. WATCH tea-comment: .claude/rules/tea-cli.md says tea prompts crash in Claude Code with no TTY and that tooling/tea-comment exists specifically to avoid subshells breaking permission matching — preserve both properties, and pass --no-input through.
|
||||
|
||||
Ported. `generate`, `pr` and `dev` are registered; 12 scripts retired.
|
||||
|
||||
**generate** — `generate-brands` and `generate-corporations` were the *third*
|
||||
and second copies of the same 24-line build-if-missing-then-exec bash that
|
||||
`tooling/atlas` carried, so both collapsed into `core.process.cargo_binary`
|
||||
rather than being ported. `generate-character-manifest` and
|
||||
`generate_corp_stubs.py` moved as modules; both had `__file__`-relative roots
|
||||
that break on move (the fourth and fifth instances of that trap this epic) and
|
||||
now use `config.repo_root()`.
|
||||
|
||||
**pr** — `watchlist-diff` now derives its watched set from
|
||||
`generator_sources.GENERATOR_SOURCES` instead of restating it, so it cannot
|
||||
drift from the stamp check (185 registered paths + 5 non-stamped extras).
|
||||
Verified with a positive control: silent on a commit touching only a test file,
|
||||
reports `economy_import/atlas.py` + `import_economics.py` on 8da9670e0.
|
||||
|
||||
**dev** — the risky third. Split per the ticket''s own test: `godot_plan()` and
|
||||
`worktree_plan()` are pure and decide *what would happen*; `install_godot()`,
|
||||
`install_rust()` and `setup_worktree()` perform it. `tooling/test_environment.py`
|
||||
pins the version pin, the `--version` and `GODOT_VERSION` precedence, the
|
||||
already-current skip decision, the unsupported-platform refusal, and both
|
||||
worktree refusals — none of them performed. Every assertion was mutation-checked.
|
||||
|
||||
## Found while porting
|
||||
|
||||
1. **`make regen-db` was about to break.** `import_economics` shells out to
|
||||
`tooling/generate-brands`, which this ticket deleted. Rerouted through
|
||||
`cargo_binary`; `generated_brands.toml` came back byte-identical, and the
|
||||
stamp registry swapped the retired wrapper for `core/process.py`. Regen run,
|
||||
stamp fresh.
|
||||
2. **The clerk has been grepping a directory that does not exist.** `load_index()`
|
||||
read `decisions/README.md`; the DQR tree moved to `governance/` long ago, so
|
||||
every clerk agent got "(not found)" as its domain index. The prompt told it to
|
||||
grep `decisions/*.md` too. Both fixed. (Clerk is disabled by default per #965,
|
||||
so this cost nothing yet — but it would have been invisible on re-enable.)
|
||||
3. **The conformance exec-check fired on the wrong receiver.** It matched any
|
||||
`x.system()`, so `platform.system()` read as `os.system()`. Narrowed to an
|
||||
`os` receiver and re-proved against a real `os.system` mutant.
|
||||
4. **The committed character manifest was stale** — it predates the 24-garment
|
||||
wardrobe. Confirmed the port is not the cause: the original script, run from
|
||||
its own directory, produces the identical new output. Regenerated.
|
||||
5. **`make setup` had a bootstrap-order problem** once `setup-rust`/`setup-godot`
|
||||
became reach verbs — they ran before `install-reach`. `install-reach` needs
|
||||
only `uv`, so it now leads the chain.
|
||||
6. `process.run` gained `input=` and `timeout=` (the clerk needs both) plus a
|
||||
`ProcessTimeout` subclass, so a killed run is distinguishable from a verdict.
|
||||
The pre-push hook''s clerk capture no longer merges stderr into stdout — under
|
||||
streaming the last merged line is a JSONL event, which would have read as an
|
||||
unrecognised verdict and blocked the push.
|
||||
|
||||
Gate: `ruff check tooling/` clean, `make test-tooling` PASS (12 checks).', 'backlog', 'medium', NULL, NULL, 'D-263', '2026-09-02 12:49:55.434', '2026-09-02 14:54:35.577', NULL, 'c010e2f8bdc2cfe4843926351d87c6bb', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Port generate, pr, and the rest of dev', 'Twelve small files, three domains, no ladder entanglement — deliberately batched to clear the tail before the two large ports (atlas planet, ledger). GENERATE: generate-brands (bash 23, wraps the Rust generate_brands binary), generate-corporations (bash 23), generate-character-manifest (py 111), generate_corp_stubs.py (py 413). PR: tea-comment (bash 41), pr-watchlist-diff (bash 37), pql-board-html (py). DEV, joining the existing selftest verb: install-rust (bash 33), install-godot (bash 108), worktree-setup (bash 49), perf-baseline (py), clerk-review (py). Standard port acceptance as on T-1281. SEVEN OF THE TWELVE ARE BASH so those are rewrites. THE THREE ENVIRONMENT SCRIPTS need the D-263 guarded-exec treatment specifically: install-godot downloads and unzips a pinned Godot build, install-rust drives rustup, worktree-setup manipulates git worktrees — port the DECISION logic (which version is wanted, is it already present, what does the tree look like) into a testable service and keep the irreducible external calls behind core/process.run. The test of a correct port is whether the decisions can be exercised WITHOUT performing them; a rewrite that cannot be tested has to be trusted instead, and trusting an installer is how a working environment becomes an unreproducible one. WATCH tea-comment: .claude/rules/tea-cli.md says tea prompts crash in Claude Code with no TTY and that tooling/tea-comment exists specifically to avoid subshells breaking permission matching — preserve both properties, and pass --no-input through.
|
||||
|
||||
Ported. `generate`, `pr` and `dev` are registered; 12 scripts retired.
|
||||
|
||||
**generate** — `generate-brands` and `generate-corporations` were the *third*
|
||||
and second copies of the same 24-line build-if-missing-then-exec bash that
|
||||
`tooling/atlas` carried, so both collapsed into `core.process.cargo_binary`
|
||||
rather than being ported. `generate-character-manifest` and
|
||||
`generate_corp_stubs.py` moved as modules; both had `__file__`-relative roots
|
||||
that break on move (the fourth and fifth instances of that trap this epic) and
|
||||
now use `config.repo_root()`.
|
||||
|
||||
**pr** — `watchlist-diff` now derives its watched set from
|
||||
`generator_sources.GENERATOR_SOURCES` instead of restating it, so it cannot
|
||||
drift from the stamp check (185 registered paths + 5 non-stamped extras).
|
||||
Verified with a positive control: silent on a commit touching only a test file,
|
||||
reports `economy_import/atlas.py` + `import_economics.py` on 8da9670e0.
|
||||
|
||||
**dev** — the risky third. Split per the ticket''s own test: `godot_plan()` and
|
||||
`worktree_plan()` are pure and decide *what would happen*; `install_godot()`,
|
||||
`install_rust()` and `setup_worktree()` perform it. `tooling/test_environment.py`
|
||||
pins the version pin, the `--version` and `GODOT_VERSION` precedence, the
|
||||
already-current skip decision, the unsupported-platform refusal, and both
|
||||
worktree refusals — none of them performed. Every assertion was mutation-checked.
|
||||
|
||||
## Found while porting
|
||||
|
||||
1. **`make regen-db` was about to break.** `import_economics` shells out to
|
||||
`tooling/generate-brands`, which this ticket deleted. Rerouted through
|
||||
`cargo_binary`; `generated_brands.toml` came back byte-identical, and the
|
||||
stamp registry swapped the retired wrapper for `core/process.py`. Regen run,
|
||||
stamp fresh.
|
||||
2. **The clerk has been grepping a directory that does not exist.** `load_index()`
|
||||
read `decisions/README.md`; the DQR tree moved to `governance/` long ago, so
|
||||
every clerk agent got "(not found)" as its domain index. The prompt told it to
|
||||
grep `decisions/*.md` too. Both fixed. (Clerk is disabled by default per #965,
|
||||
so this cost nothing yet — but it would have been invisible on re-enable.)
|
||||
3. **The conformance exec-check fired on the wrong receiver.** It matched any
|
||||
`x.system()`, so `platform.system()` read as `os.system()`. Narrowed to an
|
||||
`os` receiver and re-proved against a real `os.system` mutant.
|
||||
4. **The committed character manifest was stale** — it predates the 24-garment
|
||||
wardrobe. Confirmed the port is not the cause: the original script, run from
|
||||
its own directory, produces the identical new output. Regenerated.
|
||||
5. **`make setup` had a bootstrap-order problem** once `setup-rust`/`setup-godot`
|
||||
became reach verbs — they ran before `install-reach`. `install-reach` needs
|
||||
only `uv`, so it now leads the chain.
|
||||
6. `process.run` gained `input=` and `timeout=` (the clerk needs both) plus a
|
||||
`ProcessTimeout` subclass, so a killed run is distinguishable from a verdict.
|
||||
The pre-push hook''s clerk capture no longer merges stderr into stdout — under
|
||||
streaming the last merged line is a JSONL event, which would have read as an
|
||||
unrecognised verdict and blocked the push.
|
||||
|
||||
Gate: `ruff check tooling/` clean, `make test-tooling` PASS (12 checks).', 'done', 'medium', NULL, NULL, 'D-263', '2026-09-02 12:49:55.434', '2026-09-02 14:54:37.762', NULL, '678c0d0578c2255438d2e51829d87a64', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
|
||||
Reference in New Issue
Block a user