Fork Horse repository, listed by its owner. Publisher snapshot.

packages/forkhorse-gatekeeper/HANDOFF.md

Snapshot at 34e3175

Containing directory

9,704 bytes · textView raw
1# FH-008 final review handback
2
3Status: **ready for independent review with the limitations below; not accepted,
4merged or deployed**. Local S7/S9 are verified. The
5private enrolled-agent vendor replaces the starter sample. Full popup UX remains a
6manual check; native negative-RPC diagnostics remain disclosed below.
7
8No further in-scope offline implementation work is identified. This final handback
9supersedes the WIP designation on the earlier checkpoints. The final publication
10changes this handback only; the implementation and verified test inputs remain at
11`fa2693c4397a547992ba2f5a4b274a1d7ba98d28`. Already-passing checks were not rerun for
12this documentation-only status correction. Acceptance remains the reviewer's decision.
13
14## Provenance and scope
15
16- Branch: `fh/FH-008-gatekeeper`.
17- Published checkpoints `4ed940969e1e3a6f48cbc6a1c35326f7665b443e`,
18  `53bf918b14cb9dc7d95e9483efb28d2b40da7c1f` and
19  `2a355a8e61bfb5aef4fe5d17683d57593f2c2e23` are preserved.
20- Accepted FH-013 was integrated by normal merge `e99c96d`. Accepted main
21  `ba05c76d7743278ede25880c197933a059279474`, including FH-016, was integrated by
22  normal merge `7325fd3`. The two owned script edits were stashed before this merge
23  and restored afterward; the one merge conflict combined the deployment-order
24  helper with this vendor before implementing the sample replacement.
25- Upstream remains pinned and unmodified at
26  `8cbfb2b67e3da6222e4d7faeade0ff88eb4253bf`. All 1,676 tracked files in the
27  disposable full-OS archive were hash-compared to that pin: zero differences.
28- Owned changes are confined to this package, its lockfile importer, deployment
29  scripts and the template. Other changes arrive only through accepted main.
30- Against accepted base `ba05c76d7743278ede25880c197933a059279474`, the allowed
31  changed paths are `packages/forkhorse-gatekeeper/**`, this package's importer in
32  `pnpm-lock.yaml`, `deployment.jsonc`, `scripts/deploy.ts`,
33  `scripts/deploy.test.ts`, `scripts/deployment-config.ts`,
34  `scripts/gatekeeper-deployment.ts`, `scripts/gatekeeper-deployment.test.ts` and
35  `scripts/core-deployment.ts`. The last file only excludes the retired sample from
36  Worker-name collision checks. The exact file inventory is available with
37  `git diff --name-only ba05c76d7743278ede25880c197933a059279474...HEAD`.
38- No owner config, real credentials, external inference, Cloudflare operations,
39  board edits, deployment or canonical Git writes were performed.
40
41## Implementation and deployment
42
43`UserAccount` stores an enrolled agent credential behind native capabilities.
44Connection uses authenticated `/me`, a single-use nonce and the pinned kit handoff.
45Reconnect is staged and retains the same origin/project/agent; revocation clears
46local credentials and stops sidebar disclosure. Ownership is rechecked before
47Git tokens are minted. The picker exposes only owned forks.
48
49`getHead()` records an observation and advertises the exact commit. Pushes require
50manual OS approval, a full SHA and a fast-forward on the fork's default branch.
51Applying the action builds its scoped pack and sends a real old-SHA CAS through
52kit transport with a git User-Agent. Tokens last 60 seconds and never reach the
53agent or iframe. There is no force push, canonical write or rewriting revert.
54
55An interrupted approval submission retains its intent and can retry with the same
56gatekeeper action ID. If the OS queued it but lost its reply, that action remains
57approvable/rejectable. Retries can produce duplicate OS rows; applying the same ID
58is serialized and idempotent, so only one Git write occurs. If one duplicate is
59rejected, remaining duplicates fail closed and can be rejected in the OS. Tests
60cover both lost replies and duplicate application. Process-kill fault injection at
61every individual instruction is not claimed.
62
63The sidebar reuses the accepted dashboard's projection, mount function and CSS.
64It exposes only read-only snapshot/subscription/poll methods, reauthorizes reads,
65coalesces updates and stops on disposal. Capture interception plus transport
66rejection disable owner actions. Its srcdoc section links scroll locally; Ask an
67agent uses the actual OS `host.openPrompt` without submitting the prompt.
68
69Deployment now omits the starter sample from generated configs, build/deploy order
70and both consumers' bindings. The sample package remains as reference code. The
71template enables the replacement vendor wiring; disabling it omits the vendor
72entirely, without a sample fallback. Legacy sample settings/placeholders are
73ignored. The new Worker gets its private BASE_URL and DO migrations and deploys
74before Workshop/router. Router HTTP and Workshop vendor RPC use distinct bindings.
75MCP remains installed as accepted in FH-016. Generated-config tests show exactly
76one `GATEKEEPER_FORKHORSE` and no `GATEKEEPER_CUSTOM`; this is local wiring evidence,
77not a claim about an installed owner's admin page.
78
79## Local acceptance evidence
80
81### S7: full OS server and real Git
82
83The unchanged pinned OS ran in a disposable archive, with its own empty HOME and
84synthetic user. A deterministic local Anthropic-protocol fixture supplied the tool
85sequence; no model inference or provider was involved. The real OS executed:
86
871. Native account connection and handoff redemption.
882. Owned-fork resource selection, observed `getHead` and commit advertisement.
893. Its actual agent `createWorktree` tool, Git pull, read/write and commit.
904. Native pending approval with the remote unchanged and zero Git writes.
915. `approveAction`, action-scoped pack construction and successful Git CAS push.
92
93Final receipt: old SHA `5713416f094424cc79f1f7cb8aa03ad6218437da`, new SHA
94`0300b810687c0753b9cb715bc699fc5b842832c1`, one pull and one write. The actual bare
95repository contained `After full run-local approval` in `README.md`. The browser
96showed the same approved action, before/after SHAs, worktree head and file diff.
97
98The separate native kernel test also passed a real receive-pack race: another
99commit moved the branch after the gatekeeper read, Git rejected the old-SHA CAS,
100the losing commit was absent and the OS action remained pending. This case uses
101the native workerd kernel harness, distinct from the full-server positive flow.
102
103### S9: full OS browser and default limiter
104
105The final rebuilt sidebar advanced 347 labeled synthetic quarter-second batches
106in 86.8 seconds through the actual native account and pinned OS host. Section
107navigation preserved the iframe. Ask an agent navigated to Home with the expected
108project prompt. That prompt was not sent. Earlier full-OS picker checks listed
109only the connected fork, enabled Add connection after selection and added it to
110the composer. The retained component harness also observed 598 batches in 150
111seconds with one snapshot, one subscription and zero polls under the pinned
1128-concurrent/600-per-minute/128-pending limiter.
113
114On reopening the browser with an older synthetic account whose fixture identity
115had changed, the sidebar correctly denied it. Signing into the fresh fixture
116account succeeded. The stale-account denial is not suppressed or described as a
117successful session. No subsequent error appeared during the final S7/S9 browser
118interaction.
119
120## Checks and reproduction
121
122| Command | Result |
123| --- | --- |
124| `pnpm install --frozen-lockfile` | Exit 0 on accepted merged workspace. |
125| `pnpm --filter forkhorse-gatekeeper build` | Exit 0; browser/Worker types and all production bundle checks. |
126| `pnpm --filter forkhorse-gatekeeper test` | Exit 0; 10 Node tests and 21 workerd tests. |
127| `pnpm --filter forkhorse-gatekeeper test:local` | Exit 0; native kernel and real Git CAS race. |
128| Full local OS API driver | Exit 0; receipt above, verified in the actual browser. |
129| `pnpm test` | Exit 0; all repository suites, including package Node/workerd tests. |
130| `pnpm lint` | Exit 0; lint, script types and workspace builds. |
131| Pinned Wrangler dry-run with synthetic config | Exit 0; Worker bundling only, no owner config, networking or deployment. |
132| Full-OS preparation helper | Exit 0; disposable exact-pin archive and separate fixture extension created. |
133| `git diff --check` | Exit 0. |
134
135See [the local harness guide](test/local/README.md) for reproducible preparation and
136commands. Only this package's lockfile importer differs from accepted main. Full OS
137bootstrap fetched registry dependencies; it was not a network-free installation.
138Production `dist/worker.js` excludes the test-only Worker, synthetic credential and
139model fixture. Deployment consumes only that production artifact.
140
141## Explicit remaining boundaries
142
143- The automated browser could not adopt the OS-created disowned popup. Browser
144  form submission and the real OS API handoff were verified separately. The entire
145  popup UX remains a manual acceptance item; no provider/install acceptance is claimed.
146- Negative native RPC tests still emit expected exceptions and, in the Vitest worker
147  pool, a hung-request diagnostic. A plain returned RpcTarget reproduces it while
148  rejecting correctly, responding to a later ping and disposing. A standalone
149  Miniflare control passes without the warning. The positive full-server flow and
150  native kernel flow complete. The underlying pool/runtime cause remains unproven;
151  logs are not filtered or suppressed.
152- Pinned OS app discovery needed a reload after API-only account connection and
153  selects the first management-UI account per vendor. This package does not change
154  those upstream behaviors. Dashboard selector coupling remains guarded by tests.
155- Live Core/Artifacts, owner installation, deployment, popup UX and production
156  acceptance remain separate. No acceptance/merge authority is inferred from checks.
157