cli

Command-line interface for Radroots
git clone https://radroots.dev/git/cli.git
Log | Files | Refs | README | LICENSE

commit d9e8df4099586955db2fdbb867f4f24c2b42f053
parent 3cc102db961b75a4c72698208ed8b42833906baa
Author: triesap <tyson@radroots.org>
Date:   Sun,  9 Aug 2026 06:56:20 +0000

docs: move human authority to parent

Diffstat:
MAGENTS.md | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
MREADME | 68++++++++++++++++++++++++++++++--------------------------------------
Ddocs/engineering/local-overrides.md | 31-------------------------------
Ddocs/migration/crates-release-v1.md | 51---------------------------------------------------
Ddocs/nix.md | 26--------------------------
Mflake.nix | 1+
Atools/verify-repository-boundary.sh | 31+++++++++++++++++++++++++++++++
7 files changed, 187 insertions(+), 164 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md @@ -1,18 +1,125 @@ -# cli - code directives - -- this repo defines `radroots_cli`, the Radroots command-line interface; the primary binary is `radroots` -- treat this repo root as the source of truth for source, user-facing command behavior, repo-local validation, docs, and release-candidate readiness -- do not make this repo responsible for platform-wide signed artifacts, builder selection, publication, promotion, deployment transport, relay internals, signer internals, or SDK internals unless the public CLI contract explicitly changes -- prefer the smallest coherent change that fully addresses the request; do not mix unrelated cleanup, speculative refactors, compatibility scaffolding, or roadmap work into the same change -- inspect the relevant implementation, tests, manifests, and docs before changing behavior; read `README.md` and `Cargo.toml` before broad edits -- do not depend on private repositories, unpublished artifacts, local machine layouts, absolute paths, or internal monorepo context -- keep public docs, manifests, tests, generated artifacts, and contract surfaces aligned with behavior changes -- preserve clear boundaries between argument parsing, configuration loading, service clients, domain logic, and output formatting -- prefer explicit typed models, deterministic behavior, narrow side effects, and direct service boundaries over stringly or implicit behavior -- avoid hidden production panics; use typed errors for expected failure modes -- avoid `unsafe` unless it is strictly necessary, locally justified, and documented with nearby invariants -- do not expose secrets, private keys, credentials, tokens, invite codes, private identifiers, sensitive user data, or sensitive event content in code, logs, tests, fixtures, docs, or examples -- use checked-in, repo-owned validation first; run the smallest documented validation that credibly covers the change, and use release acceptance validation for production candidates -- `.github/**` and capsule-local CI workflows are forbidden; keep validation forge-agnostic, and place any required monorepo orchestration exclusively under the parent monorepo's root `.act/**` authority -- if validation cannot run, report exactly what was skipped and why; never claim validation passed unless it actually ran -- keep commits focused and reviewable, using `<scope>: <imperative summary>` unless a repo convention overrides it +# AGENTS.md — Radroots CLI + +These instructions apply to the complete standalone `radrootslabs/cli` +repository. + +## Repository role + +This repository owns the public `radroots_cli` package and the `radroots` +binary. It owns command parsing, invocation-scoped configuration, composition +of public Radroots library clients, stable output envelopes, exit behavior, +and CLI-specific presentation and tests. + +It does not own Radroots domain policy, durable service state, signing or +custody internals, relay internals, SDK internals, platform deployment, +publication, promotion, or non-public parent integration behavior. Preserve +those boundaries unless an approved public contract explicitly changes them. + +The repository must remain independently cloneable, buildable, testable, and +packageable. Do not depend on private repositories, parent-only contracts or +tools, sibling checkout paths, unpublished local artifacts, absolute host +paths, or an enclosing monorepo layout. + +## Authority and published-source boundary + +Repository-local machine authority is limited to manifests and locks, +`radroots.lib.source-lock.v1.toml`, and explicit machine-readable contracts +added under `contracts/**`. Source and tests are implementation evidence, and +`flake.nix` owns the standalone command surfaces. The root `README` is concise +public routing material, not a substitute for a machine contract. + +`.env.example` is non-authoritative pre-refactor evidence. It does not describe +current runtime behavior and remains only until its owning later cleanup +checkpoint; do not use it to invent or preserve configuration behavior. + +Human implementation specifications, decisions, runbooks, migration history, +qualification records, and execution evidence are parent-owned and do not ship +in this capsule. Never create or consume capsule-local `docs/**`. The parent +documentation is not a standalone command, build, test, package, or release +input. + +The physical roots `docs/**`, `.github/**`, and `.act/**` are forbidden, +including symlinks. Run `tools/verify-repository-boundary.sh` in every governed +verification lane. Do not add a capsule-local workflow definition. External +automation may invoke the repository's ordinary forge-agnostic commands, but +it must not be required by an independent clone. + +## Dependency and source-lock rules + +The public `radroots` dependency must use the canonical +`https://github.com/radrootslabs/lib.git` source, an exact immutable revision, +and the declared exact package version. Keep `Cargo.toml`, `Cargo.lock`, and +`radroots.lib.source-lock.v1.toml` consistent. Never replace it with a path, +branch, floating Git reference, private mirror, or implicit sibling override. + +An exact revision is not releasable merely because it exists locally. Before a +downstream pin or release advances, the selected upstream commit must be +publicly reachable and its source-lock evidence must be verified under the +applicable publication authority. + +## Change rules + +- Inspect the relevant manifest, lock, source lock, implementation, tests, and + public routing material before changing behavior. +- Make the smallest complete change and keep each checkpoint independently + reviewable. Do not mix unrelated cleanup or roadmap work into it. +- Preserve a clear separation between argument parsing, configuration loading, + service-client composition, domain-library calls, and output formatting. +- Prefer typed models, explicit inputs, deterministic behavior, narrow side + effects, and typed errors for expected failures. +- Do not add compatibility aliases, dual reads, dual writes, fallback behavior, + or hidden environment/runtime discovery for prototype surfaces being removed + by the active clean-slate services-hardening sequence. Change those surfaces + only in their owning implementation checkpoint. +- Keep output schemas, exit codes, help text, configuration examples, source, + tests, and machine contracts aligned with every user-visible change. +- Keep `unsafe` absent unless an approved contract makes it unavoidable; any + exception requires a narrow local invariant and dedicated tests. + +## Security and operational behavior + +Never expose or commit private keys, credentials, tokens, invite codes, +approval proofs, private identifiers, sensitive user data, or sensitive event +content. Examples and fixtures must use unmistakably synthetic values. + +Do not log secrets or raw protected material. Keep machine-readable output on +stdout, diagnostics on stderr, and non-success outcomes paired with a stable +structured error and nonzero exit status. Destructive or externally mutating +commands must remain explicit, fail closed, and require their governed +authorization rather than inferring consent from configuration or environment. + +Avoid hidden production panics. Bound input, output, network, time, and retry +work where the relevant public contract defines a limit, and preserve +cancellation and failure context without leaking sensitive internals. + +## Verification + +From an extbuild-enabled checkout, run `cargo extbuild doctor` before the first +mutating build, check, test, package, install, or generated-artifact command, +then route repository-owned commands through `cargo extbuild run -- ...`. +Standalone public verification surfaces are: + +```sh +nix run .#fmt +nix run .#check +nix run .#test +nix run .#release-acceptance +``` + +Use the smallest relevant surface during development and the complete release +acceptance surface for a production candidate. Rust changes additionally +require the relevant locked `cargo fmt`, `cargo check`, `cargo test`, and +warnings-denied `cargo clippy` lanes. Run `git diff --check` and inspect the +final status and diff before every checkpoint. + +Never claim a lane passed unless it ran successfully. Record unavailable or +environment-blocked lanes exactly, and do not treat parent-only automation as a +substitute for standalone repository validation. + +## Git and release discipline + +Preserve unrelated changes and repository identity. Do not reset, discard, +rewrite, push, tag, sign, publish, deploy, rotate credentials, or advance a +downstream revision without explicit authority for that action. Keep commits +focused and use `<scope>: <imperative summary>` unless a stronger repository +convention applies. diff --git a/README b/README @@ -1,25 +1,26 @@ # Radroots CLI `radroots` is the local-first command-line host for the release-v1 Radroots -crate graph. It consumes the canonical `radroots` facade and retains only -command parsing and presentation concerns. +crate graph. It consumes the canonical `radroots` facade and retains command +parsing, client composition, output envelopes, and presentation concerns. -The CLI is pre-release software. Its current package graph uses exact alpha -versions so a lockfile and the matching Radroots package set travel together. +The CLI is pre-release software. `Cargo.toml` pins the public Radroots library +repository at an exact Git revision; `Cargo.lock` and +`radroots.lib.source-lock.v1.toml` record the corresponding dependency graph +and source evidence. The repository never falls back to a sibling checkout. ## Install and run -Use Rust `1.97.1`, then build with the committed lockfile: +Use the toolchain declared by `rust-toolchain.toml` and the committed lockfile: ```sh cargo build --locked cargo run --locked -- --help ``` -In the Radroots development workspace, route those commands through extbuild -and opt into the ignored local override file described in -[`docs/engineering/local-overrides.md`](docs/engineering/local-overrides.md). -Release and packaged-consumer checks never use sibling path overrides. +In an extbuild-enabled checkout, run `cargo extbuild doctor` first and route +the commands through `cargo extbuild run -- ...`. A standalone checkout does +not require an enclosing Radroots workspace or a local dependency override. ## Release-v1 command model @@ -47,52 +48,43 @@ Global controls include: - `--quiet`, `--verbose`, and `--trace` for presentation detail. Machine consumers should prefer JSON for a single response and NDJSON for a -stream. A non-zero exit is paired with the structured error in the output +stream. A nonzero exit is paired with the structured error in the output envelope; scripts should evaluate both. ## Configuration -Configuration resolves in this order: command-line flags, process environment, -the selected environment file, user configuration, workspace configuration, -and built-in defaults. Unknown or retired keys fail closed. +The current executable accepts only the command-line controls shown by +`radroots --help`; it does not load `.env`, user, or workspace configuration. +`profile inspect` and `health inspect` construct and close the pinned facade's +local-only memory client. All write operations remain fail closed until their +canonical SDK orchestration is implemented by a later release. -For a repository-local development profile, copy `.env.example` to `.env` and -adjust its explicit runtime root. The important settings are: - -```text -RADROOTS_CLI_PATHS_PROFILE=repo_local -RADROOTS_CLI_PATHS_REPO_LOCAL_ROOT=infra/local/runtime/radroots -RADROOTS_CLI_OUTPUT_FORMAT=terminal -RADROOTS_CLI_ACCOUNT_SECRET_BACKEND=encrypted_file -``` - -Use `radroots profile inspect` and `radroots health inspect` to verify that the -registry-backed facade can construct and close its local-only memory client. -Write operations remain fail-closed until their canonical SDK orchestration is -enabled in a future release. +`.env.example` is retained as pre-refactor implementation evidence, not as a +description of active runtime behavior. Do not treat it as a supported +configuration contract. ## Package migration The v1 crate migration removed compatibility namespaces and the CLI-owned generic signing, transport, storage, and sync engines. The initial CLI host -uses only the final facade composition. -See [`docs/migration/crates-release-v1.md`](docs/migration/crates-release-v1.md) -for renamed commands, configuration changes, and downstream package rules. +uses only the final facade composition. `AGENTS.md` defines the current +repository boundary and contribution rules; historical migration guidance is +not a standalone build or release input. ## Verification -The standalone source checks are: +The forge-agnostic standalone checks are: ```sh -cargo fmt --all -- --check -cargo check --all-targets --locked -cargo test --all-targets --locked +nix run .#fmt +nix run .#check +nix run .#test +nix run .#release-acceptance ``` -Release qualification additionally packages the CLI, resolves every Radroots -dependency from a local registry containing `.crate` archives, extracts the CLI -archive, and repeats check, test, and `radroots --help` against that extracted -source. This catches workspace-path and package-content drift. +Each surface rejects forbidden capsule-local documentation and workflow roots +before running its Rust checks. An extbuild-enabled checkout routes these +commands through `cargo extbuild run -- ...`. ## Copyright and license diff --git a/docs/engineering/local-overrides.md b/docs/engineering/local-overrides.md @@ -1,31 +0,0 @@ -# Local Radroots package overrides - -The committed CLI manifest contains only exact versioned Radroots package -requirements. Production, release, and packaged-consumer checks must not use a -sibling source checkout. - -Before the coordinated registry publication, local development may use an -explicit Cargo config outside the release graph. Create -`.cargo/local-paths.toml` with `[patch.crates-io]` entries pointing to the -required `oss/lib` and `oss/sdk` packages, then pass it explicitly: - -```sh -cargo --config .cargo/local-paths.toml check --all-targets -cargo --config .cargo/local-paths.toml test --all-targets -``` - -The local config is ignored and must never be committed. Do not use it for -package-artifact, release-graph, or publication qualification; those lanes must -resolve the exact versions from the configured registry. - -The packaged canary must perform all of the following from disposable paths: - -1. package the required `oss/lib` crates in Cargo-resolved order; -2. package `radroots_runtime_contract_v1` and `radroots_sdk` from `oss/sdk`; -3. index the resulting `.crate` archives and their checksums in a local registry; -4. package `radroots_cli` with crates.io replaced by that registry; -5. extract the CLI archive and run locked check, test, and help smoke commands. - -Passing a source-tree check with `.cargo/local-paths.toml` is not evidence that -the packaged canary is green. The extracted package's Cargo metadata must show -registry sources for every Radroots dependency and no `path` or `git` source. diff --git a/docs/migration/crates-release-v1.md b/docs/migration/crates-release-v1.md @@ -1,51 +0,0 @@ -# Radroots crates release v1 migration - -This release moves the CLI onto the final, versioned Radroots crate graph. It -is intentionally breaking: retired compatibility imports, parallel generic -engines, and implicit workspace paths are no longer supported. - -## Dependency migration - -- Depend on `radroots = "=0.1.0-alpha"` for the supported ordinary application API. -- Keep exact versions and a committed lockfile during the coordinated alpha. -- Do not add sibling `path` dependencies to a production manifest. -- Local contributors may use the explicit ignored patch file documented in - [`../engineering/local-overrides.md`](../engineering/local-overrides.md). -- Release checks must resolve normalized `.crate` archives from a registry. - -The public crate family remains split across the existing `oss/lib` and -`oss/sdk` repositories. This migration does not create a replacement repository -or merge those repositories. - -## Runtime migration - -The CLI now composes only the canonical `radroots` facade. CLI code owns -command parsing and terminal or structured presentation; storage, signing, -transport, and sync behavior remain with the final crates. It must not -reintroduce a generic relay pagination loop, ingest reducer, outbox engine, or -signer protocol. - -The old environment and TOML groups are rejected instead of silently mapped. -Start from `.env.example`, inspect the resolved profile, and address health -actions in order: - -```sh -radroots profile inspect --format json -radroots health inspect --format json -``` - -Other resource commands remain parseable but fail closed with -`unsupported_operation` until a future release enables their canonical SDK -orchestration. This is an intentional breaking change from the private runtime. - -Automation should use `--no-input`, explicit online/offline policy, and stable -idempotency and correlation identifiers for writes. Retired commands and flags -fail during parsing; use the resource-oriented command tree shown by -`radroots --help`. - -## Compatibility policy - -No compatibility import or legacy package name is retained in the supported -surface. A downstream is compatible only when it builds with the exact registry -artifacts, consumes the current output envelope and runtime contract, and does -not require a private or sibling source checkout. diff --git a/docs/nix.md b/docs/nix.md @@ -1,26 +0,0 @@ -# Nix - -This repository uses Nix as the canonical local development and validation environment. - -## Enter The Shell - -```bash -nix develop -``` - -## Validation And Formatting - -```bash -nix run .#fmt -nix run .#check -nix run .#test -nix run .#release-acceptance -``` - -Use `nix run .#check` and `nix run .#test` as the first-line validation pair -from this repo root. - -Use `nix run .#release-acceptance` when preparing a production candidate. - -Use `nix develop` before running narrower ad hoc cargo commands from this repo -root. diff --git a/flake.nix b/flake.nix @@ -58,6 +58,7 @@ set -euo pipefail repo_root="$(git rev-parse --show-toplevel)" cd "$repo_root" + ./tools/verify-repository-boundary.sh export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib" export LIBRARY_PATH="${libraryPath}:''${LIBRARY_PATH:-}" export DYLD_FALLBACK_LIBRARY_PATH="${libraryPath}:''${DYLD_FALLBACK_LIBRARY_PATH:-}" diff --git a/tools/verify-repository-boundary.sh b/tools/verify-repository-boundary.sh @@ -0,0 +1,31 @@ +#!/bin/sh +set -eu + +if [ "$#" -gt 1 ]; then + echo "usage: $0 [repository-root]" >&2 + exit 64 +fi + +if [ "$#" -eq 1 ]; then + repository_root=$1 +else + CDPATH='' + export CDPATH + repository_root=$(cd -- "$(dirname -- "$0")/.." && pwd -P) +fi + +if [ ! -d "$repository_root" ]; then + echo "repository root is not a directory: $repository_root" >&2 + exit 64 +fi + +status=0 +for forbidden_root in docs .github .act; do + candidate=$repository_root/$forbidden_root + if [ -e "$candidate" ] || [ -L "$candidate" ]; then + echo "forbidden capsule root exists: $forbidden_root" >&2 + status=1 + fi +done + +exit "$status"