<!-- task=m-principal-provider-credential-slot-routing/08+03,04,07_secure_delivery plan=5 tag=REVIEW_REVIEW_REVIEW_REVIEW_API milestone-task=secure-transport,credential-lease,adapter-injection,revocation -->

# Bounded Cancellable Projection Fan-out Follow-up

## For the Implementing Agent

Filling the implementation-owned sections of `CODE_REVIEW-cloud-G07.md` is mandatory. Implement the item below, run every verification command exactly, paste actual notes and stdout/stderr into the review artifact, keep both active files in place, and report ready for review. Final verdicts, log archives, `complete.log`, task moves, user-review classification, and control-plane stop files belong only to the code-review workflow. If blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence; do not ask the user or classify the next state.

## Background

The enrollment-name and same-generation renewal fixes pass focused, race, package, and three-process verification. The remaining production gap is inside Control Plane projection fan-out: sends are serial, and proto-socket starts its request timeout only after a potentially unbounded socket write. One non-reading Edge can therefore block refresh for every other Edge and prevent `EdgeServer.Stop` from completing.

## Archive Evidence Snapshot

- `plan_cloud_G10_4.log` and `code_review_cloud_G10_4.log`: current-pair predicted archives; verdict `FAIL` with 1 Required, 0 Suggested, and 0 Nit findings. Fresh reviewer verification passed, but dependency inspection proved that projection fan-out and shutdown are not bounded across a stalled socket write.
- `plan_cloud_G10_3.log` and `code_review_cloud_G10_3.log`: prior loop with two Required identity/freshness findings. The current source and fresh reviewer tests prove that enrollment-name binding and immutable same-generation renewal are now implemented.
- `agent-task/archive/2026/08/m-principal-provider-credential-slot-routing/03+01,02_projection_auth/complete.log` and `agent-task/archive/2026/08/m-principal-provider-credential-slot-routing/07+01,02,05_secret_material/complete.log`: secret-free projection/cache and secret-at-rest prerequisites remain satisfied.

## Analysis

### Files Read

- `apps/control-plane/internal/wire/edge_server.go`
- `apps/control-plane/internal/wire/edge_server_test.go`
- `apps/control-plane/internal/wire/edge.go`
- `apps/control-plane/internal/wire/wire.go`
- `apps/control-plane/cmd/control-plane/server.go`
- `apps/edge/internal/authprojection/cache.go`
- `apps/edge/internal/authprojection/cache_test.go`
- `apps/edge/internal/controlplane/connector.go`
- `apps/edge/internal/controlplane/connector_test.go`
- `apps/edge/internal/transport/server.go`
- `apps/edge/internal/transport/connection_handlers.go`
- `apps/edge/internal/transport/integration_test.go`
- `packages/go/auth/auth.go`
- `packages/go/auth/auth_test.go`
- `apps/control-plane/internal/credentialstore/projection.go`
- `Makefile`
- `/config/workspace/proto-socket/go/communicator.go`
- `/config/workspace/proto-socket/go/base_client.go`
- `/config/workspace/proto-socket/go/tcp_client.go`
- `agent-roadmap/phase/operational-observability-provider-management/milestones/principal-provider-credential-slot-routing.md`
- `agent-roadmap/sdd/operational-observability-provider-management/principal-provider-credential-slot-routing/SDD.md`
- `agent-contract/inner/control-plane-edge-wire.md`
- `agent-contract/inner/edge-node-runtime-wire.md`
- `agent-spec/control/control-plane-operations.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-task/m-principal-provider-credential-slot-routing/08+03,04,07_secure_delivery/PLAN-cloud-G10.md`
- `agent-task/m-principal-provider-credential-slot-routing/08+03,04,07_secure_delivery/CODE_REVIEW-cloud-G10.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/principal-provider-credential-slot-routing/SDD.md`, status approved, lock released.
- First-line Milestone tasks remain `secure-transport,credential-lease,adapter-injection,revocation`; this follow-up preserves the scope of the secure-delivery task.
- Acceptance S02 requires projection refresh before expiry, while S10-S13 require authenticated delivery and a fresh generation/revision fence through lease acquisition, adapter admission, and revocation.
- Evidence Map S09-S13 requires TLS, lease, upstream-auth, revocation-order, and secret-scan evidence. The checklist adds deterministic stalled-client/cancellation coverage and reruns the secure-delivery race and process-level packet.

### Verification Context

- No external handoff was supplied. Repository-native evidence came from the active pair, approved SDD, current source/tests, and the local proto-socket workspace dependency.
- Fresh reviewer commands passed: focused enrollment/renewal tests, affected race tests, all Control Plane/Edge/Node package tests, the secure-delivery three-process Make target, vet, `git diff --check`, and the structural secret guard.
- The passing responsive fixtures do not cover the defect. `BroadcastProjection` calls each Edge serially, while proto-socket `SendRequest` calls `QueuePacket` before creating its timeout; TCP writes have no deadline.
- Verification remains in the current checkout with the recorded `GOCACHE`, `GOTMPDIR`, and `TMPDIR` overrides. No user-owned runner, device, credential, or external authorization is required.
- Confidence: high. The blocking and shutdown cycle follows directly from the production call order and dependency implementation.

### Test Coverage Gaps

- Existing periodic refresh coverage proves two responsive clients receive updates and immediate rejection does not skip the next client.
- No test holds one projection request or stops reading from a live Edge while asserting that another Edge is attempted promptly.
- No test cancels or stops the Edge server while a projection push is blocked and asserts bounded shutdown with no leaked send goroutine.

### Symbol References

- None. No public or existing symbol must be renamed or removed; the fix may add private projection-send helpers used only by `BroadcastProjection`.

### Split Judgment

Keep one plan. Concurrent fan-out, per-client cancellation/deadline, result aggregation, and shutdown are one lifecycle invariant; separating them would leave either unbounded delivery or a goroutine/connection leak.

### Scope Rationale

- Do not modify proto-socket in the sibling workspace; Control Plane can enforce a bounded send by racing the existing request against context/deadline and closing the stalled client to unblock its write.
- Do not change projection content, generation semantics, lease cryptography, enrollment identity, public protobuf schemas, credential migration, contracts, specs, or tracked README text.
- Preserve serialized projection snapshot creation and broadcast batches; parallelize only the per-client pushes inside one batch.

### Final Routing

- Evaluation mode: `isolated-reassessment`.
- Finalizer: `finalize-task-policy.sh`, mode `pair`; build and review closures are true for scope, context, verification, evidence, ownership, and decision, with no capability gap.
- Build scores: scope coupling 1, state/concurrency 2, blast/irreversibility 1, evidence/diagnosis 2, verification complexity 1; grade G07, base route `local-fit`, final route `recovery-boundary`, lane `cloud`, filename `PLAN-cloud-G07.md`.
- Review scores: 1/2/1/2/1; grade G07, route `official-review`, lane `cloud`, filename `CODE_REVIEW-cloud-G07.md`.
- `large_indivisible_context=false`; positive loop-risk signatures are `temporal_state`, `concurrent_consistency`, and `boundary_contract` (`loop_risk_count=3`).
- Recovery signals: `review_rework_count=4`, `evidence_integrity_failure=true`; recovery boundary is matched.

## Implementation Checklist

- [ ] Bound and parallelize projection pushes so context cancellation or a per-client deadline closes and unblocks a stalled Edge, every snapshotted Edge is attempted independently, errors are aggregated, and server stop completes promptly; pass deterministic stalled-client and shutdown regressions.
- [ ] Run the focused, race, full secure-delivery, vet, diff, and secret-structure verification commands with fresh output.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_REVIEW_API-1] Bound and cancel projection fan-out

**Problem:** `apps/control-plane/internal/wire/edge_server.go:305-333` holds `broadcastMu` and sends projection requests serially. `apps/control-plane/internal/wire/edge_server.go:267-269` waits for that broadcast in the refresh goroutine, and `apps/control-plane/internal/wire/edge_server.go:276-289` waits for the goroutine before closing the TCP server. The apparent ten-second timeout does not cover the write: `/config/workspace/proto-socket/go/communicator.go:345-360` completes `QueuePacket` before starting the timer, while `/config/workspace/proto-socket/go/tcp_client.go:97-110` writes without a deadline. A non-reading Edge can therefore block all later clients and shutdown indefinitely.

**Before (`apps/control-plane/internal/wire/edge_server.go:321-333`):**

```go
var failures []error
for _, target := range clients {
    resp, sendErr := proto_socket.SendRequestTyped[*iop.PrincipalProjectionApplyRequest, *iop.PrincipalProjectionApplyResponse](
        &target.client.Communicator, &iop.PrincipalProjectionApplyRequest{Projection: projection}, 10*time.Second)
    if sendErr != nil {
        failures = append(failures, fmt.Errorf("push credential projection to edge %q: %w", target.edgeID, sendErr))
        continue
    }
    if !resp.GetApplied() {
        failures = append(failures, fmt.Errorf("push credential projection to edge %q rejected", target.edgeID))
    }
}
return errors.Join(failures...)
```

**Solution:** Snapshot the active clients as today, then start one independent push for every target so no client waits behind another. Add a private bounded send helper that runs the existing typed request, selects on result, caller context, and a per-client deadline, and closes the target client on cancellation/deadline so a blocked queue/write unblocks. Wait for every send goroutine, retain `broadcastMu` around one complete batch, collect indexed errors in snapshot order, and return `errors.Join`; do not leave goroutines or pending requests after cancellation. A timed-out Edge must disconnect and be removed by the existing token-fenced listener.

**After (`apps/control-plane/internal/wire/edge_server.go`):**

```go
failures := make([]error, len(clients))
var sends sync.WaitGroup
for index, target := range clients {
    sends.Add(1)
    go func() {
        defer sends.Done()
        failures[index] = s.pushProjection(ctx, target, projection, projectionPushTimeout)
    }()
}
sends.Wait()
return errors.Join(failures...)
```

The private helper must close the client when `ctx.Done()` or the deadline wins, wait for the request goroutine to exit, and return an Edge-qualified cancellation/timeout error.

**Modified Files and Checklist:**

- [ ] `apps/control-plane/internal/wire/edge_server.go` — add bounded cancellable per-client sends, concurrent all-client fan-out, leak-free waiting, and deterministic aggregate errors.
- [ ] `apps/control-plane/internal/wire/edge_server_test.go` — add stalled-client isolation and stop/cancellation regressions while retaining responsive, rejection, mutation, and shutdown cases.

**Test Strategy:** Add `TestEdgeServerBroadcastProjectionDoesNotLetStalledEdgeBlockHealthyEdge` with one request handler held on a channel and one responsive handler; require the responsive attempt before releasing the stalled handler and require a bounded aggregate error. Add `TestEdgeServerStopCancelsStalledProjectionRefresh` to start a short refresh interval, wait until the stalled request begins, call `Stop`, and require prompt completion without releasing the handler first. Use deterministic channels and bounded contexts, then run the wire package with `-race`.

**Verification:**

```bash
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go test -count=1 ./apps/control-plane/internal/wire -run 'TestEdgeServer(BroadcastProjectionDoesNotLetStalledEdgeBlockHealthyEdge|StopCancelsStalledProjectionRefresh|PeriodicallyRefreshesEveryActiveEdge|BroadcastProjectionAttemptsAllActiveEdges)'
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go test -count=1 -race ./apps/control-plane/internal/wire
```

Expected: both commands exit 0; a stalled Edge is disconnected within the bound, a healthy Edge is attempted independently, cancellation stops the refresh without a goroutine leak, and responsive/rejecting clients retain current behavior.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/control-plane/internal/wire/edge_server.go` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `apps/control-plane/internal/wire/edge_server_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `agent-task/m-principal-provider-credential-slot-routing/08+03,04,07_secure_delivery/CODE_REVIEW-cloud-G07.md` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |

## Final Verification

Fresh execution is required; cached `go test` output is not acceptable.

```bash
command -v go && go version && go env GOROOT
test -f agent-task/archive/2026/08/m-principal-provider-credential-slot-routing/07+01,02,05_secret_material/complete.log
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go test -count=1 ./packages/go/auth ./packages/go/config ./packages/go/credentiallease
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go test -count=1 ./apps/control-plane/... ./apps/edge/... ./apps/node/...
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go test -count=1 -race ./packages/go/auth ./packages/go/credentiallease ./apps/control-plane/internal/credentiallease ./apps/control-plane/internal/wire ./apps/edge/internal/authprojection ./apps/edge/internal/controlplane ./apps/edge/internal/service ./apps/edge/internal/transport ./apps/node/internal/node
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery make test-control-plane-edge-wire
env GOCACHE=/config/tmp/gocache-secure-delivery GOTMPDIR=/config/workspace/.gotmp-iop-secure-delivery TMPDIR=/config/workspace/.gotmp-iop-secure-delivery go vet ./apps/control-plane/... ./apps/edge/... ./apps/node/... ./packages/go/...
git diff --check
if rg --sort path -n 'bytes[[:space:]]+(secret|provider_secret)|map<string, string>[[:space:]]+(credential|provider_auth)' proto/iop/runtime.proto; then exit 1; fi
```

Expected: every command exits 0; focused tests prove bounded fan-out and stop cancellation, race detection reports no issue, and the existing three-process fixture still proves mTLS, sealed lease delivery, exact upstream authorization, revocation ordering, and secret sentinel absence.

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