Skip to content

add direct agents and managed NAC hosting - #231

Draft
allisoneer wants to merge 232 commits into
mainfrom
allison-demo
Draft

add direct agents and managed NAC hosting#231
allisoneer wants to merge 232 commits into
mainfrom
allison-demo

Conversation

@allisoneer

Copy link
Copy Markdown

What problem(s) was I solving?

NAC’s established orchestrator/worker topology works well for planned parallel execution, but it was the only durable session behavior. We needed to support a persistent direct coding agent that could work across turns, accept steering, pursue explicit long-running goals, and delegate work without collapsing traditional child agents, managed orchestrators, and NAC workers into one topology.

That expansion also required stronger execution boundaries. Model-visible tools needed a common prepared-invocation and authorization path with canonical resource binding, hard denials, retained terminal results, cancellation, process-tree cleanup, and backend-specific execution that remains safe across Local, SSH, and optional Podman.

For managed-host dogfooding, NAC also needed an additive deployment mode with GitHub authorization, safe repository onboarding, host secrets, mounted model credentials, readiness, and a reproducible developer image. None of this should affect ordinary local or SSH use when managed configuration is absent.

Finally, feature work had accumulated in very large core/server modules, handwritten frontend DTOs could drift from Rust, and the repository lacked production-embedded browser, durability, managed-image, and source-ownership gates capable of protecting these lifecycle and safety contracts.

What user-facing changes did I ship?

Persistent session behaviors

Every new chat now selects one immutable, persisted behavior:

  • NAC orchestrator (orchestrator) preserves the existing planner, worker, thread, and workset experience. It remains the default for legacy and omitted behavior values.
  • Direct (direct) runs a persistent coding agent with native tools, durable input, goals, retained command output, and traditional child coding agents.
  • Direct with orchestrator (direct-with-orchestrator) adds control of separate managed NAC orchestrator sessions while keeping those sessions distinct from traditional children.

The selected behavior is visible for the lifetime of the chat and cannot be changed in place.

Direct-agent workflows

  • The ordinary composer remains usable while a run is active. Users can steer the current run or queue input for its successor, then edit or cancel pending items.
  • Explicit durable goals can be created, edited, paused, resumed, limited, cleared, or completed across multiple turns. Optional token budgets use settled billable usage rather than context-window estimates.
  • Direct sessions expose revision-aware file operations, retained/pageable terminal output, structured command results, and permission controls.
  • Traditional child agents can run in the foreground or background, be continued, steered, cancelled, and inspected through read-only lineage-aware transcripts.
  • direct-with-orchestrator sessions can similarly launch and manage separate orchestrator sessions using the existing NAC thread/workset topology.
  • Background delegation settles through durable, exactly-once parent inbox delivery and is reconciled after restart.

Managed NAC host

When explicitly configured, NAC now provides:

  • GitHub App device authorization, refresh/disconnect, repository and branch discovery, and HTTPS Git/gh credential delivery.
  • Safe, cancellable repository onboarding that stages under a confined root, publishes atomically to an unused destination, and creates the ordinary NAC Project last.
  • Write-only host secrets captured per command spawn, inherited across supported agent topologies, and redacted from retained output and structured results.
  • A host-supplied model profile backed by a separate read-only mounted credential.
  • Managed status, readiness details, GitHub and secret settings, responsive repository onboarding, and automatic onboarding resume after authorization.
  • A fixed non-root Linux/amd64 developer image, durable state/repository/home mounts, bounded shutdown, static image contracts, credential-independent smoke coverage, and an OIDC/ECR publication workflow.

Managed mode remains absent when no managed configuration is supplied. It does not replace ordinary local or SSH Projects.

Native web retrieval

Top-level direct sessions conditionally receive web_search and web_fetch when a usable Exa credential is available. Retrieval uses fixed Exa Search/Contents endpoints with bounded requests, retries, results, redaction, cancellation, URL validation, and normal permission evaluation. The credential is removed from model-controlled process environments, and orchestrator workers and traditional children do not receive these tools.

How I implemented it

  • Introduced a native tool kernel that separates capability exposure, argument preparation, canonical permission resources, authorization, hard safety policy, execution admission, cancellation, and rich results. MCP tools now pass through the same authorization boundary.
  • Persisted behavior, inbox items, revision/backend-bound grants, goals, traditional-child relationships, managed-orchestrator relationships, completion obligations, run recovery, and lineage in the durable store.
  • Made session admission, attachment, cancellation, settlement, recovery, and background completion generation-aware and restart-safe using operation leases and atomic store transitions.
  • Hardened shell classification, path/resource binding, mutation revision checks, terminal ownership, retained output, SSH/Podman execution, and descendant process cleanup. Authorization cannot change the backend selected at construction.
  • Added focused inward crates for shared contracts, hardened credential persistence, process supervision, and the harness-independent managed-host bounded context.
  • Split nac-server into focused application services and HTTP delivery modules while preserving the existing public HTTP/MCP behavior.
  • Made Rust routes and utoipa schemas the source of truth for checked-in OpenAPI and generated frontend types. The React client now consumes feature-owned query modules and generated wire contracts.
  • Added production-embedded Playwright journeys, durability/crash-window selections, managed-image checks, curated warning-denied Clippy policy, and an enforced 2,000-line ceiling for tracked human-authored files.
  • Integrated the current mainline conversation-fork, zero-spend initialization, cancellation, and descendant-cleanup behavior through the new store/application/process/frontend ownership seams, including portable Linux/macOS E2E process inspection.
  • Rebuilt the committed production assets. The final cleanup gives the create-session action the unique accessible name Create new session, removing ambiguity while preserving its visible wording.

Compatibility and migration notes

  • Existing and omitted session behaviors continue to load as orchestrator.
  • Managed-host behavior is entirely opt-in; unmanaged startup and ordinary local/SSH Projects retain their existing meaning.
  • Opening an existing schema-v17 store performs the backward-compatible migration to schema v24. This is an intentional downgrade barrier: older NAC binaries reject the upgraded store instead of misreading direct sessions as orchestrator sessions.
  • Existing public session behavior values, outgoing MCP semantics, project/session ownership, Local/SSH/Podman backend selection, and mainline conversation-fork behavior are preserved.

How to verify it

Verified on exact PR head debc813:

  • make ci
    • formatting and frontend lint
    • warning-denied workspace Clippy
    • 812-file source-size guard
    • 1,158 nac-core tests passed, with 9 expected optional/live-infrastructure ignores
    • 151 server library tests and 23 server binary tests
    • 19 managed, 13 credential-store, and 2 process tests
    • 179 frontend unit/component tests
    • generated OpenAPI/TypeScript drift checks
    • production asset rebuild/currentness
    • static managed-image contract
  • make test-durability — all 10 focused cancellation, recovery, crash-window, lease, relationship, and exactly-once settlement regressions passed.
  • make test-e2e — all 14 production-embedded browser journeys passed, including immutable behavior selection, the final create-session accessibility contract, direct execution, steering/inbox/goals, delegated transcripts, native Exa retrieval, managed desktop/mobile onboarding, secrets, clone completion, and clone cancellation.
  • The focused E2E cleanup suite passed on both macOS and a Debian/Linux Node container (3/3 on each), covering detached and signal-resistant descendant discovery.
  • A clean Rust 1.98 Linux run passed all seven process-supervision and snapshot tests that had failed under exact-head GitHub concurrency, including dependency-level pidfd fault injection and portable wrapper isolation.
  • The live managed Docker image smoke passed on the managed-model integration candidate before final mainline convergence, covering non-root/read-only-root execution, mounted model credentials, readiness, restart, tool inventory, and bounded shutdown. The exact current head reran the static image contract.
  • Optional external staging remains: real GitHub organization/SAML behavior, provider credentials, ECR/OIDC publication, gateway authentication, controller/PVC lifecycle, and same-volume rescheduling require platform-owned infrastructure.

Description for the changelog

Add persistent direct-agent sessions with durable steering, goals, permissions, retained terminals, and traditional or orchestrator delegation. Introduce opt-in Managed NAC hosting with GitHub repository onboarding, write-only host secrets, mounted model credentials, native Exa retrieval, hardened execution boundaries, generated API contracts, and production-level durability/browser/image verification.

Managed Arcee credential bootstrap follow-up

Managed NAC hosts can now start without a second interactive login or a long-lived API key mount. ArceeFM mints a host-scoped managed-nac authorization and nac-api delivers a strict, one-time bootstrap document. NAC imports it through the existing hardened credential store, persists refresh rotation on the host volume, and then runs independently of the bootstrap mount.

The durable receipt and credential are validated together under the Arcee credential lock. Readiness, catalog exposure, session creation, and resume require an imported receipt whose host/bootstrap provenance exactly matches a managed-nac credential and the configured Arcee origin. Legacy interactive credentials, preserved pre-existing files, corrupt data, logout/revocation, and mismatched generations fail closed without exposing or overwriting secret material. Interactive arcee-auth remains unchanged for ordinary unmanaged use, and model selection remains independent from the account-level authorization.

Additional verification on exact head 8710617:

  • make ci on the integrated allison-demo branch (1,176 core tests with 9 expected ignores, 156 server library tests, 23 server binary tests, 245 web tests, Clippy, formatting, generated API/types, production assets, and the managed-image contract).
  • make test-durability.
  • make test-e2e (18 production-embedded journeys).
  • Focused bootstrap import, refresh, crash-recovery, provenance-mismatch, secret-redaction, and preserved-legacy regression tests.
  • Managed NAC image run 33774372326 built and exercised the real linux/amd64 image. The smoke proves a fresh host cannot reach /readyz without bootstrap, imports the exact mounted bootstrap_id, survives an abrupt SIGKILL, and reaches readiness from the PVC-backed credential and receipt after the bootstrap mount is removed.\n- [ ] Live controller/ArceeFM/Kubernetes integration remains a staging gate.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@allisoneer

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

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.

3 participants