Repository navigation
Description
[Frontier] [POLICY15-02] Install the first standing policy from the Web UI on a fresh install
Parent
S15 — #316. Canonical spec: docs/specs/S15-conversational-autonomy.md (problem statement: "standing owner policy established once"; S15-D01, S15-D07, S15-D23).
Model tier
Frontier: standing authority installation semantics (what a fresh owner can authorize with one review), plus owner UI authored by Claude Opus 5.5 at effort high.
Gap found (verified on main 7f06716)
After install.sh --s15 the runtime can do no work:
- The installer writes
policy: null; the catalog lists onlybot,resource:computer,routeandmodel(no purpose, no recipient for the model provider). - The Web rules page can only propose
options.proposedPolicy(the config file's policy) and refuses an owner-entered budget (configured_budget_required). proposePolicymarks a proposal installable only with a non-null budget, although the owner-accepted orchestrator decision of 2026-11-03 allows subscription-only model routes without an owner budget via the protected subscription registry with finite concurrency and per-work bounds (metered routes still need a finite budget).
So the owner cannot establish standing policy without editing the config file, which breaks the "just works" rule and blocks the first ordinary conversation ([Frontier] [CUT15-01] Install S15 fresh on jit-vm with owner acceptance and a recoverable install #341 acceptance).
Deliverable
On a fresh install the Web setup shows a default standing-policy proposal derived from the installation's actual, active catalog — the owner's Jit bot, an "owner-requested work" purpose, the working-computer pool resource, the protected browser resource when composed, connected GitHub repositories when present (GIT15-04), the approved model route(s) and their provider recipients — with the product-default rules (ordinary work runs; communications/publication/payments/production/new private-data recipients/major changes held; no personal GitHub exception). The owner reviews the exact rows once and installs with one click. A subscription-only selection needs no budget; any metered route still requires a finite owner budget entered in the UI.
Implementation steps
- Protected default catalog: the runtime (not the config file) registers the default purpose and provider-recipient refs for an S15 installation, revisioned and owner-visible; existing explicit config catalogs keep working.
- Proposal: when no policy is installed and the config has none, compose the default proposal from the current active catalog and composed resources; include a finite default expiry (orchestrator choice: 180 days, shown to the owner, renewable from the same page) and keep every other policy field explicit.
- Installability: allow
budget: nullonly when every selection is a protected subscription route currently admitted by the subscription registry (finite concurrency/per-work bounds), otherwise require a finite budget; never infer money. - Owner budget entry for metered routes: replace the
configured_budget_requiredrefusal with the owner-entered finite budget path (amount/currency/period) that becomes part of the exact proposal hash. - UI (Claude Opus 5.5, effort high): the F1 rules/budget step and the rules page show the default proposal rows, expiry, held classes and "no personal GitHub exception"; one-click install with the existing exact-hash confirmation; renewal before expiry; th and en keys.
- Docs: update the standing-policy contract/ADR and docs/runbooks/s15-install.md owner steps.
Acceptance criteria
- A fresh install (installer-generated config) shows an installable default proposal after the owner signs in and the Codex route is available; installing it enables the first ordinary tool-backed conversation without any config edit.
- The proposal never includes a personal GitHub exception, budget amount, new recipient or resource the installation does not actually have.
- A subscription-only proposal installs with no budget; adding a metered route requires a finite owner budget.
- Expiry is finite, visible and renewable; an expired policy blocks new work honestly.
- UI authored by Claude Opus 5.5 at effort high; th and en keys.
Tests and evidence
- Composition with the installer config (
s15InstallerConfig) → default proposal rows/resources/recipients exactly as composed; install → a scripted conversation runs a VM tool call. - Subscription-only → installable without budget; metered route → refused until a finite budget is entered.
- Proposal hash binds every row; a changed catalog/resource set yields a new proposal.
- Expiry and renewal; expired → new work blocked with the policy code.
- Web rendering tests (th/en).
Requirements
FR-14/18/23/35/37/38; NFR-06/07/12/14. Acceptance: S15-AC01, S15-AC08, S15-AC16.
Blocked by
None for implementation; bundle with GIT15-04 in one PR after PRs #382 and #383 merge (shared composition files).
Do not
Do not install anything without the owner's explicit click; do not invent a budget amount; do not add personal GitHub exceptions; do not widen recipients beyond the composed provider(s); do not run Jit's full suite locally (CI runs it); do not add AI attribution; do not merge the PR yourself.
Definition of done
Locally: typecheck, git diff --check, focused policy/web/composition/runtime/installer tests. CI runs the full suite. PR body includes Closes #384.
Activity