<!-- task=m-iop-agent-cli-runtime/10+06_state_recovery plan=3 tag=REVIEW_REVIEW_REVIEW_API -->

# Keep Early Claim Release Synchronized with the Live Lease Set

## For the Implementing Agent

Implement only the early claim-release correction below. Run every verification command, fill the implementation-owned sections of `CODE_REVIEW-cloud-G06.md` with actual notes and stdout/stderr, keep both active files in place, and report ready for review. If blocked, record the exact blocker, attempted commands/output, and resume condition only 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 is owned by the code-review skill.

## Background

The preceding follow-up correctly added same-snapshot CAS fencing, integration renewal, and exact-token cleanup. One early reconciliation branch now releases a project claim from durable state without removing the same handle from the live `leaseSet`. When another independent project follows a project blocked by a foreign workspace lease, the stale tracked handle turns the local blocker into a reconciliation-wide `ErrLeaseLost`.

## Archive Evidence Snapshot

- Prior plan: `agent-task/m-iop-agent-cli-runtime/10+06_state_recovery/plan_cloud_G07_2.log`
- Prior review: `agent-task/m-iop-agent-cli-runtime/10+06_state_recovery/code_review_cloud_G08_2.log`
- Verdict: `FAIL`
- Findings: Required=1, Suggested=0, Nit=0.
- Required finding: an early project claim is released durably after a foreign workspace conflict but remains in `leaseSet`, so the next independent project is fenced by the intentionally released token.
- Affected files: `packages/go/agenttask/reconcile.go` and `packages/go/agenttask/manager_test.go`.
- Fresh reviewer evidence: the focused lease matrix, twenty-repeat matrix, race suite, shared-package suite, vet, formatting, proto generation, contract search, and `git diff --check` all passed.
- Focused failure evidence: a two-project reviewer reproducer returned `agenttask lease ownership lost during operation: project lease a-blocked no longer matches`; the independent project never ran.
- Roadmap carryover: SDD S09 and Milestone task `state-recovery` remain incomplete until a project-local ownership conflict cannot abort another project.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- Milestone link: [Milestone document](agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md)
- Task ids:
  - `state-recovery`: singleton/workspace lease, checkpoint, restart reconciliation
- Completion mode: check-on-pass

## Analysis

### Files Read

- `AGENTS.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/rules/project/domain/testing/rules.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/skills/common/plan/templates/review-stub-template.md`
- `agent-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-spec/index.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-contract/index.md`
- `agent-contract/inner/agent-runtime.md`
- `agent-contract/inner/iop-agent-cli-runtime.md`
- `agent-roadmap/current.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`
- `packages/go/agenttask/manager.go`
- `packages/go/agenttask/intent.go`
- `packages/go/agenttask/reconcile.go`
- `packages/go/agenttask/integration_queue.go`
- `packages/go/agenttask/dispatch.go`
- `packages/go/agenttask/review.go`
- `packages/go/agenttask/ports.go`
- `packages/go/agenttask/test_support_test.go`
- `packages/go/agenttask/manager_test.go`
- `packages/go/agenttask/integration_queue_test.go`
- `agent-task/m-iop-agent-cli-runtime/10+06_state_recovery/plan_cloud_G07_2.log`
- `agent-task/m-iop-agent-cli-runtime/10+06_state_recovery/code_review_cloud_G08_2.log`

No living spec directly covers the standalone AgentTask state-recovery lease lifecycle. The current code, inner contracts, approved SDD, and tests remain authoritative.

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`; status approved and lock released.
- Target: S09 / `state-recovery`.
- Acceptance: device and workspace invocation ownership remain singular, valid work is not duplicated, and ambiguous recovery blocks without guessed state.
- Evidence Map: device singleton/workspace lease and restart tests must prove no duplicate owner and exact retained state.
- The checklist therefore keeps the foreign workspace token intact, removes only the current manager's exact project claim, and proves an unrelated project continues in the same reconciliation.

### Test Environment Rules

- `test_env=local`.
- `agent-test/local/rules.md` was present and read.
- Matching profile `agent-test/local/platform-common-smoke.md` was present and read.
- Apply environment identity capture, a focused deterministic regression, twenty-repeat coverage, the existing lease matrix, race verification, shared-package regression, vet, formatting, contract search, proto generation, and `git diff --check`.
- No profile contains structural placeholders or unresolved values.
- Full-cycle or external-provider verification is not applicable because this fix changes only the host-neutral in-memory reconciliation claim lifecycle and no binary entrypoint, transport, provider, config, or proto contract.

### Test Coverage Gaps

- Existing single-project duplicate-workspace coverage proves the blocked project state and later recovery, but it does not place an independent project after the early claim release.
- Existing renewal, immediate-loss, CAS-retry, integration, cleanup, and successor-retention tests cover the rest of the lease invariant and must remain green.
- Add one deterministic two-project regression as the missing oracle.

### Symbol References

- No exported or internal symbol rename or removal is required.
- `leaseSet.Remove`, `Manager.releaseExact`, and the early `projectClaim` release call sites are the only relevant existing symbols.

### Split Judgment

Keep one plan. Removing a released claim from the live set and proving project-local isolation are one compact ownership invariant; either part alone would not close the regression.

### Scope Rationale

- Modify only `packages/go/agenttask/reconcile.go` and `packages/go/agenttask/manager_test.go`.
- Do not change `LeaseRecord`, token generation, renewal cadence, CAS fencing, integration claims, provider/reviewer/integrator behavior, contracts, SDD, roadmap state, or public APIs.
- Preserve all unrelated dirty-worktree changes.

### Final Routing

- `evaluation_mode=isolated-reassessment`
- `finalizer=finalize-task-policy.sh`, `finalizer_mode=pair`
- Build closures: scope/context/verification/evidence/ownership/decision all closed.
- Build closure basis: exact failing branch, deterministic reproducer, existing claim helpers, and bounded two-file fix.
- Build scores: scope=1, state=2, blast=1, evidence=1, verification=1; grade `G06`.
- Build base route basis: `local-fit`.
- Build route basis: `recovery-boundary`; lane `cloud`; filename `PLAN-cloud-G06.md`.
- Review closures: scope/context/verification/evidence/ownership/decision all closed.
- Review closure basis: exact contract violation, deterministic regression, and full local verification commands.
- Review scores: scope=1, state=2, blast=1, evidence=1, verification=1; grade `G06`.
- Review route: `official-review`; lane `cloud`; filename `CODE_REVIEW-cloud-G06.md`.
- Review adapter/model/effort: `codex`, `gpt-5.6-sol`, `xhigh`.
- `large_indivisible_context=false`
- Positive loop risks: `temporal_state`, `concurrent_consistency`, `boundary_contract`; count=3.
- Recovery signals: `review_rework_count=3`, `evidence_integrity_failure=false`.
- Capability gap: none.

## Implementation Checklist

- [x] Remove each early project claim from `leaseSet` before exact-token release so foreign workspace conflicts remain project-local.
- [x] Add a deterministic multi-project regression proving a blocked workspace owner does not fence an independent project and preserves the foreign lease.
- [x] Run the focused, repeated, race, shared-package, vet, formatting, contract, proto, and diff verification commands.
- [x] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_API-1] Retire early project claims before exact release

**Problem:** `packages/go/agenttask/reconcile.go:58-76` adds `projectClaim` to `leaseSet`, then the foreign-workspace branch releases its durable token and continues without removing the captured handle. The next iteration validates that intentionally released token, returns `ErrLeaseLost`, and prevents an independent project from running.

**Solution:** Pair every early project-claim release with `leases.Remove(projectClaim)` before `m.releaseExact`. Use the same local helper or ordered sequence for the post-load error, workspace-claim error, and foreign-workspace branches so no durable release can leave a stale live claim.

Before:

```go
// packages/go/agenttask/reconcile.go:58
leases.Add(projectClaim)
// ...
if workspaceClaim == nil {
	m.blockProject(ownedCtx, projectID, Blocker{ /* ... */ })
	m.releaseProject(context.WithoutCancel(ownedCtx), projectClaim.token, projectClaim.subject)
	continue
}
```

After:

```go
leases.Add(projectClaim)
releaseProjectClaim := func() {
	leases.Remove(projectClaim)
	m.releaseExact(ownedCtx, projectClaim)
}
// ...
if workspaceClaim == nil {
	m.blockProject(ownedCtx, projectID, Blocker{ /* ... */ })
	releaseProjectClaim()
	continue
}
```

**Modified Files and Checklist:**

- [x] `packages/go/agenttask/reconcile.go`: remove the captured project claim from the live set before every early exact-token release.
- [x] `packages/go/agenttask/manager_test.go`: add `TestWorkspaceLeaseConflictDoesNotFenceIndependentProject`.

**Test Strategy:** Add `TestWorkspaceLeaseConflictDoesNotFenceIndependentProject` with `a-blocked/workspace-a` and `b-independent/workspace-b`. Seed only `workspace-a` with a foreign unexpired token, run one reconciliation, and assert a nil error, the duplicate-workspace blocker on `a-blocked`, `b-independent` completed with exactly one provider invocation, the foreign token remains, and no owned project/workspace claims leak.

**Verification:** The new focused test must fail on the archived implementation and pass after the fix; repeat it with the existing lease matrix twenty times and under the package race suite.

## Modified Files Summary

| File | Item |
|---|---|
| `packages/go/agenttask/reconcile.go` | REVIEW_REVIEW_REVIEW_API-1 |
| `packages/go/agenttask/manager_test.go` | REVIEW_REVIEW_REVIEW_API-1 |

## Final Verification

```bash
command -v go && readlink -f "$(command -v go)" && go version && go env GOROOT
make proto
go test -count=1 -run '^TestWorkspaceLeaseConflictDoesNotFenceIndependentProject$' -v ./packages/go/agenttask
go test -count=1 -run '^(TestWorkspaceLeaseConflictDoesNotFenceIndependentProject|TestLeaseSupervisorRenewsAllTrackedScopesAndDeniesTakeover|TestLeaseLossImmediatelyFencesProviderAndReviewResults|TestLeaseLossImmediatelyFencesIntegrationResult|TestLeaseCleanupReleasesOwnedClaimsAndPreservesSuccessors)$' -v ./packages/go/agenttask
go test -count=20 -run '^(TestWorkspaceLeaseConflictDoesNotFenceIndependentProject|TestLeaseSupervisorRenewsAllTrackedScopesAndDeniesTakeover|TestLeaseLossImmediatelyFencesProviderAndReviewResults|TestLeaseLossImmediatelyFencesIntegrationResult|TestLeaseCleanupReleasesOwnedClaimsAndPreservesSuccessors)$' ./packages/go/agenttask
go test -count=1 -race ./packages/go/agentstate ./packages/go/agenttask
go test -count=1 ./packages/go/...
go vet ./packages/go/agentstate ./packages/go/agenttask
gofmt -d packages/go/agenttask/reconcile.go packages/go/agenttask/manager_test.go
rg --sort path -n 'Every external result|only exact tokens|atomic fence|project-local' agent-contract/inner/agent-runtime.md agent-contract/inner/iop-agent-cli-runtime.md
git diff --check
```

Every test command uses `-count=1` where fresh execution matters; cached output is not acceptable for the focused, race, or shared-package checks. Every command must exit zero.

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