FE-1159: Alpha release readiness: packaging, model allowlist, auth onboarding#299
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
build:pi-assets no longer rm -rf's dist/agents/{prompts,subagents,references}
(which deleted compiled registry.js outputs, stickily under incremental tsc);
it now removes only the copied markdown payloads. drizzle-orm and
drizzle-typebox move to dependencies — they are runtime imports of dist/db.
Cards 1-2 of memory/cards/alpha-release-readiness--packaging-fixes.md.
Co-authored-by: Cursor <cursoragent@cursor.com>
Admits the alpha-release-readiness frontier (SPEC D113-L/D114-L/D115-L,
req 29, A38-L, I59-L) and builds its model-policy tracer: a code-owned
ordered fall-through allowlist of {provider, model, thinking} entries
(claude-sonnet-4-6 direct, then via OpenRouter, thinking: low), enforced
by a registry wrapper so /model and Ctrl+P cycling stay within the
allowlist and boot applies the pinned thinking level. No-auth boot stays
healthy; models.json is deliberately not a product surface (D39-L seal).
Co-authored-by: Cursor <cursoragent@cursor.com>
npm run check:release-pack packs the tarball, asserts the compiled registry.js and all 8 live SKILL.md files ship, installs into an isolated prefix, and boots brunch --mode print from a foreign cwd — so the asset-clobber and runtime-dependency classes of release defect cannot silently return. Release/CI step, deliberately outside npm run verify. Closes the packaging-fixes scope file (card 3 of 3; file consumed). Co-authored-by: Cursor <cursoragent@cursor.com>
`brunch login` configures provider auth without a Pi binary or session: an allowlist-ordered provider picker, OAuth via Pi's public AuthStorage callback contract (auth-URL, device-code, prompt, manual-code, select) or API-key paste (canonical type: 'api_key'), writing Pi's global auth.json (PI_CODING_AGENT_DIR-relocatable, D114-L). The exit report re-runs Brunch model-policy resolution on an inMemory registry so it matches session boot exactly (D39-L seal). Consumed scope card deleted; the active no-auth-gate card is committed for safekeeping. Co-authored-by: Cursor <cursoragent@cursor.com>
…esolves No-auth is now a visible product state (D115-L, I59-L covered): the workspace entry dialog shows a non-blocking login warning, UI-capable orientation junctures J1-J6 read model availability live at fire time and suppress dialog + kick while auth is absent (J1 shows an in-chrome notice instead), and /login mid-session restores junctures without restart. Warning copy is single-sourced beside the allowlist in model-policy.ts; origination's no_model_available skip stays the no-UI backstop. Consumed scope card deleted. Co-authored-by: Cursor <cursoragent@cursor.com>
…pic-family turn Found by the FE-1159 outer walkthrough: Anthropic-family backends reject tool input schemas with a top-level oneOf/anyOf/allOf, so every provider turn failed with a 400 that the faux-provider tests could never surface. Mode companions remain enforced by the executor's structural_illegal diagnostics; a Tier-2 regression oracle now asserts no provider-facing tool schema carries a top-level union. Co-authored-by: Cursor <cursoragent@cursor.com>
…l-schema sweep Walkthrough evidence + A38-L observations land in the FE-1159 frontier entry (stale publish-sequencing note fixed); the walkthrough-found schema-legality class is admitted as coverage frontier tool-schema-convergence (FE-1163) with its row ledger. HANDOFF.md updated to match. Co-authored-by: Cursor <cursoragent@cursor.com>
PR SummaryMedium Risk Overview Packaging & dependencies: Model policy (D113-L): Brunch-owned Auth onboarding (D114-L): New No-auth product state (D115-L, I59-L): Workspace dialog shows a non-blocking warning when no allowlisted model resolves; UI orientation junctures and kick are suppressed (J1 shows notice); no-UI paths keep Release verification: Walkthrough-driven fix: Also in diff: Elicitor/executor prompts gain a shared static reference manifest; executor-surface reconciliation card marked done; minor CLI help/arg validation. Reviewed by Cursor Bugbot for commit a7ba91e. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 03a993c. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR makes the @hashintel/brunch@1.0.0-alpha.x line publishable/onboardable by hardening the packaged artifact shape, pinning a code-owned model allowlist (with a Brunch-contained ModelRegistry wrapper), adding a standalone brunch login onboarding flow that writes Pi’s auth.json, and introducing a no-auth UX + upstream gate that suppresses UI-capable junctures/kicks when no allowlisted model is available. It also adds a release-pack smoke script and closes a provider-legality regression where read_graph’s top-level union schema could 400 Anthropic-family backends.
Changes:
- Add pinned model policy + allowlisted registry wrapper, plus no-auth guidance copy surfaced in TUI/orientation flows.
- Add
brunch loginCLI subcommand (OAuth + API key) and thread login guidance through workspace preflight + session orientation gating. - Add release-pack verification (
check:release-pack) and provider-legality regression coverage (tool-schema top-level union assertion;read_graphschema change).
Reviewed changes
Copilot reviewed 42 out of 43 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/treedocs.yaml | Updates tree docs to reflect executor surface and retire orchestrator stub listing. |
| src/dev/tests/tier-2-harness.test.ts | Adds Tier-2 regression assertion for provider-legal tool schemas. |
| src/dev/tests/support/tier-2-test-support.ts | Introduces expectProviderLegalToolSchemas helper (top-level union guard). |
| src/dev/tests/faux-harness.test.ts | Updates expected system prompt copy to include shared references. |
| src/app/TOPOLOGY.md | Documents new model-policy/login/no-auth surfaces and updated boot semantics. |
| src/app/pi-session-options.ts | Adds scopedModels to Pi session option projection. |
| src/app/model-policy.ts | New: pinned allowlist, Brunch-contained registry wrapper, scoped models, no-auth copy, and resolution logic. |
| src/app/model-policy.test.ts | New: unit/integration tests for allowlist policy, scoped cycling, and no-auth behavior. |
| src/app/brunch.ts | Adds login subcommand routing and positional parsing; introduces --help handling for login. |
| src/app/brunch-tui.ts | Threads boot-time model availability + no-auth guidance into workspace preflight; wires model-policy into session boot. |
| src/app/brunch-login.ts | New: interactive login flow (OAuth/API key) that writes Pi auth.json and reports resolved allowlist policy. |
| src/app/tests/brunch-tui.test.ts | Adds test ensuring preflight receives model-availability and no-auth guidance copy. |
| src/app/tests/brunch-login.test.ts | New: tests for API-key persistence, OAuth callback flow, CLI subcommand routing, and help output. |
| src/agents/runtime/executor/compose-prompt.ts | Adds shared reference manifest to executor prompt. |
| src/agents/runtime/executor/tests/compose-prompt.test.ts | Asserts executor prompt shares elicitor reference-resource manifest surface. |
| src/agents/runtime/elicitor/compose-live-prompt.ts | Adds shared reference manifest to elicitor prompt. |
| src/agents/runtime/elicitor/snapshots/live-elicitor-prompt.md | Snapshot update to include shared references section and updated prompt-resources line. |
| src/agents/references/TOPOLOGY.md | Documents shared reference manifest ownership via registry.ts. |
| src/agents/references/registry.ts | New: shared static reference manifest registry + XML-safe renderer. |
| src/agents/prompts/tests/registry.test.ts | Adds alignment test between references topology inventory and manifest registry. |
| src/.pi/extensions/TOPOLOGY.md | Documents no-auth upstream gate behavior for session-orientation junctures. |
| src/.pi/extensions/session-orientation/registrar.ts | Adds no-auth gate to suppress junctures and optionally notify with no-auth notice on boot entry. |
| src/.pi/extensions/session-orientation/juncture.ts | Adds no-auth short-circuit for UI-capable contexts; plumbs model availability into kick deps. |
| src/.pi/extensions/session-orientation/tests/registrar.test.ts | Adds tests for no-auth suppression, notice behavior, and live re-enable after auth appears. |
| src/.pi/extensions/session-orientation/tests/juncture.test.ts | Adds test ensuring dialog/kick are suppressed when no allowlisted model is available. |
| src/.pi/extensions/brunch-data/graph/tool-schemas.ts | Removes top-level union from read_graph schema to satisfy Anthropic-family tool-schema legality. |
| src/.pi/extensions/tests/registry.test.ts | Minor update to expected runtime registry shape. |
| src/.pi/extensions/tests/brunch-data-graph.test.ts | Updates schema tests to assert provider legality and rely on adapter diagnostics for companions. |
| src/.pi/extensions/tests/agent-runtime-system-prompts.test.ts | Adds assertion that executor system prompt includes shared references section. |
| src/.pi/components/workspace-dialog/preflight.ts | Exports preflight options and threads model availability + guidance copy into component creation. |
| src/.pi/components/workspace-dialog/index.ts | Re-exports WorkspaceDialogPreflightOptions and WorkspaceDialogNoAuthGuidance types. |
| src/.pi/components/workspace-dialog/component.ts | Adds render-only no-auth guidance banner to workspace dialog component. |
| src/.pi/components/workspace-dialog/component.test.ts | New: tests for guidance banner presence/absence based on model availability. |
| src/.pi/components/workspace-dialog.ts | Re-exports new preflight option type from the stable public entry. |
| src/.pi/components/TOPOLOGY.md | Updates component topology to describe render-only no-auth warning banner boundary. |
| scripts/check-release-pack.mjs | New: packs, asserts tarball contents, installs into isolated prefix, and boots from foreign cwd. |
| package.json | Fixes build:pi-assets to avoid clobbering compiled output; adds check:release-pack; moves drizzle deps to runtime. |
| package-lock.json | Reflects dependency moves and lockfile changes for drizzle runtime deps. |
| memory/SPEC.md | Adds req 29 and decisions D113–D115 plus invariant I59 and future-direction notes. |
| memory/PLAN.md | Adds/updates alpha-release-readiness frontier and admits tool-schema-convergence sweep frontier. |
| memory/cards/tool-schema-convergence--ledger.md | New: sweep ledger describing tool-schema convergence plan and oracles. |
| memory/cards/orchestrator-tool-port--executor-surface-reconciliation.md | New: reconciliation card capturing executor surface cleanup outcomes (incl. reference-resource parity). |
| HANDOFF.md | New: session handoff capturing FE-1159 status, remaining work, and flake notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…oke leg, allowScripts refresh Publishing is manual-local release-it from a next checkout (matching main's 0.x precedent): .release-it.json enforces requireBranch next, bare-version tags, and check:release-pack as the pre-publish hook. The smoke gains an rpc-mode workspace.activate leg so the installed better-sqlite3 native binding is actually exercised (closes the acceptance-review ceiling). better-sqlite3 pinned exact so the repo allowScripts entry stays verifiable; stale pins refreshed. First publish: npm run release -- --no-increment. Co-authored-by: Cursor <cursoragent@cursor.com>
…elease smoke in SPEC HANDOFF.md's retirement rule fired (walkthrough evidence in PLAN, PR #299 submitted); its last volatile fact (roving full-suite flake) moves to a PLAN Horizon entry. A38-L advances to partially validated with the walkthrough latency evidence. SPEC verification commands gain the release-pack smoke + release-it hook note. Extensions TOPOLOGY carries the FE-1163 adapter-collapse migration note. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 42 out of 43 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/app/brunch.ts:154
parseCliArgsenablesallowPositionals: truebut does not validate the positional list. Extra positionals (e.g.brunch login extra) will be silently ignored, which can mask user mistakes and makes the CLI harder to reason about.
Consider rejecting any additional positionals beyond the single optional subcommand.
…RL opener Review induction (ln-induct) on the bot comments surfaced two fault types and their unsampled siblings: (1) accepted-but-unhonored CLI inputs — root --help/-h silently launched the TUI (regression vs the prior unknown-flag error) and --open-web/--dev-tools were silently ignored outside tui mode; the root path now prints usage and non-tui modes warn on stderr. (2) fire-and- forget spawns without error handling — a missing xdg-open crashed brunch login mid-OAuth, and the TUI's duplicate openBrowser shared the fault plus lacked the win32 branch entirely; both now ride one openUrlBestEffort with the error event swallowed per best-effort contract (URL is always printed first). Co-authored-by: Cursor <cursoragent@cursor.com>
…ntact PR-299 review: unquoted `cmd /c start <url>` splits at the first `&` (and is an injection seam for hostile URLs). rundll32 FileProtocolHandler receives the URL as plain argv with no shell parsing. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
I found two things worth tightening before this lands:
-
scripts/check-release-pack.mjs:89assumes the installed Windows shim lives under<prefix>/bin/brunch.cmd. For npm global installs with--prefixon Windows, the shim is created at<prefix>/brunch.cmd, so this smoke will false-fail on Windows. The path should branch as<prefix>/brunch.cmdon win32 and<prefix>/bin/brunchelsewhere. -
scripts/check-release-pack.mjs:82-86checks the prompt registry JS and skill markdown, but not the runtime markdown assets thatbuild:pi-assetsis specifically meant to protect:dist/agents/prompts/*.md,dist/agents/subagents/*.md, anddist/agents/references/*.md. A future asset-copy regression could still pass this release smoke while publishing a broken package. I would add explicit tarball assertions for those files.
Verified locally in a throwaway worktree: focused login/model/open-url tests pass, npm run check:release-pack passes on macOS, and git diff --check is clean.
| return 0; | ||
| } catch (error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| writeLine(options.stderr ?? options.stdout, message); |


Summary
Makes the
@hashintel/brunch@1.0.0-alpha.xline publishable and onboardable. Five built threads plus two walkthrough-driven follow-ups:build:pi-assetsno longer clobbers compiled output when copying prompt/subagent/reference markdown;drizzle-orm/drizzle-typeboxbecome runtime dependencies (both were release-blocking, spike-witnessed).anthropic/claude-sonnet-4-6, thenopenrouter/anthropic/claude-sonnet-4.6, boththinking: low) enforced by a Brunch-ownedModelRegistrywrapper;/modelcycling scoped to the allowlist.brunch login(D114-L) — standalone auth onboarding over Pi's publicAuthStorage(OAuth + API key), writing Pi'sauth.json; exit report resolves exactly like session boot.no_model_availablebackstop.npm run check:release-packpacks, asserts release-critical assets in the tarball, installs into an isolated prefix, boots from a foreign cwd, and (added at tie-off) drives an rpc-modeworkspace.activatethat creates.brunch/data.db, so the installed better-sqlite3 native binding is actually exercised.read_graphschema legality fix — the outer walkthrough found the tool's top-leveloneOf400ed every real Anthropic-family provider turn (invisible to faux-provider tests). Union removed (executor diagnostics already enforce mode companions); Tier-2 regression oracle added. Follow-on sweep admitted as FE-1163.nextcheckout (no publish CI; the old product holdslatest: 0.8.0, the alpha rides dist-tagalpha)..release-it.jsonenforcesrequireBranch: next, bare-version tags, and the release-pack smoke as pre-publish hook. First publish:npm run release -- --no-increment.better-sqlite3pinned exact; staleallowScriptspins refreshed.Outer walkthrough evidence (no-auth boot → login → live elicitation on both allowlist entries, A38-L latency/conduct) is recorded in
memory/PLAN.md§alpha-release-readiness.The four commits below the FE-1159 set are pre-rename FE-1107 executor-reconciliation work carried from this branch's prior life.
Test plan
npm run verifygreen (1501 tests)npm run check:release-packgreen, including the new SQLite-touching legPI_CODING_AGENT_DIR, no-auth boot,brunch login(OpenRouter + Anthropic), fresh boots resolve allowlisted models, junctures fire, live graph writes landrelease-itdry run parses config and stops at the expected gates (npm auth, branch guard)Post-merge
From a
nextcheckout:npm login(needs@hashintelpublish rights) →npm run release -- --no-increment.