<!-- task=m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture plan=2 tag=REVIEW_REVIEW_REFACTOR milestone-task=transfer -->

# Make the state-schema oracle clause-sensitive

## For the Implementing Agent

Filling the implementation-owned sections in `CODE_REVIEW-cloud-G04.md` is mandatory. Reconfirm the encoded predecessor PASS, implement only this oracle follow-up, run every verification command exactly, paste actual output, keep the active pair in place, and report ready for review. If blocked, record only the exact blocker, attempted commands/output, and resume condition in implementation-owned evidence fields. Do not ask the user, call user-input tools, create control-plane stop files, classify the next state, archive logs, or write `complete.log`; finalization belongs to the code-review skill.

## Background

The v1 schema now encodes the correct read-only and quarantine/resumability rules, but its tracked jq regression does not actually inspect the schema conditional it claims to protect. Removing the schema's entire `allOf` block still produces `STATE_SCHEMA_CONTRACT_PASS`, so the regression can approve a reintroduced schema/runtime mismatch. The oracle must fail closed on both invalid fixture records and invalid schema-clause shapes.

## Archive Evidence Snapshot

- The current failed pair will archive as `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/plan_local_G04_1.log` and `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/code_review_cloud_G04_1.log`; verdict: FAIL.
- Required finding: `scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq:14-23` reads only `mode.const`; quarantine category, resumability, required reason, forbidden reason, and minimum length are hardcoded or omitted instead of being validated against the tracked schema clauses.
- Reviewer reproduction removed `.$defs.record.allOf` in a temporary schema and reran the tracked oracle; it still exited 0 and printed `STATE_SCHEMA_CONTRACT_PASS`. Baseline parsing, canonical fixture evaluation, exact state-ID provenance, sensitive-text scan, and `git diff --check` passed.
- Roadmap carryover remains `milestone-task=transfer`, SDD scenario S02, with no roadmap mutation or completion claim in this follow-up.

## Analysis

### Files Read

- `scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json`
- `scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq`
- `scripts/fixtures/iop-agent-chronos-transfer-state-v1.json`
- `scripts/fixtures/iop-agent-chronos-ownership-manifest.tsv`
- `cmd/iop-chronos-transfer/main.go`
- `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/PLAN-local-G04.md`
- `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/CODE_REVIEW-cloud-G04.md`
- `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/plan_local_G05_0.log`
- `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/code_review_cloud_G05_0.log`
- `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`
- `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-chronos-extraction-decoupling/SDD.md`
- `agent-spec/runtime/iop-agent-cli-runtime.md`
- `agent-contract/inner/iop-agent-cli-runtime.md`

### SDD Criteria

- `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-chronos-extraction-decoupling/SDD.md` is `[approved]` with its lock released. The unchanged first-line scope is `milestone-task=transfer`.
- Acceptance Scenario S02 and its Evidence Map require a trustworthy full-state transfer fixture before later isolated bundle verification. The checklist therefore keeps the canonical fixture and schema contract stable while making the verifier prove that the tracked schema clauses themselves express the read-only and quarantine rules.

### Verification Context

- No external verification handoff was supplied. Repository-native evidence came from the tracked schema, fixture, jq oracle, exporter validation at `cmd/iop-chronos-transfer/main.go:785-844`, the exact predecessor completion, and fresh reviewer commands in the current checkout.
- Local preflight is Go `go1.26.2 linux/arm64`, module `/config/workspace/iop-s1/go.mod`, with `/bin/jq` available. No service, credential, provider, or external host is required.
- The canonical oracle prints `STATE_SCHEMA_CONTRACT_PASS`, but the same oracle also prints PASS after a temporary `jq '."$defs".record.allOf = []'` mutation. This directly proves the current verification is not clause-sensitive.
- Preconditions: index 03 resolves to the one archived PASS at `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log`.
- Constraints: do not change the canonical schema, fixture, ownership manifest, exporter, roadmap, contract, or spec. Confidence is high because the false-positive is deterministic and isolated to the jq oracle.

### Test Coverage Gaps

- The oracle checks canonical and four mutated records, but its quarantine branch is independent from the tracked schema `allOf` branch and does not verify the schema's `required`, `not.required`, or `quarantine_reason.minLength` clauses.
- The failure branch returns a diagnostic object with exit code 0, so command success alone is not fail-closed. The fixed oracle must return nonzero for an invalid schema or fixture contract.
- Add schema-shape mutation coverage in the same tracked jq regression and retain the existing four record mutations.

### Symbol References

- None. No Go or JSON symbol is renamed or removed.

### Split Judgment

- Keep one compact follow-up. Schema-clause extraction, fixture evaluation, mutation rejection, and fail-closed exit behavior form one verification invariant and cannot independently PASS as useful subtasks.
- Encoded predecessor index `03` remains satisfied by `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log`.

### Scope Rationale

- Exclude `scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json`: its current clauses match the exporter and SDD; only the oracle failed to protect them.
- Exclude the canonical fixture, ownership manifest, and `cmd/iop-chronos-transfer/**`: current data and production validation pass, and changing them would expand beyond the Required finding.
- Exclude roadmap/spec/contract updates: this is verification repair for an existing contract. Spec update not needed.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer=`finalize-task-policy.sh`, mode=`pair`.
- Build closures are all true. Scores are `scope=1,state=0,blast=1,evidence=1,verification=1`, grade `G04`, base `local-fit`, final route `recovery-boundary`, lane `cloud`.
- Review closures are all true. Scores are `scope=1,state=0,blast=1,evidence=1,verification=1`, route `official-review`, lane `cloud`, grade `G04`.
- `large_indivisible_context=false`; positive loop risks are `boundary_contract` and `structured_interpretation` (2); `review_rework_count=2`; `evidence_integrity_failure=true`; no capability gap.
- Canonical files: `PLAN-cloud-G04.md`, `CODE_REVIEW-cloud-G04.md`.

## Dependencies and Execution Order

1. Reconfirm the exact PASS in `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log`.
2. Make the tracked oracle clause-sensitive and fail-closed, then rerun canonical, schema-mutation, provenance, redaction, and diff checks.

## Implementation Checklist

- [ ] Reconfirm that predecessor index 03 resolves to exactly one PASS `complete.log` before changing the oracle.
- [ ] Make the jq oracle validate and consume the tracked mode, quarantine category, resumability, reason-required/forbidden, and minimum-length schema clauses.
- [ ] Keep the canonical positive case and four record mutations, add schema-clause mutation rejection, and make every aggregate failure return a nonzero exit.
- [ ] Re-run JSON parsing, exact manifest/addendum ID provenance, sensitive-text, focused schema-mutation, and diff checks without changing the canonical schema, fixture, or manifest.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REFACTOR-1] Make the oracle validate the published schema

**Problem**

`scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq:14-23` reads `mode.const` but hardcodes quarantine semantics. The aggregate at lines 46-57 never checks the schema conditional and returns a normal JSON value on failure. A temporary schema with `.$defs.record.allOf = []` therefore still exits 0 and prints `STATE_SCHEMA_CONTRACT_PASS`, contradicting the plan's clause-sensitive regression requirement.

**Solution**

Parameterize schema access and record evaluation on the supplied schema document. Validate the exact conditional shape before testing fixture records: read-only mode; quarantine category match; required category; quarantine `resumable=false`; required non-empty reason; non-quarantine `resumable=true`; and forbidden reason. Evaluate records with those extracted values, retain the four data mutations, add schema-clause mutations, and call `error(...)` for an aggregate failure so the command exits nonzero.

```jq
# before
def check_record:
  (.mode == schema_mode_const)
  and (if .category == "quarantine" then
    (.resumable == false) and has("quarantine_reason")
  else
    (.resumable == true) and (has("quarantine_reason") | not)
  end);

# after
def schema_contract($schema_doc):
  # inspect the tracked record properties and allOf conditional
  ...;

def check_record($schema_doc; $record):
  # compare the record with values and presence rules extracted above
  ...;

if $all_cases_pass then "STATE_SCHEMA_CONTRACT_PASS"
else error("state schema contract regression failed")
end
```

**Modified Files and Checklist**

- [ ] `scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq` — validate actual schema clauses, cover schema mutations, and fail nonzero.
- [ ] `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/CODE_REVIEW-cloud-G04.md` — record implementation notes and actual command output.

**Test Strategy**

- Update the tracked jq regression rather than adding a Go dependency. It must accept the canonical schema/fixture, reject all four existing record mutations, reject at least removal of the schema conditional plus inverted/removed quarantine branch clauses, and reject an empty quarantine reason.
- The final shell mutation independently removes the tracked schema conditional and requires a nonzero oracle result, proving the test is coupled to the published schema rather than only to hardcoded record rules.

**Verification**

- `jq -nr --slurpfile schema scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json --slurpfile fixture scripts/fixtures/iop-agent-chronos-transfer-state-v1.json -f scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq` — prints exactly `STATE_SCHEMA_CONTRACT_PASS` and exits 0.
- `bash -lc 'set -euo pipefail; oracle_tmp=$(mktemp -d); trap '\''rm -rf -- "$oracle_tmp"'\'' EXIT; jq '\''."$defs".record.allOf = []'\'' scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json >"$oracle_tmp/schema.json"; set +e; output=$(jq -nr --slurpfile schema "$oracle_tmp/schema.json" --slurpfile fixture scripts/fixtures/iop-agent-chronos-transfer-state-v1.json -f scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq 2>&1); rc=$?; set -e; test "$rc" -ne 0; test "$output" != "STATE_SCHEMA_CONTRACT_PASS"; printf "SCHEMA_MUTATION_REJECTED\n"'` — prints exactly `SCHEMA_MUTATION_REJECTED` and exits 0.

## Modified Files Summary

| File | Item |
|------|------|
| `scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq` | REVIEW_REVIEW_REFACTOR-1 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/05+03_state_fixture/CODE_REVIEW-cloud-G04.md` | REVIEW_REVIEW_REFACTOR-1 |

## Final Verification

1. `bash -lc 'set -euo pipefail; mapfile -t predecessor_logs < <({ test ! -f agent-task/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log || printf "%s\n" agent-task/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log; find agent-task/archive -path "*/m-iop-agent-chronos-extraction-decoupling/03+02_inventory_closure/complete.log" -type f -print 2>/dev/null; } | sort -u); test "${#predecessor_logs[@]}" -eq 1; awk "BEGIN {in_summary=0; found=0} /^## Summary$/ {in_summary=1; next} in_summary && /^## / {in_summary=0} in_summary && /final verdict: PASS/ {found++} END {exit found==1?0:1}" "${predecessor_logs[0]}"; printf "%s\n" "${predecessor_logs[0]}"'` — exactly one predecessor PASS.
2. `jq -e . scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json scripts/fixtures/iop-agent-chronos-transfer-state-v1.json >/dev/null && printf 'JSON_PARSE_PASS\n'` — both JSON documents parse.
3. `jq -nr --slurpfile schema scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json --slurpfile fixture scripts/fixtures/iop-agent-chronos-transfer-state-v1.json -f scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq` — prints exactly `STATE_SCHEMA_CONTRACT_PASS` and exits 0.
4. `bash -lc 'set -euo pipefail; oracle_tmp=$(mktemp -d); trap '\''rm -rf -- "$oracle_tmp"'\'' EXIT; jq '\''."$defs".record.allOf = []'\'' scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json >"$oracle_tmp/schema.json"; set +e; output=$(jq -nr --slurpfile schema "$oracle_tmp/schema.json" --slurpfile fixture scripts/fixtures/iop-agent-chronos-transfer-state-v1.json -f scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq 2>&1); rc=$?; set -e; test "$rc" -ne 0; test "$output" != "STATE_SCHEMA_CONTRACT_PASS"; printf "SCHEMA_MUTATION_REJECTED\n"'` — the oracle rejects a schema with its conditional removed.
5. `bash -lc 'set -euo pipefail; manifest_ids=$(mktemp); fixture_ids=$(mktemp); trap '\''rm -f -- "$manifest_ids" "$fixture_ids"'\'' EXIT; awk -F "\t" '\''NR>1 && $2=="state" {print $1}'\'' scripts/fixtures/iop-agent-chronos-ownership-manifest.tsv | LC_ALL=C sort >"$manifest_ids"; jq -r '\''.records[] | select(.source_manifest=="original") | .logical_id'\'' scripts/fixtures/iop-agent-chronos-transfer-state-v1.json | LC_ALL=C sort >"$fixture_ids"; test "$(wc -l <"$manifest_ids")" -eq 10; cmp "$manifest_ids" "$fixture_ids"; test "$(jq -r '\''[.records[] | select(.source_manifest=="d04-addendum") | .logical_id] | sort | join(",")'\'' scripts/fixtures/iop-agent-chronos-transfer-state-v1.json)" = "state:cache-root,state:temp-root"; printf "STATE_ID_PROVENANCE_PASS\n"'` — original and addendum IDs remain exact.
6. `bash -lc 'set -euo pipefail; set +e; rg -n '\''/home/|/Users/|token|credential|secret|private_key'\'' scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json scripts/fixtures/iop-agent-chronos-transfer-state-v1.json scripts/fixtures/iop-agent-chronos-transfer-state-v1.contract-test.jq; scan_rc=$?; set -e; case "$scan_rc" in 0) exit 1;; 1) :;; *) exit "$scan_rc";; esac; printf "SENSITIVE_SCAN_PASS\n"'` — no host path or sensitive pattern appears and scanner errors fail closed.
7. `git diff --check` — exits 0 with no output.

After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
