feat(lifecycle): add irreversible resident retirement - #116
feat(lifecycle): add irreversible resident retirement#116ian-de-marcellus wants to merge 2 commits into
Conversation
Co-Authored-By: GPT-5.6 Codex <noreply@openai.com>
Co-Authored-By: GPT-5.6 Codex <noreply@openai.com>
antra-tess
left a comment
There was a problem hiding this comment.
From the 08-26 review sweep, plus maintainer direction after discussion. The mechanism you built is genuinely careful — two forced turns, cooling-off, one-use challenge, timing-safe compare, honest semantics text, append-only fsynced seal — and the integration suite is strong. The requested changes are architectural first, then a short list of holes found in review.
Architectural direction: the resident-facing surface of this belongs in connectome-host, not the framework. The framework is the right home for the enforcement primitive — the seal file, loadRetirementSeals, and the inference-denial guards can only live here. But the tool itself — its name, description/consent text, ceremony shape (challenge, cooling-off, confirmation phrase), and any operator-notification policy — should be host-composable rather than a fixed built-in. Concretely: AF exposes an imperative API (e.g. framework.retireResident(name, {reason}) — irreversible, sealed, guarded — plus the lifecycle status query and perhaps the challenge/cooling-off helpers), and connectome-host builds the resident-facing tool on top, so deployments can shape the wording, the ceremony, and whether a human is notified at request time. Your two-turn design would make a fine default implementation of that host-side surface; we just don't want its exact wording and policy frozen into AF.
Findings that apply to the enforcement half regardless:
-
Fork resurrection (must-fix):
createConversationAgentseeds a conversation fork from the retired template's still-compiling context under a fresh agent name — every retirement guard checks the fork's name and passes, so a single channel message can revive the retired resident's full context and identity prompt. Needs a router guard (refuse spawning from a retired template), or an explicit statement that forks are outside the seal's scope. -
puppetToolCall interaction (landed on main after you branched): with the lifecycle tool on
getToolsForAgent's surface, puppet's existence check passes,executeToolCallfails 'unknown tool', and the forged 'resident requested retirement (errored)' pair is stored into the sealed identity's history. Exclude the lifecycle tool from puppet's surface on rebase. -
Torn seal line — decided: fail loud and fail closed is the intended behavior. A torn/invalid line in
resident-retirements.jsonlrefusing to boot the whole host is accepted; please pin it with a test (and cover challenge-TTL expiry) so it's deliberate rather than incidental, and document the recovery expectation (manual inspection of the named file:line). -
Minor: gate timers/sleep state for a retiree stay armed (permanent dropped-request churn — clear them in
stopResidentAuthoredActivity); running ephemeral subagents spawned by the resident aren't stopped at confirmation (document or stop them).
Suggested path: keep this PR's seal + guards + denial surface + tests as the framework primitive with the imperative API, and move the tool definition + ceremony to a companion connectome-host PR — happy to discuss the interface split there. Also needs a rebase (#123/#126 conflicts).
Problem
Persistent resident agents can end a turn or enter reversible dormancy, and operators can erase stored data, but there is no agent-callable terminal lifecycle state that permanently prevents future inference while preserving the identity’s Chronicle and history.
Changes
AgentConfig.retirementand a per-residentresident_lifecycletool. Ephemeral agents and per-channel conversation forks do not receive it.Tests
npm run build: passnpm test: 598 pass / 0 fail / 1 existing skipgit diff --check: passNot verified
Out of scope
Companion PRs
A companion
connectome-hostrecipe change is prepared on ian-de-marcellus/connectome-host:feat/resident-retirement.Merge and release this Agent Framework change first. The Host companion can then update its dependency range and lockfile to the released version before becoming ready to merge.
If only this PR lands, the generic lifecycle API becomes available to hosts, but Connectome recipes do not yet expose it.
CHANGELOG.mdupdated under## Unreleased.🤖 Generated with OpenAI Codex