MINT_APPLY_CRITIC_2026-07-27.md

pipelines/MINT_APPLY_CRITIC_2026-07-27.md

MINT APPLY CRITIC — §§7-12 schema mint, working tree @ HEAD cd33879 (uncommitted)

Fresh-context adversarial critic. READ-ONLY on C:/dev/humanity-forgotten; this file is the sole write.

Spec = mint_design_A_build_space.md + mint_design_B_item_ally.md (reconciled sections binding).

VERDICT

NO-GO AS LANDED · GO-WITH-FIXES ON THE MINTED CONTENT.

The content that DID land is high-fidelity: nothing extra was minted, nothing existing was destroyed,

the tuning firewall is clean to zero, every new FK resolves, and the four new teeth are genuinely

armed (I fired them against mutated live rows, not just their fixtures). But the pass stopped at the

append-only half of the spec and skipped the baseline/harness/manifest half — so **run_gates.py

exits 1 with Overall: FAIL**, and four MAJOR spec obligations are unmet. This is not committable

until MAJOR-1 and MAJOR-2 are applied.

Evidence base: git status --short, full git diff, programmatic reads of all 13 new CSVs +

fk_spec.json + registry_extensions.json + gates_config.json, a full run_gates.py run,

--self-test on all four new gates, and in-process mutation of live rows through the tooth functions.

---

MAJOR

MAJOR-1 · docs/fidelity_baseline.json was never refreshed — the fidelity gate is RED

must refresh it via --emit-baseline in the same commit, or the gates go red").

jointly… added_rows: T0_Worldstate_Variables/Sheet1 17 → 21 jointly." B §6.4 step 5 —

"python harness/registry_fidelity.py --emit-baselinein the same commit (the standing rule;

skip it and the gates go red)."

added_registries = 12 (spec 25); added_rows["T0_Worldstate_Variables/Sheet1"] = 17

(spec 21). harness/scorecard.json"gate": "FAIL" with 13 extra_registry findings

(every new table), one row_extension {observed: 21, declared: 17}, and one

extension_content hash mismatch. python harness/run_gates.pyOverall: FAIL, exit code 1.

UNPIPED, in the same commit as the rows; re-run run_gates.py UNPIPED and confirm green.

MAJOR-2 · APPEND_LEGAL_IDS did NOT go 12 → 14, and the WS_043-046 domains are undeclared

docstring's 'six' is stale text to fix in the same pass"; "Both rows' domain declarations land in

the same commit as the rows, or every ws.bonus_selection_state / ws.bonus_respec_ledger

write resolves as an unresolved-head finding." B §1.6 and §6.4 step 6 say the same for

WS_045/WS_046.

`frozenset({"WS_008","WS_010","WS_012","WS_018","WS_019","WS_020","WS_021","WS_026","WS_027",

"WS_028","WS_031","WS_034"})twelve ids, neither WS_044 nor WS_046`. The L18-21 docstring

still says "legal ONLY on the six object/ledger/cumulative variables … WS_008, WS_012, WS_018,

WS_019, WS_026, WS_027". No domain declaration exists for WS_043-046.

("CO-LANDING DEPENDENCY, not applied in this pass (harness out of scope)"). A self-declared

deviation is still a deviation; the spec gave no license to re-scope, and the failure is latent

rather than visible only because no spine doc writes these keys yet.

keyed-replace and take no +), fix the stale "six" docstring, and add the four domain declarations.

MAJOR-3 · check_rarity_firewall.py classes (e), (P), (S) are SILENTLY vacuous — the gate's own not-armed promise is false

reports-zero` defect class, landed inside a brand-new tooth).

(P) (predicate lint) and (S) (exclusion symmetry). The landed harness/gates_config.json _note

promises: "every not-yet-armed assertion **prints its reason under 'DECLARED NOT-ARMED' in its own

scorecard every run**."

exclusive_with_refs are blank on all 5. cls_e (L222-234) short-circuits on if tok and …;

cls_p (L265) on if not expr: continue; cls_s (L281-290) builds an empty set per row. Zero

cells are examined. The not-armed note is gated on if not affixes: (L457) — the table is

non-empty, so nothing is printed. harness/rarity_firewall_scorecard.md shows

DECLARED NOT-ARMED (6) listing only four (f) columns, (c) and (a) — (e)/(P)/(S) are absent —

and reports FAIL (0) / WARN (0) — none. A clean green over three checks that ran on nothing.

Rune/Flora/Mineral rarity_class cells, which is the M2 reconciliation's load-bearing proof.

a class's input column is 100% blank, independent of row count. (Root cause is MODERATE-1.)

MAJOR-4 · The entire Vector-B / Vector-C column layer was silently re-scoped into a new _deferred block

Vector-C re-pins, are absent; roster items 9-15 of B's own TABLE ROSTER).

is modified — git status --short lists only T0_Worldstate_Variables/Sheet1.csv under

registries/. docs/registry_extensions.json extensions is byte-identical (0 keys added,

0 removed); no imprint-loot, status-framework, defensive-properties, ally-build or

counter-coverage key exists.

carries no defensive_class column (Family B §4.2's Vector-C extension has not landed)."

T0_Creature_Roster.status_immunity does not exist.

applies_to_tags = defensive_class=parry|catch references a column that does not exist. Spec

B §1.2: "IMP_0005 is deliberately the fifth seed: §12's own named bonus kind … is **unauthorable

until §1.7's weapon defensive_class exists — the two land together.**" They did not.

item-ally-extension-columns, that documents the deferral honestly and correctly explains why the

manifest keys must not be declared without the columns (I1/I3 would fire). The reasoning is sound;

the re-scope was still not the apply's to make, and the spec's landing order does not permit it.

re-scope ruled explicitly — and in the meantime pull IMP_0005 or blank its applies_to_tags.

---

MODERATE

MODERATE-1 · Six required: yes columns landed 100% blank; no tooth asserts required-ness

(every Lane-B option). T0_Bonus_Option_Registry.role_tags (col 15, required yes) — blank on the

same 7. The fk_spec floor min_tokens: 5 is satisfied by Lane A alone, so the FK coverage

check conceals the gap.

on 5 of 5. This is the direct cause of MAJOR-3.

13 of 13. The colour-independence floor has no data.

integrity-gated command model (L1/L2 cannot be overridden · L3 trust threshold · L4/L5 free) is the

column's entire reason for existing and is quoted verbatim in the spec.

rather than invisible.

MODERATE-2 · Two min_values: 0 floors registered — a rule that cannot fail

min_values: 0 floor (a rule that cannot fail) never exists even briefly"; "Registered **at

first data, not at empty-table creation**."

T0_Boss_Attack_Rail.id_formats.attack_row_id.min_values = 0. Both tables are header-only (0 rows).

MODERATE-3 · _deferred.familiar-bond-ladder not removed, though its table now exists

registry_extensions.json in the same commit, or the manifest points at a home that exists (**a

stale pointer is the defect class this project keeps catching**)."

says the table is "to be registered in docs/fk_spec.json once minted" — it now is.

T0_Familiar_Registry's 22 notes cells still point readers at the deferred address.

MODERATE-4 · docs/DOC_MAP.md untouched — 13 registries and 4 scorecards land orphaned

scorecard"; B §6.4 step 9 "a table is not done until it is listed there". Standing project rule

(anti-orphan-wire-everything-doc-map).

or build_space_scorecard returns 0.

---

MINOR

bond_ability_id = BA_\d{4} min_values 110". Landed 5 rows / min_values: 5`. The choice is

defensible (110 against 5 rows would be an instant insufficient_coverage FAIL) and check_ally_build

honestly WARNs "(B2) bond ladder covers 1/22 familiars (5/110 rows)". But it is a stated-number

deviation, and the floor no longer defends the ratified 22×5 shape. Record the choice explicitly.

§2.1 enumeration is 15 (source_ref / notes share one markdown row). The apply followed the

enumeration and is correct; fix the roster number, not the CSV.

Path.relative_to (check_build_space.py L168, check_rarity_firewall.py L120, and the two

siblings). Fails loudly, never silently, so robustness only.

axis among the 7 seeded). Faithful to the spec's own §9.4/§9.5 seed sets — spec-internal, not an

apply defect. Recorded so it is not later read as drift.

the INT-tier key axis — the table's stated primary discriminator — is vacuous in the landed data.

Spec-consistent (the §1.4 seeds are integrity-gated, not INT-gated); recorded as an authoring debt.

---

VERIFIED CLEAN (each independently checked, not taken on the apply's word)

Spec fidelity — roster and widths. Exactly 13 new registries: Family A's 5 + Family B's 8,

matching the joint arithmetic. Nothing extra was minted. Column widths match the

post-reconciliation TABLE ROSTER on all 13: Bonus_Pool 25 · Bonus_Option 32 · Role_Axis 15 ·

Spec_Purpose 14 · Role_Composition_Rule 14 · Rarity_Grade 24 · Imprint_Affix 26 · Equipment 26 ·

Loadout_Set 15 (see MINOR-2) · Familiar_Bond_Ability 15 · Ally_Behavior_Policy 21 · Boss_Attack_Rail

24 · Status_Table 26.

WS_043-046 allocation matches the M1 reconciliation exactly — id, variable_name, owner,

append-legality and inner shape, including B's bonus_pick_refs[] correctly landing as a DERIVED

read over WS_043 rather than a stored copy, and the loadout ceiling stated as

T0_Loadout_Set_Definition's row count rather than restated as a number.

Gate roster 25 → 29 with the spec'd names and order (build_space, rarity_firewall,

counter_class_coverage, ally_build); run_gates.py itself needed no edit and drove all 29.

Each gate calls selftest() inside run() (e.g. check_build_space.py L843) and raises if a

ruler rotted — the gates_config claim on that point is true.

Teeth are genuinely armed, verified by mutation, not by fixture alone.

("pick_class=minor carries lane='B', expected A"); setting gate_index=6 with a grade_index

fires T-A2 ("the Portal / the Crossing of the Abyss confers no grade").

live GAS Composure → no finding; registry enum cast_pattern + enum_set → 0 FAILs.

PENDING_ATTRIBUTE_CHANNELS holds exactly the seven M7 names, and the scorecard emits

exactly seven T-A5 WARNs — never promoted to FAIL, as M7 requires.

counter_class_coverage A1 correctly declares parry rows would FAIL-as-unjudgeable, refusing a

clean zero.

Non-destruction — the diff is pure-additive. All 21 pre-existing docs/fk_spec.json entries are

byte-identical (EXISTING fk_spec entries MODIFIED: []), and its _note is unchanged.

docs/registry_extensions.json extensions block: 0 keys added, 0 removed. The Worldstate CSV diff

is 4 appended lines, 0 deletions. No other registry file is touched, so

expected_cell_diffs (4,215), added_columns, added_tabs, overwide_rows, extension_hashes (19)

and stub_superseded do not move — exactly as A §10 requires. Zero existing rows, cells or edges

modified anywhere.

Data correctness. All 13 CSVs are BOM-less, parse cleanly, and have no ragged rows. Every new

FK/soft-ref spot-checked against its live target and resolves: combat / mobility / healing

are real ability_class values (54 live); A_F_002 and A_E_002 are real ability_ids; BRUTE is

a real weapon_class; FAM_01, RN_0018, FL_0001 all present; every role_tag / role_axis_ref

/ spec_purpose_ref in Family B resolves into Family A's rosters (the M3 fix, working). The fidelity

gate's FK pass reports 0 fk_dangling, 0 id_format, 0 pk_violation, 0 insufficient_coverage

across all new edges — the FAIL is purely the un-refreshed baseline of MAJOR-1.

Josh's verbatim seeds are faithfully carried. The five Fire Bolt Lane-A bonuses in order

(cast_time_reduction → resistance_pierce → elemental_superiority → raw_damage → crit_chance); the

three Fire Bolt Lane-B transformatives; the four Tremor Stomp transformatives including the

BOPT_00014 / BOPT_00016 wall-ring pair on a shared exclusion_group = tremor_wall_ring with

persistence_class enum_set + physical_properties_array add — and A_E_002's base row untouched,

which is §5H.4's ruling honoured by construction. Seven role axes including the canon-cited

ROLE_GROUP_TERRAIN with tier_c_team_ref = Environmental Manipulation; six spec purposes; four

composition rules with RCR_001 (measured vector) at precedence 1; five imprint affixes; three

loadout sets with departs_with_companion = FALSE on all three; ten status kinds matching the ten

shipped tags; eight ally policies whose disposition_legal_set correctly withholds aggressive at

L1/L2 and permits it from L3 per §1.4; the W1 Shell bond ladder at rungs 1/25/50/75/100.

FIREWALL — clean to zero. A programmatic scan of every cell in all 13 new tables found

0 non-ordinal numeric values. magnitude_ref, threshold_ref, breadth_floor_ref and

expected_pick_band_ref are blank in every row of every table that carries them. The five

struct-mirror float columns exist only on T0_Boss_Attack_Rail, which is header-only — so the one

enumerated exception is currently vacuous, exactly as M8 intends.

MYTHIC expresses questline-only on both axes. (item_grade, mythic) and (pool_option, mythic)

each carry obtainable_by_roll = FALSE, gate_kind = questline; the firewall's unrollable set

resolves to {creature_spawn:legendary, item_grade:mythic, item_grade:signature, pool_option:mythic};

T0_RNG_Drop_Table holds 0 rows and no option row carries rarity_class = mythic; POOL_0007 is the

sole grade_ceiling = mythic pool, matching Combat §12's Legendary-form-at-Proficiency-99 seed. The

shared ladder carries uncommon and signature, so the 11 live Flora/Mineral cells keep their values

and class (d) passes across live data — the M2 reconciliation verified working, no live cell moved.

---

RANKED FIX ORDER

1. MAJOR-1 (--emit-baseline) — without it nothing else can be committed.

2. MAJOR-2 (APPEND_LEGAL_IDS 12→14 + the four WS domain declarations + the stale docstring).

3. MAJOR-3 (column-scoped NOT-ARMED notes in check_rarity_firewall.py) + MODERATE-1 (its root cause).

4. MAJOR-4 — land the Vector-B/C layer, or get the re-scope ruled; until then pull or blank IMP_0005.

5. MODERATE-2/3/4, then the MINORs.

Generated by harness/site/structure_site.py — the URL path is the repo path. review root