chore(tooling): T-1272 + T-1274 — close E3: no hyphens left, and the lint ignores come off

T-1272 (a verification, as rescoped). No directory Python imports carries a
hyphen any more. The hyphenated script trees were emptied by the per-domain
moves, not renamed. What still has a hyphen is never imported: the three Rust
crates, and the provenance under tooling/archive/, which has no __init__.py.
CLAUDE.md and DEVOPS still pointed at tooling/db/, and pyproject still
predicted the rename; all three fixed.

T-1274. E402, E702 and F841 were ignored for the whole tree from T-1066 on
(43 / 41 / 21 violations). All three are back on:

- E402: the planet modules' imports only sat below their path constants
  because they used to follow a sys.path insert, gone since T-1288. Hoisted.
  The Blender payloads keep a per-file exception, because they extend
  sys.path under Blender's own Python.
- E702: the paired component assignments in three planet maths files are
  deliberate, so they get a per-file exception scoped to those files.
- F841: 10 dead locals removed from live code, each checked for side effects
  first; logo_uv keeps its call, which creates the UV layer.
- tooling/archive/ is excluded: it is provenance, and "fixing" a one-shot
  falsifies the record of what actually ran.

Evidence the lint is real: violations fed through stdin fire in a domain
module, and E402 stays quiet only on a payload path. Evidence nothing moved:
globe renders are pixel-identical before and after for an oceanic, a frozen
and a gas-giant body, and the ledger edit was regenerated (stamp fresh,
generated_brands.toml unchanged).

One finding, noted in the code rather than fixed: planet_renderer computed an
oblate-spheroid ray scale and never used it, so `oblateness` shapes no globe.
Wiring it in would change every globe render; that is a decision to make
deliberately, not a lint fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 20:05:07 +02:00
co-authored by Claude Opus 5.5
parent 59b3fc4caa
commit 6fb0ba0e3d
17 changed files with 110 additions and 69 deletions
+15
View File
@@ -553,3 +553,18 @@ DONE 2026-09-23. reach atlas map data [--check] + reach atlas map svg, nested un
ARCHIVED, NOT PORTED: generate-star-map.py + star-map-seed.json + sculpt + tune (tooling/archive/map-bootstrap/). The generator unconditionally rewrites docs/design/star-map.json from an S-NNN-keyed seed, so re-running it would erase the GJ migration and every hand edit since. sculpt and tune operate only on S-NNN edges. .claude/rules/diagrams.md used to tell agents to "edit the generator and re-run it"; it now documents three cases: concentric SVG is a live render, the 7 sector d2 files are frozen S-keyed output (T-1294), and realcoords/topology SVGs have no generator at all.', NULL, '2026-09-23 17:59:58', '2026-09-23 17:59:58.221', '2026-09-23 17:59:58.221', NULL, 'fa1c80235ce06db1f459dae246ba37dc', 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 ('06GCYT8JBRCX13ZD51SY4SX1WW', 'status', 'backlog', 'done', NULL, '2026-09-23 17:59:58', '2026-09-23 17:59:58.641', '2026-09-23 17:59:58.641', NULL, '410fcc34e85dc80deb099cf6cb59a31f', 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 ('06G5FZCVZXH6M00C57EXMZD0SG', 'description', 'economy-db, garment-fit, garment-qa, planet-gen and pql-migrate are not importable — a hyphen is not a valid Python identifier — so nothing under them can be reached from the package. Rename to economy_db, garment_fit, garment_qa, planet_gen, pql_migrate (final names to be confirmed by the domain map, T-1271, which may fold some of them into a domain rather than keep them as top-level packages). NOT renamed, and this corrects the epic description: tooling/econ-sim, tooling/line-previewer and tooling/test-client are RUST crates — Cargo.toml plus src/, zero .py files. A hyphen only matters for something Python must import, so all three keep their names and simply stay outside package discovery. The epic named only econ-sim; the other two were found in the survey. Use git mv so history follows, and expect the blast radius to be wide: the Makefile references these paths in many targets, the pre-push hook runs tests from planet-gen and economy-db by path, tooling/generator_sources.py registers economy-db source paths for the systems.db stamp, and .claude/settings.json has per-path permission entries. Grep for each old name across Makefile, .config/hooks, .claude, docs and tooling itself before declaring done. VERIFY BY RUNNING, not by grepping: make test-tooling must pass, since it invokes planet-gen and economy-db tests directly and is the only thing that will actually prove the paths still resolve.
RESCOPED 2026-08-31 on picking up the epic — this is now a VERIFICATION, not a rename, and it runs last rather than first. The domain map (T-1271) empties all five hyphenated directories rather than renaming them: planet-gen becomes domains/planet, economy-db becomes domains/db, garment-fit is 22 Blender payloads plus one module so it splits between the carve-out and character, garment-qa goes to character, and pql-migrate moves to archive/ as provenance. Renaming each to an underscore form FIRST and then moving its contents would be two moves where one suffices, through an intermediate name that never appears in any commit anyone reads. So the deliverable becomes: after the per-domain ports land, confirm that no directory Python must import still carries a hyphen, and that nothing references the old paths — Makefile, .config/hooks, .claude, docs, tooling/generator_sources.py. The three Rust crates (econ-sim, line-previewer, test-client) keep their hyphens and are excluded from discovery; a hyphen only matters for something Python imports. Blocked on the per-domain ports rather than blocking them.', 'economy-db, garment-fit, garment-qa, planet-gen and pql-migrate are not importable — a hyphen is not a valid Python identifier — so nothing under them can be reached from the package. Rename to economy_db, garment_fit, garment_qa, planet_gen, pql_migrate (final names to be confirmed by the domain map, T-1271, which may fold some of them into a domain rather than keep them as top-level packages). NOT renamed, and this corrects the epic description: tooling/econ-sim, tooling/line-previewer and tooling/test-client are RUST crates — Cargo.toml plus src/, zero .py files. A hyphen only matters for something Python must import, so all three keep their names and simply stay outside package discovery. The epic named only econ-sim; the other two were found in the survey. Use git mv so history follows, and expect the blast radius to be wide: the Makefile references these paths in many targets, the pre-push hook runs tests from planet-gen and economy-db by path, tooling/generator_sources.py registers economy-db source paths for the systems.db stamp, and .claude/settings.json has per-path permission entries. Grep for each old name across Makefile, .config/hooks, .claude, docs and tooling itself before declaring done. VERIFY BY RUNNING, not by grepping: make test-tooling must pass, since it invokes planet-gen and economy-db tests directly and is the only thing that will actually prove the paths still resolve.
RESCOPED 2026-08-31 on picking up the epic — this is now a VERIFICATION, not a rename, and it runs last rather than first. The domain map (T-1271) empties all five hyphenated directories rather than renaming them: planet-gen becomes domains/planet, economy-db becomes domains/db, garment-fit is 22 Blender payloads plus one module so it splits between the carve-out and character, garment-qa goes to character, and pql-migrate moves to archive/ as provenance. Renaming each to an underscore form FIRST and then moving its contents would be two moves where one suffices, through an intermediate name that never appears in any commit anyone reads. So the deliverable becomes: after the per-domain ports land, confirm that no directory Python must import still carries a hyphen, and that nothing references the old paths — Makefile, .config/hooks, .claude, docs, tooling/generator_sources.py. The three Rust crates (econ-sim, line-previewer, test-client) keep their hyphens and are excluded from discovery; a hyphen only matters for something Python imports. Blocked on the per-domain ports rather than blocking them.
DONE 2026-09-23 (verification, as rescoped). No directory Python imports carries a hyphen. What still does: the three Rust crates (econ-sim, line-previewer, test-client) and the provenance subdirs of tooling/archive/, none of which has an __init__.py (checked), so package discovery cannot reach them. Stale path references fixed: CLAUDE.md and docs/DEVOPS.md still pointed asset connectors at tooling/db/; pyproject''s package-discovery comment still predicted a rename. Remaining mentions of the old names are deliberate "Formerly ..." provenance in module docstrings, legacy notes in the ticket-cli rule, and .cache/garment-qa output paths (a cache dir, not code). make test-tooling passes, which is the run-not-grep proof the ticket asked for.', NULL, '2026-09-23 18:04:57', '2026-09-23 18:04:57.393', '2026-09-23 18:04:57.393', NULL, '341beb7798caf26f2023116f77e48658', 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 ('06G5FZEM6JT5KKVE1RZ68DENSC', 'description', 'The ruff config currently ignores E402 (module-level import not at top of file), E702 (multiple statements on one line) and F841 (unused local variable). The E402 debt is script-style sys.path.insert-before-imports, which is exactly what a real package removes — so most of it should evaporate once files move under tooling/domains/ and import normally. Deliverable: after the moves land, re-enable E402 and fix or explicitly per-file-ignore whatever remains; then assess E702 and F841 on their own evidence rather than assuming they go the same way. Do this LAST in the epic, since running it mid-move means fixing violations in files that are about to move again. Note the honest possibility that E402 cannot be fully re-enabled: the Blender payloads (T-1273) may legitimately need sys.path manipulation before imports because they run under Blender''s bundled interpreter — if so, a per-file ignore scoped to tooling/scripts/blender/ is the right answer, not carrying a global ignore for the whole tree. A narrow documented exception is worth more than a broad silent one.', 'The ruff config currently ignores E402 (module-level import not at top of file), E702 (multiple statements on one line) and F841 (unused local variable). The E402 debt is script-style sys.path.insert-before-imports, which is exactly what a real package removes — so most of it should evaporate once files move under tooling/domains/ and import normally. Deliverable: after the moves land, re-enable E402 and fix or explicitly per-file-ignore whatever remains; then assess E702 and F841 on their own evidence rather than assuming they go the same way. Do this LAST in the epic, since running it mid-move means fixing violations in files that are about to move again. Note the honest possibility that E402 cannot be fully re-enabled: the Blender payloads (T-1273) may legitimately need sys.path manipulation before imports because they run under Blender''s bundled interpreter — if so, a per-file ignore scoped to tooling/scripts/blender/ is the right answer, not carrying a global ignore for the whole tree. A narrow documented exception is worth more than a broad silent one.
DONE 2026-09-23. E402, E702 and F841 re-enabled tree-wide (they were ignored for all of tooling/ since T-1066: 43/41/21). tooling/archive/ is excluded from lint: it is provenance that never runs, and a "fixed" one-shot stops being a record of what ran. Two narrow per-file exceptions, each documented in pyproject: E402 for tooling/scripts/blender/*.py (payloads extend sys.path under Blender''s Python), and E702 for the three planet maths files, where paired component assignments are deliberate. Both proven: violations fed via stdin fire in a domain module, and E402 does not fire for a payload path.
E402: the planet modules'' late imports hoisted. They only sat low because they used to follow a sys.path insert (gone since T-1288).
F841: 10 dead locals removed from live code, each checked for side effects. logo_uv keeps its call, since creating the UV layer IS the effect. One FINDING, left as a note: planet_renderer computed an oblate-spheroid ray scale and never used it, so `oblateness` does not shape any globe. Wiring it in would change every globe render, so that is a decision for later, not a lint fix. Globe renders were checked pixel-identical before/after for an oceanic, a frozen and a gas-giant body. The one ledger edit (specialization.py) is a stamped source: regen run, stamp fresh, generated_brands.toml unchanged.', NULL, '2026-09-23 18:04:57', '2026-09-23 18:04:57.989', '2026-09-23 18:04:57.989', NULL, '3872d462d93fc083a89ea7995aa4a92f', 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 ('06G5FZCVZXH6M00C57EXMZD0SG', 'status', 'backlog', 'done', NULL, '2026-09-23 18:04:58', '2026-09-23 18:04:58.465', '2026-09-23 18:04:58.465', NULL, '0193b698d7a17d0fb079832ba05810ce', 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 ('06G5FZEM6JT5KKVE1RZ68DENSC', 'status', 'backlog', 'done', NULL, '2026-09-23 18:04:58', '2026-09-23 18:04:58.472', '2026-09-23 18:04:58.472', NULL, 'ce88f7efd90155d73670ce9c27d47b2c', 2) ON CONFLICT(hash) DO NOTHING;
+22
View File
@@ -688,3 +688,25 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
DONE 2026-09-23. reach atlas map data [--check] + reach atlas map svg, nested under atlas like planet. Parity: star_map_data.json regenerates with a ONE-LINE diff, the _meta.note that named the old script path; the SVG is byte-identical to the old script''s output on the same data (the committed SVG itself is stale vs current data, T-1294). make check-star-map / star-map-data kept as one-line delegates because pre-pr-client and pre-pr-validate depend on check-star-map.
ARCHIVED, NOT PORTED: generate-star-map.py + star-map-seed.json + sculpt + tune (tooling/archive/map-bootstrap/). The generator unconditionally rewrites docs/design/star-map.json from an S-NNN-keyed seed, so re-running it would erase the GJ migration and every hand edit since. sculpt and tune operate only on S-NNN edges. .claude/rules/diagrams.md used to tell agents to "edit the generator and re-run it"; it now documents three cases: concentric SVG is a live render, the 7 sector d2 files are frozen S-keyed output (T-1294), and realcoords/topology SVGs have no generator at all.', 'done', 'medium', NULL, 'tooling', 'D-263', '2026-09-23 17:56:04.830', '2026-09-23 17:59:58.640', NULL, '030333d5dbd367b41dd9429c17ca3ac2', 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 ('06G5FZCVZXH6M00C57EXMZD0SG', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Verify no hyphenated Python directory survives the moves', 'economy-db, garment-fit, garment-qa, planet-gen and pql-migrate are not importable — a hyphen is not a valid Python identifier — so nothing under them can be reached from the package. Rename to economy_db, garment_fit, garment_qa, planet_gen, pql_migrate (final names to be confirmed by the domain map, T-1271, which may fold some of them into a domain rather than keep them as top-level packages). NOT renamed, and this corrects the epic description: tooling/econ-sim, tooling/line-previewer and tooling/test-client are RUST crates — Cargo.toml plus src/, zero .py files. A hyphen only matters for something Python must import, so all three keep their names and simply stay outside package discovery. The epic named only econ-sim; the other two were found in the survey. Use git mv so history follows, and expect the blast radius to be wide: the Makefile references these paths in many targets, the pre-push hook runs tests from planet-gen and economy-db by path, tooling/generator_sources.py registers economy-db source paths for the systems.db stamp, and .claude/settings.json has per-path permission entries. Grep for each old name across Makefile, .config/hooks, .claude, docs and tooling itself before declaring done. VERIFY BY RUNNING, not by grepping: make test-tooling must pass, since it invokes planet-gen and economy-db tests directly and is the only thing that will actually prove the paths still resolve.
RESCOPED 2026-08-31 on picking up the epic — this is now a VERIFICATION, not a rename, and it runs last rather than first. The domain map (T-1271) empties all five hyphenated directories rather than renaming them: planet-gen becomes domains/planet, economy-db becomes domains/db, garment-fit is 22 Blender payloads plus one module so it splits between the carve-out and character, garment-qa goes to character, and pql-migrate moves to archive/ as provenance. Renaming each to an underscore form FIRST and then moving its contents would be two moves where one suffices, through an intermediate name that never appears in any commit anyone reads. So the deliverable becomes: after the per-domain ports land, confirm that no directory Python must import still carries a hyphen, and that nothing references the old paths — Makefile, .config/hooks, .claude, docs, tooling/generator_sources.py. The three Rust crates (econ-sim, line-previewer, test-client) keep their hyphens and are excluded from discovery; a hyphen only matters for something Python imports. Blocked on the per-domain ports rather than blocking them.
DONE 2026-09-23 (verification, as rescoped). No directory Python imports carries a hyphen. What still does: the three Rust crates (econ-sim, line-previewer, test-client) and the provenance subdirs of tooling/archive/, none of which has an __init__.py (checked), so package discovery cannot reach them. Stale path references fixed: CLAUDE.md and docs/DEVOPS.md still pointed asset connectors at tooling/db/; pyproject''s package-discovery comment still predicted a rename. Remaining mentions of the old names are deliberate "Formerly ..." provenance in module docstrings, legacy notes in the ticket-cli rule, and .cache/garment-qa output paths (a cache dir, not code). make test-tooling passes, which is the run-not-grep proof the ticket asked for.', 'backlog', 'high', NULL, NULL, 'D-263', '2026-08-31 13:23:53.471', '2026-09-23 18:04:57.393', NULL, '37caf488cc64c19db6f3389aa2699d59', 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 ('06G5FZEM6JT5KKVE1RZ68DENSC', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Retire the ruff ignores the package makes unnecessary', 'The ruff config currently ignores E402 (module-level import not at top of file), E702 (multiple statements on one line) and F841 (unused local variable). The E402 debt is script-style sys.path.insert-before-imports, which is exactly what a real package removes — so most of it should evaporate once files move under tooling/domains/ and import normally. Deliverable: after the moves land, re-enable E402 and fix or explicitly per-file-ignore whatever remains; then assess E702 and F841 on their own evidence rather than assuming they go the same way. Do this LAST in the epic, since running it mid-move means fixing violations in files that are about to move again. Note the honest possibility that E402 cannot be fully re-enabled: the Blender payloads (T-1273) may legitimately need sys.path manipulation before imports because they run under Blender''s bundled interpreter — if so, a per-file ignore scoped to tooling/scripts/blender/ is the right answer, not carrying a global ignore for the whole tree. A narrow documented exception is worth more than a broad silent one.
DONE 2026-09-23. E402, E702 and F841 re-enabled tree-wide (they were ignored for all of tooling/ since T-1066: 43/41/21). tooling/archive/ is excluded from lint: it is provenance that never runs, and a "fixed" one-shot stops being a record of what ran. Two narrow per-file exceptions, each documented in pyproject: E402 for tooling/scripts/blender/*.py (payloads extend sys.path under Blender''s Python), and E702 for the three planet maths files, where paired component assignments are deliberate. Both proven: violations fed via stdin fire in a domain module, and E402 does not fire for a payload path.
E402: the planet modules'' late imports hoisted. They only sat low because they used to follow a sys.path insert (gone since T-1288).
F841: 10 dead locals removed from live code, each checked for side effects. logo_uv keeps its call, since creating the UV layer IS the effect. One FINDING, left as a note: planet_renderer computed an oblate-spheroid ray scale and never used it, so `oblateness` does not shape any globe. Wiring it in would change every globe render, so that is a decision for later, not a lint fix. Globe renders were checked pixel-identical before/after for an oceanic, a frozen and a gas-giant body. The one ledger edit (specialization.py) is a stamped source: regen run, stamp fresh, generated_brands.toml unchanged.', 'backlog', 'low', NULL, NULL, 'D-263', '2026-08-31 13:24:07.860', '2026-09-23 18:04:57.989', NULL, '778edc1e9a5f0864f993c1d5d5d1ba8f', 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 ('06G5FZCVZXH6M00C57EXMZD0SG', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Verify no hyphenated Python directory survives the moves', 'economy-db, garment-fit, garment-qa, planet-gen and pql-migrate are not importable — a hyphen is not a valid Python identifier — so nothing under them can be reached from the package. Rename to economy_db, garment_fit, garment_qa, planet_gen, pql_migrate (final names to be confirmed by the domain map, T-1271, which may fold some of them into a domain rather than keep them as top-level packages). NOT renamed, and this corrects the epic description: tooling/econ-sim, tooling/line-previewer and tooling/test-client are RUST crates — Cargo.toml plus src/, zero .py files. A hyphen only matters for something Python must import, so all three keep their names and simply stay outside package discovery. The epic named only econ-sim; the other two were found in the survey. Use git mv so history follows, and expect the blast radius to be wide: the Makefile references these paths in many targets, the pre-push hook runs tests from planet-gen and economy-db by path, tooling/generator_sources.py registers economy-db source paths for the systems.db stamp, and .claude/settings.json has per-path permission entries. Grep for each old name across Makefile, .config/hooks, .claude, docs and tooling itself before declaring done. VERIFY BY RUNNING, not by grepping: make test-tooling must pass, since it invokes planet-gen and economy-db tests directly and is the only thing that will actually prove the paths still resolve.
RESCOPED 2026-08-31 on picking up the epic — this is now a VERIFICATION, not a rename, and it runs last rather than first. The domain map (T-1271) empties all five hyphenated directories rather than renaming them: planet-gen becomes domains/planet, economy-db becomes domains/db, garment-fit is 22 Blender payloads plus one module so it splits between the carve-out and character, garment-qa goes to character, and pql-migrate moves to archive/ as provenance. Renaming each to an underscore form FIRST and then moving its contents would be two moves where one suffices, through an intermediate name that never appears in any commit anyone reads. So the deliverable becomes: after the per-domain ports land, confirm that no directory Python must import still carries a hyphen, and that nothing references the old paths — Makefile, .config/hooks, .claude, docs, tooling/generator_sources.py. The three Rust crates (econ-sim, line-previewer, test-client) keep their hyphens and are excluded from discovery; a hyphen only matters for something Python imports. Blocked on the per-domain ports rather than blocking them.
DONE 2026-09-23 (verification, as rescoped). No directory Python imports carries a hyphen. What still does: the three Rust crates (econ-sim, line-previewer, test-client) and the provenance subdirs of tooling/archive/, none of which has an __init__.py (checked), so package discovery cannot reach them. Stale path references fixed: CLAUDE.md and docs/DEVOPS.md still pointed asset connectors at tooling/db/; pyproject''s package-discovery comment still predicted a rename. Remaining mentions of the old names are deliberate "Formerly ..." provenance in module docstrings, legacy notes in the ticket-cli rule, and .cache/garment-qa output paths (a cache dir, not code). make test-tooling passes, which is the run-not-grep proof the ticket asked for.', 'done', 'high', NULL, NULL, 'D-263', '2026-08-31 13:23:53.471', '2026-09-23 18:04:58.465', NULL, 'fb95d8dc691d821950d0116becbaaef2', 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 ('06G5FZEM6JT5KKVE1RZ68DENSC', 'task', '06G1S3D0M1TQW0GMFBBPQZG3ZM', 'Retire the ruff ignores the package makes unnecessary', 'The ruff config currently ignores E402 (module-level import not at top of file), E702 (multiple statements on one line) and F841 (unused local variable). The E402 debt is script-style sys.path.insert-before-imports, which is exactly what a real package removes — so most of it should evaporate once files move under tooling/domains/ and import normally. Deliverable: after the moves land, re-enable E402 and fix or explicitly per-file-ignore whatever remains; then assess E702 and F841 on their own evidence rather than assuming they go the same way. Do this LAST in the epic, since running it mid-move means fixing violations in files that are about to move again. Note the honest possibility that E402 cannot be fully re-enabled: the Blender payloads (T-1273) may legitimately need sys.path manipulation before imports because they run under Blender''s bundled interpreter — if so, a per-file ignore scoped to tooling/scripts/blender/ is the right answer, not carrying a global ignore for the whole tree. A narrow documented exception is worth more than a broad silent one.
DONE 2026-09-23. E402, E702 and F841 re-enabled tree-wide (they were ignored for all of tooling/ since T-1066: 43/41/21). tooling/archive/ is excluded from lint: it is provenance that never runs, and a "fixed" one-shot stops being a record of what ran. Two narrow per-file exceptions, each documented in pyproject: E402 for tooling/scripts/blender/*.py (payloads extend sys.path under Blender''s Python), and E702 for the three planet maths files, where paired component assignments are deliberate. Both proven: violations fed via stdin fire in a domain module, and E402 does not fire for a payload path.
E402: the planet modules'' late imports hoisted. They only sat low because they used to follow a sys.path insert (gone since T-1288).
F841: 10 dead locals removed from live code, each checked for side effects. logo_uv keeps its call, since creating the UV layer IS the effect. One FINDING, left as a note: planet_renderer computed an oblate-spheroid ray scale and never used it, so `oblateness` does not shape any globe. Wiring it in would change every globe render, so that is a decision for later, not a lint fix. Globe renders were checked pixel-identical before/after for an oceanic, a frozen and a gas-giant body. The one ledger edit (specialization.py) is a stamped source: regen run, stamp fresh, generated_brands.toml unchanged.', 'done', 'low', NULL, NULL, 'D-263', '2026-08-31 13:24:07.860', '2026-09-23 18:04:58.472', NULL, 'b2db3b5f93dd2d2f04a4981bb30a2813', 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;