Ship a first-run trust loop: openspine init (#118) - #269
Conversation
…#118) Replace the repository-setup ceremony with one non-interactive command that establishes the trust loop: seed key -> approval anchor -> test. - Add `openspine init --owner <telegram_user_id> [--name <display>]`: writes the configuration and owner-only seed key file, binds the single trusted owner principal (fresh data root only, via the same identity::bootstrap_owner_principal the kernel uses at boot), runs readiness, and prints a plain-language trust ceremony with honest next steps. - Require the real owner id up front and reject a conflicting id on an existing install: the owner binding is immutable and the kernel fails closed on a mismatch, so a placeholder would trap the owner. - Extract shared, non-interactive key-material helpers (cli/bootstrap.rs) reused by the interactive `openspine setup` wizard; add owner Telegram id to StarterConfig. - Document the trust ceremony in docs/first-run.md; lead README and the site quickstart with `openspine init`. - Tests: unit coverage for the config/key writing and owner-immutability guard; an end-to-end smoke that spawns the binary in a clean temp dir and asserts the loop completes (config, 0600 seed keys, owner principal, ceremony report). Kernel trust boundaries are untouched: no new ungated path, the deterministic pipeline is unchanged, and the principal init writes is exactly the one boot would create. Closes #118
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 3 minutes Limit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (13)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
Adds
openspine init --owner <telegram_user_id> [--name <display>]: a single, non-interactive command that turns a built binary into a running, governed install, replacing the repository-setup ceremony as the documented first-run path.The command establishes the trust ceremony end to end:
openspine.env(artifact/grant/webhook keys, mode 0600).identity::bootstrap_owner_principalthe kernel uses at boot.provider login, Telegram, Gmail).Also: extracts shared non-interactive key-material helpers (
cli/bootstrap.rs) reused by the interactiveopenspine setupwizard; adds the owner Telegram id toStarterConfig; documents the ceremony indocs/first-run.md; leads the README and site quickstart withopenspine init.Why
The value-equation audit found setup effort and time-to-first-value were the weakest variables. The old public path asked users to clone, build, copy an example YAML, and hand-edit a Telegram id before seeing the product. This collapses local first-run into one command while keeping every kernel trust boundary intact — no new ungated path, deterministic pipeline unchanged, and the principal
initwrites is exactly the one boot would create.Design decision (raised by review)
--owneris the Telegram user id (the authoritative trusted-principal binding), not just a display name. A display-name-only init would bind theStarterConfigplaceholder (telegram_user_id: 1) as the authoritative owner on first boot;bootstrap_owner_principalis fail-closed, so a later real id would trap the user with an unbootable install. Requiring the real id up front removes that trap.initalso only writes the principal on a demonstrably fresh data root, so it never appends a bootstrap audit against a store the kernel has not yet validated.Testing
./scripts/check.sh— green (fmt, clippy, full suite, 45/45 openspec specs, claims register).--owner; conflicting--owneron an existing install is rejected.tests/first_run_smoke.rs): spawns the binary in a clean temp dir and asserts the loop completes — config, 0600 seed keys, owner principal (kernel.db), and ceremony report.Scope note
The
#118issue body also sketches a maximalist onboarding vision (preflight engine, Gmail thread picker, boundary/receipt DTOs) from a superseded auto-generated plan ("Restructured into the cohesive roadmap"). A real Lyra draft needs a live provider + Docker + Telegram + Gmail and cannot run in the specified clean-temp-dir smoke; those rungs are surfaced truthfully as next steps, matching the ticket's "distinguish required configuration, optional capability, and current alpha limits."Implementation notes (summary)
--owner= Telegram user id (+--name), to avoid binding thetelegram_user_id: 1placeholder as the authoritative fail-closed owner.initbootstraps the principal only on a fresh data root, preserving run()'s validate-before-bootstrap ordering (main.rs 300-317).StarterConfig::to_config()hardcoded the placeholder owner id;bootstrap_owner_principalis idempotent + fail-closed on config mismatch.--owner= Telegram user id acceptable vs. a display name?Closes #118
Summary by cubic
Introduces
openspine init: a single command that turns a built binary into a running, governed install. This replaces the repo-setup ceremony to cut first-run friction while preserving the kernel’s trust boundaries and deterministic boot.openspine setup. New behavior:openspine init --owner <telegram_user_id> [--name]writes config and seed keys, bootstraps the owner on a fresh data root, then prints readiness and the trust ceremony. Interactiveopenspine setupremains available.initrequires a real--owneron fresh installs and rejects a conflicting id on existing installs. It only bootstraps the owner when no encrypted state exists; otherwise the kernel performs the validated bootstrap on next start.initwritesopenspine.envat mode 0600, never overwrites existing entries, and refuses to mint a newOPENSPINE_ARTIFACT_KEYover populated state to avoid orphaning the vault.cli/bootstrap.rs) and reuses them in the wizard. Adds the owner Telegram id toStarterConfig. No ungated authority path is introduced; it uses the sameidentity::bootstrap_owner_principalas boot.Rollout and migration
openspine init --owner <telegram_user_id> [--name] [--config <path>]. This is now the documented first-run path.openspine initto fill missing keys; it will not rebind the owner. Keep your existingopenspine.envif the data dir holds encrypted state; a new artifact key will be refused.openspine init(README, site quickstart,docs/first-run.md). Tests cover config/key writing, owner-id guard, and an end-to-end smoke of the trust loop.Written for commit e1692bb. Summary will update on new commits.