Verdict: APPROVE (source and preview scope only). Reviewer model ID: claude-fable-5-1. Read-only; no commands, writes or deploys were made.
What the delta does. The compiled registry gains five entries with provisionable false and no foreign origin. The Docs chooser type is parameterised by slug and display name, mounted once per integrated app inside the existing host, duplicate-cookie, session and CSRF middleware. Templates take the app name and form action from the compiled registry, never from request input.
Checks passed against the frozen source:
- Authority and scoping. Choices are filtered by the session person_ref and by the chooser's own app slug. The route validator binds app slug to origin with exact string equality, so a sheets row pointing at a docs or mail host refuses the whole result with 503. Test covers this per app.
- Stale membership. Selection re-queries membership after CSRF and session checks. Removed membership returns 404 per app.
- Duplicate cookies, host, CSRF. The path guard now covers all twelve routes before session middleware. Foreign Origin returns 403. Host refusal is middleware-wide and unchanged.
- Scriptless continuation. The continuation template is unchanged: meta refresh plus a plain no-referrer link, no script. The title string comes from the registry.
- Preview launcher. The operator preview map still wins over the chooser link. Catalog tests updated to six anchors and no invented destinations.
- Provisioning not weakened. No Go code reads the provisionable flag. The operator provisioning constructor is wired only in tests in this binary. The wider app set does let the roster source serve sheets, slides, calendar, meet and memoria rows, but only the operator transaction can create those rows.
- Integration claim is supportable. Sheets, slides, calendar and meet pin the handoff module; the memoria journey log exercises Home identity tests. Docs was already reviewed.
- Gate. The log at home-team-entry-gate.log shows vet, build, test and race steps all ok with no FAIL lines, ending at the connect race step.
Test naming. The added tests are TestNativeAppChoicesKeepTeamAndAppBoundaries and TestProviderAndUnknownAppsDoNotBecomeTeamConsumers, not a TestNativeAppChoosers function.
Spec updates required before merge to main (project convention puts these in the implementation commit):
implementation/directory-runtime.mdstill says the registry has one supported entry and that other apps are not declared ready. Record six integrated entries, all provisionable false, and cite the consumer evidence per app.implementation/docs-team-chooser.mddescribes a Docs-only chooser and templates. Note the shared parameterised chooser and that the catalog Meet status changed from Coming soon.implementation/team-entry.md"Directory and Docs stages" should state that the same chooser now serves the five other native apps with no provisioning change.- Home spec §11 should record that six integrated entries exist and that the New button and grid remain unimplemented.
Minor, non-blocking: the constructor error string still says "Docs"; the docs field on the features struct duplicates the first chooser; the registry slice is allocated on every request in the path guard.
Rollout preconditions unchanged by this delta. Public app domains remain existing instances. The change adds no bare-host gateway and does not touch old content, deep links or private credentials. An operator deployment path and a restored-backup drill are still needed before any public Home cutover.