Skip to content

Verify and close the projectless-adopt epic (relay) #587

Closed

Description

@barelyworkingcode

Child of #585. The close child (relay). Security story: it waits with the parent for the owner's approval.

User story

As the owner, I want the projectless-adopt epic merged to relay's main only after its checks pass on both heads together, so that main never holds half of it.

Acceptance criteria

  • Adopt a terminal Claude in no project: adopt, relaunch paths, session mark, audit, fakerelay #586 is merged to epic/585-projectless-adopt with its review and evidence lines.
  • A sync PR from sync/585-main merges main into the epic branch and says Closes #587.
  • The repo suite and the --stack run pass on the epic head, on a stack built with eve's epic head.
  • The devbox pass shows each step of the verification task below.
  • A Verified: line on this issue names the final epic head.
  • merge-check passes on the epic PR to main, and relay merges before eve.

What I'd notice

Nothing new. The change appears on main in one step.

Close lines (relay)

  1. The verification task runs on the epic head after line 4: the repo suite, then stack-up on the epic head and the --stack run, then stack-down. Relay: one run. This issue gets the Verified: line.
  2. Any push after line 1 means line 1 runs again on the new head.
  3. Every child is merged to the epic branch, with review and evidence lines in place.
  4. main is merged into the epic branch by a sync PR whose head is sync/585-main and whose body says Closes #587. Conflicts are resolved on it.
  5. Close Adopt a terminal Claude in no project: adopt, relaunch paths, session mark, audit, fakerelay #586 with a comment naming its PR.
  6. merge-check passes on the epic PR to main.
  7. Merge under the joint close task on Epic: adopt an outside Claude session that is in no project #585 (step c). Confirm main green, close the parent (step d), delete the epic branch.
  8. The run report's final body (run-report finish, by the coordinator).

Verification task

On the devbox, on the epic head after line 4, as step b of the joint close task. Unlock the devid keychain and run npm ci in the eve checkout first. No devlock.

  • repo-suite: (cd e2e && go test -race -timeout 30m ./features/).
  • devboxverify: stack-up r587 --relay <relay checkout at the epic head> --eve <eve checkout at its epic head>, go run ./cmd/devboxverify --stack <stack.json> --phase api, stack-down r587 (also on a failure).
  • real-app on the stack, in scratch folders only:
    1. Start a terminal Claude in a scratch folder outside every project. Its row shows Adopt on the Agents rail. Tap Adopt.
    2. The managed row shows "Unsandboxed". relay session list --json shows unsandboxed: true.
    3. In the Chief of Staff, ask it to pass a message to that agent and tap Send on the card. The agent's thread shows the message.
    4. Ask the agent for a tool call that needs approval. The permission prompt shows; Allow runs it.
    5. Drop in. The terminal row shows "Unsandboxed". A Chief of Staff send now answers dropped_in.
    6. Close the terminal. The session is idle and headless again, still "Unsandboxed", in the same folder.
    7. A Chief of Staff send reaches it again.
    8. relay audit --event session_adopt and --event session_swap show no_project: true rows.
    9. Refusals: a second scratch Claude whose folder is removed before Adopt answers "Can't adopt" with directory_unusable. A third whose folder is made a project between listing and Adopt answers changed. A Pi in no project shows "Not in a project, so it can't be adopted." and no button.
  • Post Verified: <head sha> · repo-suite: <result> · devboxverify: <result> · real-app: <result> · log: <link or path> here.

Tasks

Contract

This child adds no code. Its PRs are the sync PR and relay's epic PR to main (Closes #587). merge-check judges both on the files that differ from main, so this list is the union of #586's paths. Conflict resolution stays inside them.

File ownership

The dev and test-writer paths of #586 and #594, as their contracts list them, and no other:

  • cmd/devboxverify/README.md
  • cmd/devboxverify/journey_adopt.go
  • cmd/relay/outside_session_ops.go
  • cmd/relay/session_adopt.go
  • cmd/relay/session_chief_of_staff.go
  • cmd/relay/session_dropin.go
  • cmd/relay/session_launch.go
  • cmd/relay/session_rebind.go
  • cmd/relay/session_routes.go
  • cmd/relay/session_swap.go
  • cmd/relay/session_unsandboxed.go
  • docs/FEATURES.md
  • docs/THREAT-MODEL.md
  • docs/audit-log.md
  • docs/cli.md
  • docs/events.md
  • docs/fakerelay.md
  • docs/outside-sessions.md
  • docs/routes.md
  • docs/session-adoption.md
  • docs/session-host.md
  • e2e/features/bug594_unsandboxed_permission_test.go
  • e2e/features/g1_outside_adopt_test.go
  • e2e/features/g1_outside_adopt_unsandboxed_test.go
  • fakerelay/internal/sessions/adopt.go
  • fakerelay/internal/sessions/dropin.go
  • fakerelay/internal/sessions/register.go
  • fakerelay/internal/sessions/session.go
  • fakerelay/internal/sessions/terminal.go
  • fakerelay/internal/world/validate.go
  • fakerelay/prooftest/adopt_test.go
  • internal/outsidesessions/probe.go
  • internal/sessions/hostapi/dispatch.go
  • internal/sessions/hostapi/server.go
  • internal/sessions/hostapi/types.go
  • internal/sessions/ledger/ledger.go
  • internal/sessions/provider/claude.go
  • internal/sessions/provider/shimspawn.go
  • internal/sessions/session/manager.go
  • internal/sessions/terminal/manager.go
  • internal/sessions/terminal/session.go
  • internal/sessions/types/session.go

Test surface

The whole repo suite and the --stack api run (every journey, not a selection), plus the real-app pass above. Nothing new is written here.

Waits:

  • Merges and child state: merge-check exit codes and gh issue and PR state.
  • stack-up: its process exit and a valid stack.json. stack-down: its process exit.
  • Suite and harness: their process exits.
  • real-app: each step waits on what the screen shows (the button, the chip, the card state, the terminal row) or on the CLI's exit. The agent's replies are model output with no signal: a bounded wait, and the log says so.

Budget

0 lines of new code. Conflict resolution only inside the paths above; anything else stops and asks.

Activity

  1. barelyworkingcode commented on Oct 22, 2026

    @barelyworkingcode
    OwnerAuthor

    Coordinator approval: inherits the approved epic's listed batches, 2026-10-22

  2. barelyworkingcode commented on Oct 22, 2026

    @barelyworkingcode
    OwnerAuthor

    Verified: 74dc7d9 · repo-suite: ok relaye2e/features 867.671s · devboxverify: SUMMARY pass=10 fail=0 blocked=0 notrun=2 (stack with eve ff056b5) · real-app: PASS steps 1-9 (step 4 on a fresh adopted session: prompt shown, Allow ran it; step 6 read from relay session list) · log: /tmp/c585/close2

  3. barelyworkingcode commented on Oct 22, 2026

    @barelyworkingcode
    OwnerAuthor

    Contract amendment: the ownership list names the 42 files of relay#586 and relay#594 explicitly, so merge-check can read it. No new path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    taskOne batch of an epic

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions