Uh oh!
There was an error while loading. Please reload this page.
docs(qa-checklist): attachments-storage maintenance — totalSize step fix, ADR-0104 D3 receipt clause, and the scratch authz fixture landed permanently - #7716
Merged
huangyiirene merged 2 commits intoAug 11, 2026
Conversation
…ceipt clause against ADR-0104 D3 Two checklist-maintenance edits falling out of the attachments-storage QA run (#7635), both in docs/qa/platform-checklist/areas/attachments-storage.json. upload-session-abort (#7671) — the chunked-init step told the runner to POST `size`. The route destructures `totalSize` and answers 400 INVALID_REQUEST without it (storage-routes.ts:274-276), so a runner following the old text could not open a session at all. The step now names `totalSize` and the 5 MiB `chunkSize` floor (Math.max(reqChunkSize ?? 5242880, 5242880), line 280), which silently rewrites totalChunks when a caller asks for less. Clause 4's failed/expired enforce-or-remove finding from the same run is NOT touched here — it is owned by #7667. inline-grid-receipt-cells (#7669) — the run scored clause 3 `partial` against a product that is correct. The clause demanded a resolved stored-file object with receipt.name and an absolute http(s) URL; under ADR-0104 D3 the STORED form is the bare opaque sys_file id and the resolved {id, name, size, mimeType, url} shape is the read/expand form whose url is "derived, never stored". The clause now asserts the opaque id plus the field-ownership stamp (ref_object/ref_id/ref_field/acl) that proves the reference is managed rather than a placeholder; title, step text and source follow, and a negative pins the drift so a future run does not re-score the shipped shape as a defect. Both items bump revision with a history entry per README.md lifecycle. check:platform-checklist carries only the pre-existing `qa: UNCLASSIFIED` red (#7347), unchanged by these edits.
…s a permanent, replayable recipe Fixes the gap that would force blocked(fixture) on this area's entire authz core every run: stock showcase has no private files-enabled parent — its only `enable.files` object is showcase_project, which is public_read_write AND readable through the showcase `everyone` baseline. Run #7635 closed that at runtime, touching no repo file, and scored the items instead of blocking them. This lands that provisioning permanently, checklist-side. New AREA-LEVEL `fixtures` block on the area document, carrying one recipe (`qa-scratch-authz`) as an ordered call sequence a runner can replay literally: 1. POST /api/v1/packages — scratch package 2. PUT /meta/objects/qa_vault?package=… — private + enable.files 3. PUT /meta/objects/qa_shared?package=… — public_read + enable.files 4. PUT /meta/objects/qa_nofiles?package=… — no files (FILES_DISABLED probe) 5. two fresh sign-ups, sys_user ids resolved system-side 6. sys_user_permission_set bindings: A read-not-edit, B baseline-only Every call is grounded at file:line rather than transcribed from the run narrative: the install body shape is pinned in client.test.ts:2144-2166; `sharingModel`'s enum and `enable.files`' default-false live at object.zod.ts:1827 and :281; `?package=` is read as query.package and threaded to saveMetaItem at runtime/src/domains/meta.ts:262,319; the PUT is manage_metadata-gated per ADR-0066 D1. Two honest knownGaps ride along — the SDK's meta.saveItem does not send `?package=` (so steps 2-4 must be raw HTTP), and the personas' exact permission-set bodies were never captured by the run, so step 6 is specified by outcome and must be verified rather than trusted. The recipe is written once at area level and referenced by the three consuming items through `fixtures.provisioning.use`, so four items cannot drift into four copies of the same twenty-call sequence. download-authz-both-sides, read-inherits-parent-rls and attach-requires-parent-edit each opt in, restate their stale "not demonstrable on stock seeds" knownGaps as closed-by-recipe with the dogfood pin named as the fallback, and bump revision with history. attach-requires-parent-edit additionally names qa_nofiles as the FILES_DISABLED probe target instead of showcase_account, which is files-disabled only incidentally and would go green for the wrong reason if that ever changed. Checklist-side only, per the card's scope note: no showcase seed code, no coverage.json. check:platform-checklist carries only the pre-existing `qa: UNCLASSIFIED` red (#7347); check:nul-bytes green.
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
This was referenced Aug 11, 2026
huangyiirene
marked this pull request as ready for review
August 11, 2026 12:10
Uh oh!
There was an error while loading. Please reload this page.
huangyiirene
deleted the
claude/issue-7671-7669-7670-attachments-checklist
branch
August 11, 2026 12:25
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#7671
Fixes#7669
Fixes#7670
Three packed checklist-maintenance cards from the
attachments-storageQA run (#7635). All three land in one file —docs/qa/platform-checklist/areas/attachments-storage.json— which is why they were packed into one branch and one PR. Docs-only: no product code, no showcase seed code, nocoverage.json.Per-card ledger
upload-session-abort· step 1POST /upload/chunked { filename, mimeType, size, chunkSize }…{ filename, mimeType, totalSize, chunkSize }+ the 5 MiBchunkSizefloor spelled out, andstorage-routes.ts:274-281added tosourceinline-grid-receipt-cells· acceptance clause 3 (0-indexed, the batch-payload clause)receipt.name… an http(s) url"sys_fileid, asserted together with the field-ownership stamp (ref_object/ref_id/ref_field/acl) that proves the reference is managed. Title, step text, a new negative, andsource(ADR +storage-routes.ts) followfixturesblock +fixtures.provisioningon 3 itemsqa_vault/qa_shared/qa_nofiles+ two-persona provisioning existed only as prose in run #7635; three items carried standing "not demonstrable on stock seeds" gapsqa-scratch-authzrecipe (6 ordered calls, each grounded at file:line), referenced by the three consuming items; their knownGaps restated as closed-by-recipe with the dogfood pin named as fallbackdiff --stat: 1 file changed, 109 insertions(+), 21 deletions(-) — one file, 1:1 with the scope above.#7671 — the step text was unrunnable, not merely imprecise
The chunked-init route destructures
totalSizeand answers400 INVALID_REQUESTwithout it, so a runner following the old step could not open a session at all:The 5 MiB floor is recorded in the same breath because it silently rewrites
totalChunkswhen a caller asks for less — a runner computing chunk counts client-side would otherwise disagree with the server for reasons the checklist never mentioned.⛔ Clause 4's
failed/expiredenforce-or-remove finding from the same run is not touched here — it belongs to #7667, which is not in this pack. Likewise #7668's stale-@objectstack/corepin problem onattach-requires-parent-editclause 3.#7669 — the checklist was wrong, the product is right
Run #7635 scored this clause
partialagainst correct behaviour. Under ADR-0104 D3 (docs/adr/0104-field-runtime-value-shape-contract.md:211-224) the stored form of a file field is an opaquefileIdstring — "the inline{url, name, size}blob is retired from the write path" — while the resolved{ id, name, size, mimeType, url }shape is the expanded form produced at read time, whoseurlis "derived, never stored".storage-routes.ts:250-252documents the same id as "the value a file field stores as a reference (ADR-0104 D3)".So the clause was asserting a contract the ADR had already retired. It now asserts what the run actually proved and what D3 actually requires. A new negative pins the drift itself, so a future run does not re-score the shipped shape as a defect:
D3's parent-derived read gating is cross-referenced to
download-authz-both-sides(which already carries the non-entitled personas) rather than duplicated here — the same "cross-reference, do not duplicate" discipline this item already applies to the ADR-0059 form-side guard.#7670 — landed checklist-side, as the card scoped it
The card's ⛔ clause said to stop and fork-report if the right landing turned out to be showcase seed code. It did not: the run's own provisioning was pure runtime HTTP against a live app, so it lands as a replayable recipe, and no repo code is touched. (A seeded private files-enabled showcase object would be the better long-term fix and is recorded as such in
read-inherits-parent-rls' knownGaps — it is a separate, product-side change, not this card.)The recipe is written once at area level and referenced by items via
fixtures.provisioning.use, because three (soon four) items need the identical twenty-call sequence and inlining it per item is how ledger entries drift apart. Every call carries its ownsourcecitation:{ manifest, enableOnInstall?, overwrite? }— pinned inpackages/client/src/client.test.ts:2144-2166;POST /api/v1/packagesis the dispatcher install route (rest-route-ledger.ts:312)sharingModeltop-level enum —packages/spec/src/data/object.zod.ts:1827(ADR-0090 D4)enable.filesdefault-false opt-in —object.zod.ts:281([objectui/framework] enable.files: generic Attachments related-list (Salesforce Notes & Attachments parity) #2727)?package=read asquery.package, threaded tosaveMetaItem—packages/runtime/src/domains/meta.ts:262,319PUTismanage_metadata-gated (ADR-0066 D1, finding: after ADR-0106, a restricted caller's GET → edit → PUT of an object schema DELETES the fields that were masked out of their read #6603) — a bare session is not enough, so that is a statedrequiresTwo gaps are recorded honestly rather than papered over: the SDK's
meta.saveItemdoes not send?package=(packages/client/src/index.ts:701-707), so steps 2-4 must be raw HTTP or the objects land outside the package; and the two personas' exact permission-set payloads were never captured by run #7635, so step 6 is specified by outcome (read-not-edit for A, baseline-only for B) with an instruction to verify the split independently before scoring any storage clause.Gates
pnpm check:platform-checklistcoverage.json · qa: UNCLASSIFIED(#7347). Identical onorigin/mainbefore any edit; recorded, not chased. No new problem introduced: revision/history pairing, id shape and clause/oracle structure all validate across the 5 revised items.JSON.parsegreen; 8 items, allprovisioning.usevalues resolve to theqa-scratch-authzkeyhistoryentry per README.md lifecyclepnpm check:nul-bytesOK (scanned 7104 text files … no raw ASCII control bytes); plus a targeted control-byte self-scan of the edited file (clean)Docs-only, releases nothing → no changeset;
skip-changesetapplies.Note for the PM (not blocking)
The area-level
fixturesblock is a new shape for this ledger:README.md's "Item anatomy" documentsfixturesonly per-item, and the validator is presence-level so it neither blesses nor rejects the area-level form. It is self-documented by a$commentinside the block, but the convention arguably belongs inREADME.mdalongside the item anatomy. That file was outside this pack's declared surface, so it was deliberately left alone rather than edited on the side.Generated by Claude Code