feat(core): pure loadUwrProfile validator (PR-UWR-RUNTIME-LOADER) - #18
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slot and authorization
This PR executes PR-UWR-RUNTIME-LOADER — the afi-core row of the §7 authorization ledger in afi-governance
decisions/uwr-runtime-consumption-v0.1.md.Go-ahead (RC-10.5): the row was flipped to "Yes — row flip merged by owner per RC-12 (recorded 2026-07-13)" by owner merge of afi-governance PR #11 (merge commit
fbd0c46).What this adds
validators/UwrProfileLoader.ts— a pureloadUwrProfile(profileJson: unknown): Readonly<UniversalWeightingRuleConfig>validator/mapper. Nofs, no path resolution, no afi-config dependency: the caller supplies the already-parsed document. It enforces the RC-5 identity predicate exactly:defaultUwrConfig's per axis (near-misses refused, incl. 1-ULP drift);["structure", "execution", "risk", "insight"]in content and order (UP-4);profileIdequals the pinneduwr-weighted-lifts-v0.1andsupersedesequalsdefaultUwrConfig.id(uwr-default-stub);Refusals throw
UwrProfileLoadErrorwith a machine-checkablereason(the RC-4 fail-closed triggers for the future PR-UWR-RUNTIME-READ). Fail-closed hardening: all document fields are read once, as own properties only (inherited/prototype-supplied values and accessor-backed documents cannot satisfy the predicate or alter values post-validation), and the returned frozen config spreadsdefaultUwrConfigitself with the registered profile id — identity by construction: registry-supplied numbers can never flow into the result. The returnedidrecords which governed profile the values were validated against; it does not signal registry consumption (RC-6/RC-8 semantics unchanged).validators/__tests__/UwrProfileLoader.test.ts— 20 vitest tests: happy path, frozen/no-mutation, RC-5 identity withdefaultUwrConfig, bit-identicalcomputeUwrScoreunder loaded vs default config (incl. the UP-5 golden anchor0.1875), full refusal matrix (shape, schema, profileId incl. alias-as-id and stub-id, supersedes, axes reorder/drop/extend/rename, weights shape/near-miss/NaN), hostile-input hardening (single-read accessors, prototype-chain inputs), and a dev-only sibling-registry integration test (it.skipIf, same pattern as the KAT suites) proving the live afi-config registry document loads.validators/UniversalWeightingRule.ts— the RC-8-sanctioned TODO comment update only (+5/-1 comment lines;defaultUwrConfigvalues andcomputeUwrScoresignature byte-untouched).No subpath-export change was required: the existing
"./validators/*"wildcard already exposesafi-core/validators/UwrProfileLoader.js(emission todist/validators/verified).Validation (RC-10 gates)
ce8c1de), untouched by this PR.npm test --if-present→ vitest, which auto-selects non-watch run mode under CI; the build check passed on this head).Review
An 8-angle adversarial review ran before opening. Fixed: single-read/own-property hardening (TOCTOU + prototype-chain false-accepts), identity-by-construction return,
WEIGHT_KEYSderived from the pinned axes and compile-checked againstUniversalWeightingRuleConfig, merged validation loops (casts eliminated), test dedup. Declined with rationale: zod rewrite (predicate deliberately reads literally as RC-5 for auditability; reason codes are the contract), fixture trimming (the inline mirror is CI's only realistic-document coverage since the sibling test skips there), and two findings whose fixes exceed this slot's authorization — noted below.Notes for the owner (out of this slot's scope, no action taken)
validators/UniversalWeightingRule.tssince390b440, so the blob-identity wording invalidators/__tests__/kats/README.mdand the KAT test header ("blob-identical between 390b440 and 2541853") stays true as a claim about those pinned commits but no longer extends to HEAD. Comment-only divergence; the executable sha256 pin covers the KAT JSON and is untouched. Suggest folding a two-line dated addendum into PR-UWR-KAT-RERUN.UWR_PROFILE_IDand this loader'sPINNED_UWR_PROFILE_IDboth hardcode the profile id with no test asserting their equality (the reactor guardrail cross-checks against the sibling registry, which transitively ties them). A reactor-side import or guardrail extension belongs to PR-UWR-RUNTIME-READ / STAMP-SEMANTICS.Scope guarantees
No runtime registry read; no reactor changes; no scoring behavior change (loaded config is provably value-identical — golden anchor asserted); no reward/mint/settlement;
defaultUwrConfigunmodified; no KAT/schema/registry values touched; UP-8 untouched; testnet-provisional throughout; no production scoring-law claim.🤖 Generated with Claude Code