# Dynamic nono permissions implementation plan ## Purpose Replace the current directory-selected static Pi profiles with a trusted launcher that composes least-privilege permissions from reviewed capability bundles. The rollout must preserve normal development workflows while separating personal, work, maintenance, and high-risk capabilities. This plan turns the findings in `/tmp/nono-dynamic-permissions-audit.md` into implementation slices. It does not authorize profile activation, credential changes, or production access by itself. Each policy change still requires a resolved-policy review before activation. ## Current implementation anchors The work starts from these repository-owned surfaces: - `scripts/pi-sbx-profile.py` validates the launcher configuration and selects a static profile by longest directory match. - `scripts/pi-sbx.fish` launches the selected profile and Pi runtime inside the `pi-agents.slice` systemd scope. - `config/pi-sbx.example.json` documents the current directory-to-profile configuration. - `scripts/test_pi_sbx_profile.py` and `scripts/test_pi_sbx_launcher.py` cover routing and launch validation. - `profiles/nono/*.json` contains the repository-managed static profiles. - `docs/nono.md` and the tracked source at `skills/tools/nono-profiles/` document profile operations; `.pi/skills/nono-profiles` is a generated link and is not edited directly. Known drift must be treated as an input to the rollout: the active `pi-local` and `pi-work` profiles are repository symlinks, while active `pi-orca-local` and `pi-harness-tools` are regular files that may differ from Git. ## Outcomes and security invariants The rollout is complete when normal Pi sessions have only the capabilities required by the active repository, provider, enabled integration set, and explicitly selected launch mode. Every slice must preserve these invariants: 1. **Reviewed grants only.** Repository files may suggest capabilities, but only the trusted catalog in this repository may grant them. 2. **Trusted pre-sandbox code.** The production launcher and catalog run from a user-owned, maintenance-installed snapshot that normal Pi sessions cannot modify. Environment overrides, writable source checkouts, and arbitrary installed profile names cannot replace production inputs. 3. **Restrictive composition.** The new baseline derives from nono's `default` profile rather than the broad `nolabs-ai/pi` profile. Additive inheritance must not be used to claim that a child narrows its parent. 4. **Isolated state.** Normal personal and work sessions receive separate Pi state, credentials, SSH agents, caches where required, one exact per-launch temporary directory, and exact state and active-worktree access from the trusted repository map. Core fragments contain no worktree grant, so a read-only repository cannot inherit read/write access. A session receives no broad `/tmp`, `$TMPDIR`, runtime-session parent, sibling-worktree, or shared worktree-root grant. Extension source and global instructions remain read-only. 5. **Command-scoped privilege.** Git, SSH, GitHub CLI, package managers, child agents, deployment tools, and maintenance commands receive their own command policies. The outer Pi process does not inherit their credentials or broad network access. 6. **Controlled in-process extensions.** A normal session loads only its reviewed extension allowlist. Privileged extension operations are disabled or moved to controlled subprocesses because nono cannot isolate extensions inside Pi. 7. **Explicit high-risk modes.** Voice, browser, Docker, release, production, and maintenance access require an explicit launch flag and appear in the printed permission plan. 8. **Fail closed.** Unknown repositories, capabilities, providers, extensions, dynamic endpoints, malformed configuration, or invalid generated profiles stop the launch with an actionable error. There is no implicit default profile for an unknown repository. 9. **Verifiable policy.** Generated profiles are mode `0600`, live under a caller-owned `$XDG_RUNTIME_DIR`, pass `nono profile validate --strict`, and can be inspected with `nono profile show`. 10. **Negative evidence.** Every capability has at least one test proving the corresponding access is absent when the capability or mode is not selected. ## Boundaries ### In scope - Trusted capability catalog and canonical repository mapping. - Per-launch nono profile generation, validation, explanation, and caching. - Explicit environment filtering. - Command policies for development tools and child processes. - Exact local socket and loopback endpoint grants. - Separate normal and privileged launch modes. - Migration of `/srv/data/code`, `/srv/work`, and selected `/srv/data/repo-store` repositories. ### Deferred until their dedicated slices - Docker, browser control, deployment, release, production credentials, and Pi/package updates. - Automatic grants inferred from `package.json`, scripts, extension metadata, or repository-controlled manifests. - Broad local-network access. - Direct SSH from the outer Pi session. ## Delivery model Use one worktree per slice. Durable linked worktrees live outside primary checkouts under `/srv/data/worktrees//`; `/run` is reserved for disposable session state. Assign the file ownership below before implementation so parallel branches do not edit the same files. Shared integration files are updated only by the named integration slice or during a scheduled integration pass. A slice is complete only when: - its focused automated tests pass; - every new or changed profile passes strict validation; - positive and negative integration checks produce saved, secret-free evidence; - required Linux host checks run with nono 0.74 rather than skip; - credentialed live checks have separate, manually approved evidence when fixtures cannot prove the real route; - affected documentation is updated; - an agent other than the implementer reviews the changes. ## Work graph ```text Slice 0: containment and drift reconciliation | v Slice 1: policy contract and restrictive base ----+ Slice 2: test and evidence harness ---------------+---- run in parallel | | +--------------------+--------------------------+ v Slice 3: catalog and profile generator | +--> Slice 4A: personal/work Git and SSH -----+ +--> Slice 4B: GitHub CLI credential broker --+---- run in parallel | | +---------------- pilot acceptance gate <-----+ | +--------------------+--------------------------+---------------------+ v v v v Slice 5A Slice 5B Slice 6A Slice 6B1 Node/Bun Python/Rust/Go/Java local integrations child isolation | | | | +--------------------+--------------------------+---------------------+ v Slice 6B2: workflow/toolchain broker | v Slice 7A: Docker/browser Slice 7B: release/production Slice 7C: maintenance run independently after explicit approval | v Slice 8: repository migration batches and legacy-profile retirement ``` Slices in the same row may proceed in parallel after their listed dependencies are complete. A branch must not activate profiles or modify user credential stores as part of automated testing. ## Slice 0: Containment and profile drift reconciliation **Goal:** establish a reviewable baseline before adding dynamic behavior. **Owner surfaces:** existing `profiles/nono/*.json`, `config/pi-links.json`, a new `config/pi-package-lock.json`, and `docs/nono-profile-baseline.md`. Slice 3 alone owns edits to `docs/nono.md` during integration. **Work:** 1. Compare every active `~/.config/nono/profiles/pi-*.json` entry with its repository counterpart, including resolved inheritance and saved grants. 2. Decide, with explicit user approval, whether each divergent active file is imported into Git or replaced by a repository symlink. Any temporary regular-file exception requires an owner, expiry date, resolved-policy evidence, and a tested restoration command. 3. Remove unapproved saved grants from the proposed repository policy, especially writes to global instructions, workflow state, extension source, and unrelated Pi state. 4. Inventory `~/.pi/agent/settings.json` and other active personal/work Pi settings into a secret-free lock record keyed by immutable package and extension source revisions. Treat `config/pi-links.json` as resource-link ownership, not as package-source authority. Define precedence and reconciliation between the lock record, active settings, and link configuration. 5. Inventory every file and marker under `~/.config/nono/profile-drafts/`. Validate its internal profile name against its filename, capture resolved grants, then either import an approved draft or move it to a timestamped quarantine outside nono's draft search path. The current `pi-local-dictate.json` mismatch and socket grants require explicit disposition. 6. Verify the installed `nolabs-ai/pi` package source, lock metadata, and active wiring. A `pinned: false` record or mismatch between installed content and lock state blocks normal activation. 7. Replace `latest`, unversioned registry entries, SSH Git package references, and floating Git URLs with reviewed immutable versions. Any unresolved floating source blocks normal-profile activation. 8. Define a maintenance-only path for `/update`, package installation, extension installation, managed links, and active-profile activation. Normal extension allowlists must exclude the `update` extension even though `config/pi-links.json` exposes its source. 9. Capture the current positive workflows that the new baseline must preserve without recording tokens, key material, or sensitive environment values. **Acceptance criteria:** - Every active Pi profile is either a repository symlink or a time-bounded exception with an owner, expiry, evidence, and restoration test. - No normal repository profile includes an interactive saved grant that is absent from Git. - Every active package, extension, and installed nono package source matches immutable lock metadata; unresolved floating or `pinned: false` sources block activation. - Every pending nono draft is approved and imported or quarantined, and mismatched names or untracked socket grants remain inactive. - The `update` extension and its command are unavailable in normal personal and work sessions. - Maintenance tests prove tracked source files are promoted into generated/installed destinations rather than editing `.pi/skills` or other generated links directly. - The current state can be restored from repository files and documented activation steps. **Dependency:** none. This is the only slice that should modify existing active-profile definitions before the proof of concept. ## Slice 1: Policy contract and restrictive base **Goal:** prove that Pi can start from a narrow baseline without inheriting broad `~/.pi`, network, socket, or service-launch grants. **Owner surfaces:** `profiles/nono/pi-core-personal.json`, `profiles/nono/pi-core-work.json`, `profiles/nono/provider-*.json`, `extensions/lm-studio/`, `docs/adr/.md`, `skills/tools/nono-profiles/`, and `tests/nono/capabilities/core/`. This slice does not own the catalog schema, launcher routing, or shared test helpers. **Work:** 1. Confirm nono 0.74's installed schema and behavior for multiple `extends`, `command_policies`, environment policy, caller relationships, credential routes, loopback ports, and strict validation. 2. Record the chosen composition contract in a short ADR before locking the catalog schema. Update the existing nono skill documentation where it incorrectly assumes one parent. 3. Create `pi-core-personal` and `pi-core-work` baselines derived from `default` with: - exact runtime, reviewed extension, instruction, configuration, and session-state reads; - exact mutable session/config/state paths; - no worktree grant in the reusable core fragment; handwritten composition fixtures add the active worktree as read-only or read/write exactly as the future trusted repository map declares; - one exact per-launch temporary directory supplied by the trusted launcher, with no broad `/tmp` or `$TMPDIR` grant; - an explicit environment allowlist that removes raw credential names from the outer process, including `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GITHUB_TOKEN`, `GH_TOKEN`, `MORPH_API_KEY`, and unselected `SSH_AUTH_SOCK`; the trusted provider catalog owns the complete tested list; - one selected provider route; - no package registries, SSH, Docker, browser, microphone, deployment credentials, or broad localhost access. 4. Separate extension source from extension state. Confirm that normal sessions cannot modify global instructions, installed extension code, authentication state, other Pi profiles, or sibling repositories. 5. Materialize the normal in-process extension allowlist as a generated, isolated Pi `settings.json` under the selected personal/work state root. Its package/extension entries come only from `config/pi-package-lock.json` and the trusted repository map. Disable `pi-ask` arbitrary notification commands, `/update`, the legacy `workflow` extension, background shell jobs, and any privileged direct spawn path until a controlled subprocess policy exists. The `develop-workflow` skill adds no executable or permission boundary; it composes only tools already available to the parent session. 6. Import the unmanaged `~/.pi/agent/extensions/lm-studio.ts` implementation into a repository-managed extension at `extensions/lm-studio/index.ts`, lock its source revision, and change its fixed base URL contract to `http://127.0.0.1:1234/v1`. Maintenance moves the old extension to the quarantined state store and removes its active settings entry. A duplicate-provider test fails if the old source, another `lm-studio` registration, or `localhost` base URL remains loadable. 7. Define and own stable profile fragments for `provider-lm-studio`, `provider-openai`, `provider-anthropic`, and `provider-morph`, granting only one route at launch. Prove nono 0.74's `tcp_connect_ports` behavior with real loopback fixtures listening on ports 1234 and 1235: the selected provider must connect to 1234 while 1235 and every other loopback port fail. Do not use hostname-only `allow_domain` as evidence of port restriction. If the fixture cannot prove exact enforcement, `provider-lm-studio` remains unavailable until a separately reviewed mediated relay is designed. **Acceptance criteria:** - A minimal Pi session starts for both personal and work state roots. - The selected provider works while non-selected provider hosts, raw key environment names, and credentials are absent from the environment and process table. - Reads outside the exact Pi state, declared active-worktree access, and per-launch temporary paths fail; writes to a read-only active worktree fail; another session's temporary directory is inaccessible. - LM Studio, when selected, reaches only `127.0.0.1:1234`. - `/update`, the legacy `workflow` extension, arbitrary notification commands, and unbrokered background shell jobs are unavailable; skill-led development cannot widen the parent session's policy. - The repository-managed LM Studio provider uses only the exact `127.0.0.1:1234` base URL, the old unmanaged source is quarantined, duplicate registration fails, and a real two-port fixture proves all other loopback ports are denied. - All base and provider profiles pass strict validation and resolved-policy review. **Dependency:** Slice 0's baseline inventory. It may run in parallel with Slice 2. ## Slice 2: Integration test and evidence harness **Goal:** make least privilege measurable before command brokers are implemented. **Owner surfaces:** `tests/nono/harness/`, `tests/nono/fixtures/core/`, `scripts/test_nono.py`, `scripts/nono-evidence.py`, and the evidence schema at `config/nono/evidence.schema.json`. Capability slices own only `tests/nono/capabilities//`. Slice 3 owns any root package-script integration. **Work:** 1. Build fixture repositories, isolated temporary HOME/XDG directories, fake sockets, fake provider endpoints, and stub executables. Tests must not depend on personal keys or live tokens. 2. Add helpers that accept handwritten fixture profiles, run `nono profile validate --strict`, inspect the resolved policy, execute a command, and record a redacted result. Slice 3 later supplies the production generator through a stable adapter rather than duplicating generation here. 3. Encode the audit's required negative matrix: - broad `/tmp`, the runtime-session parent, and another live or abandoned session's temporary directory denied; - sibling linked worktrees and unrelated durable worktree roots denied; - direct SSH denied; - personal key route absent from work and work key route absent from personal; - sibling repositories and unrelated Pi state inaccessible; - global instructions and extension source read-only; - Docker, browser control, dictation, `/update`, and production credentials absent in normal mode; - non-selected provider routes and known raw provider-key environment names absent. 4. Encode synthetic positive fixtures for future Git, GitHub CLI, package-manager cache, exact provider-port, and exact socket policies. Mark deferred capability positives as fixture contract tests, not proof that the production capability exists. 5. Separate hermetic tests, mandatory Linux/nono 0.74 host tests, and manually approved live credential tests. Missing nono or a wrong version fails the security gate; optional local services may skip only their own capability check with a recorded reason. 6. Implement source at `scripts/nono-evidence.py`, but execute it only as the digest-verified `pi-sbx-evidence` command from the installed trusted snapshot. It supports `run ` and `summarize `. Raw mode-`0600` evidence lives under `$XDG_STATE_HOME/pi-sbx/evidence//` for 30 days. A redacted, schema-validated summary is written to `docs/nono-migration/evidence///.json` and records schema version, repository/commit, policy and installed-snapshot digests, nono version, test IDs/results, approver, timestamps, and hashes rather than raw command output. 7. Add canary-secret tests covering environment values, arguments, stdout/stderr, and exception text. Summary generation fails if a canary or configured credential-name pattern survives redaction. **Acceptance criteria:** - One command runs the hermetic negative suite. - The pilot gate requires the Linux/nono 0.74 suite to execute with zero skips in core, Git/SSH, and GitHub CLI policy checks. - Live credentialed Git and `gh` evidence is collected separately through explicit manual approval and is never replaced by a skipped test. - A deliberately broad fixture causes at least one negative test to fail, proving the harness detects over-granting. - Test output identifies the capability, expected policy, and actual denial or allowance. - Evidence summaries validate against the schema, contain no canary secrets, and can be traced to retained raw evidence during the 30-day review window. **Dependency:** Slice 0 only. Slice 1 supplies real profiles later, but harness development can start against fixtures. ## Slice 3: Trusted catalog and per-launch profile generator **Goal:** replace static directory routing with reviewed capability composition and a validated runtime profile. **Owner surfaces:** `scripts/{pi-sbx,pi-orca}.fish`, `scripts/{pi-sbx-profile,orca-nono-profile}.py`, `config/pi-sbx.example.json`, `config/nono/schema.json`, `config/nono/catalog.json`, `config/nono/repositories.json`, `tests/nono/generator/`, `scripts/test_pi_sbx_*.py`, root package-script integration, `systemd/user/pi-agents.slice`, new session-runtime and garbage-collection units under `systemd/user/`, `README.md`, and `docs/nono.md`. **Work:** 1. Define a versioned catalog schema for capability fragments, repository assignments, provider selection, extension requirements, privileged modes, and runtime selection. 2. Define the only provider-selection grammar as `pi-sbx [launcher options] [--provider ] -- [Pi arguments]`. The flag may occur once and only before `--`; `--provider=`, provider/model selectors after `--`, environment selectors, and child overrides are rejected. Without the flag, the trusted repository entry must name exactly one `defaultProvider`; the launcher fails if it is missing or ambiguous. A flag may choose only from that entry's `approvedProviders`. The launcher injects the resolved provider/model into Pi and exports immutable `PI_SBX_PROVIDER` metadata to child-policy generation so children inherit the route rather than reparsing Pi arguments. 3. Install the production launcher, catalog, schema, repository map, approved fragments, and evidence producer as an atomic, versioned snapshot under a user-owned libexec/config path that normal Pi profiles cannot write. The checkout is only a development source; maintenance promotes a reviewed digest. 4. Remove production trust in `PI_SBX_PROFILE_COMMAND`, arbitrary `PI_SBX_CONFIG`, inherited `PI_SBX_PROFILE`/`ORCA_NONO_PROFILE`, and legacy `set `. Tests use a separate test entry point or explicit test-only API that production launch code cannot enable from inside a sandbox. Add tamper tests for environment overrides, argument-boundary confusion, symlinks, writable catalogs, and launches from writable `harness-tools`. 5. Resolve the physical Git worktree root, Git common directory, nested-repository boundary, and submodule relationship. Match only canonical primary checkouts and durable worktrees from the trusted map. Durable linked worktrees use `/srv/data/worktrees//` and remain outside both the primary checkout and `/run`; unknown repositories and unregistered worktrees fail closed with no `pi-orca-local` or other implicit fallback. 6. Treat repository manifests and enabled extensions as compatibility checks only. A requested or discovered capability that is not approved for the canonical repository stops launch. 7. Materialize dynamic values before entering the sandbox, including the Orca hook port, exact Unix sockets, selected SSH-agent socket, isolated Pi state root, and a cryptographically unique session ID. 8. Require `$XDG_RUNTIME_DIR` to resolve to `/run/user/`, be owned by the launching UID, and have no symlinked path component. Create `/run/user//pi-sbx`, `/run/user//pi-sbx/cache`, and the session runtime parent as mode `0700` directories opened with no-follow semantics. Never grant the sandbox a runtime parent directory. 9. Launch Pi through a transient user service that owns `/run/user//pi-sbx/sessions//tmp` as a mode-`0700` runtime directory. Set `TMPDIR` to that exact path and grant only that path to the generated profile. A trusted supervisor holds an exclusive lock on a no-follow mode-`0600` lease file for the complete session lifetime and records the boot ID, supervisor PID/start time, and cgroup path/identity. Use service-managed runtime-directory cleanup, with a trusted `ExecStopPost` fallback if required by the installed systemd version, so normal exit, cancellation, and process crashes remove the directory; the sandbox cannot select, preserve, or clean its own runtime path. 10. Add defense-in-depth cleanup for user-manager or host failures. A trusted garbage-collection service runs at launcher startup and on a timer. It considers a mode- and owner-validated session directory abandoned only after at least 24 hours and only when it can acquire the lease lock, the recorded PID/start-time identity is absent, the recorded cgroup is absent or reports `populated 0`, and no matching live systemd unit exists. Any malformed identity, unavailable check, disagreement, or evidence of a live process preserves the directory and reports it for maintenance review. `/run/user/` termination and reboot provide the final cleanup layer; logout alone is not considered sufficient when lingering user services are enabled. Prove these liveness checks and an enforceable per-session runtime-space bound on the target host before activation; if either cannot be enforced, fail the pilot rather than risking live-session deletion or exposing unrestricted scratch space under `/run`. 11. Canonically serialize the profile and cache it at `/run/user//pi-sbx/cache/.json`. The digest includes normalized generated policy, installed launcher/catalog/wrapper/fragment digests, generator build digest, nono version/schema, package/extension lock state and source revisions, repository/worktree/common-directory identity, provider, runtime, mode flags, and dynamic endpoints. Document excluded runtime metadata. 12. Write a mode-`0600` temporary file in the same cache directory, flush it, atomically rename it, then reopen with no-follow semantics. On every cache hit, require a regular file owned by the launching UID with mode `0600`, rehash the file and every installed input, rerun every selected dynamic endpoint validator and authenticated health check, and rerun `nono profile validate --strict`. Recheck device, inode, size, owner, mode, content digest, and dynamic endpoint identity immediately before `nono run`; any change deletes the entry and fails the launch rather than regenerating silently. Add concurrent-writer, symlink, hard-link, replacement, partial-write, stale-version, endpoint-replacement, and tampered-content tests. 13. Print a concise permission plan containing repository, active worktree, temporary directory, provider, state root, capabilities, privileged flags, dynamic sockets/ports, installed snapshot digest, and generated-profile path. Add a JSON format for tests and diagnostics. 14. Add explicit flags for `--voice`, `--browser`, `--docker`, `--release`, `--production`, and `--maintenance`. Initially, unimplemented high-risk flags fail with an explanatory error rather than silently degrading. 15. Preserve compatibility exports only where required. Make `PI_SBX_PROFILE` and `ORCA_NONO_PROFILE` refer to the generated policy in a form consumers can resolve. 16. Retain `pi-sbx-profile show`, `list`, and `resolve` as read-only views of the installed trusted map. Remove `set`, `unset`, and `set-root`; `orca-nono-profile.py` returns a migration error for mutating commands and forwards only read-only commands, while `pi-orca.fish` forwards to `pi-sbx` without selecting a profile. **Acceptance criteria:** - The same reviewed inputs produce byte-identical canonical policy apart from documented excluded runtime metadata. - Cache invalidation occurs when generator code, nono version/schema, base/fragment content, package lock, extension revision, or any other policy input changes. - Unknown repositories, unapproved or ambiguously selected providers, provider/model flags after `--`, child provider overrides, extensions, capabilities, malformed dynamic endpoints, unsafe runtime directories, writable installed inputs, and tampered overrides fail before `nono run`. - Linked worktrees, shared Git common directories, nested repositories, and submodules have explicit isolation tests before their mappings are approved; unregistered and sibling worktrees remain inaccessible. - The launcher never accepts a repository-controlled profile path or capability definition. - Every session receives one exact private `TMPDIR`; broad `/tmp`, runtime parents, and other sessions' paths are denied. Normal exit and cancellation remove the directory; crash leftovers expire only after lease, PID/start-time, cgroup, and unit checks all prove inactivity; unknown or conflicting liveness preserves data; and the tested aggregate space bound stops an active session from exhausting `/run`. - Cache hits pass strict validation and content rehash; tampered entries and every tested filesystem race fail before `nono run`. - Existing compatibility commands have the restricted read-only semantics above, and all launcher/profile tests pass. **Dependencies:** Slices 1 and 2. ### Pre-pilot cutover gate Slice 3 prepares and tests this transaction, but maintenance executes it only after the required Slice 4A and applicable Slice 4B implementations are ready for pilot use. The cutover tool writes a mode-`0600` journal at `$XDG_STATE_HOME/pi-sbx/cutover.json`, stages a complete version directory, and changes one `current` symlink with an atomic rename only after every preflight passes. **Staged transaction:** 1. Resolve `nono` to one approved absolute path and digest. Stage the launcher/catalog/evidence snapshot, schema-v2 config, `pi-agents.slice`, personal/work Pi state roots and generated settings, global managed links, compatibility commands, and rollback manifest under a new version ID. 2. Run staged postcondition checks: strict profile validation; owner/mode/digest checks; `scripts/pi-links.mjs check`; user-systemd unit validation; personal/work state separation; no checkout symlink in executable resolution; and no stale install instructions in `README.md`, `docs/nono.md`, or `config/pi-sbx.example.json`. 3. Replace each repository legacy profile (`pi-local`, `pi-orca-local`, `pi-work`, and `pi-harness-tools`) with a validated retired deny profile that has no workdir, network, socket, credential, URL-opening, or service-launch capability. Move broad active, draft, and rollback copies into a host-only mode-`0700` store outside every normal profile grant. 4. Stage `~/.local/bin/pi-sbx` and `pi-sbx-profile` links to the versioned snapshot. Stage `pi-orca` and `orca-nono-profile` as the restricted read-only compatibility entry points. Stage schema-v2 config with no `defaultProfile` or arbitrary profile-name mapping. 5. Record every old/new path, device/inode, digest, owner/mode, systemd unit, Pi state root, global link, and intended postcondition in the journal. Flush staged files and the journal, then atomically flip the `current` version pointer and reconcile the four command links. 6. Run the mandatory pre-pilot test against names and paths. Prove old config, checkout symlinks, inherited `PI_SBX_PROFILE`/`ORCA_NONO_PROFILE`, repository profile paths, absolute and symlinked draft/quarantine/rollback paths, legacy mutating commands, compatibility wrappers, direct `nono run --profile `, and frozen socket-bearing profiles cannot launch a usable Pi policy. 7. Verify final postconditions for the approved `nono` binary, `pi-agents.slice`, state roots, global links, commands, documentation, active nono profile directory, retired repository profiles, and installed snapshot. Record the test/evidence IDs in the journal and mark it committed. **Interrupted-cutover recovery:** before the pointer flip, delete the staged version and restore paths recorded in the journal. After the pointer flip, either complete reconciliation to the new version or atomically return `current` to the recorded prior version, restore command links and systemd state, and rerun the prior version's postconditions. An unresolved journal blocks every launch and prints the maintenance recovery command. The pilot cannot begin until the committed journal and Slice 2 evidence prove every postcondition. The rollback store is inaccessible to normal profiles and can be used only through the host-authorized, expiring rollback procedure. ## Slice 4A: Personal/work Git and SSH command chains **Goal:** support normal Git-over-SSH without giving Pi direct SSH or cross-context keys. **Owner surfaces:** `profiles/nono/git-personal.json`, `profiles/nono/git-work.json`, `profiles/nono/ssh-personal.json`, `profiles/nono/ssh-work.json`, `config/nono/ssh-agents.json`, the trusted worktree registry under `config/nono/`, `systemd/user/pi-sbx-ssh-{personal,work}.service`, new sources under `scripts/nono/{git-ssh,worktrees}/`, and `tests/nono/capabilities/{git-ssh,worktrees}/`. This slice does not edit the generator schema or catalog index. **Work:** 1. Implement separate caller chains: - `session -> git-personal -> ssh-personal -> personal agent` - `session -> git-work -> ssh-work -> work agent` 2. Implement `pi-sbx-ssh-agent` and two user-systemd services owned by UID 1000. They start empty `ssh-agent` processes at `/run/user/1000/pi-sbx/ssh-personal.sock` and `/run/user/1000/pi-sbx/ssh-work.sock`, remove stale sockets on start/stop, and terminate at user-manager shutdown. `config/nono/ssh-agents.json` records for each context the exact private-key path, approved public-key SHA-256 fingerprint, host aliases, and socket path; these values require explicit user approval before installation. 3. Provide executable host procedures: `pi-sbx-ssh-agent start `, `load `, `status `, and `stop `. `load` derives and checks the public fingerprint before `ssh-add`, then verifies `ssh-add -l` contains exactly the approved fingerprint. `status` checks process ancestry, UID, socket type/owner/mode/inode, configured fingerprint set, and host mapping. The launcher runs `status` before selecting the socket and never inherits a caller-supplied `SSH_AUTH_SOCK`. 4. Define live acceptance as a host-invoked `pi-sbx-evidence run git-ssh-live-` after interactive key loading. It performs approved fetch and dry-run/non-destructive push checks, verifies the remote host key and wrapper log digest, and records only fingerprints and result hashes. Missing approved key paths/fingerprints, extra loaded keys, stale agents, or unavailable live evidence block pilot acceptance. 5. Restrict Git filesystem access to nono Git macros for the active worktree, common directory, top level, and config files. Add parent access only to a trusted worktree broker for explicitly tested clone/worktree operations; the outer session never receives `/srv/data/worktrees` or a repository's worktree parent. Model linked worktrees, shared object stores, nested repositories, and submodules so common-directory access does not silently expose sibling checkout paths. 6. Implement the trusted worktree broker around `/srv/data/worktrees//`. It creates and registers canonical linked worktrees, records repository/branch/path/creator/time and active-unit identity in trusted state, and removes a worktree only after proving it is inactive, clean, free of untracked files, and not ahead of its reviewed upstream. Dirty, untracked, unpushed, ambiguous, or active worktrees require explicit maintenance review and are never deleted solely because of age. Run `git worktree prune` only after the checkout removal is verified. 7. Record that linked worktrees share refs and an object store: pathname isolation protects sibling checkout files but does not provide branch-level confidentiality. Repositories requiring confidentiality between tasks use separately registered clones with independent object stores instead of linked worktrees. 8. Deny direct SSH from the session. Use a maintenance-installed immutable SSH wrapper to enforce reviewed host aliases, ports, trusted `known_hosts`, and the appropriate dedicated agent socket. Treat nono's port restriction as defense in depth, not hostname enforcement. 9. Prevent alternate caller paths through `GIT_SSH`, `GIT_SSH_COMMAND`, repository/global/system Git config, aliases, hooks, credential helpers, alternate Git/SSH binaries, shell expansion, and same-port unapproved hosts. 10. Add HTTPS Git destinations separately from SSH destinations. 11. Test the observed personal `git.jb.codes:7722` and work `bitbucket.org:22` routes with safe fixtures before the live evidence procedure. **Acceptance criteria:** - Direct `ssh` and every tested Git/SSH bypass path fail from both sessions. - Personal and work fixture keys cannot cross contexts; missing, stale, foreign-owned, or substituted agent sockets fail launch. - Fixture fetch/push succeeds automatically, and live fetch/push succeeds through the correct agent after explicit manual approval in each pilot repository. - Registered external worktrees work without granting their shared parent or sibling checkout paths; unsafe removal attempts preserve the checkout and report the blocking state; confidential-task fixtures use independent clones. - Unapproved SSH hosts, same-port hosts, ports, command arguments, config overrides, hooks, alternate binaries, and agent sockets fail. **Dependencies:** Slice 3 and the test harness from Slice 2. May run in parallel with Slice 4B. ## Slice 4B: GitHub CLI credential broker **Goal:** support repository-scoped `gh` operations without exposing the real keyring token to Pi. **Owner surfaces:** `profiles/nono/github-cli.json`, `config/nono/github-cli.json`, new broker sources under `scripts/nono/github-cli/`, and `tests/nono/capabilities/github-cli/`. This slice does not edit Git/SSH policy files or the catalog index. **Work:** 1. Create `config/nono/github-cli.json` with required, user-approved fields for keyring service/account selector, GitHub host, repository owner/name, allowed REST operation templates, and asset hosts. The selector is resolved and tested by maintenance without recording the token; an unset, ambiguous, or changed selector blocks installation. 2. Implement the fixed boundary `session -> gh-wrapper command policy -> nono credential route -> api.github.com`. The nono route is the only component that resolves the real keyring token. It supplies an invocation-scoped phantom as `GITHUB_TOKEN` to the wrapper; the wrapper copies that phantom to `GH_TOKEN`, unsets `GITHUB_TOKEN`, and execs the pinned `gh` binary. The outer Pi process, wrapper arguments, and child commands never receive the real token. 3. Normal mode permits only REST operations beneath `https://api.github.com/repos///...` plus approved downloads from `objects.githubusercontent.com` and `release-assets.githubusercontent.com`. GraphQL, `/user`, organization, account, gist, package, and other repository endpoints are denied until separately modeled. A deferred `gh-admin` capability owns cross-repository operations. 4. Define a REST-only pilot fixture command set before activation: relative `gh api repos//...` reads, approved issue/PR mutations through exact relative REST paths, and release asset download where needed. Record the exact CLI arguments, HTTP method/path templates, and response fixtures in `tests/nono/capabilities/github-cli/`; any unmodeled request fails closed. 5. The wrapper rejects `gh auth token`, `gh auth login`, `gh auth refresh`, `gh api graphql`, `gh api` with an absolute URL, extension execution, aliases, and config overrides. Tests assert `gh auth token` fails and never returns even the phantom. 6. Require `pi-sbx-evidence run github-cli-live` after explicit host approval. It checks the approved fixture commands against the pilot repository, verifies the broker and endpoint-policy digests, and records no response bodies or credentials. A pilot that does not need GitHub CLI omits this capability rather than weakening the gate. **Acceptance criteria:** - Normal `gh` operations against the pilot repository work through the proxy. - The real token is absent from Pi's environment, process arguments, generated policy, logs, and command output. - Cross-repository and unapproved endpoint requests fail in normal mode. - `gh auth token`, auth mutation, GraphQL, aliases/extensions, absolute API URLs, cross-repository requests, and every unmodeled endpoint fail without revealing the real or phantom credential. - The keyring selector, repository identity, method/path fixtures, pinned `gh` digest, and live evidence are approved before an applicable pilot passes. **Dependencies:** Slice 3 and the test harness from Slice 2. May run in parallel with Slice 4A. ## Pilot acceptance gate Do not add package managers or privileged integrations until one personal Git repository and one work Git repository pass the complete proof of concept. The pilot runs only Git/SSH and applicable `gh` operations; it does not run Node, Maven, or other package-manager workflows: - restrictive personal/work bases; - explicit environment filtering; - generated runtime profiles; - separate Git/SSH chains with direct SSH denial; - command-scoped GitHub CLI credentials where applicable; - approved SSH key paths/fingerprints and mandatory live Git evidence for both contexts; - approved GitHub selector/endpoints/fixtures and live evidence when `github-cli` is selected; - repository-managed exact LM Studio source/base-URL evidence when `--provider lm-studio` is selected; - pre-pilot cutover evidence proving legacy static profiles and compatibility paths are inactive; - positive and negative evidence reviewed by someone other than the implementers. A failed pilot returns to the owning slice. Do not compensate by broadening the outer Pi profile. ## Slice 5A: Node, npm, pnpm, and Bun bundles **Goal:** add JavaScript toolchains without granting registries and caches to Pi itself. **Owner surfaces:** `profiles/nono/{node-npm,pnpm,bun}.json` and disjoint tests under `tests/nono/capabilities/{node-npm,pnpm,bun}/`. **Work:** grant each command the active repository, exact cache/store paths, required registry and artifact hosts, and a token-free normal configuration. Separate install/build/test from publish. Cover lockfile-respecting commands used by the mapped repositories. Treat npm/pnpm/Bun lifecycle scripts and `npm test`, `npm run`, `pnpm run`, and equivalents as shell-spawning paths: prove their children inherit the package-manager command sandbox and cannot invoke SSH, Docker, browsers, deployment tools, sibling repositories, raw credentials, or an alternate package binary. Keep `workflow` disabled until Slice 6B2 integrates its executor with these completed policies. **Acceptance criteria:** installs, builds, and tests work in representative npm, pnpm, and Bun fixtures; adversarial lifecycle/run scripts remain inside the command policy; sibling repositories, unrelated caches, privileged commands, and raw credentials remain unavailable; publish credentials and commands are absent outside release mode. **Dependencies:** pilot acceptance. May run in parallel with Slices 5B, 6A, and 6B1. ## Slice 5B: Python, Rust, Go, and work Java bundles **Goal:** add remaining normal language toolchains as independently reviewable fragments. **Owner surfaces:** `profiles/nono/{python-uv,rust,go,maven-work,gradle-work}.json` and matching disjoint directories under `tests/nono/capabilities/`. Assign one owner per language fragment so this slice can be split into four parallel branches. **Work:** grant only each active repository, virtual environment or build output, exact caches, required registry/toolchain hosts, and mediated work artifact credentials where necessary. Keep publishing, Docker, deployment, and production routes out of these fragments. **Acceptance criteria:** representative restore/build/test workflows succeed; each tool can access only its own caches and hosts; work artifact credentials are command-scoped; publishing credentials remain absent. **Dependencies:** pilot acceptance. Each language fragment may proceed independently. ## Slice 6A: Exact local integrations **Goal:** make local application and voice access opt-in and endpoint-specific. Provider policy, including LM Studio, remains owned by Slice 1. **Owner surfaces:** `profiles/nono/orca-hooks.json`, `profiles/nono/herdr.json`, `profiles/nono/dictation.json`, their endpoint discovery helpers, and `tests/nono/capabilities/{orca,herdr,dictation}/`. Slice 1 exclusively owns `provider-lm-studio`. **Work:** 1. Read `/home/jb/.config/orca/agent-hooks/endpoint.env` with no-follow semantics and require UID 1000 ownership, mode `0600`, trusted parent directories, and a regular file. Require its mtime to postdate the trusted running Orca process start, validate the port, environment, and version, perform an authenticated health handshake with the endpoint token, snapshot device/inode/content digest, and recheck them before launch. A stale, replaced, unauthenticated, wrong-environment, or wrong-version endpoint fails closed. 2. Pass only the validated Orca hook values required by the integration; Pi never receives read access to the endpoint file itself. Repeat file freshness, identity, digest, and authenticated health checks on every generated-profile cache hit. 3. Validate `/home/jb/.config/herdr/herdr.sock` and `/run/user/1000/pi-dictate.sock` on every launch and cache hit: trusted parent paths, no symlink, Unix-socket type, UID 1000 owner, reviewed mode, stable device/inode, expected user-systemd service identity, and peer PID/UID from `SO_PEERCRED` where supported. Recheck immediately before `nono run`; stale, replaced, or wrong-service sockets fail closed. Put dictation behind `--voice`. 4. Remove general `127.0.0.1` and inherited localhost URL-opening access from normal profiles. 5. Prove whether Herdr/tmux receiving panes run under the same nono policy. Leave command execution disabled when containment cannot be demonstrated. 6. Keep model files, audio devices, PipeWire, GPU devices, and service data outside the Pi policy. **Acceptance criteria:** each integration works only when selected; stale or malformed endpoints fail closed; unrelated loopback ports and sockets are unreachable; `--voice` is visible in the permission plan and is absent by default. **Dependencies:** pilot acceptance. May run in parallel with Slices 5A, 5B, and 6B1. ## Slice 6B1: Child-agent and background-task isolation **Goal:** isolate spawned Pi, Claude, Codex, bounded background jobs, Herdr panes, and tmux panes without enabling repository toolchain execution or the legacy `workflow` extension. **Owner surfaces:** `profiles/nono/{child-pi,child-claude,child-codex,background-jobs}.json`, new spawn-wrapper sources under `scripts/nono/child-agents/`, isolated child-state configuration, and `tests/nono/capabilities/child-agents/`. Coordinate with extension owners but avoid editing Slice 6A's socket fragments or shared extension files concurrently. **Work:** 1. Inventory every spawn path in active subagent, `pi-ask`, update, and background-task extensions. Classify each in-process operation as safe UI/state access, disabled behavior, or a brokered subprocess. Keep the legacy `workflow` extension absent from generated settings. 2. Route child Pi, Claude, and Codex through command policies with isolated child state and the immutable provider selected by Slice 3. 3. Broker only named background jobs and notification commands that do not invoke repository toolchains; keep arbitrary commands, package updates, and direct privileged spawn paths disabled. 4. Define caller relationships and prohibit privileged-command escalation through child commands. 5. Verify Herdr and tmux targets launch under equivalent or narrower generated policies before enabling command delivery. 6. Add containment tests for nested children, background completion, cancellation, inherited environment, provider override denial, notification commands, package-update denial, and artifact paths. **Acceptance criteria:** child commands receive no broader filesystem, network, credential, socket, environment, or provider access than declared; nested child tests prove containment; unsandboxed Herdr/tmux targets are rejected; bounded extension behavior remains functional without the legacy `workflow` extension or toolchain execution. **Dependencies:** pilot acceptance. May run in parallel with Slices 5A, 5B, and 6A. ## Slice 6B2: Skill-led development toolchain evidence > [ADR 0006](adr/0006-skill-led-development-workflow-04SEP2026.md) supersedes the planned `workflow` extension profile, spawn wrapper, generated-settings entry, and capability suite. Do not create those surfaces. **Goal:** prove that `develop-workflow` uses only the parent session's approved Git, package-manager, verification, and child-agent command policies. **Owner surfaces:** evidence under the existing Slice 5 and Slice 6B1 suites. The skill itself owns no nono profile, executable, wrapper, extension entry, or permission grant. **Work:** exercise representative skill-led assignments through the already completed toolchain and child-agent policies. Verify that model-selected commands cannot bypass executable allowlists, lifecycle/run-script containment, provider binding, repository boundaries, or cancellation. An unmodeled executable or repository without the required fragment fails exactly as it does for direct parent tool use. **Acceptance criteria:** skill-led tasks cannot broaden parent or child policy, select another provider, invoke high-risk commands, read sibling repositories, or access raw credentials. The legacy `workflow` extension remains absent from generated settings. **Dependencies:** Slices 5A, all applicable 5B language fragments, and Slice 6B1. It does not run in parallel with the toolchain policy it consumes. ## Slice 7: High-risk modes Start each mode as its own branch and approval decision. The trusted pre-sandbox launcher accepts high-risk flags only from an interactive host terminal when no parent nono sandbox is detected. High-risk modes cannot be combined unless the trusted catalog explicitly defines and tests that exact combination; `--yes` and environment-based authorization are unsupported. ### Slice 7A: Docker and browser Create separate `docker-high-risk` and `browser-high-risk` modes. Treat the Docker socket and browser control as trusted escape hatches that can bypass ordinary filesystem or network constraints. Require the user to type the selected mode and canonical repository before launch. Test denial without the flag, noninteractive invocation, invocation from a sandbox, conflicting flags, and access to the other high-risk mode. ### Slice 7B: Release and production Create separate release and production modes with environment-specific credential routes, exact APIs, and command allowlists. Keep package publishing separate from deployment and production data operations. The trusted launcher requires a second interactive confirmation naming the environment and repository immediately before credential activation; production mutations also require the deployment command's own approval mechanism where available. Record who approved, policy digest, repository revision, mode, and time without recording credentials. ### Slice 7C: Maintenance Create a maintenance-only profile for Pi updates, package/extension installation, `scripts/pi-links.mjs`, immutable package-lock reconciliation, trusted launcher/catalog snapshot installation, nono draft/profile work, and active symlink activation. For `/srv/data/code/harness-tools`, normal mode grants repository read-only access; only this host-authorized maintenance profile grants exact repository source paths read/write for policy development and promotion. Add an `opensrc` command policy with read access to the source repository, write access only to `/srv/data/opensrc`, and required package/source hosts. Normal profiles retain read-only runtime and extension source and cannot invoke `/update`. Activation remains an explicit host-side step. Review whether `pi-sbx.fish`'s hardcoded systemd limits belong in the installed snapshot and test that maintenance updates do not silently change them. **Shared acceptance criteria:** each mode is absent by default; requires the documented host-side interactive authorization; prints mode, repository, blast radius, and policy digest before confirmation; rejects all unapproved flag combinations and sandbox-origin launches; has positive and negative tests; and produces a redacted approval record before activation. **Dependencies:** the pilot and Slice 3's mode mechanism. Individual modes may proceed in parallel after explicit user approval. ## Slice 8: Repository migration and legacy retirement **Goal:** move repositories in small, observable batches and remove the broad static path only after evidence shows it is unnecessary. **Owner surfaces:** disjoint batch files under `config/nono/repositories.d/`, matching redacted evidence under `docs/nono-migration/`, and eventual legacy-profile removal in an integration-only branch. Migration branches do not edit `config/nono/repositories.json` directly. **Batches:** 1. Preserve the already accepted pilot mappings: one personal Git repository and one work Git repository, exercising core, Git/SSH, and applicable `gh` policies without invoking Node, Maven, or other package managers. 2. Map `/srv/data/code/harness-tools` to a self-protection policy: repository and policy sources are read-only in normal mode, the installed launcher/catalog remains inaccessible, and writes are available only through the explicitly authorized maintenance mode. Test both mappings from the repository root and linked worktrees. 3. Content/config and offline Git/editor repositories. 4. Personal Node/Bun/Python repositories. 5. Rust/Go/native/ML repositories. 6. Work Java and UI repositories. 7. Large mixed-service repositories. 8. Infrastructure and production applications, only after their high-risk modes exist. 9. Extension-development repositories under `/srv/data/repo-store`, read-only during normal use and writable only when selected as the active repository. For each repository: 1. Inventory actual commands and enabled extensions. 2. Propose the smallest reviewed capability list. 3. Run the full negative suite and representative positive workflow through the installed `pi-sbx-evidence run `. 4. Review the schema-validated summary and retained raw nono evidence for denied required access and unexpected allowed access. 5. Add only the exact missing capability. Never grant a shared parent directory to clear an unexplained denial. 6. Record the approved mapping, owner, policy digest, reviewer, and evidence-summary path. **Acceptance criteria:** every mapped repository has an owner, reviewed capability list, positive workflow evidence, and negative isolation evidence; unknown repositories always fail closed; static `pi-local`, `pi-orca-local`, `pi-work`, and `pi-harness-tools` routing is retired only after no active mapping depends on it. ## Integration ownership and conflict controls To keep parallel work mergeable: - Slice 0 owns existing static profiles, `config/pi-package-lock.json`, `config/pi-links.json`, and `docs/nono-profile-baseline.md` only. - Slice 1 owns core/provider fragments, its ADR, nono skill corrections, and `tests/nono/capabilities/core/`. - Slice 2 owns `tests/nono/harness/`, `tests/nono/fixtures/core/`, and `scripts/test_nono.py`; capability branches consume its API without editing it. - Slice 3 owns catalog/schema/index files, repository-map format and pilot entries, launcher code and flags, existing launcher tests, root package-script integration, and `docs/nono.md`. - Each later capability branch owns named fragment files and one disjoint `tests/nono/capabilities//` directory. It supplies an integration handoff for Slice 3 to add catalog indexes or shared docs. - Slice 8 owns disjoint repository-map batch files under `config/nono/repositories.d/` after the pilot; Slice 3's integration pass builds any canonical index. - Rebase each slice before integration. Run strict validation and the full security matrix after every catalog or generator merge. ## Verification matrix | Capability | Positive proof | Negative proof | | --- | --- | --- | | Trusted launcher/cutover | Installed snapshot digest and committed cutover journal match; approved launch succeeds | Interrupted journal, environment overrides, writable inputs, checkout/profile paths, retired profiles, stale links, symlink substitution, sandbox-origin high-risk launch, and arbitrary profile names fail | | Base filesystem | Active registered worktree has exactly its mapped read-only or read/write access; exact mutable Pi state and the per-launch temporary directory are writable | A read-only worktree cannot be written; broad `/tmp`, runtime parents, other sessions, sibling or unregistered worktrees, global instructions, extension source, other Pi state, `~/.ssh`, and `~/.config/gh` are inaccessible or read-only as designed | | Temporary lifecycle | Normal exit and cancellation remove the private runtime directory; approved active use remains within its aggregate bound | Cleanup preserves a held lease, matching PID/start time, populated cgroup, live unit, or inconclusive identity; proven crash leftovers expire, unsafe paths survive for review, and an active session cannot exhaust `/run` | | Worktree lifecycle | Broker creates, registers, resolves, and safely removes an external clean worktree | Broad worktree-root access, age-only deletion, dirty/untracked/unpushed removal, active-worktree removal, and linked-worktree confidentiality claims fail | | Environment/extensions | Reviewed extensions and selected mediated provider credential work | Raw credential variables, old LM Studio source, duplicate providers, `/update`, the legacy `workflow` extension, arbitrary notification commands, and unbrokered shell jobs are absent | | Provider | Trusted default or one pre-boundary approved flag selects the route; LM Studio reaches port 1234 | Ambiguous/post-boundary/child overrides, non-selected providers, LM Studio port 1235, and broad localhost fail | | Git/SSH | Fetch/push uses the correct provisioned agent and immutable wrapper | Direct SSH, stale/substituted agent, bypass config, alternate binary, same-port host, wrong agent, wrong host, and wrong port fail | | GitHub CLI | Active-repository operation succeeds through proxy | Real token exposure, cross-repository API, and unapproved endpoints fail | | Package manager/skill-led tasks | Restore/build/test uses exact cache and hosts; 6B2 proves `develop-workflow` cannot exceed completed parent policies | Lifecycle/run-script escape, unrelated cache, publish token, privileged command, and unapproved registry fail | | Orca/Herdr | Authenticated current endpoint and verified socket peer succeed on launch and cache hit | Stale/replaced/wrong-service endpoint and unrelated socket/port fail | | Dictation | Voice request succeeds with `--voice` | Socket, audio stack, model data, and GPU remain absent by default | | Child agents | Declared bounded child task completes | Child cannot broaden filesystem, network, credentials, sockets, environment, or provider | | High-risk modes | Explicit host-authorized workflow succeeds and records policy digest | Missing confirmation, conflicting flags, sandbox invocation, or another mode's capability fails | | Generator/evidence | Strict validation, dynamic revalidation, deterministic cache hit, and trusted evidence summary succeed | Unknown or malformed inputs, stale digests/endpoints, tampered cache/evidence producer, and unsafe runtime/cache paths stop before launch | ## Rollback Keep broad legacy profile content only in the host-only rollback store; repository paths contain retired deny profiles. A static fallback requires a host-side authorization record containing an owner, repository, reviewed profile digest, reason, and expiry of at most seven days. Maintenance copies that exact digest to a mode-`0600` ephemeral runtime path that the trusted launcher binds to the named repository for the authorized period. The launcher refuses direct rollback-store/repository paths, expired or mismatched records, inherited profile variables, and arbitrary profile names. If a generated-profile launch blocks required work: 1. save redacted denial evidence; 2. explicitly authorize the last reviewed static-profile digest for that repository and limited period; 3. run the restoration test and launch with the time-bounded compatibility option; 4. fix the owning capability or generator slice; 5. rerun both positive and negative tests before restoring dynamic routing. Remove the compatibility option after all mapped repositories complete Slice 8. Rollback is never automatic because silent fallback would hide fail-open behavior. ## Immediate next actions 1. Complete Slice 0 and obtain approval for active-profile reconciliation. 2. Assign parallel worktrees for Slice 1 and Slice 2. Run a read-only Slice 3 schema spike in parallel, but do not edit Slice 1 or Slice 2 owner surfaces and do not finalize interfaces until Slice 1 confirms nono composition behavior. 3. Select one personal and one work Git pilot repository that exercise Git-over-SSH and, where applicable, GitHub CLI, without requiring package-manager commands. 4. Lock the pilot acceptance checklist, SSH-agent provisioning procedure, and live credential evidence procedure before implementing Slices 4A and 4B. 5. Defer package-manager, non-SSH local sockets, child-agent, Docker, browser, release, production, and maintenance grants until the pilot gate passes. The two dedicated SSH-agent sockets are the only socket capabilities permitted by the pilot, and frozen legacy socket-bearing profiles remain deactivated by the cutover gate.