<!-- task=m-openai-compatible-output-validation-filters/02+01_repeat_guard plan=1 tag=REVIEW_OFR-REPEAT -->

# Repeat guard review follow-up: fragment-safe actions and trustworthy evidence

## For the Implementing Agent

Filling the implementation-owned sections in `CODE_REVIEW-*-G??.md` is mandatory. Run every verification command, paste actual notes and stdout/stderr into the active review file, keep the active PLAN/CODE_REVIEW files in place, and report ready for review; only the code-review skill may finalize or archive the task. If blocked, record only the exact blocker, attempted commands/output, and resume conditions 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`.

## Background

The first review reproduced two decision errors: fragmented tool arguments bypass the repeated-action stop, and an older result change hides the latest no-progress pair. The required six-paragraph fixture is also incomplete, while the live harness cannot distinguish a successful guard intervention from a run that never repeated. This follow-up repairs those decision boundaries and makes local and dev evidence independently judgeable.

## Archive Evidence Snapshot

- Predecessor dependency: `agent-task/archive/2026/07/m-openai-compatible-output-validation-filters/01_resume_notice_builder/complete.log` records PASS and satisfies subtask `+01`.
- Prior plan: `agent-task/m-openai-compatible-output-validation-filters/02+01_repeat_guard/plan_cloud_G10_0.log`.
- Prior review: `agent-task/m-openai-compatible-output-validation-filters/02+01_repeat_guard/code_review_cloud_G10_0.log`, verdict FAIL.
- Required findings:
  - `stream_gate_filters.go` fingerprints each tool delta independently instead of assembling one call.
  - `stream_gate_policy.go` lets any older result change mask the latest identical action/result pair.
  - the dev harness accepts non-2xx responses and observes only already-released downstream text, not the guard lifecycle.
  - the Korean rolling fixture is one duplicated generated block, not the required six-paragraph chunked stream/history matrix.
- Affected files: `apps/edge/internal/openai/stream_gate_filters.go`, `stream_gate_policy.go`, `stream_gate_filters_test.go`, `stream_gate_policy_test.go`, `stream_gate_pipeline_test.go`, and `stream_gate_vertical_slice_test.go`.
- Reviewer verification: `git diff --check`, fresh targeted package tests, and `make test` passed. Two temporary reviewer-only regressions failed with `split repeated action decision = "pass", want fatal` and `latest identical action/result churn was hidden by older progress`; the temporary probe file was removed. No valid dev smoke was run because the implementation lacked a clean remotely addressable deployment ref.
- Roadmap carryover: S03, S04, S09, S10, S11, and S12 remain open under task `repeat-guard`.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md`
- Milestone link: [Milestone document](agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md)
- Task ids:
  - `repeat-guard`: rolling content/history/action repetition detection and safe continuation
- Completion mode: check-on-pass

## Analysis

### Files Read

- Rules and workflow: `agent-ops/rules/project/rules.md`, `agent-ops/rules/common/rules-roadmap.md`, `agent-ops/rules/common/rules-agent-spec.md`, `agent-ops/skills/common/router.md`, `agent-ops/skills/common/code-review/SKILL.md`, `agent-ops/skills/common/plan/SKILL.md`, `agent-ops/skills/common/finalize-task-routing/SKILL.md`, `agent-ops/rules/project/domains/edge.md`, `agent-ops/rules/project/domains/platform-common.md`, `agent-ops/rules/project/domains/testing.md`.
- Test rules: `agent-test/local/rules.md`, `agent-test/local/edge-smoke.md`, `agent-test/local/platform-common-smoke.md`, `agent-test/local/testing-smoke.md`, `agent-test/dev/rules.md`, `agent-test/dev/edge-smoke.md`, `agent-test/dev/platform-common-smoke.md`, `agent-test/dev/testing-smoke.md`.
- Roadmap and design: `agent-roadmap/current.md`, `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md`, `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md`, `agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md`.
- Contracts and specs: `agent-contract/index.md`, `agent-contract/outer/openai-compatible-api.md`, `agent-contract/inner/edge-config-runtime-refresh.md`, `agent-spec/index.md`, `agent-spec/runtime/stream-evidence-gate.md`, `agent-spec/input/openai-compatible-surface.md`, `agent-spec/runtime/provider-pool-config-refresh.md`.
- Active/prior task evidence: the active plan/review pair before archive and the exact predecessor `complete.log` listed in `Archive Evidence Snapshot`.
- Source: `apps/edge/internal/openai/chat_decode.go`, `responses_decode.go`, `stream_gate_filters.go`, `stream_gate_policy.go`, `stream_gate_runtime.go`, `openai_request_rebuilder.go`, `filter_observation_sink.go`, `packages/go/streamgate/filter_contract.go`, `packages/go/streamgate/event.go`, `packages/go/streamgate/evidence_tail.go`.
- Tests: `apps/edge/internal/openai/stream_gate_filters_test.go`, `stream_gate_policy_test.go`, `stream_gate_pipeline_test.go`, `stream_gate_vertical_slice_test.go`.

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md`; status approved and implementation lock released.
- Target task: `repeat-guard`.
- S03: six Korean multibyte paragraphs; 200/500-rune pending and committed look-behind; cursor, opening/prefix suppression, temperature candidates, and one terminal.
- S04: any released tool/action side effect converts repeat repair to a safe terminal stop.
- S09: completed action fingerprints use full tool deltas; identical latest action/result is no-progress; a repeated current action is held and blocked; changed result releases the guard.
- S10: assistant-only provenance and supported reasoning aliases can anchor a repeat; user provenance and distinct action progress do not.
- S11: only the latest decision-relevant completed result controls progress; latest identical failure/churn remains blockable; exhausted continuation candidates stop safely; final content is not silently suppressed.
- S12: no inferred cross-request TTL, session, or lineage.
- These rows define the fragment assembly and latest-pair code changes, the deterministic six-paragraph/history fixtures, and the raw-free observation requirements for the clean dev run. No checklist item may be marked complete without its mapped evidence.

### Test Environment Rules

- Chosen environments: `local + dev`.
- Local rules read: `agent-test/local/rules.md` and the matched edge/platform-common/testing profiles. Apply `go version && go env GOMOD`, fresh `-count=1` Go tests, `git diff --check`, and `make test`; cached output is not acceptable for targeted tests.
- Dev rules read: `agent-test/dev/rules.md` and the matched edge/platform-common/testing profiles. OpenAI-compatible changes require the dev Edge input-surface smoke. The roadmap additionally requires `ornith:35b` aggregate capacity 4 plus one queued request, five concurrent requests, three runs.
- Test Environment Preflight:
  - runner/workdir: `ssh toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev`;
  - required state: clean deployment-basis ref, branch/HEAD recorded, source synced, all participating Edge and macOS/Linux/Windows Nodes rebuilt/redeployed/restarted from that same ref;
  - binary/config: `build/dev-runtime/bin/edge`, `build/dev-runtime/edge.yaml`, Edge id `edge-toki-labs-dev`, OpenAI-compatible port `18083`, Node transport `18084`;
  - identity: record source commit plus binary checksums/version/help and running process start time; verify provider capacities `onexplayer-lemonade=3`, `rtx5090-lemonade=1`;
  - external assumptions: remote runner macOS/arm64, OneXPlayer and RTX5090 providers reachable through their profile-defined direct hosts, credentials injected only from the remote environment;
  - prior blocker: the reviewed checkout was dirty feature work while the clean runner was at `origin/main=e24207916a8ac83169a398af6458256a0f1332e0`; no valid live run was possible. Resume only after the reviewed code exists at an allowed clean ref, then clean-sync, rebuild, deploy, restart, and prove matching identities before smoke.
- Raw prompt, SSE, provider logs, and tokens stay under ignored `agent-test/runs/**`; tracked artifacts contain only sanitized decision/provider/correlation/fingerprint/offset/status evidence.

### Test Coverage Gaps

- Split tool arguments: existing `TestRepeatGuardActionProgressMatrix` supplies one complete JSON fragment and misses real multi-delta Chat/Responses calls.
- Latest no-progress: existing progress tests cover all-identical and one changed pair, but not older progress followed by latest identical churn.
- S03 fixture: existing generated block is duplicated in one event; it does not cover six paragraphs, chunk boundaries, both thresholds, or a filter-level assistant-history anchor.
- Live evidence: the current harness can pass HTTP failures and cannot observe repeat-guard evaluation/arbitration/recovery/terminal events.
- Existing continuation and single-terminal tests remain useful and must stay green.

### Symbol References

- No symbol rename or removal is planned.
- If the repeat guard is split into internal text/action filter instances, update every construction/registration assertion in `stream_gate_policy.go`, `stream_gate_filters_test.go`, `stream_gate_policy_test.go`, and `stream_gate_pipeline_test.go`; the configured public capability remains `output.repeat_guard`.

### Split Judgment

- One compact invariant is indivisible: held output must be released only after full-call/current-history semantics prove it is not a repeat, and the same decision must be observable without raw payloads.
- Directory dependency `+01` is satisfied by `agent-task/archive/2026/07/m-openai-compatible-output-validation-filters/01_resume_notice_builder/complete.log`.
- No new sibling task is needed; fragment holding, latest-pair policy, acceptance fixtures, and lifecycle evidence share the same filter/runtime boundary.

### Scope Rationale

- Keep public OpenAI request/response schemas, provider-error matching, schema validation, managed-length continuation, and cross-request storage out of scope.
- Do not infer caller identity/session/TTL or mutate final assistant content, signed/encrypted reasoning, unknown fields, or completed tool output.
- Do not add dependencies or place verification helpers/artifacts in the repository.
- Existing contract/spec/config edits are validated and changed only if the corrected internal text/action hold shape makes their current statements inaccurate.

### Final Routing

- `evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh`; `finalizer_mode=pair`.
- Build closures: scope/state/blast/evidence/verification are all closed; scores `2/2/2/2/2`, grade `G10`, base/final route basis `grade-boundary`, lane `cloud`, canonical file `PLAN-cloud-G10.md`.
- Review closures: scope/state/blast/evidence/verification are all closed; scores `2/2/2/2/2`, route basis `official-review`, lane `cloud`, grade `G10`, adapter `codex`, model `gpt-5.6-sol`, reasoning effort `xhigh`, canonical file `CODE_REVIEW-cloud-G10.md`.
- `large_indivisible_context=false`.
- Positive loop risks: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `structured_interpretation`, `variant_product`; count `5`.
- Recovery signals: `review_rework_count=1`, `evidence_integrity_failure=false`; risk boundary matched, recovery boundary did not.
- Capability gap: none.

## Implementation Checklist

- [ ] [REVIEW_OFR-REPEAT-1] Hold and assemble complete tool calls before repeated-action decisions, and derive progress from the latest decision-relevant completed pair.
- [ ] [REVIEW_OFR-REPEAT-2] Add the exact S03/S09/S10/S11 deterministic regressions across Chat, Responses, rolling, look-behind, and terminal boundaries.
- [ ] [REVIEW_OFR-REPEAT-3] Make the dev harness consume raw-free guard lifecycle evidence and complete the clean same-ref `ornith:35b` capacity+1 × 3 run.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_OFR-REPEAT-1] Fragment-safe action and latest-pair policy

#### Problem

- `apps/edge/internal/openai/stream_gate_filters.go:128` puts text, reasoning, and tool fragments under one rolling threshold.
- `apps/edge/internal/openai/stream_gate_filters.go:232` fingerprints each tool fragment independently, so `{"id":` + `1}` never equals completed history fingerprint `{"id":1}`.
- `apps/edge/internal/openai/stream_gate_policy.go:202` scans every historical pair and permanently sets progress after any older result change.

#### Solution

Separate internal hold semantics while preserving the configured `output.repeat_guard` capability: keep content/reasoning on the rolling filter and register an internal action sibling that terminal-gates tool fragments. At terminal/provider-error evaluation, group pending fragments by stable call ID, require one consistent name, concatenate arguments in event order, canonicalize the complete JSON once, and compare it with the history fingerprint. Never release an incomplete or conflicting call as a clear repeated-action decision.

Before (`apps/edge/internal/openai/stream_gate_filters.go:128`):

```go
case openAIOutputFilterRepeatGuard:
    req, err := streamgate.NewFilterHoldRequirementRolling(
        f.channel,
        []streamgate.EventKind{
            streamgate.EventKindTextDelta,
            streamgate.EventKindReasoningDelta,
            streamgate.EventKindToolCallFragment,
        },
        f.holdRunes,
    )
```

After:

```go
case openAIOutputFilterRepeatGuard:
    return rollingRepeatTextRequirement(f.channel, f.holdRunes)
case openAIOutputFilterRepeatActionGuard:
    return terminalRepeatActionRequirement(
        f.channel,
        []streamgate.EventKind{
            streamgate.EventKindToolCallFragment,
            streamgate.EventKindTerminal,
        },
    )
```

Before (`apps/edge/internal/openai/stream_gate_policy.go:202`):

```go
for i := 1; i < len(b.completedActions); i++ {
    if b.completedActions[i-1].resultFingerprint != b.completedActions[i].resultFingerprint {
        snapshot.hasCompletedProgress = true
    }
}
```

After:

```go
if len(b.completedActions) >= 2 {
    previous := b.completedActions[len(b.completedActions)-2]
    current := b.completedActions[len(b.completedActions)-1]
    snapshot.hasCompletedProgress =
        previous.resultFingerprint != current.resultFingerprint
    if previous.actionFingerprint == current.actionFingerprint &&
        previous.resultFingerprint == current.resultFingerprint {
        snapshot.repeatedActions[current.actionFingerprint] = 1
    }
}
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/stream_gate_filters.go`: split text/action hold requirements and assemble complete calls by ID.
- [ ] `apps/edge/internal/openai/stream_gate_policy.go`: register both internal repeat filters under one capability and compute latest-pair progress.
- [ ] `apps/edge/internal/openai/stream_gate_filters_test.go`: split/interleaved/conflicting/incomplete fragment decision matrix.
- [ ] `apps/edge/internal/openai/stream_gate_policy_test.go`: older-progress/latest-churn and latest-changed-result regressions.
- [ ] `apps/edge/internal/openai/stream_gate_pipeline_test.go`: registry/priority/hold and release ordering with the sibling action filter.
- [ ] `agent-contract/outer/openai-compatible-api.md`, `agent-spec/runtime/stream-evidence-gate.md`, `agent-spec/input/openai-compatible-surface.md`, `configs/edge.yaml`: inspect and update only statements made inaccurate by the corrected internal hold shape.

#### Test Strategy

- Write `TestRepeatGuardSplitToolArguments` in `stream_gate_filters_test.go` with Chat-shaped, Responses-shaped, interleaved call IDs, incomplete JSON, and mismatched-name fixtures. Assert the repeated complete call is fatal, a distinct complete call passes, and no partial fragment is released before the terminal decision.
- Extend registry/pipeline tests to assert rolling text and terminal-gated action filters share `output.repeat_guard` eligibility without duplicate downstream release.
- Write `TestOpenAIRepeatHistoryLatestPairWins` in `stream_gate_policy_test.go` with an older changed result followed by two identical action/results; assert `completedProgress()==false` and the current repeated action remains blockable.

#### Verification

```bash
go test -race -count=1 ./apps/edge/internal/openai -run 'Test(RepeatGuardSplitToolArguments|OpenAIRepeatHistoryLatestPairWins|OpenAIOutputFilterRegistrations)'
```

Expected: PASS; complete repeated calls stop, partial/interleaved calls do not leak or cross-contaminate, and only the latest pair controls progress.

### [REVIEW_OFR-REPEAT-2] Exact acceptance fixtures

#### Problem

- `apps/edge/internal/openai/stream_gate_filters_test.go:89` repeats one generated rune block inside one event.
- The suite lacks a filter-level assistant-history anchor decision and does not combine six Korean paragraphs with chunked 200/500-rune pending/look-behind boundaries.

#### Solution

Build one explicit six-paragraph Korean fixture with distinct paragraph separators, split it at deterministic UTF-8-safe rune offsets, and replay it across multiple normalized deltas. Reuse the same fixture for rolling threshold, committed look-behind, assistant-only history anchor, user exclusion, reasoning aliases, side-effect stop, and downstream continuation checks.

Before (`apps/edge/internal/openai/stream_gate_filters_test.go:87`):

```go
for _, threshold := range []int{200, 500} {
    block := uniqueKoreanRunes(threshold/2 + 80)
    event := repeatTextEvent(t, streamgate.EventKindTextDelta, block+block)
```

After:

```go
paragraphs := koreanRepeatParagraphFixture(t)
chunks := splitRepeatFixtureAtRuneOffsets(paragraphs, []int{...})
for _, threshold := range []int{200, 500} {
    runRepeatFixture(t, threshold, chunks)
}
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/stream_gate_filters_test.go`: six-paragraph chunked rolling/look-behind/history/action matrix.
- [ ] `apps/edge/internal/openai/stream_gate_policy_test.go`: assistant/user provenance, aliases, latest result, and no-lineage assertions tied to the shared fixture.
- [ ] `apps/edge/internal/openai/stream_gate_vertical_slice_test.go`: Chat and Responses continuation/safe-stop integration with one response start and one terminal.

#### Test Strategy

- Replace the synthetic coverage with `TestRepeatGuardSixParagraphKoreanRolling`, `TestRepeatGuardAssistantHistoryAnchorDecision`, and table cases for 200/500 thresholds.
- Extend `TestRepeatGuardStreamOpenNoDuplicatePrefix` or add endpoint-specific subtests for Chat and Responses. Assert safe byte cursor, no duplicate opening/prefix, caller temperature preservation, omitted `0.2/0.4/0.6` candidates, side-effect fatal stop, and one terminal.
- Keep protected/final/unknown values as sentinels and assert they are neither candidates nor suppressed.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run 'Test(RepeatGuardSixParagraphKoreanRolling|RepeatGuardAssistantHistoryAnchorDecision|RepeatGuardStreamOpenNoDuplicatePrefix|RepeatGuardToolSideEffectNoRepair)'
```

Expected: PASS for both thresholds and endpoints, with exact single-release/terminal assertions and no raw sentinel exposure.

### [REVIEW_OFR-REPEAT-3] Truthful dev lifecycle evidence

#### Problem

- `apps/edge/internal/openai/stream_gate_vertical_slice_test.go:2413` does not reject non-2xx responses.
- `apps/edge/internal/openai/stream_gate_vertical_slice_test.go:2426` hard-codes provider `unavailable`.
- `apps/edge/internal/openai/stream_gate_vertical_slice_test.go:2430` inspects only released text, so it cannot prove guard evaluation, upstream abort, recovery/safe stop, or a sanitized `not_reproduced` result.
- The prior dev run was not executed because no clean same-ref deployment basis existed.

#### Solution

Require HTTP 2xx, valid SSE framing, one terminal, and a complete set of raw-free `streamgate_filter_observation` JSON records captured from a dedicated Edge log segment under the ignored run directory. Group records by stable correlation ID; record actual provider/model, repeat filter outcome/descriptor, arbitration, recovery strategy or safe terminal, and final commit. Classify `not_reproduced` only when the repeat filters were evaluated/pass for a successful request. If a repeat violation appears, require matching abort plus continuation or safe-stop observations and verify that duplicate content was not released.

Before (`apps/edge/internal/openai/stream_gate_vertical_slice_test.go:2426`):

```go
evidence := devRepeatGuardSmokeEvidence{
    Run: run, Attempt: attempt, Model: model, Provider: "unavailable",
    StatusCode: resp.StatusCode, Result: "not_reproduced",
    Decision: "no_repeat_observed",
}
```

After:

```go
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
    return devRepeatGuardSmokeEvidence{}, fmt.Errorf("unexpected status %d", resp.StatusCode)
}
evidence, err := correlateRepeatGuardObservations(
    run, attempt, model, resp.StatusCode, terminal, observations,
)
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/stream_gate_vertical_slice_test.go`: validate HTTP/SSE, parse a bounded ignored observation log segment, correlate lifecycle evidence, and emit only sanitized summaries.
- [ ] `apps/edge/internal/openai/filter_observation_sink_test.go`: if parsing exposes a missing stable field, add allowlist/raw-safety coverage without logging payloads.
- [ ] `agent-test/runs/output-filter-recovery/**`: runtime-only ignored prompt/SSE/observation files; do not track or cite raw content.
- [ ] Active `CODE_REVIEW-*-G??.md`: record clean-ref preflight, rebuild/deploy identity, command output, sanitized 15-attempt summary, and any exact blocker.

#### Test Strategy

- Add local parser tests for non-2xx rejection, malformed/missing terminal rejection, pass → `not_reproduced`, violation → continuation, violation → safe stop, missing provider, missing correlation, and raw sentinel exclusion.
- Run the live harness only after clean same-ref rebuild/redeploy/restart. Use five concurrent `ornith:35b` requests for three runs; require capacity peak 4, queue at least 1, and final `in_flight=0`, `queued=0`.
- If the bounded run does not reproduce repetition, record only sanitized `not_reproduced` rows backed by evaluated/pass observations; do not claim a recovery path.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run 'TestDevRepeatGuard(SmokeEvidence|ObservationCorrelation)'
```

Expected: PASS for all local evidence parser cases; the env-gated live entry may skip locally.

On the clean dev runner, after source/build identity verification:

```bash
IOP_OPENAI_BASE_URL=http://127.0.0.1:18083 \
IOP_OPENAI_MODEL=ornith:35b \
IOP_OPENAI_SMOKE_CONCURRENCY=5 \
IOP_OPENAI_SMOKE_RUNS=3 \
IOP_OPENAI_SMOKE_PROMPT_FILE=agent-test/runs/output-filter-recovery/repeat-prompt.txt \
IOP_OPENAI_SMOKE_ARTIFACT_DIR=agent-test/runs/output-filter-recovery/repeat-guard \
IOP_OPENAI_SMOKE_OBSERVATION_FILE=agent-test/runs/output-filter-recovery/repeat-guard/edge-observations.jsonl \
go test -count=1 -v ./apps/edge/internal/openai -run '^TestDevRepeatGuardOrnithSmoke$'
```

Expected: exit 0; 15 successful correlated attempts, actual provider present, valid repeat-guard evaluated evidence for every request, truthful `reproduced` or `not_reproduced`, capacity/queue recovery, and no raw payload/token in stdout or tracked files.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/stream_gate_filters.go` | REVIEW_OFR-REPEAT-1 |
| `apps/edge/internal/openai/stream_gate_policy.go` | REVIEW_OFR-REPEAT-1 |
| `apps/edge/internal/openai/stream_gate_filters_test.go` | REVIEW_OFR-REPEAT-1, REVIEW_OFR-REPEAT-2 |
| `apps/edge/internal/openai/stream_gate_policy_test.go` | REVIEW_OFR-REPEAT-1, REVIEW_OFR-REPEAT-2 |
| `apps/edge/internal/openai/stream_gate_pipeline_test.go` | REVIEW_OFR-REPEAT-1 |
| `apps/edge/internal/openai/stream_gate_vertical_slice_test.go` | REVIEW_OFR-REPEAT-2, REVIEW_OFR-REPEAT-3 |
| `apps/edge/internal/openai/filter_observation_sink_test.go` | REVIEW_OFR-REPEAT-3, only if an observation allowlist gap is proven |
| `agent-contract/outer/openai-compatible-api.md`, `agent-spec/runtime/stream-evidence-gate.md`, `agent-spec/input/openai-compatible-surface.md`, `configs/edge.yaml` | REVIEW_OFR-REPEAT-1, only if current wording becomes inaccurate |
| `agent-test/runs/output-filter-recovery/**` | REVIEW_OFR-REPEAT-3, ignored runtime evidence only |

## Dependencies and Execution Order

1. Dependency `01_resume_notice_builder` is satisfied by `agent-task/archive/2026/07/m-openai-compatible-output-validation-filters/01_resume_notice_builder/complete.log`.
2. Complete REVIEW_OFR-REPEAT-1 before acceptance fixtures because the fixture expectations depend on the corrected hold shape.
3. Complete local REVIEW_OFR-REPEAT-2 and the evidence parser in REVIEW_OFR-REPEAT-3 before creating a clean deployment basis.
4. Run clean same-ref dev verification last; do not reuse the July 24 runtime or deploy a dirty patch.

## Final Verification

```bash
go version && go env GOMOD
git diff --check
go test -race -count=1 ./apps/edge/internal/openai -run 'Test(RepeatGuardSplitToolArguments|OpenAIRepeatHistoryLatestPairWins|RepeatGuardSixParagraphKoreanRolling|RepeatGuardAssistantHistoryAnchorDecision|DevRepeatGuardSmokeEvidence|DevRepeatGuardObservationCorrelation)'
go test -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai
make test
```

Expected: all commands exit 0; targeted Go output is fresh and uncached.

Dev preflight must record:

```bash
git status --short
git rev-parse --abbrev-ref HEAD
git rev-parse HEAD
git fetch origin main
git rev-parse origin/main
go version && go env GOMOD
./build/dev-runtime/bin/edge --help
./build/dev-runtime/bin/edge version
shasum -a 256 ./build/dev-runtime/bin/edge
go test -count=1 ./apps/edge/...
./build/dev-runtime/bin/edge smoke openai --base-url http://127.0.0.1:18083
```

Before the final live command, prove the checkout is clean at the approved ref and every participating Edge/Node binary and running process was rebuilt/redeployed/restarted from that ref. Record Edge id/ports, actual provider capacities, binary identities, and observation-log path. If any identity cannot be established, do not run against stale binaries; record the exact blocker and resume condition.

Then run the REVIEW_OFR-REPEAT-3 live command exactly as written and verify 15 sanitized attempt rows, capacity peak/queue behavior, final provider recovery, and no tracked raw artifact.

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