- Config.MCPTokensPurge + scheduleEntry branch
- app.go constructs runner with mcpTokensPurgeAdapter
- Registered as 'mcp_tokens_purge' in RunnerFns map
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- mcpTokens dep added to Supervisor; nil-safe (test fixtures may skip)
- RevokeBySession called after audit Record in onExit
- app.go wires mcpTokenSvc (was nil placeholder)
- Integration test: fakeSupMCPTokens verifies onExit calls RevokeBySession
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- extraEnv overrides agent_kinds.encrypted_env same-name keys (spec §6.1 #11)
- Prevents admin from hard-coding ACW_MCP_TOKEN in agent_kinds
- SessionService passes nil for now; system token wiring lands in I4
- BuildSpawnEnv exported for testing the override priority
- Fix app.go NewSupervisor call to match updated signature (from I5)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- workspace.ResetStuckSyncStatuses now returns affected IDs so app.New can record one workspace.sync_aborted_on_restart audit per reset row
- worktree_prune audit metadata gains workspace_id and path alongside existing branch
- updated fakeRepo + integration test for new ResetStuckSyncStatuses signature
- add TestWorktreePrune_AuditMetadataContainsWorkspaceIDAndPath
Deferred audit retrofits from Plan #5 self-review:
- WebhookNotifier now records a job.enqueue audit row after each
successful repo.Enqueue (best-effort: failures are warn-logged, not
propagated). Added optional audit.Recorder + *slog.Logger params to
NewWebhookNotifier.
- WorktreePrune.executionPhase now records a worktree.pruned audit row
after each successful FinishPruneSuccess. Added optional audit.Recorder
param to NewWorktreePrune.
- app.go wires the existing auditRec into both constructors.
- integration_test.go: drop the _ = auditRec suppression and pass
auditRec into the webhook notifier so the closed-loop test exercises
the audit emit path.
Final cross-cutting review finding: shutCtx was shared between
server.Shutdown and dispatcher.Shutdown, with jobs.Stop's wall-clock
time burning the budget in between. Under load, dispatcher.Shutdown
could receive an already-dead ctx and skip draining in-flight async
notify dispatches (including webhook enqueues). Mirror the errCh
branch by creating a fresh 10s drainCtx for dispatcher.Shutdown.
Code review fixes for T16:
- Pass cfg.Jobs.ShutdownGrace+5s to jobs.Stop call-site context (was
hard-coded 30s, would mask configured longer grace).
- Guard jobs.Stop block on cfg.Jobs.Enabled so disabled jobs don't
spin up the no-op shutdown goroutine + timer.
- Use clock.Real().Now() in deadLetterFn for consistency with the rest
of the jobs wiring.