Repository navigation
Commit d1ea236
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi992ENsi4QDy53qYTKqkVjaX)_
Fixes #25839
Clause-②: no
Metadata-protocol: none
Part of the 18.2.0 release sweep, wave anchor #25807. This applies all
18 checklist-accuracy findings that Tier 1 record #25815
(`release-18.2.0-tier1`, at `6679644a`) logged against
`docs/qa/platform-checklist/areas/attachments-storage.json`.
Only checklist text changes. 10 items each take one `revision` bump and
one `history` row. Each row cites #25815 and the finding. There is no
product code, test, pin, `RUNNER.md` or changeset change.
`attachments-storage.field-accept-maxsize-server-enforced` is untouched.
- Base `f6c61932`. The file has had no commit on `main` since the card
was filed (last change `0f1eeeee`, 2026-10-22). Every pin named below
was re-read on `main`. None of the read paths changed between `9753d163`
and `f6c61932`.
- A scripted span editor made every edit and never re-serialises the
file. It re-parses the result and asserts three things: the new document
equals the old one with the declared ops applied; each changed item has
revision +1 and exactly one appended row; and the 1 item it did not
touch is byte-identical.
- All 18 lines were stale text. None describes a product defect, so no
card is owed.
## How RUNNER rule 6 was applied
A pin scores only the layer it drives. Each edit names the layer from
the pin's own harness: route-handler unit (a registered `RouteHandler`
with a hand-built request and response, or a mock HTTP server), engine
(ObjectQL in-process), or HTTP (a booted stack). Where a pin stops above
a clause's oracle layer, the item now says the pin scores that clause
`partial` and names the leg to drive by hand. Where a ref claimed a
whole item, it is scoped per clause.
## Changes
| finding (#25815) | item | field | what changed | pin read (layer) |
|:--|:--|:--|:--|:--|
| a2 uploader leg not driven; n1 no re-read after a refused attach |
`attach-requires-parent-edit` | `automated.ref` | clause 2 narrowed to
the three delete answers pinned. The uploader-without-parent-edit leg
and negative[1] for attaches are named as hand-driven | permission
matrix: uploaders are the admin and memberA on public_read_write
`att_case`. Cases (b), (item 3) and (#2727) never re-read
`sys_attachment` (HTTP) |
| a1 literal `[1]` vs pin `[0]` | `chunked-upload-integrity` |
`acceptance[1].verify` | the literal belongs to steps[0]'s fixture. A
pin-scored verdict records the pin's `[0]` |
`storage-chunked-resume-integrity.dogfood.test.ts` 'REFUSED: …'
withholds chunk 0 of two (HTTP) |
| a2 owner case is a parent reader; url not followed |
`download-authz-both-sides` | `automated.ref` | clause 2 scoped to the
envelope. The uploader-bypass and bytes legs are named as hand-driven |
permission matrix '(e-read)' (HTTP) |
| a2 upload requests not captured | `inline-grid-receipt-cells` |
`acceptance[2].verify` | says the pin asserts only the chip |
`grid-file-upload.spec.ts` (browser, live backend) |
| a3 no sys_file read, no batch success | `inline-grid-receipt-cells` |
`acceptance[3].verify` | names both legs as hand-driven (steps[7]) |
same spec |
| n1 a `data:` URL passes the string checks |
`inline-grid-receipt-cells` | `negative[1]` | a pin-scored verdict rests
on the follow-up storage GET leg | same spec |
| a1 sweep in-process; failed byte delete unit-only |
`orphan-tombstone-reap` | `acceptance[1].verify` | names the layers. The
failed-delete leg scores partial unless staged | permission matrix
lifecycle block (`lifecycle.sweep()` in-process);
`attachment-lifecycle.test.ts` (fake engine, mock logger) |
| bare ref | `presigned-upload-roundtrip` | `automated.ref` | scoped to
acceptance[0]'s committed owner_id, acceptance[2]'s envelope and
acceptance[4]'s 401. The rest is named as hand-driven | permission
matrix; the `uploadFile` helper asserts statuses only (HTTP) |
| a4 no sys_file count | `presigned-upload-roundtrip` | `automated.ref`
| the no-row half is named as hand-driven | '(e) anonymous presigned
upload' (HTTP) |
| a3 probe half and warning text at unit | `read-inherits-parent-rls` |
`acceptance[3].verify` | names both pins' layers. The warning is
asserted by fragment at unit only |
`attachment-read-leaf.integration.test.ts` (engine + SQL driver, silent
logger); `attachment-read-leaf.test.ts` (stand-in engine, recording
logger) |
| a2 live-holder half unit; live legs unpinned |
`sys-file-status-pipeline` | `acceptance[2].verify`, `automated.ref` |
unit half scores partial. The holder-less 404 and post-re-attach 200 go
to steps[6]/[7]. The ref says acceptance[2] where it said 'clause 3' |
`tombstone-download-live-reference.test.ts` (mock HTTP server, fake
engine) |
| a1 pending 404 has no HTTP pin | `sys-file-status-pipeline` |
`acceptance[1].verify` | the unit case never scores the api clause;
drive steps[1] | same file, 'leaves `pending` refused' |
| a1–a3 handler-level; restart at kernel |
`upload-limits-scope-and-ownership` | `automated.ref` | each pin's layer
named. acceptance[1]–[3] score partial and are hand-driven |
`storage-limits`, `upload-scope-vocabulary`, `upload-door-ownership`
(route-handler unit; the settings save inside one `ObjectKernel`) |
| a5 hydrate pins engine-level | `upload-limits-scope-and-ownership` |
`automated.ref` | acceptance[5] is hand-driven (steps[4]) | both
`engine-file-hydrate-*` (engine) |
| a2/a3/n0/n1 unit pins not in ref | `upload-session-abort` |
`automated.ref` | adds the `createUploadSessionReapGuard` block, per
clause | `attachment-lifecycle.test.ts` (unit, stub adapters; the veto
case asserts a warn call, not its text) |
| a5 410 unit pin not in ref | `upload-session-abort` | `automated.ref`
| adds the 'terminal upload-session statuses (#7667)' cases, scored at
their layer only | `storage-routes.test.ts` (route-handler unit) |
| bare ref scores a1 alone | `upload-session-abort` | `automated.ref` |
the matrix file is scoped to acceptance[1] | permission matrix '(item 4
+ multipart-abort guard)' |
The first row carries two card lines (a2 and n1), so 17 rows cover all
18 card lines, and every one is applied.
## Retired objectui pin wording
#26035 left the retired pin wording in the area JSON to these cards.
This file has no hits for `objectui:(build|refresh|bump|clean)`,
`build-console.sh`, `.objectui-sha` or `objectuiPin`, either before or
after this change. Pin-era statements in two items this PR edits are
corrected.
- `download-authz-both-sides`: the ref said "a console bundle this repo
does not build". It now says the console is built from `ui/` by `pnpm
console:build` into the gitignored `packages/console/dist`.
`source[3]`'s `objectui packages/app-shell/...` path now reads
`ui/packages/app-shell/src/views/RecordAttachmentsPanel.tsx`.
- `inline-grid-receipt-cells`: `knownGaps[0]` said "AUTOMATION IS PINNED
IN THE objectui REPO, NOT HERE", with the spec runnable only "in an
objectui checkout". Since the objectui import, the spec is
`ui/e2e/live/grid-file-upload.spec.ts` in this tree. `automated.ref` and
`source[1]` now name that path. `knownGaps[0]` now says how to run it
from `ui/` (`pnpm test:e2e:live`, with a backend on port 3000 and the
console dev server on port 5180), and it keeps the rule that an unrun
pin is a claim, not evidence. This change rides on the item's one
revision bump, and its history row says so. Earlier history rows are
records and are left as written.
## Acceptance notes
- `RUNNER.md`'s standing fact on objectui-pinned automation ("Some items
carry an `automated.ref` that lives ENTIRELY in the `objectui` repo")
still says this repository holds none of those specs and builds no
console bundle. Both are stale since the objectui import. By that
entry's own rule, `inline-grid-receipt-cells` has now left the set,
because its ref names a path that exists here. `RUNNER.md` is outside
this card's file surface. #26101 kept its own items' objectui-only
framing in step with that entry, so the two cards now differ on this
point. Carrier: the devx seat (#25850 / #26035).
## Gates (head `75c55dcc`)
- `pnpm check:platform-checklist` exits 0: `16 areas, 329 items (324
active, 1 planned)`.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derives 13 families, and all 13 were run.
Each exited 0. `check:doc-formula-expressions` first exited 3 on an
unbuilt prerequisite, which measured nothing. After `turbo run build
--filter=@objectstack/formula --filter=@objectstack/lint` under the
verify lock, it exited 0. `--ran` reconciliation: 13 derived, 13 run, 0
NOT-MEASURED (a derived zero: every row records an exit code).
- `skip-changeset`: the only change is under `docs/qa/`, which no
package publishes.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VZNpUpuT1YtHY5bfFn3xN8)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 40bba68 commit d1ea236
1 file changed
Lines changed: 91 additions & 31 deletions
0 commit comments