feat(governance): require approved plans for Builder - #205
Merged
Conversation
Persist the prepared workspace base and published delivery base in run records, deliveries, receipts, and the public API. Refs #147
alvaroloes
marked this pull request as ready for review
August 26, 2026 18:09
Member
Author
|
Ready for maintainer review. The branch incorporates the unique base-SHA provenance commit from #166 as |
Member
Author
|
@adrian-lorenzo, the Gate 1 foundation is ready for maintainer review. Exact head |
adrian-lorenzo
approved these changes
Aug 27, 2026
Bobbyap72
added a commit
to Bobbyap72/facility
that referenced
this pull request
Aug 28, 2026
Adds a client-side filter box on the Stories page that narrows visible stories by title match, and lets a bare story number jump straight to that story. Ambiguity is now handled explicitly, both locally and via the API: - Locally: if two repos on the board share the same number, that's reported as ambiguous rather than silently opening the first match. - Off-board: the story-detail endpoint's 409 response now returns the candidate repos (repoId/repoOwner/repoName/storyType), so the UI can render a real picker instead of a dead-end message. API failures (5xx, network errors) are now distinguished from a genuine 404 — the UI never claims a story doesn't exist when the truth is "couldn't check right now." Tests: apps/web/test/story-jump.test.ts covers both local and API ambiguity, not-found, and error paths via the extracted pure resolveLocalJump/interpretJumpResponse functions. Verified: pnpm --filter @facility/web typecheck / test, and pnpm --filter @facility/api typecheck (43 pre-existing errors on main, unrelated to this change, traced to theam#205 — confirmed by running the same typecheck against a clean upstream/main checkout).
This was referenced Aug 28, 2026
Bobbyap72
added a commit
to Bobbyap72/facility
that referenced
this pull request
Aug 28, 2026
Adds a client-side filter box on the Stories page that narrows visible stories by title match, and lets a bare story number jump straight to that story. Ambiguity is handled explicitly, both locally and via the API: - Locally: if two repos on the board share the same number, that's reported as ambiguous rather than silently opening the first match. - Off-board: the story-detail endpoint's 409 response now returns the candidate repos (repoId/repoOwner/repoName/storyType), so the UI renders a real Link-based picker instead of a dead-end message. A request-generation counter (jumpSeq) guards against out-of-order async responses: submitting a new number invalidates any in-flight lookup, so a stale response can never navigate the user to the wrong story or overwrite newer state. Covered by a component-level regression test (stories-board.test.tsx) that deliberately resolves an older request after a newer one and asserts only the newer one navigates. The async jump status (checking/not-found/error/ambiguous) is announced through an aria-live region. API failures (5xx, network errors) are distinguished from a genuine 404 — the UI never claims a story doesn't exist when the truth is "couldn't check right now." Tests: - apps/web/test/story-jump.test.ts: pure local/API ambiguity, not-found, and error resolution logic. - apps/web/test/stories-board.test.tsx: component-level regression for out-of-order async responses. - services/api/test/github-platform-lane.test.ts: extended to assert the 409 response's error.details.matches carries the correct candidate repos. Verified: pnpm --filter @facility/web typecheck / test, targeted services/api test run for the modified test (both pass). The full services/api suite currently has pre-existing failures on main unrelated to this change, traced to theam#205 (builderPlanPolicy / workspaceBaseSha schema drift) — confirmed by running the same typecheck against a clean upstream/main checkout before any of this branch's changes were applied.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
Adds an opt-in
builderPlanPolicyproject control withoptionalandrequiredmodes.When
requiredis enabled, Builder accepts only one exact, unexpired Architect plan that:The issue digest covers title, body, state, author, URL, normalized labels and material comments. Facility progress/publication comments and the exact
/builderapproval command are excluded because they are consequences of the plan; substantive text accompanying/builderremains material.Freshness is checked against GitHub when the human approval is executed, again when the worker receives the queued run, and once more after the worker atomically claims it. The runner checkout is pinned to the approved base SHA, so a later branch-head change aborts before the model runs. A stale or unverifiable plan fails closed before credentials or sandbox creation and records the expected and observed hashes in the audit trail.
This revision composes the base-SHA provenance work from #166. Its original commit author is preserved in
8d6e40f.It also makes Architect plan publication a durable, recoverable control-plane lane:
plan_acceptanceproposal/open event commit atomically;404cases are handled without recreating a stale Gate;Why
This is the fail-closed Human Gate 1 for #204. It prevents Builder from using a merely similar, machine-approved or outdated plan while keeping the approval, plan, repository revision, issue revision and final worker decision attributable.
No legacy proposal is promoted or backfilled. After this control plane is merged and deployed, a project enabling
requiredmust run Architect again and approve the newly generated proposal.Verification
Exact governance implementation head
fe208e235faa4d96ac0d70d591f5c291ae356257:pnpm test:critical— DB 18/18, CLI 98/98, API 543/543, gateway 57/57pnpm typecheck— 16/16 tasks; API typecheck repeated after the final deltapnpm lint— 416 files passedpnpm migrations:check— two compatible migrations checked (0042,0043)git diff --check— passedCurrent PR head
2e121bff320d8cf4e2aa2dfe7ab68f69649904ecadds only the final operational UI/documentation wording correction; Biome andgit diff --checkpass locally. Hosted run32997376591passedverifyin 5m46s,self-host-buildin 8m44s andsandbox-e2ein 11m42s. Conventional commit-subject and PR-title checks also passed.The full local
pnpm verifywrapper is not claimed because its external dependency-audit phase was not run locally. The hosted workflow owns that final check.Activation boundary
optionaluntil this PR is reviewed, merged and confirmed live on the internal Facility instance.builder_plan_freshness_unavailable.GitHub cannot atomically lock an issue while Facility launches a sandbox. Facility therefore revalidates immediately after worker claim, executes only the immutable approved plan, and pins the repository checkout; a subsequent issue edit requires a new Architect run for any later approval.
Remote GitHub comment creation also remains technically at-least-once after an ambiguous response because the API provides no idempotency key. The stable marker, delayed backoff and reconciler bound and repair that residual window.
Refs #204
Incorporates #166