Skip to content

fix(server): make J5 agent archive reversible and separate deletion - #132

Merged
Jacksondr5 merged 3 commits into
j5/mainfrom
j5/lifecycle-alignment
Sep 12, 2026
Merged

Jacksondr5 merged 3 commits into
j5/mainfrom
j5/lifecycle-alignment

Conversation

@Jacksondr5

Copy link
Copy Markdown
Owner

What Changed

Make J5 agent archive reversible while keeping deletion permanent. Archive preserves identity, Squadron home and provenance, hides the agent from the default directory, blocks new messaging, and closes Exchanges with durable notices. list_participants(include_archived: true) exposes archived agents; unarchive restores addressability without reopening Exchanges or replaying cancelled work.

Deletion removes current membership and placement while preserving surviving agents and historical provenance. Migration 11 adds distinct archive/unarchive/delete events; legacy participant.left records remain permanently retired.

Why

J5 previously treated archive as permanent retirement. This aligns lifecycle behavior with upstream before integration, using only J5-owned code and existing orchestration commands. Send admission is serialized against archive so no new Exchange can be stranded. Queued deliveries are withdrawn before being marked cancelled; accepted running work is recorded as delivered when ordinary archive leaves it executing. archive_agent retains its confirmation and interruption behavior.

Validation

  • Implementation agent: 130 distinct tests passed across 12 focused files; scoped lint, server typecheck and diff checks passed.
  • Independent Fable review of 6660cec298b6ddd01326ea4b0a6c6d331794a998: ready to land; 93 tests passed across nine focused files. Reviewed for correctness, simplicity, YAGNI and fork discipline.
  • Coverage includes direct/reactor transition deduplication, repeated archive cycles, replay/rebuild, migration compatibility, recipient and sender archive cancellation, unarchive without queued replay, and accepted running deliveries.
  • Tests use in-memory SQLite and an orchestrator harness. No live database, provider process, browser, desktop/mobile or remote connection verification was performed.

Remaining limits

A persistent cancellation transport error can repeatedly select the earliest delivery and delay later deliveries. Independent review classified this as a non-blocking follow-up; the proposed fix reuses delivery failure backoff. Pending-steer cancellation and the queue-promotion-wins race were inspected but not independently forced in new tests.

Migration 11 rebuilds ledger tables to extend SQLite constraints. Legacy recovery and physical orphan-content cleanup remain outside this change.

Implemented with GPT-6 Astra in the Codex harness; independently reviewed with Claude Fable 5.1 in the Claude agent harness. PR prepared with GPT-6 in Codex.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 effective changed lines (test files excluded in mixed PRs). labels Sep 12, 2026
@Jacksondr5

Copy link
Copy Markdown
Owner Author

Live web verification completed on 6660cec298b6ddd01326ea4b0a6c6d331794a998; current head 56b47ef5281ee17f71837254b418b5089fb51391 adds only the CI test correction described below.

  • Controlled local Chromium/Playwright, isolated dev home, disposable project, and real Codex GPT-5.6-Sol turns. No shared database writes, copied-project execution, deployment, or dependency changes.
  • A consistent read-only VACUUM INTO copy of existing data passed migration 11 and the production persistence-startup initializer: integrity_check=ok, zero foreign-key violations. The copied data was kept separate from the interactive server.
  • Created a Squadron through the UI. A live agent opened one human ask and one peer ask to its disposable child. The archive confirmation listed both asks. Single-target archive through the browser's application command produced one archive fact and two dropped Exchanges; the child received its terminal system notice. The human inbox became empty after refresh, with a durable dropped row and notice ID. This matches IB6: the archive warning is the visible notice; dropped asks do not get a terminal UI shelf.
  • The archived parent disappeared from the normal sidebar and appeared in Settings → Archive. Live list_participants calls confirmed it is absent by default, included with archived=true, and unaddressable with include_archived=true.
  • UI Unarchive restored the same identity and Squadron, without new registration or reopened Exchanges. A second archive/unarchive cycle also preserved the original two dropped Exchanges.
  • Real app command receipts for active turn / queued sentinel / archive / unarchive were sequences 281 / 293 / 298 / 299. The queued sentinel was cancelled and never ran. The immediate active fixture was interrupted by the real application/provider lifecycle path; this pass does not establish that ordinary archive always leaves an active run running. The direct-service distinction remains covered by focused tests. archive_agent confirmation/interruption was not separately exercised with a live provider in this pass.
  • UI Delete removed the parent membership; no parent placement remained. Its child stayed visible. A live directory call reported placement_parent_id=null, with spawned-by provenance still identifying the deleted parent; peer history and notices survived.
  • Created a disposable legacy fixture through the canonical ledger API (participant.joined then legacy participant.left) while the isolated server was stopped, without projection seeding. After restart and UI Unarchive, the legacy participant remained absent even from the inclusive directory, with no replacement membership or unarchive fact. The source data snapshot contained no existing legacy-retired rows.

Final durable evidence:

participant.archived = 2; participant.unarchived = 2; participant.deleted = 1
exchange.dropped = 2; open Exchanges = 0
human inbox = dropped / sender-retired / terminal notice present
live membership = surviving child only
legacy history = participant.joined, participant.left; live membership absent
browser page errors = 0

Runtime observations: expected missing-editor/non-remote-repository probes, a provider-update banner, and one malformed spawn_agent reasoning argument that the live agent corrected. No lifecycle failure was found. Local screenshots and the sanitized durable audit are retained under /tmp/pr132-live.H6RuFO/evidence; server home /tmp/pr132-live.H6RuFO/ui, web http://localhost:6462, server port 14502.

CI exposed one stale startup-test assertion expecting 10 J5 migrations. Commit 56b47ef5281ee17f71837254b418b5089fb51391 compares applied migration IDs/names with the current manifest instead. 14 focused compatibility tests pass; scoped lint, formatting and server typecheck pass. No production code changed after Fable's READY TO LAND review. The previously reviewed lifecycle suite remains 130 focused tests plus Fable's 93 independent tests. No new bot/reviewer findings were present when checked. Squash auto-merge will be pinned to the current head and will honor required checks.

@Jacksondr5
Jacksondr5 enabled auto-merge (squash) September 12, 2026 18:47
@Jacksondr5
Jacksondr5 merged commit 6b4eb55 into j5/main Sep 12, 2026
20 checks passed
@Jacksondr5
Jacksondr5 deleted the j5/lifecycle-alignment branch September 12, 2026 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant