<!-- task=m-iop-agent-cli-runtime/20+13,17_project_log_journal plan=4 tag=REVIEW_API -->

# Type Malformed JSONL as an Archive Conflict

## For the Implementing Agent

Filling every implementation-owned section in `CODE_REVIEW-*-G??.md` is mandatory. Implement the checklist, run every verification command, paste actual notes and stdout/stderr into the review file, keep both active files in place, and report ready for review; finalization is owned by the code-review skill. 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`.

## Background

The fourth review confirmed exclusive archive ordinal ownership and typed malformed-intent handling, but found one remaining corruption classification gap. A syntactically malformed JSONL payload whose bytes match the persisted intent checksum returns a raw decoder error instead of the archive verifier's typed `ErrArchiveConflict`, even though the journal and artifacts correctly remain unmodified.

## Archive Evidence Snapshot

- Prior task: `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal`
- Predicted current-loop evidence: `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/plan_cloud_G09_3.log` and `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/code_review_cloud_G09_3.log`
- Verdict: FAIL
- Findings: one Required finding for checksum-consistent malformed JSONL escaping typed archive-conflict classification; no Suggested or Nit findings
- Affected files: `apps/agent/internal/projectlog/store.go`, `apps/agent/internal/projectlog/store_test.go`
- Verification evidence: all declared focused, package, race, vet, formatting, and diff commands passed; a reviewer-only focused reproducer returned `projectlog: decode jsonl: ...` and failed `errors.Is(err, ErrArchiveConflict)`
- Roadmap carryover: this remains an S12 `project-logs` journal subset and does not claim the Milestone Task on PASS; EventSink mapping, WORK_LOG projection, and the complete dynamic frontier remain in later children

## Analysis

### Files Read

- `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/PLAN-cloud-G09.md`
- `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/CODE_REVIEW-cloud-G09.md`
- `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/plan_cloud_G09_2.log`
- `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/code_review_cloud_G09_2.log`
- `apps/agent/internal/projectlog/store.go`
- `apps/agent/internal/projectlog/store_test.go`
- `apps/agent/internal/projectlog/record.go`
- `packages/go/agentstate/store.go`
- `agent-contract/index.md`
- `agent-contract/inner/iop-agent-cli-runtime.md`
- `agent-spec/index.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`
- `agent-ops/rules/project/domain/agent/rules.md`
- `agent-test/local/rules.md`
- `agent-task/archive/2026/07/m-iop-agent-cli-runtime/13_agent_domain/complete.log`
- `agent-task/archive/2026/07/m-iop-agent-cli-runtime/17+13_project_log_records/complete.log`

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`
- Status: approved; SDD lock released; no active SDD `USER_REVIEW.md`
- Targeted scenario: S12, Milestone Task `project-logs`
- Acceptance: stable task loop/attempt/locator identity and exactly-once archive/cleanup only after terminal closure
- Evidence Map: S12 requires archive reconciliation fixtures and exactly-once archive evidence
- Plan effect: the checklist preserves the existing no-mutation behavior while making malformed JSONL a typed conflict in both Archive and Reconcile. PASS remains child-level evidence and does not claim `project-logs`.

### Verification Context

- Supplied handoff: none
- Repository-native sources: `agent-test/local/rules.md`, active and archived loop evidence, the project-log store and tests, the standalone runtime contract, and SDD S12
- Preflight: `/config/.local/bin/go` resolves to `/config/opt/go/bin/go`; `go version go1.26.2 linux/arm64`; `GOROOT=/config/opt/go`
- Current checkout: intentionally dirty shared checkout with unrelated sibling task artifacts; this child owns only `store.go`, `store_test.go`, and its active review evidence
- Fresh reviewer results: both declared focused commands, the final focused matrix, full package suite, project-log/agentstate race suite, vet, formatting, and `git diff --check` passed
- Reviewer reproducer: a pending archive's JSONL was replaced with malformed JSON and the intent checksum was updated to those exact bytes; Reconcile returned a raw `decode jsonl` error instead of satisfying `errors.Is(err, ErrArchiveConflict)`
- External verification: not applicable; deterministic filesystem/CAS tests require no service, credential, remote runner, port, or OS-specific device
- Gap: existing tests cover malformed intent, checksum mismatch, manifest drift, and timeline drift, but not syntactically malformed JSONL after checksum admission
- Confidence: high; the failure is a deterministic local filesystem reproducer at one verifier branch

### Test Coverage Gaps

- Archive path: no regression proves checksum-consistent malformed JSONL returns `ErrArchiveConflict` while retaining the exact journal revision and artifact bytes.
- Reconcile path: no regression proves the same typed error and no-mutation behavior during restart recovery.
- Intent, checksum-mismatch, manifest, timeline, immutable ordinal, retry, and concurrent suffix cases remain covered.

### Symbol References

None. No symbol is renamed or removed.

### Split Judgment

Keep one plan. The production change and its Archive/Reconcile regressions are one compact typed-error boundary and cannot produce useful independent completion evidence. Predecessor `13_agent_domain` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/13_agent_domain/complete.log`; predecessor `17+13_project_log_records` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/17+13_project_log_records/complete.log`.

### Scope Rationale

Modify only `store.go`, `store_test.go`, and the active review evidence file. Do not change archive/journal schemas, lock ownership, CAS pruning, `agentstate.Store`, EventSink mapping, WORK_LOG rendering, CLI wiring, contracts, SDD, roadmap state, or the complete S12 scenario.

### Final Routing

- status: `routed`
- evaluation_mode: `isolated-reassessment`
- finalizer: `finalize-task-policy.sh pair`
- build closures: scope/context/verification/evidence/ownership/decision all closed; no capability gap
- build grade scores: scope `1`, state `1`, blast `1`, evidence `1`, verification `1` -> `G05`
- build base route: `local-fit`; recovery boundary matched with `review_rework_count=4` and `evidence_integrity_failure=false`
- build route: `recovery-boundary`, lane `cloud`, filename `PLAN-cloud-G05.md`
- review closures: scope/context/verification/evidence/ownership/decision all closed; no capability gap
- review grade scores: scope `1`, state `1`, blast `1`, evidence `1`, verification `1` -> `G05`
- review route: `official-review`, lane `cloud`, filename `CODE_REVIEW-cloud-G05.md`
- large_indivisible_context: `false`
- matched loop risks: `temporal_state`, `structured_interpretation` (count `2`)
- capability-gap evidence: none

## Implementation Checklist

- [ ] Wrap checksum-admitted malformed JSONL decode failures with `ErrArchiveConflict` while retaining decoder detail, and add deterministic Archive/Reconcile no-mutation regressions.
- [ ] Run fresh focused, package, race, vet, formatting, and diff verification.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_API-1] Type Malformed JSONL as Archive Conflict

#### Problem

`apps/agent/internal/projectlog/store.go:517-520` verifies the JSONL checksum and then returns a raw `decodeJSONL` error. Persisted JSONL can therefore pass checksum admission against its intent but escape `ErrArchiveConflict` when its syntax is malformed, violating the verifier's typed-conflict contract.

#### Solution

Wrap the JSONL decoder failure with `ErrArchiveConflict` while retaining the decoder detail. Preserve missing JSONL as `ErrArchiveIncomplete`, checksum mismatch as `ErrArchiveConflict`, and all existing record/manifest/timeline validation.

Before (`store.go:517-520`):

```go
records, err := decodeJSONL(jsonlData)
if err != nil {
	return archiveIntent{}, nil, fmt.Errorf("projectlog: decode jsonl: %w", err)
}
```

After:

```go
records, err := decodeJSONL(jsonlData)
if err != nil {
	return archiveIntent{}, nil, fmt.Errorf("%w: decode jsonl: %v", ErrArchiveConflict, err)
}
```

#### Modified Files and Checklist

- [ ] `apps/agent/internal/projectlog/store.go` — expose malformed persisted JSONL through the typed archive-conflict sentinel without losing decoder context.
- [ ] `apps/agent/internal/projectlog/store_test.go` — add Archive and Reconcile regressions for checksum-consistent malformed JSONL with exact artifact/journal retention assertions.

#### Test Strategy

Add `TestArchiveRejectsMalformedJSONLWithMatchingIntentChecksum` and `TestReconcileRejectsMalformedJSONLWithMatchingIntentChecksum` in `store_test.go`. Materialize a pending archive, replace JSONL with invalid syntax, update the intent checksum to those exact bytes, snapshot all four artifacts plus journal payload/revision, and require `errors.Is(err, ErrArchiveConflict)` with byte-for-byte and revision identity after Archive or Reconcile. Do not use timing sleeps.

#### Verification

```bash
go test -count=1 ./apps/agent/internal/projectlog -run 'Test(Archive|Reconcile)RejectsMalformedJSONLWithMatchingIntentChecksum'
```

Expected: both paths return typed `ErrArchiveConflict`, preserve every artifact byte, and retain the exact journal payload/revision.

## Dependencies and Execution Order

- `13_agent_domain` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/13_agent_domain/complete.log`.
- `17+13_project_log_records` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/17+13_project_log_records/complete.log`.
- Implement REVIEW_API-1, run its focused regression, then run the complete package/race matrix.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/agent/internal/projectlog/store.go` | REVIEW_API-1 |
| `apps/agent/internal/projectlog/store_test.go` | REVIEW_API-1 |
| `agent-task/m-iop-agent-cli-runtime/20+13,17_project_log_journal/CODE_REVIEW-cloud-G05.md` | implementation evidence |

## Final Verification

```bash
gofmt -w apps/agent/internal/projectlog/store.go apps/agent/internal/projectlog/store_test.go
go test -count=1 ./apps/agent/internal/projectlog -run 'TestStore|TestArchive|TestReconcile'
go test -count=1 ./apps/agent/internal/projectlog
go test -count=1 -race ./apps/agent/internal/projectlog ./packages/go/agentstate
go vet ./apps/agent/internal/projectlog
test -z "$(gofmt -d apps/agent/internal/projectlog/store.go apps/agent/internal/projectlog/store_test.go)"
git diff --check
```

Expected: every fresh focused/package/race test passes; vet, formatting, and diff checks are clean; checksum-admitted malformed JSONL is always a typed conflict and never mutates retained evidence. Cached Go test output is not acceptable.

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