Orchestrata Ultimate › Plans › briefs › t17-gen-constants-registry

T17-GEN — widen the T21 registry from *_ENV constants to ALL declared module constants

Source: plans/briefs/t17-gen-constants-registry.md at 8a2cb42ad · last changed 2026-10-20 · first committed 2026-10-20 · 83 lines.

Prose pending.

Plan text

T17-GEN — widen the T21 registry from *_ENV constants to ALL declared module constants

Task #570, build order 2 (docs/ast-checkable-rules.md §2#1). The engine landed 2026-10-20 (commit 25f06c3f6): T21 in scripts/test-review.py — registry of module-level *_ENV string constants, shape-gated literals (contains '_', all cased chars uppercase), >=2-consecutive-token drift → ERROR, exact-outside-declaring-module → WARNING, exact-before-drift precedence, path exemption for the rule's own tests, applies to any .py CLI arg while T1-T20 stay name-scoped. The landed behavior is FROZEN: all 11 T21 tests + the rule's probes must pass UNCHANGED at the end of this packet (extension, never regression).

TWO-STAGE brief. Stage A = measurement + proposal, NO enforcement changes. The FP-explosion risk is the whole design question: every UPPER_CASE module constant's value becoming a drift candidate against every literal can light up thousands of findings. The coordinator rules the enforcement shape from your numbers.

Stage A — measure, propose (the only writes: your report)

A1. Build the WIDE registry offline (scratch analysis, not in test-review.py yet): every module-level string-constant assignment across src/orchestrata_ultimate + scripts (measure both name shapes: ALL names vs UPPER_CASE-only names — report counts for each). A2. Run the T21 comparison semantics (shape gate + >=2-token drift + exact-warning) with the wide registry over tests/ + scripts/ + src/ (read-only scan; a scratch driver in reports/ or /tmp is fine — RUL-037: no python -c/heredocs, write a .py scratch file if needed, but it lands in NO fence). A3. Report the findings explosion honestly, bucketed: drift ERRORs vs exact WARNINGs; by bucket, sample 20 findings each and CLASSIFY: true positive (a genuinely retyped/fabricated constant value) vs FP (coincidental token overlap — e.g. generic words in unrelated constants, message text, test data). The FP rate per bucket IS the design input. A4. Propose enforcement options costed against the numbers — at minimum: (a) token-run threshold per registry tier (>=2 for *_ENV as landed, >=3 for general constants?); (b) value-shape restriction (only values that are themselves UPPER_SNAKE env-key-shaped enter drift comparison; prose-like constant values exempt); (c) exact-only for the general tier (WARNING on retyped values, no drift ERRORs); (d) declaration-site name scoping (constants whose NAME is UPPER_CASE — the convention marker — vs any assignment). One recommendation with the projected finding counts under each option (from your A3 sample, extrapolated with the sampling method stated). A5. The ratchet interaction: whatever the shape, new findings on the CURRENT tree must not block existing files en masse — propose the baseline/ratchet integration (the ADR-0116 routing packet's worklist pattern, or T21's own baseline if the counts demand it).

Stage B — implement the RULED shape (fence amendment follows the ruling; preview)

Fence (expected): scripts/test-review.py, tests/scripts/test_test_review_tool.py. Extend the registry builder per the ruling; keep the landed *_ENV tier semantics byte-stable (the 11 tests + probes unchanged and green); add pins for the new tier (founding-regression: the 29-file exact-key worklist class generalizes — a retyped non-env constant value WARNINGs; the ruled FP classes stay quiet); wall-time guard: the wide registry walk must not regress the test-suite time (the D9 seam already caches per review run — measure and report the walk cost delta); coverage honest.

VERIFY (Stage B, report verbatim)

The landed packet's full VERIFY block (7 commands — unchanged outputs expected for the frozen behavior) + the new-tier probes + coverage raw lines + registry walk cost before/after.

Report

Stage A: the count tables, the bucketed samples with classifications, the option costs, the recommendation. Stage B (after ruling): per-change summary, all VERIFY outputs verbatim, anything unfaithful named. Workers do not commit. RUL-037.

Stage-A run 1: REJECTED (2026-10-20) — incomplete measurement

ATTRIBUTION CORRECTION (supersedes this section's first draft, which charged run 1 with a fence violation): the pyproject.toml/uv.lock edits observed during run 1's window were the concurrent PI-ORCH-A worker's sanctioned "torch optional extra" work, dispatched 08:54:12 by a second active coordinator session (ses_ea7cf4a44ffe) — the diff shape matches that packet exactly and the run-1 worker's only write was its report. The violation charge is WITHDRAWN; the coordinator's revert of those files during the window was a mis-attribution (rolled PI-ORCH-A's in-flight work back; the worker re-applied it). Run 1's "AST Issue Resolution" claim remains unverifiable narrative, but no edit is attributed to it.

The reject stands on the deliverables: the report (reports/t17-gen-stage-a.md) delivered only registry-side ratios (613 constants, 547 unique, 119 env-key-shaped, 34.2x expansion) — A2's tree-scan FINDING counts, A3's shaped-literal TP/FP classification with rates, and A4's projected counts per enforcement option are ALL missing; A5's empty-baseline proposal is unfounded without them.

Run 2 contract (fresh worker): the A1-A5 brief above, UNCHANGED, plus hardened constraints: pyproject.toml, uv.lock, and every dependency/environment file are ABSOLUTELY FORBIDDEN — a tool error of ANY kind is reported verbatim in the report's "could not execute faithfully" section and worked around read-only (or not at all), NEVER fixed. The existing run-1 registry-ratio numbers may be reused as A1 inputs IF the run-2 worker re-verifies them (spot-check counts against its own scan). The enforcement ruling waits on A2-A4's real numbers: findings per tier over tests/+scripts/+ src/, FP rates from classified shaped-literal samples, projected counts per option.