Skip to content

feat: add agent-native session control#180

Merged
almogdepaz merged 11 commits into
mainfrom
feat/session-open
Jul 19, 2026
Merged

feat: add agent-native session control#180
almogdepaz merged 11 commits into
mainfrom
feat/session-open

Conversation

@almogdepaz

@almogdepaz almogdepaz commented Jul 15, 2026

Copy link
Copy Markdown
Owner

summary

  • add wolfpack session create <project> for server-owned top-level sessions
  • add wolfpack agent spawn <project> for same-harness children; retain wolfpack session open as a deprecated compatibility alias
  • pass launch prompts atomically as opaque argv values with no terminal-readiness race or shell interpolation
  • expose stable broker sessionId values across create/spawn/list/status/read/send/wait/kill
  • resolve human names or opaque IDs against structured identity and fail closed on ambiguity
  • provide lightweight JSON list/status paths without terminal preview scraping
  • persist structured parent identity and notify the active desktop parent so the browser can open the child in its existing grid ownership flow
  • preserve ordinary global/tailnet auth policy and side-effect-free help paths
  • reject deploy-local.sh --broker=yes before mutation when invoked from a broker-owned Wolfpack session
  • replace the kernel-socket-timing CI test with deterministic backpressure coverage of the real broker forwarder

command contract

wolfpack session create <project> [--harness <agent>] [--prompt <instruction>] [--json]
wolfpack agent spawn <project> [--prompt <instruction>] [--json]
wolfpack list --json
wolfpack session status|read|send|wait <session-or-id> ...
wolfpack kill <session-or-id> [--json]

verification

  • Bun: 1,785 passed
  • Rust: 174 passed
  • Playwright: 86 passed, 109 intentional project skips
  • strict TypeScript passed
  • dependency audit: 0 vulnerabilities
  • schema/assets deterministic
  • four-target compiled build and CLI help passed
  • shell syntax and shellcheck passed
  • git diff --check passed
  • fresh GitHub Actions test job passed

deployed QA

  • top-level create, child spawn, deprecated alias, stable-ID list/status/read/send/wait/kill, --no-enter, coded JSON failures, and ambiguous-selector rejection passed
  • atomic top-level and child prompts matched through real PTYs
  • structured parent identity and desktop child auto-grid passed in the deployed browser
  • disposable QA sessions were removed

project-prefix selection remains tracked separately in #178. alternate-screen snapshot isolation is independent in #184.

@almogdepaz almogdepaz changed the title feat: add agent-native session open feat: add agent-native session control Jul 17, 2026
@almogdepaz

Copy link
Copy Markdown
Owner Author

edc delivery + security + quality review

scope: main@ed009b3...bebb0b0 (feat/session-open)
context loaded: server-api-runtime, broker-transport-ts, browser-client, cli-install-service, ralph-automation, tests, known issues

delivery verdict: partially delivered / needs confirmation
architecture fit: questionable
security recommendation: approve
quality verdict: conditional

delivery / architecture finding

important — parent replacement during successful sub-session allocation is not fail-closed

  • category: partial requirement / integration completeness
  • requirement: .plans/006-session-open-tailnet-trust.md:52-58 says regression coverage should prove “parent disappearance or uuid replacement during allocation fails closed before another create attempt”; .plans/006-session-open-tailnet-trust.md:86-87 also reserves stable parent-change failures and notes parent identity may need to be in the event to avoid stale intent.
  • implementation evidence: src/server/session-open.ts:126-181 captures parentIdentity, creates the child, then only rechecks the parent before notification. if that recheck fails, lines 171-173 swallow it as best-effort notification and lines 175-181 still return success.
  • test evidence: tests/unit/session-open.test.ts:198-249 covers parent disappearance/replacement only after a typed duplicate retry. the success-path replacement case at tests/unit/session-open.test.ts:299-316 explicitly expects result.ok === true and only suppresses notification.
  • why it matters: if the intended contract is “fail closed on parent replacement during allocation,” the current success path can leave a child session created with a stale parent identity while the api reports success. if the intended contract is only “don’t notify the wrong browser,” the plan/docs overstate fail-closed behavior and should be corrected so future reviewers don’t enforce the wrong invariant.
  • action: standardize_contract
  • recommendation: either (a) make successful allocation revalidate parent identity and fail/delete/mark the child on parent replacement before returning, or (b) update the plan/docs to state that post-create parent replacement suppresses only browser notification and does not roll back the child.

delivery / architecture notes

material contract coverage otherwise looks good:

  • cli create/spawn/open are server-owned and one-request (src/cli/session-control.ts:458-486).
  • prompt passing is argv-level, not terminal typing or shell interpolation (src/server/broker-backend.ts:280-307).
  • session selectors resolve names or broker ids and reject ambiguity (src/server/session-selector.ts:11-34, wired through src/server/routes.ts:293-320).
  • browser grouping uses structured parent identity instead of parsing child names (public/app.ts parent grouping helpers around the session list rendering).
  • deployment guard rejects broker replacement from a broker-owned wolfpack session before mutation (scripts/deploy-local.sh:21-24).

security

no exploitable security finding survived review.

checked:

  • auth boundary: new endpoints stay under ordinary /api/* jwt-when-configured policy; no service-auth fallback added to the shared cli path.
  • injection: initialPrompt is passed as $1 argv (src/server/broker-backend.ts:280-307), not interpolated into the shell command.
  • filesystem/project validation: session-create/open use exact project names and validateProjectDirPure before side effects (src/server/routes.ts:714-727, src/server/routes.ts:781-794).
  • process/session mutation: create/kill/send/status paths route through server/broker authority; no browser-owned pty truth source added.
  • deployment: --broker=yes self-termination guard exists before build/install/restart.

limitations: review was diff/context based; i did not run the claimed bun/rust/playwright suites locally.

quality finding

advisory — test suite encodes the weaker stale-parent behavior

  • category: test value
  • evidence: tests/unit/session-open.test.ts:299-316 simulates a replaced parent after creation and asserts success with suppressed notification.
  • why it matters: if fail-closed allocation is the intended behavior, this test will keep the bug green. if success/no-notify is intended, the plan’s fail-closed wording is the stale artifact.
  • recommendation: align this test with the chosen contract; don’t leave tests and plan asserting different invariants.

@almogdepaz

Copy link
Copy Markdown
Owner Author

fixed the stale-parent session-open finding in 3fcf1d4. openSubSession now revalidates the parent session/id after child creation before returning success or notifying; notification errors remain best-effort only after that invariant passes. added regression coverage for post-create parent disappearance and UUID replacement. verification: bun test tests/unit/session-open.test.ts; bun test tests/unit/session-open.test.ts tests/integration/api.test.ts tests/unit/session-control-fast-path.test.ts; bun run typecheck; bun test.

@almogdepaz
almogdepaz merged commit a345dc6 into main Jul 19, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant