- 13-SECURITY-REVIEW.md: every T-13 threat with its strictest severity and
disposition, protecting code, named tests and the 31 removal checks,
all failing as required; the CSV export logging fix and the Phase 9
route inventory update
- 13-VALIDATION.md: per-task map 13-01-T1 to 13-06-T3 all green, the gate
command, coverage per package, Wave 0 ticked, status validated
- REQUIREMENTS.md: API-03, API-04, API-06 and API-07 complete
- deferred-items.md: 13-06 findings (process-wide job dispatcher, scalar
mapping body, tmpfs quota)
- scripts/check-phase13.sh with --self-test, --go, --parity, --named,
--removal, --coverage, --evidence and --all, modelled on check-phase12
- Parity reads the replay's own coverage line: 157 ported and passing,
0 failing, 14 recorded and not ported; every TestFonotekaNuxtFlows
subtest, the three wishlist goldens, docs checks and the corpus scan
- Coverage floors of 80% for surf, conga, lagoon, tide and the four
application packages, the user plugin's classes and every function of
controllers/registration.go, and the controllers package's pre-phase value
- 31 anchor-exact removal checks with cmp restore, dirty-file refusal and
a signal-safe restore; FORCE_COLOR unset by the gate itself
- TestOverlapConstraintFallsThrough: an earlier member that matches the
literals but not its Where constraint must let a later member answer;
the routes.php pairs cannot show this, since each member's own handler
re-checks its constraints and the pairs differ in their literals (T-13-23)
- surf: a transitive three-route family, HEAD and sorted Allow on family
paths, a family across two plugins with per-member middleware, refused
trailing-slash and multi-segment shapes
- conga: refusal messages name kind and queue, a configured queue counts
as served, a delayed unregistered dispatch waits scheduled
- lagoon: prohibited under a wildcard, on a dotted path and after bail
- tide: quoted, RFC 5987 and multi-date download names; a captured id
beside a masked notification id
- Phase 13 repos name sm-user-plugin and summercms.go
- wishlist match/apply-release, the credential /test routes and the CSV
Discogs pick move to Phase 14 (D-01, D-02); notifications drop prune,
a Phase 14 console command (D-06); CSV and digest job bodies are Phase 14
- API-03, API-04, API-06, INTG-01 and INTG-02 follow; statuses untouched
- lagoon.ValidateRequest supports Laravel 9 prohibited (!required, not
implicit); with no catalog line its message is validation.prohibited
- tide compares Content-Disposition with real calendar dates masked on both
sides; a different name, an invalid date or a one-sided date still diffs
- tide.NormalizePublications masks a Carbon +00:00 $.data.payload.created_at
and an uncaptured positive integer $.data.payload.id as {{id}}
- the album-date test's outside-album sibling moves off payload.created_at,
which now has its own mask
- READMEs and docs describe the rule and both masks
- a kind no plugin registered always inserts through the insert-only River
client, so Dispatch and Enqueue no longer fail River's unknown-kind check
while the in-process worker runs
- while a worker runs, such a kind must name a queue no worker serves;
an empty queue, default, scheduled, a configured queue or a registered
job's queue is ErrUnregisteredKindQueue and nothing is written
- README and docs/services/jobs.md describe jobs whose worker ships later
- compile groups routes ServeMux refuses side by side into overlap families
and registers each under one generated method-less pattern
- the family handler tries members in registration order on literals and
Where constraints, sets their path values and runs their own wrapped chain
- no match answers the bare 404; a method mismatch answers ServeMux's 405
and Allow for the same table without the overlap
- unsupported shapes (same shape, {name...}, shadowing route) fail at boot
- README and docs/services/routing.md describe the behaviour
Browser checks on sm-bm-app passed: datetime popover time, discard confirm, and list date formatting. Phase 12.2 UAT is complete.
Co-authored-by: Cursor <cursoragent@cursor.com>
BM UAT on v0.1.1 showed a date-only calendar for datetime fields, a stuck discard dialog, and raw ISO timestamps when columns.yaml omitted type. The picker now edits time in the popover, confirm sits above the calendar, and omitted time.Time / Date / TimeOfDay columns compile as datetime / date / time.
Co-authored-by: Cursor <cursoragent@cursor.com>
Close the seven code-review findings in disposition and leave the phase pending on browser checks plus the v0.1.1 tag.
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep form save behind in-flight uploads, make retries idempotent via X-Upload-Id, cap remaining JSON bodies, and surface pending pivot type errors instead of zeroing them.
Co-authored-by: Cursor <cursoragent@cursor.com>
- 12.2-SECURITY-REVIEW.md maps T-12.2-01 to T-12.2-36 and the supply
chain rows to the controls as built and their passing tests, with the
parent-predicate removal check and the residual risks
- 12.2-VALIDATION.md: per-task map with real task ids, all green,
nyquist_compliant and wave_0_complete set
- deferred-items.md: out-of-scope findings for follow-up
- sessionKey, dateFormat, FileuploadField (protected thumbnails and
keyboard reorder backstops), RelationChildModal, RelationPivotModal,
RelationManager row actions and create-screen deferral, date and time
list cells; typed deferred relation-schema and file-list fixtures
- scripts/check-phase12.2.sh: go, security (named tests, refuses missing
or skipped), spa, openapi, dist, docs, hygiene and app stages, a
detector self-test, one PASS or FAIL line per stage under --all
The partial-segment check read only DateField segments, so a time-mode
field (Reka TimeField, data-reka-time-field-segment) with some segments
typed was never flagged. Read both segment attributes. DatepickerField
tests cover both UI-SPEC backstops (Escape focus and disabled days, the
fixed-zone datetime round trip) and the partly filled time case.
- lagoon: Date and TimeOfDay through JSON, text and real DATE/TIME
columns; Fill text fallback without changing earlier conversions;
required on zero dates; deferred_bindings shape, store isolation and
envelope; PurgeDeferred cut-off, after-commit blobs, SKIP LOCKED,
skipped types and the deferred:purge command
- attach: Store limits, extensions, MIME patterns, default lists, key
shape and blob cleanup; IsAllowedImage formats, polyglots, ceiling
- conga and pact: framework purge schedule entry and forged jobs; the
six relation child hook interfaces
- cabana: fileupload and datepicker compile, upload, remove, caption,
reorder and bounds; deferred commit order, rollback, applied-only and
concurrent saves; relation contracts, forms, CRUD, deferral, schema
Six sequential plans: framework gaps, notifications/credentials/onboarding, wishlist, CSV, public views, unit tests and gate. Research open questions marked resolved per the plan-count checkpoint.
- acme.deferred fixture plugin over testdata/deferred (test-only), two
controllers, recording Form and Relation hooks, two admins
- TestRelationChildScope*: every child route answers 404 for another
parent, a hidden parent and another admin's pending child, changes
nothing; undeclared toolbar buttons 403 before SQL; pivot whitelist
- TestProtectedFile*: foreign, pending and public files 404; only jpeg,
png, gif and webp inline; nosniff, no-store and sandbox CSP everywhere
- RelationManager renders create/link/delete/unlink in declared order with
one primary, opens the child modal (update or view form) or the pivot
modal on row click, and deletes selected children behind a busy confirm
- RelationChildModal creates and edits children with its own session key
(X-Child-Session-Key) so uploads and dates work inside it
- RelationPivotModal edits link details; the picker links one record with
its pivot values when the relation has a pivot form
- deferrable managers render on the create screen with owner id 0, the
form's X-Session-Key and the pending note, and mark the form dirty
- the registry resolves RelationManager lazily (child forms close an
import cycle); DataTable gains openable rows and a trailing cell
- relation lang keys in en and pl; rebuilt boardwalk dist
- pin @internationalized/date 3.12.4 as a direct admin dependency (approved)
- dateFormat.ts parses and emits date, datetime (local display, UTC emit,
ignoreTimezone wall clock) and time values without the global Date
- DatepickerField on Reka DatePicker and TimeField with locale segments,
calendar popover, clear button, min/max and yearRange bounds
- list cells of type date and time render the stored string
- datepicker lang keys in en and pl; rebuilt boardwalk dist
- sessionKey.ts: one 32-byte base64url key per form mount, sent only in headers
- api/files.ts: FileRoutes over the record and child file routes, XHR upload with progress, 401 refresh and retry
- FileuploadField and FileCaptionModal per UI-SPEC section 3: dropzone, image grid, rows, per-item states, client pre-checks, reorder, protected previews
- FormView provides FORM_SESSION, counts pending changes as dirty and sends X-Session-Key on create and update
- fileupload lang keys in en and pl, admin-spa docs note, deferred smoke test, rebuilt dist
- record id 0 with X-Session-Key manages deferrable relations: create, link, unlink, delete and pivot edits are held in deferred_bindings
- the record's create save applies relation bindings with the file bindings; an ineligible link is a 422 on the relation-manager field
- child forms upload files through .../records/{child}/files/{field} keyed by X-Child-Session-Key; the child save commits them
- boot refuses a deferrable relation with create whose related model no plugin lists in Models()
- loadChild finds a child with one query carrying the parent predicate; a foreign child is 404
- GET/PUT .../records/{child} and POST .../delete (all or nothing) per relation kind
- hasMany link adopts NULL-key rows and unlink clears the key; pending created children are never candidates
- link accepts pivot values for one id through the pivot.form whitelist; GET/PUT .../pivot/{child}
- Link and Unlink share linkRelated/unlinkRelated for the deferred commit