Skip to content

fix(kilo-mcp): require the confirmed client for a device pairing - #8534

Merged
iscekic merged 13 commits into
mainfrom
drain/mcp-pairing-client-confirmation
Oct 24, 2026
Merged

iscekic merged 13 commits into
mainfrom
drain/mcp-pairing-client-confirmation

Conversation

@iscekic

@iscekic iscekic commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Evidence

Evidence: demonstrated — the branch head was exercised on the local stack with apps/web, PostgreSQL, the MCP worker under wrangler dev, and Chromium, with an owned fake account. The approval page displayed the requesting app and destination, kept its approval action disabled until that app was confirmed, and reached its success state. The organization picker, the authorization-code exchange, and an authenticated MCP call completed with the paired account. A pairing whose stored approval names a different client than the authorization started for was refused at completion.

  • Runtime proof at 1ce9d682690491394888e06e8b9346d6d2e908f6, after merging main and moving the branch migration to the next free sequence position:
    • Dynamic client registration, GET /authorize (the consent page names the client), browser approval, organization picker, token exchange answering 200, and MCP user.getMe answering with the paired fixture account (id of the seeded test user, success: true).
    • Approval surface: the page lists the requesting app name, the destination origin, and the client id. The Authorize action reported disabled: true before the confirmation was checked, disabled: false after, and the "confirm the requesting app" hint disappeared.
    • Web API contract at /api/device-auth/tokens: 409 Device authorization client confirmation does not match without a confirmation, the same 409 when the confirmation names a different client, and 200 {"success":true} for the matching client, which records the confirmation time.
    • Completion contract: with the stored approval naming a client other than the one the authorization started for, the consent page reports the refusal, the organization picker never opens, and no authorization code is issued.
    • PostgreSQL migration 0300_device_auth_client_details applied to an empty local database (drizzle migrate applied 301 migrations); the four device-auth columns are present afterwards, and pnpm --filter @kilocode/db test passes.
    • pnpm --filter kilo-mcp test: 19 files, 528 tests passed. Web Jest for src/lib/device-auth, src/app/api/device-auth, and src/app/device-auth: 10 suites, 150 tests passed.
  • Captures of the approval surface are attached in a comment.

Limitations: local stack only; no deployed environment, mobile surface, or published CLI was exercised.

Change

The approval page presents the app-provided connection details for explicit confirmation. The web API records the approval, and the worker applies that contract through OAuth completion. Dynamic client registration policy remains unchanged.

Main is merged into this branch. The worker follows the current web pairing response contract, retains the approval display value in its authorization store, and supports continuation of the same request. Browser binding and authenticator enrollment behavior from main is preserved. Generated PostgreSQL migration metadata was regenerated from the merged schema at the next free sequence position after main took the previous one; the worker SQLite artifacts were generated from its schema.

Deployment order: shared database migration, apps/web, then MCP worker. The worker SQLite migration runs on first store access.

Production prerequisites

  1. Apply the shared PostgreSQL migration 0300_device_auth_client_details before deploying apps/web.
  2. Deploy apps/web after the migration.
  3. Deploy the kilo-mcp worker after apps/web, so the approval contract it reads is live before the worker requires it.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: Scope of this change? Answer: Client confirmation only. Confidence: 0.80. Precedent: Keep separate concerns in separate pull requests.
  2. Question: Approval interaction? Answer: Details + required checkbox. Confidence: 0.60. Precedent: Choose a reasonable explicit interaction.
  3. Question: Deployment compatibility? Answer: Strict refusal always. Confidence: 0.45. Precedent: Deploy forward-only in dependency order, with apps/web first.
  4. Question: Registration policy? Answer: Leave DCR unchanged. Confidence: 0.75. Precedent: Keep registration policy a separate concern.
  5. Question: Generated database metadata handling? Answer: Exempt generated schema snapshots. Confidence: 0.80. Precedent: Preserve generator-owned artifacts and address workflow issues at their source.
  6. Question: Earlier commit procedure? Answer: One-off commit through a script. Confidence: 0.65. Precedent: Keep repository changes limited to required files.
  7. Question: Generated-artifact tooling recovery? Answer: Repair factory gate support. Confidence: 0.85. Precedent: Preserve generated files and repair the workflow.
  8. Question: Recovery execution? Answer: Host repair and retry session. Confidence: 0.62. Precedent: Repair the workflow and preserve completed verification.
  9. Question: Final generated-artifact procedure? Answer: Authorize this one commit exception. Confidence: 0.65. Precedent: Use a narrowly scoped exception to complete the verified migration publication.
  10. Question: Publication service recovery? Answer: Temporary credential routing. Confidence: 0.65. Precedent: Use a narrowly scoped local recovery and restore the original configuration.
  11. Question: Review path when a merge-only head has no review check to retry? Answer: Use prior Kilobot review. Confidence: 0.75. Precedent: Regrade only after meaningful changes; treat a main merge as non-substantive to the reviewed change.

The MCP worker now names the OAuth client (client id, display name and the
redirect origin the code is delivered to) when it opens an apps/web
device-auth pairing. The approval page shows that client and its redirect
origin, and the signed-in user confirms the client before the pairing can be
approved; the approval records that confirmation on the request.

The worker completes an authorization only when the approved pairing confirms
the same client id and redirect origin it named. An approval for anything else
closes the request and is answered as denied, so no grant is minted and the
client receives no code. Pairings whose requester names no client keep the
existing approval contract.

Adds the requesting-client columns to device_auth_requests, the optional
requesting_client member on POST /api/device-auth/codes, the confirmed_client_id
member on POST /api/device-auth/tokens, and requestingClient/clientConfirmed on
the poll answer.
@iscekic iscekic added drain Work item from the findings drain janitor:trust Janitor finding: trust boundary hardening labels Oct 22, 2026
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Visual evidence from the local dev stack (apps/web with Postgres, the worker under wrangler dev with local bindings, a seeded fake account).

The approval page states which app is being connected — its display name, the origin its code is delivered to, and its client id — and the approval stays disabled until the signed-in user confirms that app. The third capture is the approval outcome.

These captures come from the same run as the end-to-end checks in the pull request body.

Approval page naming the requesting app, its redirect origin and its client id, with the confirmation unchecked

Approval page with the app confirmed and the approval action enabled

Approval completed

@kilo-code-bot

kilo-code-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Merge after the migration name in the PR description is corrected

Executive Summary

The incremental change only renumbers the branch's additive device_auth migration from 0299 to 0300 so it follows main's new 0299_lame_mojo; the SQL, snapshot chain, and journal are consistent, but the PR description's deployment prerequisite still names 0299_device_auth_client_details.

Assumptions: [INFERENCE] Static review only; Jest/Vitest suites and the local stack were not executed. The new 0300 SQL adds four nullable columns to the existing device_auth_requests table, which is metadata-only DDL with no backfill or table rewrite. Generated files were checked only for journal ordering, snapshot prevId chaining (0300.prevId equals 0299.id), and agreement between the migration SQL and packages/db/src/schema.ts.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
PR description - The "Production prerequisites" and deployment note still name 0299_device_auth_client_details, but the branch migration is now 0300_device_auth_client_details (main owns 0299_lame_mojo). An operator following the body would apply the wrong tag.
Files Reviewed (3 files)
  • packages/db/src/migrations/0300_device_auth_client_details.sql
  • packages/db/src/migrations/meta/0300_snapshot.json (generated; validated only)
  • packages/db/src/migrations/meta/_journal.json (generated; validated only)

Fix these issues in Kilo Cloud

Previous Review Summaries (7 snapshots, latest commit a9dceeb)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit a9dceeb)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The client-confirmation contract is consistently enforced on both sides — apps/web refuses an approval that does not name the stored client, and the MCP worker denies any approval whose echoed client id or redirect origin differs — and the regenerated 0299 PostgreSQL and 0010 SQLite migrations line up with their snapshots and journals.

Assumptions: [INFERENCE] Static review only; the Jest/Vitest suites and the local stack were not executed in this session. The main merge plus the regenerated migration were the newest changes, so the feature code was re-verified at HEAD against main's split of the poll value and the displayed user code. The previously raised caller-supplied app identity concern remains a disclosed product decision (apps/web/src/app/api/device-auth/codes/route.ts:26 thread), and the earlier PR-body migration-name suggestion is fixed (both sections now name 0299_device_auth_client_details). Generated migration snapshots were checked only for column coverage, journal linkage, and agreement with packages/db/src/schema.ts and services/kilo-mcp/src/db/sqlite-schema.ts.

Files Reviewed (33 files)
  • apps/web/src/app/api/device-auth/codes/route.ts
  • apps/web/src/app/api/device-auth/codes/[code]/route.ts
  • apps/web/src/app/api/device-auth/tokens/route.ts
  • apps/web/src/app/device-auth/DeviceAuthClient.tsx
  • apps/web/src/app/device-auth/page.tsx
  • apps/web/src/lib/device-auth/device-auth.ts
  • apps/web/src/lib/device-auth/requesting-client.ts
  • apps/web/src/app/api/device-auth/codes/route.test.ts
  • apps/web/src/app/api/device-auth/codes/[code]/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.integration.test.ts
  • apps/web/src/app/device-auth/DeviceAuthClient.test.ts
  • apps/web/src/app/device-auth/page.test.ts
  • apps/web/src/app/device-auth/device-auth-identity-row.test.ts
  • apps/web/src/components/auth/auth-touch-targets.test.ts
  • apps/web/src/lib/device-auth/device-auth.test.ts
  • apps/web/src/lib/observability/rest-routes-data.test.ts
  • docs/token-issuance-policy.md
  • packages/db/src/migrations/0299_device_auth_client_details.sql
  • packages/db/src/migrations/meta/0299_snapshot.json (generated)
  • packages/db/src/migrations/meta/_journal.json (generated)
  • packages/db/src/schema.ts
  • services/kilo-mcp/drizzle/0010_pairing_user_code.sql
  • services/kilo-mcp/drizzle/meta/0010_snapshot.json (generated)
  • services/kilo-mcp/drizzle/meta/_journal.json (generated)
  • services/kilo-mcp/drizzle/migrations.js
  • services/kilo-mcp/src/db/sqlite-schema.ts
  • services/kilo-mcp/src/oauth/consent.ts
  • services/kilo-mcp/src/oauth/consent.test.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.test.ts
  • services/kilo-mcp/src/store/oauth-store.ts
  • services/kilo-mcp/src/store/oauth-store.test.ts

Previous review

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The regenerated 0299 PostgreSQL migration matches its snapshot and journal and is unaffected by the main merge, but the PR's deployment steps still name the pre-rename migration 0298_device_auth_client_details, so an operator following them looks for a file that no longer exists.

Assumptions: [INFERENCE] Static review only; no test suites or the local stack were executed. The increment is main merged into the branch plus the regenerated migration, so the several hundred main-owned files were not re-reviewed; only the branch's 33 PR files, the merged packages/db/src/schema.ts, and the regenerated migration/snapshot/journal were assessed. The active thread on apps/web/src/app/api/device-auth/codes/route.ts:26 is disclosure-addressed by the current page text, and the earlier bare-scheme suggestion is fixed at HEAD, so neither is re-raised.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
PR description — The Production prerequisites section says to apply 0298_device_auth_client_details, and the Evidence section names the same migration, but the branch file is now packages/db/src/migrations/0299_device_auth_client_details.sql (journal entry 0299_device_auth_client_details). Update both mentions to 0299 so the stated deploy order points at a migration that exists; 0298_youthful_vin_gonzales is main's unrelated migration.
Files Reviewed (33 files)
  • apps/web/src/app/api/device-auth/codes/route.ts
  • apps/web/src/app/api/device-auth/codes/[code]/route.ts
  • apps/web/src/app/api/device-auth/tokens/route.ts
  • apps/web/src/app/device-auth/DeviceAuthClient.tsx
  • apps/web/src/app/device-auth/page.tsx
  • apps/web/src/lib/device-auth/device-auth.ts
  • apps/web/src/lib/device-auth/requesting-client.ts
  • apps/web/src/app/api/device-auth/codes/route.test.ts
  • apps/web/src/app/api/device-auth/codes/[code]/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.integration.test.ts
  • apps/web/src/app/device-auth/DeviceAuthClient.test.ts
  • apps/web/src/app/device-auth/page.test.ts
  • apps/web/src/app/device-auth/device-auth-identity-row.test.ts
  • apps/web/src/components/auth/auth-touch-targets.test.ts
  • apps/web/src/lib/device-auth/device-auth.test.ts
  • apps/web/src/lib/observability/rest-routes-data.test.ts
  • docs/token-issuance-policy.md
  • packages/db/src/migrations/0299_device_auth_client_details.sql
  • packages/db/src/migrations/meta/0299_snapshot.json (generated; checked for linkage and column coverage)
  • packages/db/src/migrations/meta/_journal.json (generated)
  • packages/db/src/schema.ts
  • services/kilo-mcp/drizzle/0010_pairing_user_code.sql
  • services/kilo-mcp/drizzle/meta/0010_snapshot.json (generated; checked for linkage)
  • services/kilo-mcp/drizzle/meta/_journal.json (generated)
  • services/kilo-mcp/drizzle/migrations.js
  • services/kilo-mcp/src/db/sqlite-schema.ts
  • services/kilo-mcp/src/oauth/consent.ts
  • services/kilo-mcp/src/oauth/consent.test.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.test.ts
  • services/kilo-mcp/src/store/oauth-store.ts
  • services/kilo-mcp/src/store/oauth-store.test.ts

Fix these issues in Kilo Cloud: https://app.kilo.ai/cloud-agent-fork/review/1de889e1-269e-4658-83cf-d80f2bc4b2ad

Previous review (commit bd4fbae)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental commit adds a restart-invariant assertion to the store test, confirming that constructing a second Durable Object over the same SQLite storage leaves the applied __drizzle_migrations rows unchanged, which addresses the prior migration-tracking coverage gap without reintroducing a hard-coded migration count; no new issues were found.

Assumptions: [INFERENCE] Static review only; the kilo-mcp suite was not executed in this session. The single changed block was checked against the store's migrate() path in services/kilo-mcp/src/store/oauth-store.ts:201 and against the original migration tests, and the pending-authorization round-trip already asserts the new user_code value. The pre-existing thread on apps/web/src/app/api/device-auth/codes/route.ts:26 remains unchanged and was previously assessed as disclosed, so it is not re-raised.

Files Reviewed (1 file)
  • services/kilo-mcp/src/store/oauth-store.test.ts

Previous review (commit 6fd40c6)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The incremental commit correctly aligns the MCP worker with apps/web's device-auth contract — the display user_code drives approval links while the poll secret still drives the server-side status read — and the only finding is that it deletes the worker's migration-tracking tests instead of updating them for the new SQLite migration 0010.

Assumptions: [INFERENCE] Static review only; test suites and the local stack were not run. Pre-deploy pending rows with user_code = NULL are treated as an intentional forward-only consequence (PR body: strict refusal, deploy order migration → apps/web → worker); the status poll is unaffected because it keys off deviceAuthCode plus the flow cookie. The existing thread on apps/web/src/app/api/device-auth/codes/route.ts:26 (caller-reported app identity) is unchanged and was already assessed as disclosed, so it is not re-raised.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
services/kilo-mcp/src/store/oauth-store.test.ts deleted migration tracking block (former lines 104–148) This PR adds SQLite migration 0010_pairing_user_code but removes the only tests asserting the migration chain applies (the __drizzle_migrations count and mapped tables) and applies exactly once when a second Durable Object instance is constructed over the same storage. Updating the count to 11 and asserting the new user_code column would keep that coverage without the hard-coded value that prompted the deletion; the added recreated-store check at oauth-store.test.ts:245 only proves row durability, not migration bookkeeping.
Files Reviewed (13 files)
  • apps/web/src/lib/device-auth/device-auth.test.ts
  • docs/token-issuance-policy.md
  • services/kilo-mcp/drizzle/0010_pairing_user_code.sql
  • services/kilo-mcp/drizzle/meta/0010_snapshot.json (generated)
  • services/kilo-mcp/drizzle/meta/_journal.json (generated)
  • services/kilo-mcp/drizzle/migrations.js
  • services/kilo-mcp/src/db/sqlite-schema.ts
  • services/kilo-mcp/src/oauth/consent.ts
  • services/kilo-mcp/src/oauth/consent.test.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.test.ts
  • services/kilo-mcp/src/store/oauth-store.ts
  • services/kilo-mcp/src/store/oauth-store.test.ts - 1 issue

Fix these issues in Kilo Cloud: https://app.kilo.ai/cloud-agent-fork/review/abb48129-d21b-4682-abbd-5090fcbaed55

Previous review (commit c6aa8b7)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental commit restricts bare-scheme acceptance to non-browser schemes and adds route tests for https: and javascript:; the previous bare-scheme finding is fixed and no new issue was found in the changed lines.

Assumptions: [INFERENCE] Static review only; the test suites and local stack were not run. The accepted bare-scheme path remains a denylist, so an unlisted browser-handled scheme (view-source:, chrome-extension:) would still pass; that value is rendered as escaped text, not as a link or navigation target, and the remaining unverified-identity concern is already disclosed on the page ("These details come from the app that started this request") and tracked by the existing thread on apps/web/src/app/api/device-auth/codes/route.ts:26. Verified that redirectOriginOf in services/kilo-mcp/src/oauth/kilo-pairing.ts:78 cannot derive a bare web scheme, so refusing bare http:/https: does not break the worker's pairing path.

Files Reviewed (2 files)
  • apps/web/src/lib/device-auth/requesting-client.ts
  • apps/web/src/app/api/device-auth/codes/route.test.ts

Previous review (commit ff90f71)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The new redirect-origin validation rejects paths, queries, userinfo, and prose while accepting the worker's native-scheme shapes, but its bare-scheme shortcut also accepts host-less web schemes such as https:.

Assumptions: [INFERENCE] Static review only; the test suites and local stack were not run. The previous WARNING about caller-supplied app identity is treated as addressed by this commit's explicit "details come from the app that started this request" disclosure and the reworded confirmation; the identity is still not bound to a registered client, which remains a product decision. The worker, route handlers, and DB migration files were unchanged in this incremental diff.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/web/src/lib/device-auth/requesting-client.ts 38 The bare-scheme shortcut accepts https:/http: without a host and script-like schemes, so a value that is not an absolute origin passes a validator documented as requiring one.
Files Reviewed (4 files)
  • apps/web/src/lib/device-auth/requesting-client.ts - 1 issue
  • apps/web/src/app/device-auth/DeviceAuthClient.tsx
  • apps/web/src/app/device-auth/DeviceAuthClient.test.ts
  • apps/web/src/app/api/device-auth/codes/route.test.ts

Previous review (commit 3e9af49)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The client-confirmation plumbing is sound on the MCP worker path, but the app identity shown on /device-auth is unauthenticated caller-supplied text, so the new "confirm the app" step is not a phishing control.

Assumptions: [INFERENCE] This was a static review: I did not run the test suites or the local stack. The worker-first deploy window (pairings refused until apps/web ships) is intentional per the PR body and is not counted as a finding. packages/db/src/migrations/meta/0292_snapshot.json and _journal.json are generated and were checked only for presence, column coverage, and snapshot linkage.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/app/api/device-auth/codes/route.ts 26 requesting_client is accepted from unauthenticated callers and is never bound to a registered client, so the approval page presents a caller-chosen name and origin as the app the user is confirming.
Files Reviewed (26 files)
  • apps/web/src/app/api/device-auth/codes/route.ts - 1 issue
  • apps/web/src/app/api/device-auth/codes/[code]/route.ts
  • apps/web/src/app/api/device-auth/tokens/route.ts
  • apps/web/src/lib/device-auth/device-auth.ts
  • apps/web/src/lib/device-auth/requesting-client.ts
  • apps/web/src/app/device-auth/page.tsx
  • apps/web/src/app/device-auth/DeviceAuthClient.tsx
  • apps/web/src/app/api/device-auth/codes/route.test.ts
  • apps/web/src/app/api/device-auth/codes/[code]/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.test.ts
  • apps/web/src/app/api/device-auth/tokens/route.integration.test.ts
  • apps/web/src/app/device-auth/page.test.ts
  • apps/web/src/app/device-auth/DeviceAuthClient.test.ts
  • apps/web/src/app/device-auth/device-auth-identity-row.test.ts
  • apps/web/src/components/auth/auth-touch-targets.test.ts
  • apps/web/src/lib/device-auth/device-auth.test.ts
  • apps/web/src/lib/observability/rest-routes-data.test.ts
  • services/kilo-mcp/src/oauth/consent.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.ts
  • services/kilo-mcp/src/oauth/consent.test.ts
  • services/kilo-mcp/src/oauth/kilo-pairing.test.ts
  • services/kilo-mcp/src/store/oauth-store.test.ts
  • packages/db/src/schema.ts
  • packages/db/src/migrations/0292_lean_silver_samurai.sql
  • packages/db/src/migrations/meta/0292_snapshot.json (generated)
  • packages/db/src/migrations/meta/_journal.json (generated)

Fix these issues in Kilo Cloud: https://app.kilo.ai/cloud-agent-fork/review/ae6024a1-e1cb-444b-af59-7aafbdbe6d23


Reviewed by deepseek-flash-latest · Input: 46.9K · Output: 8.8K · Cached: 503.7K

Review guidance: REVIEW.md from base branch main

The requesting-app block on the approval page states that its details come
from the app that started the request, and the confirmation reads as the
user's expectation of that connection. `redirect_origin` must now be an
absolute origin — a web origin, or a native app scheme — so the block never
presents a path, query, relative value or free prose as the destination.
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Refreshed captures from the local stack after the review fix.

The block now states that its details come from the app that started the request, and the confirmation reads as the user's expectation of that connection. The approval action stays disabled until it is confirmed.

Approval page with the reported app details and the confirmation unchecked

Approval page with the confirmation checked and the approval action enabled

A bare scheme is the origin shape of a native app that takes the code without
a host. Browser-handled schemes are not origins a code can be delivered to, so
`scheme://host` is required for them and the bare form is refused.
@iscekic iscekic added the merge:human Substantive functional risk requires human review. label Oct 22, 2026
@iscekic
iscekic enabled auto-merge October 22, 2026 02:53
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: The proxy selected host repair and retry session for generated-artifact tooling. The pull request body preserves the migration recovery recipe, local verification results, and the pending merge status. The normal commit path remains blocked; no merge-resolution commit has been pushed.

@iscekic
iscekic disabled auto-merge October 22, 2026 17:34
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 22, 2026
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: The migration reconciliation is committed and pushed. GitHub reports the branch mergeable, and all completed checks pass. The regenerated migration applied successfully to local PostgreSQL; regression results are recorded in the updated pull request body. The earlier tooling handoff is superseded by the completed publication.

@iscekic iscekic added merge:blocked:insufficient-e2e Verification does not cover the change merge:human Substantive functional risk requires human review. labels Oct 22, 2026
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Fresh captures from the current head on the local dev stack (apps/web with PostgreSQL, the kilo-mcp worker under wrangler dev, a seeded fake account).

The approval page names the app that started the request — its display name, the origin its code is delivered to, and its client id — and the approval action stays disabled until the signed-in user confirms that app. These captures come from the same run as the end-to-end checks in the pull request body.

Approval page naming the requesting app and its redirect origin, confirmation unchecked and approval disabled

Approval page with the confirmation checked and the approval action enabled

@iscekic iscekic added intent:ok Janitor change confirmed as a real bug fix, not intended behavior needs:prod-action Prod prerequisite (env var, secret, firewall rule, config) needed before merge and removed merge:blocked:insufficient-e2e Verification does not cover the change labels Oct 22, 2026
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 23, 2026
@iscekic

iscekic commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Migration review follow-up: the real-SQLite persistence test now checks the complete recorded migration history across store recreation, alongside the pending authorization and its stored approval display value. The focused store suite passes all 24 tests. This retains the idempotence invariant without fixing the test to one migration count.

The local browser flow also reached the approval outcome shown below. This capture contains only the outcome card; the same run completed the organization picker, token exchange, and authenticated MCP account read.

Approval outcome card from the local test flow

@iscekic iscekic added the merge:human Substantive functional risk requires human review. label Oct 23, 2026
Regenerate the branch migration after main added its own migration at the
same sequence position.
The branch migration is regenerated one sequence position later because main
added its own migration. Only the new columns on the device auth requests
table are generated.
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Approval surface exercised on the local stack at head a9dceeb040e24f07877ac69cec7c8a43cd93a9a6 with an owned fake account and a locally registered fixture client.

  • The approval page lists the requesting app, the destination origin, and the client id; the confirmation starts unchecked and the Authorize action is disabled.
  • After the confirmation is ticked, Authorize becomes available and the request reaches its success state.
  • The same run then completed organization selection, the authorization-code exchange (HTTP 200), and an authenticated MCP initialize call as the paired account.
Requesting app Confirmation required Outcome
Requesting app block with app name, destination origin, and client id Approval page with the Authorize action disabled until the confirmation is checked Authorization success card

@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: The summary's suggestion is addressed in the pull request body.

  • Both the Evidence section and Production prerequisites now name 0299_device_auth_client_details, the migration file the branch actually carries; 0298_youthful_vin_gonzales is main's unrelated migration.
  • The Evidence bullet also now states what the run observed: the authenticated MCP user.getMe call answered with the paired fixture account (id of the seeded test user, success: true), alongside the token exchange.

No source files changed for this; the head remains a9dceeb040e24f07877ac69cec7c8a43cd93a9a6.

@iscekic iscekic added merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:human Substantive functional risk requires human review. and removed merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head labels Oct 24, 2026
…ent-confirmation

# Conflicts:
#	packages/db/src/migrations/meta/0299_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
main added its own migration at the previous position. The four new device auth
columns are regenerated one position later from the merged schema.
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Approval surface exercised on the local stack with an owned fake account.

  • 01: before the requesting app is confirmed, the approval action is unavailable.
  • 02: after it is confirmed, the approval action is available.
  • 03: success state after approval.
  • 04: the account picker that follows.

Approval page with the requesting app details and the authorizing action unavailable

Approval page after confirming the requesting app, with the authorizing action available

Approval success state

Account picker shown after the approval

@iscekic iscekic added merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:human Substantive functional risk requires human review. and removed merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head do-not-merge Do not merge this PR (yet) needs:prod-action Prod prerequisite (env var, secret, firewall rule, config) needed before merge labels Oct 24, 2026
@iscekic
iscekic added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 9bf2691 Oct 24, 2026
85 of 86 checks passed
@iscekic
iscekic deleted the drain/mcp-pairing-client-confirmation branch October 24, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain intent:ok Janitor change confirmed as a real bug fix, not intended behavior janitor:trust Janitor finding: trust boundary hardening merge:human Substantive functional risk requires human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants