Просмотр исходного кода

Docs: SPEC §9 + §13 — backfill v0.22.0..v0.25.0 + R01-N19..N34 era

Closes the older staleness flagged in 07772b3: §13 jumped from
14b1cfd straight to ef9b9b8, skipping 45 commits, and §9 had no
entries for R01-N22..N28 (security fixes), R01-N29/N30/N32/N33/N34
(accepted-by-design closures), v0.22.0 (Apache 2.0 + CHANGELOG +
SPDX headers), v0.23.0 (OIDC_ENABLED kill-switch + prod-bootstrap
guard + Runtime-panel refresh), v0.24.0 (2-pane hamburger popup +
non-admin task actions), v0.25.0 (welcome/login logo polish + Status
column drop + audit-log local time + beamer header center), the
present-view brand logo / sprint switcher / htmx CSP indicator fix,
and the REVIEW_02 audit landing.

§9 entries follow the brief style — 3-10 lines each, SHA + one-
sentence summary, intentionally lighter than the detailed R01-N12
/ R01-N19 / R01-N20 / R01-N21 / R02-* entries. Future readers
should reach for the commit messages or CHANGELOG.md for detail;
§9 is the index, not the manual. Inserted in chronological order
between the "New sprint form" entry and R02-N02 — that matches the
shipping timeline (May 7 evening through May 8/9 for the REVIEW_02
audit landing).

§13 picks up all 45 commits in reverse-chrono order between the
existing 14b1cfd and ef9b9b8 lines, including the cebaf0b doc
commit that closed R01-N16/N17/N18 (which marked the end of the
prior backfill epoch — its own SHA was missing from §13 because
the commit itself was the last one to refresh the list).

This commit's own SHA is, as is the convention here, not in §13;
it can be backfilled by a future doc-refresh commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ClaudePriv@chiappa.zhdk.ch 6 часов назад
Родитель
Сommit
9e6945867d
1 измененных файлов с 144 добавлено и 0 удалено
  1. 144 0
      SPEC.md

+ 144 - 0
SPEC.md

@@ -1633,6 +1633,105 @@ OIDC kill-switch (`OIDC_ENABLED=false`):
       same way the sprints table on `/` does — also mirrored on
       JS-built rows in `sprint-planner.js::buildTaskRow`.
 
+- [x] **R01-N22 — migrations move to deploy time + refuse-to-serve
+      safety net** (`43b2fc9` / `114de03`). `bin/docker-entrypoint.sh`
+      now runs `php bin/migrate.php` before Apache binds the port; the
+      request path only checks for pending migrations and 503s on
+      mismatch (no auto-migration mid-request). Closes the "fatal
+      error during migration leaves the schema partially applied"
+      class of failure. Fix from `doc/REVIEW_01.md`.
+
+- [x] **R01-N23 — soft erasure via `users.tombstoned_at`**
+      (`22a3840` / `3853dda`). Privacy-request flow: a TOMBSTONE
+      action on `users` zeroes identifying columns and stamps
+      `tombstoned_at`; the row stays for FK integrity so audit
+      history doesn't break. Fix from `doc/REVIEW_01.md`.
+
+- [x] **R01-N24 — JSON body cap (1 MiB) + batch cap (5000 items)**
+      (`821122d` / `abe9595`). All JSON endpoints reject oversized
+      bodies and oversized arrays before any parse/loop work, so a
+      runaway or malicious client can't OOM PHP or hold a worker.
+      Fix from `doc/REVIEW_01.md`.
+
+- [x] **R01-N25 + R01-N26 + R01-N27 — `X-Permitted-Cross-Domain-Policies`,
+      one-shot delete-chip flash, backgrounded session GC**
+      (`f6ce13f` / `1f11117` / `32d03fc` / `b706a17`). Three LOW-severity
+      fixes batched: response header pinned to `none`; the post-delete
+      success chip is now a one-shot session flash (no replay on
+      refresh); the entrypoint runs a backgrounded session-file GC
+      loop so stale `sess_*` files don't pile up under low traffic.
+      Fixes from `doc/REVIEW_01.md`.
+
+- [x] **R01-N28 — drop dead `$changed[]` accumulator**
+      (`216c15d` / `8e5a8d1`). `SettingsController::update` built a
+      `$changed[]` list it never read; deleted along with surrounding
+      bookkeeping. Fix from `doc/REVIEW_01.md`.
+
+- [x] **R01-N29 / R01-N30 / R01-N32 / R01-N33 / R01-N34 —
+      accepted-by-design** (`8e5a8d1` / `1edc853`). Five findings
+      closed without code changes after audit-side concurrence: N29
+      (`Migrator::file_get_contents` — migrations are committed code
+      reviewed in PRs and now run at deploy time post-N22); N30
+      (import_upload colour-mapping — only emitter is admin-gated
+      `GET /sprints/import`); N32 (sprint delete confirmation —
+      server-side `confirm_name` check is authoritative,
+      `data-confirm-name` is JS UX); N33 (`data-csrf` exposure —
+      standard fetch/htmx pattern, token rotation + strict CSP keep
+      it safe); N34 (migrations/ on disk — committed code,
+      deploy-time apply per N22). Closes `doc/REVIEW_01.md` with no
+      open findings.
+
+- [x] **Release v0.22.0** (`7449fb2`). Apache 2.0 license,
+      `CHANGELOG.md`, and per-file SPDX headers. No behavioural
+      change.
+
+- [x] **OIDC kill-switch + prod-bootstrap guard + Runtime-panel
+      refresh — Release v0.23.0** (`60aeb55` / `56e6526` / `5f6febf`
+      / `3f014af`). New `OIDC_ENABLED=false` env var (default on)
+      hard-disables OIDC and routes all sign-ins through
+      `LOCAL_ADMIN_*` — meant for dev / testing / on-prem deploys.
+      The bootstrap path refuses to start in prod when ENTRA vars
+      look unconfigured (loud over silent). The admin-only Runtime
+      panel on `/` reads the OIDC enabled/disabled state and
+      surfaces app version + creator from `App\Meta::VERSION` /
+      `::CREATOR`.
+
+- [x] **2-pane task hamburger popup + non-admin actions —
+      Release v0.24.0** (`8c72e7a` / `31506c6` / `2a20f35` /
+      `970ebe4`). Per-task hamburger menu becomes a 2-pane popup
+      (action list left, sprint flyout right for move/copy).
+      Non-admin viewers get a reduced action set (info popover, no
+      destructive ops). Task title row gains inline reference icons
+      + a per-row info popover. The beamer view keeps the hamburger
+      trigger visible so the popup works there too.
+
+- [x] **Welcome/login logo polish + Status column drop —
+      Release v0.25.0** (`cdb1249` / `8b2bd48` / `90b10d5` /
+      `5f28590` / `d8e7f89` / `b8a6603` / `5cbecee`). Five SVG logo
+      concepts shipped under `doc/`; concept #3 (cycle, with radial
+      indigo glow) wired in as the page-header brand mark + SVG
+      favicon. Welcome / local-login flows centre the logo above the
+      card at 144 px. The Home sprint table drops its Status column
+      (derivable from start/end dates, no audit signal lost).
+      Audit-log "When" flips to viewer-local time
+      (`dd.mm.YYYY HH:mm:ss`); the beamer view centres vertical
+      worker-name headers in their cells (`964a2f5` / `d2e570e`).
+
+- [x] **Present view: brand logo + sprint switcher + htmx CSP fix**
+      (`f10a1dd` / `4ae4db6` / `1dba877`). Beamer view picks up the
+      header brand mark; a sprint-switcher dropdown sits next to
+      Close so the operator can hop to a neighbouring sprint without
+      visiting `/`. Side issue: htmx was injecting an inline
+      indicator `<style>` that would have required relaxing the
+      strict CSP — fixed by disabling the indicator-style injection
+      so `style-src 'self'` stays.
+
+- [x] **REVIEW_02 audit landing** (`937fbfd` / `dab0e66`). Initial
+      simplification + maintainability audit at `doc/REVIEW_02.md`,
+      paired with a workflow note requiring SPEC.md to be read
+      before any finding. R02-N01..N03 (above) are the resulting
+      fixes.
+
 - [x] **R02-N02 — Task-row markup unified between server and JS**
       (`d5a09ff`). `sprint-planner.js::buildTaskRow` hand-rolled
       ~150 lines of `<tr>` construction to mirror what
@@ -1918,6 +2017,51 @@ a004c1a Build: split Dockerfile into 4 targets + dev compose overlay + Makefile
 57f4143 Fix R02-N03: extract SessionGuard::requireAdminForm + drop SprintController::gateJsonAdmin
 22d5e2a Docs: mark R02-N01 fixed, refresh SPEC §5 / §9 / §13
 14b1cfd Fix R02-N01: drop JS-side capacity arithmetic, server is authoritative
+dab0e66 doc/REVIEW_02.md: require reading SPEC.md before any finding
+a0ccd12 Docs: mark R02-N02 fixed-in-d5a09ff
+d5a09ff Fix R02-N02: clone <template data-task-row-template> instead of mirroring _task_list in JS
+937fbfd doc/REVIEW_02.md: simplification + maintainability audit
+1dba877 Present view: sprint switcher dropdown next to Close
+4ae4db6 CSP: stop htmx from injecting its inline indicator <style>
+f10a1dd Present view: add brand logo to the header
+5cbecee Release v0.25.0: welcome/login logo polish + drop Status column
+b8a6603 Home: drop the Status column from the sprint table
+d8e7f89 Welcome/login: move logo inside the card and triple its size (48 → 144)
+5f28590 Welcome: match local-login layout with centered logo above the box
+90b10d5 Brand: cycle logo in the page header + SVG favicon
+8b2bd48 Logo 3 (cycle): add a radial indigo glow inside the loop
+cdb1249 Doc: add 5 SVG logo concepts and a light/dark preview page
+d2e570e Beamer: horizontally center vertical worker-name headers in their cells
+964a2f5 Audit log: render When in viewer's local time, dd.mm.YYYY HH:mm:ss
+970ebe4 Release v0.24.0: 2-pane task hamburger popup; non-admin task actions
+2a20f35 Beamer: keep the task hamburger trigger visible
+31506c6 Hamburger popup: 2-pane layout, sprint flyout, non-admin actions
+8c72e7a Task title row: inline reference icons + per-row info popover
+3f014af Release v0.23.0: OIDC kill-switch + prod-bootstrap guard + Runtime-panel refresh
+5f6febf Runtime panel on / shows app version + creator; OIDC reads enabled/disabled
+56e6526 Docs: CHANGELOG entry for OIDC_ENABLED kill-switch + prod-bootstrap guard
+60aeb55 Add OIDC_ENABLED kill-switch for dev / testing on local-admin only
+7449fb2 Release v0.22.0: Apache 2.0 license + CHANGELOG + per-file headers
+1edc853 Docs: mark R01-N32/N33/N34 accepted-by-design
+8e5a8d1 Docs: mark R01-N28 fixed-in-216c15d; R01-N29/N30 accepted-by-design
+216c15d Fix R01-N28: drop dead $changed[] in SettingsController::update
+b706a17 Docs: mark R01-N25/N26/N27 fixed in f6ce13f/1f11117/32d03fc
+32d03fc Fix R01-N27: backgrounded session-file GC loop in entrypoint
+1f11117 Fix R01-N26: one-shot session flash for post-delete chip
+f6ce13f Fix R01-N25: X-Permitted-Cross-Domain-Policies: none
+abe9595 Docs: mark R01-N24 fixed in 821122d
+821122d Fix R01-N24: 1 MiB body cap + 5000-item batch cap on JSON endpoints
+3853dda Docs: mark R01-N23 fixed in 22a3840
+22a3840 Fix R01-N23: users.tombstoned_at — soft erasure for privacy requests
+114de03 Docs: mark R01-N22 fixed in 43b2fc9
+43b2fc9 Fix R01-N22: move migrations to deploy time, refuse-to-serve safety net
+f3ba328 Docs: mark R01-N21 fixed in 00bcf73
+00bcf73 Fix R01-N21: pin Twig auto-escape with regression tests
+2ea4b0b Docs: mark R01-N20 fixed in f1aa924
+f1aa924 Fix R01-N20: Response::redirect rejects non-path locations
+99f9850 Docs: mark R01-N19 fixed in f59f368
+f59f368 Fix R01-N19: CSP report-uri + audit endpoint
+cebaf0b Docs: mark R01-N16 / R01-N17 / R01-N18 closed, refresh SPEC §3 / §9 / §11 / §13
 ef9b9b8 Fix R01-N16, doc R01-N17: composer-audit helper + admin-manual cadence note
 a0b717e Fix R01-N18: trust OIDC email only when issuer hasn't marked it unverified
 50f9bd2 Docs: mark R01-N09 / R01-N13 / R01-N14 fixed, refresh SPEC §3 / §9 / §11 / §13