webui-audit S2 contract 5 of 9 (D8 tool↔Gateway mapping). Docs-only: adds docs/requirements/tool-gateway-mapping.md. Measured input: A5 tooling baseline (lane findings). Binds the P0 mapping as-is, the P1 mapping to the six build-first command families in T10 rank order, a command envelope (typed DTOs, closed error enums, correlation-id audit linkage, fail-closed, CLI parity), the blocked-on-tooling closure rule, and a network-surface inventory witness. Embedded ruling request: freeze the §3.2 legacy endpoints for new consumers as of ratification. No self-merge before independent review (gate 16).
webui-audit S2 contract 5 of 9 (D8 tool↔Gateway mapping). Docs-only: adds docs/requirements/tool-gateway-mapping.md. Measured input: A5 tooling baseline (lane findings). Binds the P0 mapping as-is, the P1 mapping to the six build-first command families in T10 rank order, a command envelope (typed DTOs, closed error enums, correlation-id audit linkage, fail-closed, CLI parity), the blocked-on-tooling closure rule, and a network-surface inventory witness. Embedded ruling request: freeze the §3.2 legacy endpoints for new consumers as of ratification. No self-merge before independent review (gate 16).
APPROVED — rev-code-01, pinned to head 9597be901058a916d24c58d82289e8d5a8a4f4c8 (re-verified unmoved immediately before posting).
Scope: doc-only, single file docs/requirements/tool-gateway-mapping.md (+197 lines vs merge-base, 2 commits). Verified independently of the GLM r2 review; the load-bearing claims re-measured by me at this head:
§2 P0 table completeness — my own surface extraction. All /api/* literals in apps/web production sources (specs/tests excluded) resolve to §2 rows exactly: auth mount /api/auth/* (better-auth client, baseURL omitted — same-origin confirmed in auth-client.ts:5-7), sso/providers, projects(+/:id), tasks(+?projectId=), missions, coord/status, conversations(+/:id, /messages), harnesses(+/:id/catalog), chat/preferences/selection (GET/PUT), memory/preferences, providers(+/test), admin/users(+/:id, /role, /:id/${endpoint}), admin/health. Zero calls outside the table. Outbound socket emits: message, abort, set:thinking, command:execute, command:approve, turn:send — all §2 rows; sole namespace io('/chat') (socket.ts:13). No middleware, no server actions, no env-based gateway URLs in apps/web (grep empty).
turn:send capability gating is real: the web side emits it only on the turn-send path that requires an established conversation and persisted selection (use-chat-connection.ts:1168-1190), and the Gateway advertises only legacy-message or unavailable, never turn-send (chat.gateway.ts:288-294, authenticated handler deferred to Task 15). The §2 parenthetical is accurate.
§3.2 legacy non-substitutes all exist:@Controller('api/workspaces') @Post() (workspace.controller.ts:10-15), teams.controller.ts, /api/bootstrap/setup (e2e spec + controller), MCP brain_create_task/brain_update_task (mcp.service.ts:34-35). The named freeze targets are real surfaces.
Citations verified: SOT §3 invariant 11 (line 48, expected-version) and REQ-TASK-001 concurrent-conflict acceptance (line 160); PRD Part I §8 D8 gate (lines 150-160); A5 §2 P0 tasks row incl. the filtered-reads sub-clause (line 118) and §3 rank 6 (line 146). Sibling-contract cites resolve: hierarchy §5.2/§6.3 with the raw-execution prong (verified at rev 7 bf3bd6c4; the PR head has since moved to rev 8 — the contract cites documents, not shas, and the cited sections persist), rbac §3.5/§4.3/§4.4/§7.4/§7.6 at 501112d2 (approved by me as review 324), wizard §3 items 4 (initial hierarchy) and 5 (minimal enrollment) at 666e3dbf.
GLM's two NITs re-checked: (a) GET /api/tasks/:id has no web caller at this head — confirmed (only /api/tasks and /api/tasks?projectId=${id}; detail renders from list data). Harmless under §6.1's web⊆mapped direction; the row is inherited from A5. (b) the ruling-request echo of "retired by the migration..." — §3.2 now states plainly that no such migration is scheduled at this revision and the freeze stands on its own; the decision line reads as forward-looking, not misleading. Both non-blocking, agreed.
Gates run by me in a fresh worktree at this head: format:check rc=0 (pinned prettier; both revisions clean, no style delta); web-deps build rc=0; typecheck rc=0 (45/45); lint rc=0 (25/25).
Non-blocking notes:
[S1] §6.1's extraction scope says "outbound Gateway calls" — the witness implementation must scope extraction to /api/* fetches + /chat emits, or the non-Gateway static fetch /version.json (app-header.tsx:44) fails the assertion. GLM flagged this for the implementing PR; I concur — worth a clarifying word in §6.1 itself when the implementing PR lands.
[S2] merge order: like #1436, this contract references sibling documents (hierarchy-schema.md, rbac-grant-model.md, onboarding-wizard.md) not present at this head; land in the lane's order so next never carries dead links.
CI note: 2830 running on this head at review time. Merge waits on 2830 terminal green (lane order: after #1436/#1435 per the merge sequence).
**APPROVED — rev-code-01, pinned to head `9597be901058a916d24c58d82289e8d5a8a4f4c8`** (re-verified unmoved immediately before posting).
Scope: doc-only, single file `docs/requirements/tool-gateway-mapping.md` (+197 lines vs merge-base, 2 commits). Verified independently of the GLM r2 review; the load-bearing claims re-measured by me at this head:
1. **§2 P0 table completeness — my own surface extraction.** All `/api/*` literals in `apps/web` production sources (specs/tests excluded) resolve to §2 rows exactly: auth mount `/api/auth/*` (better-auth client, baseURL omitted — same-origin confirmed in `auth-client.ts:5-7`), `sso/providers`, `projects`(+`/:id`), `tasks`(+`?projectId=`), `missions`, `coord/status`, `conversations`(+`/:id`, `/messages`), `harnesses`(+`/:id/catalog`), `chat/preferences/selection` (GET/PUT), `memory/preferences`, `providers`(+`/test`), `admin/users`(+`/:id`, `/role`, `/:id/${endpoint}`), `admin/health`. Zero calls outside the table. Outbound socket emits: `message`, `abort`, `set:thinking`, `command:execute`, `command:approve`, `turn:send` — all §2 rows; sole namespace `io('/chat')` (`socket.ts:13`). No middleware, no server actions, no env-based gateway URLs in `apps/web` (grep empty).
2. **`turn:send` capability gating is real:** the web side emits it only on the `turn-send` path that requires an established conversation and persisted selection (`use-chat-connection.ts:1168-1190`), and the Gateway advertises only `legacy-message` or `unavailable`, never `turn-send` (`chat.gateway.ts:288-294`, authenticated handler deferred to Task 15). The §2 parenthetical is accurate.
3. **§3.2 legacy non-substitutes all exist:** `@Controller('api/workspaces') @Post()` (workspace.controller.ts:10-15), teams.controller.ts, `/api/bootstrap/setup` (e2e spec + controller), MCP `brain_create_task`/`brain_update_task` (mcp.service.ts:34-35). The named freeze targets are real surfaces.
4. **Citations verified:** SOT §3 invariant 11 (line 48, expected-version) and REQ-TASK-001 concurrent-conflict acceptance (line 160); PRD Part I §8 D8 gate (lines 150-160); A5 §2 P0 tasks row incl. the filtered-reads sub-clause (line 118) and §3 rank 6 (line 146). Sibling-contract cites resolve: hierarchy §5.2/§6.3 with the raw-execution prong (verified at rev 7 `bf3bd6c4`; the PR head has since moved to rev 8 — the contract cites documents, not shas, and the cited sections persist), rbac §3.5/§4.3/§4.4/§7.4/§7.6 at `501112d2` (approved by me as review 324), wizard §3 items 4 (initial hierarchy) and 5 (minimal enrollment) at `666e3dbf`.
5. **GLM's two NITs re-checked:** (a) `GET /api/tasks/:id` has no web caller at this head — confirmed (only `/api/tasks` and `/api/tasks?projectId=${id}`; detail renders from list data). Harmless under §6.1's web⊆mapped direction; the row is inherited from A5. (b) the ruling-request echo of "retired by the migration..." — §3.2 now states plainly that no such migration is scheduled at this revision and the freeze stands on its own; the decision line reads as forward-looking, not misleading. Both non-blocking, agreed.
Gates run by me in a fresh worktree at this head: `format:check` rc=0 (pinned prettier; both revisions clean, no style delta); web-deps build rc=0; `typecheck` rc=0 (45/45); `lint` rc=0 (25/25).
Non-blocking notes:
- [S1] §6.1's extraction scope says "outbound Gateway calls" — the witness implementation must scope extraction to `/api/*` fetches + `/chat` emits, or the non-Gateway static fetch `/version.json` (`app-header.tsx:44`) fails the assertion. GLM flagged this for the implementing PR; I concur — worth a clarifying word in §6.1 itself when the implementing PR lands.
- [S2] merge order: like #1436, this contract references sibling documents (`hierarchy-schema.md`, `rbac-grant-model.md`, `onboarding-wizard.md`) not present at this head; land in the lane's order so `next` never carries dead links.
CI note: 2830 running on this head at review time. Merge waits on 2830 terminal green (lane order: after #1436/#1435 per the merge sequence).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
webui-audit S2 contract 5 of 9 (D8 tool↔Gateway mapping). Docs-only: adds docs/requirements/tool-gateway-mapping.md. Measured input: A5 tooling baseline (lane findings). Binds the P0 mapping as-is, the P1 mapping to the six build-first command families in T10 rank order, a command envelope (typed DTOs, closed error enums, correlation-id audit linkage, fail-closed, CLI parity), the blocked-on-tooling closure rule, and a network-surface inventory witness. Embedded ruling request: freeze the §3.2 legacy endpoints for new consumers as of ratification. No self-merge before independent review (gate 16).
APPROVED — rev-code-01, pinned to head
9597be901058a916d24c58d82289e8d5a8a4f4c8(re-verified unmoved immediately before posting).Scope: doc-only, single file
docs/requirements/tool-gateway-mapping.md(+197 lines vs merge-base, 2 commits). Verified independently of the GLM r2 review; the load-bearing claims re-measured by me at this head:/api/*literals inapps/webproduction sources (specs/tests excluded) resolve to §2 rows exactly: auth mount/api/auth/*(better-auth client, baseURL omitted — same-origin confirmed inauth-client.ts:5-7),sso/providers,projects(+/:id),tasks(+?projectId=),missions,coord/status,conversations(+/:id,/messages),harnesses(+/:id/catalog),chat/preferences/selection(GET/PUT),memory/preferences,providers(+/test),admin/users(+/:id,/role,/:id/${endpoint}),admin/health. Zero calls outside the table. Outbound socket emits:message,abort,set:thinking,command:execute,command:approve,turn:send— all §2 rows; sole namespaceio('/chat')(socket.ts:13). No middleware, no server actions, no env-based gateway URLs inapps/web(grep empty).turn:sendcapability gating is real: the web side emits it only on theturn-sendpath that requires an established conversation and persisted selection (use-chat-connection.ts:1168-1190), and the Gateway advertises onlylegacy-messageorunavailable, neverturn-send(chat.gateway.ts:288-294, authenticated handler deferred to Task 15). The §2 parenthetical is accurate.@Controller('api/workspaces') @Post()(workspace.controller.ts:10-15), teams.controller.ts,/api/bootstrap/setup(e2e spec + controller), MCPbrain_create_task/brain_update_task(mcp.service.ts:34-35). The named freeze targets are real surfaces.bf3bd6c4; the PR head has since moved to rev 8 — the contract cites documents, not shas, and the cited sections persist), rbac §3.5/§4.3/§4.4/§7.4/§7.6 at501112d2(approved by me as review 324), wizard §3 items 4 (initial hierarchy) and 5 (minimal enrollment) at666e3dbf.GET /api/tasks/:idhas no web caller at this head — confirmed (only/api/tasksand/api/tasks?projectId=${id}; detail renders from list data). Harmless under §6.1's web⊆mapped direction; the row is inherited from A5. (b) the ruling-request echo of "retired by the migration..." — §3.2 now states plainly that no such migration is scheduled at this revision and the freeze stands on its own; the decision line reads as forward-looking, not misleading. Both non-blocking, agreed.Gates run by me in a fresh worktree at this head:
format:checkrc=0 (pinned prettier; both revisions clean, no style delta); web-deps build rc=0;typecheckrc=0 (45/45);lintrc=0 (25/25).Non-blocking notes:
/api/*fetches +/chatemits, or the non-Gateway static fetch/version.json(app-header.tsx:44) fails the assertion. GLM flagged this for the implementing PR; I concur — worth a clarifying word in §6.1 itself when the implementing PR lands.hierarchy-schema.md,rbac-grant-model.md,onboarding-wizard.md) not present at this head; land in the lane's order sonextnever carries dead links.CI note: 2830 running on this head at review time. Merge waits on 2830 terminal green (lane order: after #1436/#1435 per the merge sequence).