fix(validate): auto-populate omitted locked_parameters instead of hard-failing (#298)#299
Conversation
…d-failing (AI-native-Systems-Research#298) The DESIGN gate required the design agent to echo every `campaign.locked_parameters` key verbatim into `bundle.experiment_spec.verified_parameters`. A single omitted key hard-failed the whole iteration before any experiment ran — pure friction, since the campaign already declares the value. In one recent 6-iteration campaign this killed 5 of 6 iterations. `_validate_locked_parameters` now distinguishes: - Omitted key — auto-populate `verified_parameters[k]` from `campaign.locked_parameters[k]` (mutating the bundle in place) and continue. The campaign is the unambiguous source of truth. - Deviating value — the bundle set a *different* value than the campaign locked. Still a hard-fail, listing every deviation. The AI-native-Systems-Research#246 anti-mirage protection is fully preserved. `validate_design` snapshots the bundle before validation and persists the auto-filled values back to `bundle.yaml` (via atomic_write) so downstream phases read the campaign's canonical values. `compute_campaign_spec_diff` (the soft-audit mirror) now skips omitted keys so it doesn't re-flag auto-filled values as violations. A present-but-wrong-TYPE `experiment_spec` / `verified_parameters` (not a mapping) still hard-fails — we auto-fill omissions, not structurally broken bundles. Tests: reworked the two `test_f1_*` missing-key tests (which encoded the old hard-fail behavior) into `test_298_*` covering auto-fill, the missing-block and missing-experiment_spec cases, the mixed omit+deviate case, malformed-type still-fails, end-to-end validate_design pass + on-disk persistence, still-fail-on-deviation, and compute_campaign_spec_diff ignoring omitted keys. Docs: CLAUDE.md spec-fidelity section, campaign-authoring-guide.md, and friction-245-resolution.md updated for the omission-vs-deviation distinction. Closes AI-native-Systems-Research#298 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review notesThanks for this — the omission-vs-deviation distinction is the right call, and the PR is well-documented (CLAUDE.md, authoring guide, and the F1 resolution row all tell a consistent story) with clean, behavioral tests. The anti-mirage deviation path is genuinely preserved and covered at both the unit and end-to-end levels. A few things stood out that I think are worth addressing before merge; happy to be wrong on any of these. The common thread in the two bigger items is that a previously pure validator ( Would recommend fixing before merge1. 2. Auto-population is silent. Worth considering3. 4. Test gap on the new malformed- Minor / optional
Nice work overall — items 1 and 2 are the ones I'd prioritize. 🤖 Reviewed with Claude Code. |
…ass-only persist, WARN on auto-fill, structured OSError (AI-native-Systems-Research#298) Follow-up to PR AI-native-Systems-Research#299 review (susiejojo). The auto-fill change turned a previously pure validator into one with a disk side-effect; this makes that side-effect safe and observable. 1. Persist only on PASS (review pt.1). `atomic_write` ran immediately after `_validate_locked_parameters`, before the remaining design validators. A run that ultimately returned status:"fail" (including the mixed omit+deviate case) could still leave a gate-rewritten bundle.yaml on disk. The write now happens once, just before the final return, gated on `not errors and bundle_mutated`. A failing gate leaves the file exactly as the agent authored it. 2. Auto-fill is no longer silent (review pt.2). _validate_locked_parameters now returns a WARN:-prefixed advisory naming every injected key (same convention as _validate_physical_realism / AI-native-Systems-Research#85). validate_design routes it to `warnings`, so the human gate has a record of which verified_parameters were gate-injected vs agent-authored. compute_campaign_spec_diff still reports clean. 3. Structured OSError (review pt.3). The persist write is wrapped so a read-only FS / ENOSPC / permission error returns {"status":"fail","errors":[...]} instead of escaping as a raw traceback from a function whose contract is {"status","errors"}. 4. Mutation detection uses copy.deepcopy + structural `!=` instead of json.dumps(..., default=str) string-rendering compare (review minor) — exact and future-proof. Tests: WARN-contract assertions on the unit tests; new test_298_malformed_experiment_spec_still_fails (review pt.4), test_298_no_persist_when_gate_fails, test_298_no_spurious_write_when_all_present, test_298_persist_is_idempotent, and test_298_compute_campaign_spec_diff_no_experiment_spec_is_all_omitted. compute_campaign_spec_diff comment reworded to credit the local guard, not call-ordering. Full suite: 1344 passed. Refs AI-native-Systems-Research#298 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed in 87760c5. Walking through the items: 1. Persist even when validation fails — fixed. You're right that the write sat before the other design validators and would leave a gate-rewritten 2. Auto-population is silent — fixed. 3. 4. Test gap on malformed Minors — all taken:
Full suite: 1344 passed. 🤖 Reviewed with Claude Code |
|
Thanks for the thorough turnaround — I went through
The minors are all in too — One small optional follow-up: item 3's LGTM. 🤖 Reviewed with Claude Code |
07ca3ac
into
AI-native-Systems-Research:reflective
Problem
The DESIGN gate required the design agent to copy every
campaign.locked_parameterskey verbatim intobundle.experiment_spec.verified_parameters. A single omitted key hard-failed the whole iteration before any experiment ran — pure friction, since the campaign already declares the value. In one recent 6-iteration campaign this killed 5 of 6 iterations, none of which reached the experiment phase._validate_locked_parametersconflated two very different cases:locked_parametersschema field to enforce campaign spec-fidelity in bundles #246: DESIGN silently rewriting locked workload params).Both hard-failed. Only the second should.
Change
_validate_locked_parameters— the missing-key branch now auto-populatesverified_parameters[k]fromcampaign.locked_parameters[k](mutating the bundle in place) and continues. The value-mismatch branch is unchanged and still hard-fails, listing every deviation.validate_design— snapshots the bundle before validation and, if auto-fill mutated it, persists the filledverified_parametersback tobundle.yaml(viaatomic_write) so downstream phases read the campaign's canonical values.compute_campaign_spec_diff(soft-audit mirror) — skips omitted keys so it no longer re-flags auto-filled values as violations.experiment_spec/verified_parameters(not a mapping) still hard-fails — we auto-fill omissions, not structurally broken bundles.Why this is safe
The #246 anti-mirage protection is fully preserved: a bundle that sets a different value than the campaign still hard-fails. We only stop punishing bundles that leave a locked value unspecified, where the campaign is unambiguously the source of truth.
Acceptance criteria
locked_parameterskeys passes DESIGN, with the omitted values populated from the campaign (and persisted tobundle.yaml).verified_parametersvalue different from the campaign's still hard-fails, listing every deviation.compute_campaign_spec_diffreports no violation for auto-populated (omitted) keys.Tests
The two
test_f1_*tests that encoded the old hard-fail-on-omission behavior are reworked intotest_298_*, covering: auto-fill of an omitted key, missingverified_parametersblock, missingexperiment_specblock, the mixed omit+deviate case, malformed-type still-fails, end-to-endvalidate_designpass + on-disk persistence, still-fail-on-deviation, andcompute_campaign_spec_diffignoring omitted keys.tests/test_friction_245.py— 38 passed. Full suite — 1339 passed.Docs updated:
CLAUDE.mdspec-fidelity section,docs/campaign-authoring-guide.md,docs/friction-245-resolution.md.Closes #298
🤖 Generated with Claude Code