diff --git a/.planning/phases/19.4-oidc-provider-on-wristband/19.4-REVIEW-DISPOSITION.md b/.planning/phases/19.4-oidc-provider-on-wristband/19.4-REVIEW-DISPOSITION.md new file mode 100644 index 00000000..2a543276 --- /dev/null +++ b/.planning/phases/19.4-oidc-provider-on-wristband/19.4-REVIEW-DISPOSITION.md @@ -0,0 +1,93 @@ +--- +phase: 19.4 +review: 19.4-REVIEW.md +titles: json +findings: + - id: WR-01 + severity: warning + disposition: open + title: "A replayed authorization code does not revoke refresh tokens rotated after the first exchange" + - id: WR-02 + severity: warning + disposition: open + title: "The consent page never shows the `offline_access` grant" + - id: WR-03 + severity: warning + disposition: open + title: "`import-winter --force` leaves refresh tokens and MCP state behind and wipes MCP clients" + - id: WR-04 + severity: warning + disposition: open + title: "Imported PHP clients whose redirect URIs Go now rejects cannot be edited in the admin" + - id: WR-05 + severity: warning + disposition: open + title: "Editing a pairwise client silently changes every user's `sub`" + - id: WR-06 + severity: warning + disposition: open + title: "The communities claim's \"log and return []\" fallback poisons the token transaction on Postgres" + - id: IN-01 + severity: info + disposition: open + title: "`http://[::1]` is a loopback host for matching but cannot be registered" + - id: IN-02 + severity: info + disposition: open + title: "`RevealStore.Take` reads and forgets in two non-atomic steps" + - id: IN-03 + severity: info + disposition: open + title: "`KeyRing` caches signers by kid forever" + - id: IN-04 + severity: info + disposition: open + title: "Concurrent rotations fail instead of being idempotent" + - id: IN-05 + severity: info + disposition: open + title: "Dead `existing` map in the import" + - id: IN-06 + severity: info + disposition: open + title: "The refresh grant issues an id_token for a narrowed scope without `openid`" + - id: IN-07 + severity: info + disposition: open + title: "The consent redirect URL breaks a consent URL that has a fragment" + - id: IN-08 + severity: info + disposition: open + title: "The decision and switch-account POSTs have no body cap of their own" + - id: IN-09 + severity: info + disposition: open + title: "The gate's additive check misses some export removals" +open: 15 +total: 15 +recorded: 2026-10-19T20:05:26.804Z +--- + +# Phase 19.4: Code Review Disposition + +| Finding | Severity | Disposition | Source | +|---------|----------|-------------|--------| +| WR-01 | warning | open | - | +| WR-02 | warning | open | - | +| WR-03 | warning | open | - | +| WR-04 | warning | open | - | +| WR-05 | warning | open | - | +| WR-06 | warning | open | - | +| IN-01 | info | open | - | +| IN-02 | info | open | - | +| IN-03 | info | open | - | +| IN-04 | info | open | - | +| IN-05 | info | open | - | +| IN-06 | info | open | - | +| IN-07 | info | open | - | +| IN-08 | info | open | - | +| IN-09 | info | open | - | + +Dispositions: `open` (recorded, not yet triaged), `fixed`, `skipped`, `deferred`. +Set `deferred` by hand and put the reason in the Source cell; both are preserved. A `|` in the reason is kept as prose and escaped on the next run. +Re-running the gate keeps every row it can. A row the current review no longer reports is kept and its Source cell flagged, so a finding does not leave this record silently. ONE exception: when a finding id is REUSED by a different finding, the earlier decision cannot keep a row — the id is taken — and it is dropped. A RECORDED decision (anything but `open`) is named on the console when that happens; a row still at `open` is replaced silently, because `open` records no decision to lose.