docs(09): record code review disposition

This commit is contained in:
Jakub Zych
2026-09-27 23:52:18 +02:00
parent ee79c7f2c9
commit 2ad19bda21

View File

@@ -0,0 +1,178 @@
---
phase: 09
review: 09-REVIEW.md
titles: json
findings:
- id: CR-01
severity: critical
disposition: open
title: "Writable numeric fields cannot be saved; bad field values return 500 instead of 422"
- id: WR-01
severity: warning
disposition: open
title: "Required-permission wildcards never match, and multiple required codes use ALL rather than Winter's ANY"
- id: WR-02
severity: warning
disposition: open
title: "Navigation shows a denied parent item, including its label and target controller"
- id: WR-03
severity: warning
disposition: open
title: "Create, update and delete are not gated by the compiled list and form declarations"
- id: WR-04
severity: warning
disposition: open
title: "A form field that is `required` but limited by `context` makes every create fail"
- id: WR-05
severity: warning
disposition: open
title: "Relation link and unlink ignore the panel's toolbarButtons"
- id: WR-06
severity: warning
disposition: open
title: "A relation list without an explicit `sort` fails when the first column is not sortable"
- id: WR-07
severity: warning
disposition: open
title: "Relation column order depends on a fixed 16-space YAML indentation"
- id: WR-08
severity: warning
disposition: open
title: "List search returns 500 for non-text searchable columns, and the scaffold creates one"
- id: WR-09
severity: warning
disposition: open
title: "Scaffolded admin controllers have no permissions and no record source"
- id: WR-10
severity: warning
disposition: open
title: "Cabana silently reuses any guard already registered under the name \"backend\""
- id: WR-11
severity: warning
disposition: open
title: "Login identifier can resolve to the wrong admin; admin:create does not prevent login/email collisions"
- id: WR-12
severity: warning
disposition: open
title: "The dummy hash cost is fixed at 10 while real hashes use the configured cost (timing oracle)"
- id: WR-13
severity: warning
disposition: open
title: "Admin passwords are passed as command-line flags"
- id: WR-14
severity: warning
disposition: open
title: "Logout cannot revoke a token whose access lifetime has expired but whose refresh window is still open"
- id: WR-15
severity: warning
disposition: open
title: "The editors pivot `granted_by` stores a backend_users id in a frontend-user column"
- id: WR-16
severity: warning
disposition: open
title: "Reflection helpers skip embedded structs and fall back to case-insensitive Go field names"
- id: WR-17
severity: warning
disposition: open
title: "User-level `backend_users.permissions` is ignored, so Winter denies are lost at cutover"
- id: WR-18
severity: warning
disposition: open
title: "The phase gate's zero-test check applies per invocation, not per package"
- id: WR-19
severity: warning
disposition: open
title: "Plugin hooks and scopes query outside the CRUD transaction"
- id: IN-01
severity: info
disposition: open
title: "A no-op relation mutation returns `{}`"
- id: IN-02
severity: info
disposition: open
title: "Relation search does not escape LIKE wildcards"
- id: IN-03
severity: info
disposition: open
title: "`last_page` is inconsistent between the list and relation endpoints"
- id: IN-04
severity: info
disposition: open
title: "Page parsing and the offset computation can overflow"
- id: IN-05
severity: info
disposition: open
title: "Controllers with unroutable IDs are accepted"
- id: IN-06
severity: info
disposition: open
title: "The bulk-delete decoder is looser than the relation decoder"
- id: IN-07
severity: info
disposition: open
title: "Dead dropdown branches and SQL built by string concatenation in the albums controller"
- id: IN-08
severity: info
disposition: open
title: "The password-reset cutoff also rejects logins made within about 1-2 seconds of the reset"
- id: IN-09
severity: info
disposition: open
title: "Album scoping hides database errors as an empty list"
- id: IN-10
severity: info
disposition: open
title: "Read-only GETs take row locks"
- id: IN-11
severity: info
disposition: open
title: "Logout reports success without revoking when no blacklist is configured"
- id: IN-12
severity: info
disposition: open
title: "The scaffold marks a file that must be edited as \"DO NOT EDIT\""
open: 32
total: 32
recorded: 2026-09-27T21:52:17.704Z
---
# Phase 09: Code Review Disposition
| Finding | Severity | Disposition | Source |
|---------|----------|-------------|--------|
| CR-01 | critical | open | - |
| WR-01 | warning | open | - |
| WR-02 | warning | open | - |
| WR-03 | warning | open | - |
| WR-04 | warning | open | - |
| WR-05 | warning | open | - |
| WR-06 | warning | open | - |
| WR-07 | warning | open | - |
| WR-08 | warning | open | - |
| WR-09 | warning | open | - |
| WR-10 | warning | open | - |
| WR-11 | warning | open | - |
| WR-12 | warning | open | - |
| WR-13 | warning | open | - |
| WR-14 | warning | open | - |
| WR-15 | warning | open | - |
| WR-16 | warning | open | - |
| WR-17 | warning | open | - |
| WR-18 | warning | open | - |
| WR-19 | 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 | - |
| IN-10 | info | open | - |
| IN-11 | info | open | - |
| IN-12 | 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.