fix(agent-access): harden ssh-agent session lifecycle #80
No reviewers
Labels
No labels
W6d-automerge-calibration
agent/claude-code
agent/codex
agent/hermes
agent/iskra
agent/ollama
agent/patchwarden
automerge-candidate
class/security-sensitive
cutover-gate
dependency/blocked
dependency/blocks-others
dependency/cross-repo
dependency/needs-confirmation
domain:agents
domain:ci
domain:docs
domain:forgejo
domain:infra
domain:memory
domain:runtime
domain:signal
domain:ux
flow/architecture
flow/blocked
flow/deployed
flow/done
flow/implementation
flow/intake
flow/maintained
flow/observed
flow/ready
flow/refining
flow/retired
flow/review
iterating
judge/codex-candidate
judge/hermes-candidate
judge/low-confidence
judge/needs-refinement
judge/operator-needed
judge/p0
judge/p1
judge/p2
judge/p3
judge/park
judge/patchwarden-candidate
judge/stale-priority
kind/adr
kind/bug
kind/chore
kind/feature
kind/infra
kind/ops
kind/refactor
kind/research
large-impact
merge/auto
merge/manual
merge/manual-dependency-conflict
merge/manual-failing-tests
merge/manual-merge-conflict
merge/manual-missing-review
merge/manual-operator-preference
merge/manual-red-zone
merge/manual-security-sensitive
merge/manual-unclear-scope
merge/manual-unknown
meta
mode:operator-only
mode:patchwarden-iskra-approved
mode:safe-auto
needs-operator-decision
needs-triage
not-ready
observed/erroring
observed/needs-followup
observed/pending
observed/retire-candidate
observed/unused
observed/used
operator-emotional
owner-attention
phase/02
phase/03
priority:p0
priority:p1
priority:p2
priority:p3
proposed
ready-for-agent
ready-for-operator
recovery
review:claude-reviewed
review:codex-reviewed
review:dziadek-reviewed
review:needs-human
risk/exposure
risk/process
risk/product
risk/runtime
safety:external-write
safety:no-prod-mutation
safety:prod-impact
safety:secret-touch
size/large
size/medium
size/small
size/tiny
size/unknown
source/adr
source/agent-generated
source/manual
source/operator-chat
source/voice-note
status:blocked
status:codex-ready
status:merged:pending-evidence
status:needs-evidence
status:operator-needed
status:parked
tier/full
tier/lite
tier/stacked
tier:0-platform-substrate
tier:1-iskra-value-layer
tier:2-tools-products-modules
type:bug
type:chore
type:docs
type:feat
type:policy
type:research
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
pdurlej/platform!80
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "codex/issues/79-agent-access-lifecycle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Canary status: approve_with_evidence_gap — 3-iteration cap reached; final SHA
852e04aa55740789033b0a1d52f955fc204bb86bmitigates the last code finding locally, with no 4th canary rerunCanary Context Pack
Product story
The first Agent Access Plane SSH slice is merged, but the local session lifecycle still needs boring operator-safe cleanup. Codex should be able to inspect and clean non-secret ssh-agent session state without needing the OpenClaw private key again, and without accidentally deleting handles to a live or unknown session.
What changed
--listfor non-secret session inventory with lifecycle status: active, stopped, expired, unknown.--prunefor stopped and expired session directories only.--pruneskips active and unknown/malformed sessions by default.ssh-agent; if shutdown cannot be confirmed, the session directory is kept.metadata.session_idexactly matches the session directory name; mismatches becomeunknownand are not pruned.agent.sock,stopped_at, list/prune usage, and socket access-bearing semantics.Why it changed
PR #77 intentionally shipped the narrow SSH capability first and left lifecycle hardening as follow-up #79. This PR closes that gap before more Agent Access Plane capabilities reuse the same runtime shape.
Files touched
scripts/agent-access/codex-openclaw-ssh-agentcontrol-plane/platformctl/tests/test_agent_access_ssh_agent.pydocs/agent-access/codex-openclaw-ssh.mdstate/runtime-layout.mdRelevant context
state/runtime-layout.md: canonical non-secret runtime state structure.Runtime evidence
PYTHONPATH=control-plane pytest -q control-plane/platformctl/tests/test_agent_access_ssh_agent.py->10 passedPYTHONPATH=control-plane pytest -q control-plane/platformctl/tests->157 passedgit diff --check-> pass--listlisted two stopped prior sessions,--prunepruned both, next--listreturnedNO_SESSIONS--list->NO_SESSIONS;--prune->PRUNE_DONE count=0Canary iteration notes
defer; mitigated unknown auto-prune, prune-before-agent-stop, and naive timestamp handling.defer; mitigated non-objectmetadata.json, prune help text mismatch, and keeping state when recorded agent shutdown cannot be confirmed.defer; mitigated the remaining real code finding locally by requiringmetadata.session_id == session_dir.namebefore trusting metadata.approve_with_evidence_gap, notapprove_merge, because canary cap prevents a 4th rerun after the final local patch.Known constraints
agent.sockremains an access-bearing bearer capability while the ssh-agent is alive; this PR documents that and leaves active/unknown sessions untouched by prune.Explicit out-of-scope
Requested decision
Operator may merge if accepting the evidence gap above. Otherwise split/rewrite is the clean terminal alternative under the hard cap.
Merge blockers
--prunedeleting active or unknown/malformed sessions.--pruneremoving stopped/expired session handles when recorded agent shutdown cannot be confirmed.Spec sources read
scripts/agent-access/codex-openclaw-ssh-agent: implementation target from PR #77.control-plane/platformctl/tests/test_agent_access_ssh_agent.py: existing acceptance tests and new regression coverage.docs/agent-access/codex-openclaw-ssh.md: operator runbook for the wrapper.state/runtime-layout.md: runtime state layout contract.Closes #79
1b3bbf004ede0188be35de0188be3594a6cddec694a6cddec6852e04aa55Canary terminal update for PR #80
defer; mitigated unknown auto-prune and prune-before-agent-stop risks.defer; mitigated non-object metadata, prune help text mismatch, and unconfirmed agent-shutdown cleanup.defer; final real code finding was metadata/session-id mismatch. Final SHA852e04aa55740789033b0a1d52f955fc204bb86bnow treats mismatched metadata asunknownand skips prune; local tests pass.Terminal action after hard cap:
approve_with_evidence_gap.Residual gap: no 4th canary rerun on final SHA; product-gpt kept reporting an empty PR description even though the PR body is present via Forgejo API; size concern remains visible. Operator can merge accepting this, or choose split/rewrite.
Superseded by split/rewrite path.
Operator decision: this access-plane hardening is security-sensitive, so more review friction is intentional. I am not asking to merge this combined PR. I will split it into smaller PRs with narrower canary surfaces.
Pull request closed