Repository navigation
Commit ecb7b44
fix(spec): describe CompleteUploadRequest.eTag as stored, not compared (#24695)
Closes #24648
Clause-②: no
## What changes
`CompleteUploadRequestSchema.eTag`
(`packages/spec/src/api/storage.zod.ts`) described itself as `S3 ETag
verification`. No runtime path verifies it. The description now says
what runs:
> ETag the client reports for the uploaded object. Stored on the file
record as sent and not compared with anything: no storage adapter
reports a stored object's ETag. Before committing, the door checks that
the storage backend holds bytes under the file's key and, when the
upload declared a size, that the held size equals it.
Route: amend the describe, per the triage lean and the claim. No shape
change, no new check, no retirement. The key keeps the same type and
optionality.
## Evidence the new sentence is accurate (read on `origin/main`
3a931fc)
- `packages/services/service-storage/src/storage-routes.ts`, `POST
/storage/upload/complete`: the body's `eTag` goes into
`store.updateFile(fileId, { status: 'committed', etag: eTag ?? undefined
})`. It is stored verbatim and never read before that write.
- In the same file, `heldBytesRefusal` (added with PR #24643) runs
before the write. It refuses when `storage.exists(file.key)` is false.
When the row declares a size, it also refuses when
`storage.getInfo(file.key).size` differs from that size. Its own
docblock says the eTag is not compared, because no adapter's `getInfo`
reports the stored object's ETag.
- `StorageFileInfo` (`packages/spec/src/contracts/storage-service.ts`)
has no `etag` member.
## Files
- `packages/spec/src/api/storage.zod.ts`: the describe.
- `content/docs/references/api/storage.mdx`: regenerated by `pnpm
--filter @objectstack/spec check:generated --fix`, which proved only
`check:docs` stale and ran `gen:docs`. Not edited by hand.
- `.changeset/24648-etag-describe.md`: `@objectstack/spec` patch.
No test pins the old sentence. The only occurrences of `S3 ETag
verification` were the schema and the generated reference page. The key
is not in any `packages/spec/liveness/*.json` ledger. The one hit in
`qa.json` is the substring inside `parseTagsFlag`. No other open PR
touches `storage.zod.ts` or `references/api/storage.mdx`; I read the
file lists of all open PRs before opening this one.
## Verification (head 57b0e5a, after merging origin/main)
- `pnpm --filter @objectstack/spec build`: exit 0.
- `pnpm --filter @objectstack/spec typecheck`: exit 0, including the
`check:test-typecheck` layer.
- `pnpm --filter @objectstack/spec test`: 702 files passed, 21349 tests
passed, 1 todo.
- `pnpm --filter @objectstack/spec check:generated`: red before the
regeneration (1 of 14 stale: `content/docs/references/**`). Green after
`--fix`.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: derived 104 commands. All 104 ran. 103 exit
0 (6 of them were re-run after building their declared prerequisites:
`@objectstack/lint` and its closure, `@objectstack/formula`,
`@objectstack/client-react`, `@objectstack/objectql`).
- NOT MEASURED: `pnpm check:dual-build-cjs-loads`. Reason: it needs a
whole-workspace `pnpm build` (29 or more packages have no `dist/`), and
that build does not fit the local budget. The diff changes one describe
string and no package entry point. Declared to CI.
## Acceptance notes
- Enforcing the eTag would be a contract addition: an `etag` on
`StorageFileInfo`, the S3 adapter reporting `HeadObject`'s `ETag`, and a
compare at the commit door. Retiring the key would be a protocol change.
Both are left out, per triage.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 41edf73 commit ecb7b44
3 files changed
Lines changed: 12 additions & 2 deletions
File tree
- .changeset
- content/docs/references/api
- packages/spec/src/api
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
77 | 82 | | |
78 | 83 | | |
79 | 84 | | |
| |||
0 commit comments