You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
metadata: the cached /meta item read sends Last-Modified as the time of the read, not of the item, so the header carries no information #31196
Filing gate: ① product defect (an HTTP cache header that states something false), found while fixing #31171 (PR #31195, dev hand-off; the flake's cause). ⛔ Not a claim. Triage sets the grade and the lane.
Reader: the seat that owns packages/metadata-protocol (protocol-search-and-cache.ts) and packages/rest (meta-item-read-routes.ts).
Dedupe (open AND closed): Last-Modified meta → 4 hits, the only related one is #31171 (the flake this causes in a test, fixed in the test only).
reach: every cached GET /api/v1/meta/:type/:name; read from the code on main, observed in queue builds 42383103865 and 42385456389 (two reads of one unchanged item answered Last-Modified one second apart).
class: c · type: Bug
packages/metadata-protocol/src/protocol-search-and-cache.ts ~147 returns lastModified: new Date().toISOString() beside the item's content etag.
packages/rest/src/meta-item-read-routes.ts ~974 renders it as Last-Modified. Two reads of an unchanged item a second apart answer different Last-Modified values with the same ETag.
Expected
Last-Modified is the item's own last change (its stored updated_at / publish time) when the protocol knows it, or the header is omitted when it does not — never the read time. Freshness stays gated by the ETag (no-cache), unchanged.
Acceptance: two reads of one unchanged item answer the same Last-Modified (or none); a publish moves it.
The cached GET /api/v1/meta/:type/:name sends Last-Modified as the time of the read, not the item's own modification time. The header carries no information, and an If-Modified-Since revalidation always answers "modified". ETag revalidation works, so nothing is broken. It is also the cause of the Queue-flake anchor: src/domains/mcp-object-schema-mask.test.ts #31171 flake, which was fixed in the test only.
p3: a false but harmless header. Lane domain:server (metadata-protocol + rest). finding removed, pm:queue.
Claim: PM loop round 1 · 2026-11-07T18:10Z
Session: session_01FEkQ5p9eu5KqN5GP7JZAGe (card thread, dev) · seat session_01FEkQ5o8PE7ZtVjcor51wBZ
Account: os-project-manager
Branch: claude/project-thread-qb6zil
Worktree: objectstack-issue-31196
Domain: domain:server
Seat: domain:server#5
File surface: packages/metadata-protocol/src/protocol-search-and-cache.ts, possibly packages/rest/src/meta-item-read-routes.ts, their tests, root .changeset/; ⛔ packages/spec/**
Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: thread default (order asked medium; the coordinator sets effort only on the maintainer's word)
Clause-②: no — lastModified is already optional in the published http-cache.zod.ts; omitting it or sourcing the item's own time stays inside it
Metadata-protocol: none
Responsibility: packages/metadata-protocol cached item read (objectstack) | ETag revalidation (no-cache) keeps caching correct | every cached GET /api/v1/meta/:type/:name (If-Modified-Since always answers modified)
Thread-read: 6710978221
Premise: holds: protocol-search-and-cache.ts:147 sets lastModified: new Date().toISOString() and meta-item-read-routes.ts:973-974 renders it, on origin/main66bf5b4a
Serial constraints cleared: none — no open PR or pm:dispatched card touches either file
Scope: Fixes #31196. Order: /mnt/project-files/pm-orders/server/order-31196.md. Summons: the maintainer's 「server 再开两个座位」「并发都是5」 (this project, 2026-11-07); grading per 「定级你可以自己决定」 is triage's here (graded on the card).
os-dev-report
{
"issue": 31196,
"status": "done",
"branch": "claude/project-thread-qb6zil",
"pr": "#31248",
"session": "session_01FEkQ5p9eu5KqN5GP7JZAGe",
"premise_still_valid": true,
"summary": "getMetaItemCached stamped lastModified with the read time (protocol-search-and-cache.ts); the REST door only renders it. The by-name read (readMetaItem) now records the adopted sys_metadata row's updated_at (created_at fallback, canonicalIsoInstant) on its active envelope as a non-enumerable Symbol.for key (new served-row-changed-at.ts); the cached read answers it, and answers no lastModified key for an item no stored row serves, so the door sends no Last-Modified. ETag, Cache-Control and the published GetMetaItemResponse envelope are unchanged. REST door unchanged; If-Modified-Since was never read by the protocol and still never answers 304 (pinned).",
"tests": "metadata-protocol src/protocol.cached-item-last-modified.test.ts 4/4 (same lastModified on two reads; save and publish each move it, a pending draft does not; code-shipped item has no key; envelope serialisation unchanged; ETag/no-cache CONTROL) and rest src/meta-item-cached-last-modified.test.ts 3/3, both re-run green on 7ff2b9e. Package suites on f59f3fa+565bea38 (later commits test-only): metadata-protocol 323 files passed | 4 skipped, 22531 tests passed | 26 skipped; rest 394 files passed, 7489 passed | 332 skipped; typecheck both packages exit 0 on 7ff2b9e; scoped eslint packages/metadata-protocol packages/rest exit 0 on 7ff2b9e. Ablation via ablation-replace.mjs (src-resolved, no dist): spread replaced by lastModified: new Date().toISOString(), (anchor 1->0, replacement 0->1, blob c29eebfc->c033ddc6): 3 failed | 1 passed, expected '2026-11-07T08:05:00.000Z' to be '2026-11-07T08:00:00.000Z' and expected [ Array(5) ] to not include 'lastModified'; restored blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands: 69 families on 7ff2b9e, all run, exit 0 each; --ran: 69 derived accounted for, 69 run, 0 NOT-MEASURED (record /mnt/project-files/pm-orders/server/31196-gates-ran.txt). Earlier rounds red only on the new test doubles, fixed in-test: engine-double-contract (ledger --write), objectql-double-limit, where-matcher, test-source-alias. CI check-runs on PR #31248: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches → PR #31248); this os-dev-report comment via post-stamped.mjs (POST issues/31196/comments). git push not counted.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: seat · packages/runtime/src/domains/mcp-object-schema-mask.test.ts (PR #31195) comment says the protocol stamps lastModified with the read time; false after this PR for Last-Modified (the Date header half holds), masking harmless; not touched, outside the claimed surface",
"carrier: none · deviation: file surface grew past the claim by protocol-meta-item-reads.ts, new served-row-changed-at.ts, a one-word export in sys-metadata-repository.ts, and scripts/engine-double-contract.pinned.json (the change time is reachable only inside readMetaItem; getMetaItem envelope version is a hash digest)",
"carrier: none · deviation: origin/main merged once (no-op at 66bf5b4); main moved to 30f23fe since, touching none of these files; not re-merged"
]
}
Activity
objectstack-fleet commentedon Nov 7, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p3 ·
domain:server· 2026-11-07T17:55Z⛔ Not a claim.
GET /api/v1/meta/:type/:namesendsLast-Modifiedas the time of the read, not the item's own modification time. The header carries no information, and anIf-Modified-Sincerevalidation always answers "modified". ETag revalidation works, so nothing is broken. It is also the cause of the Queue-flake anchor: src/domains/mcp-object-schema-mask.test.ts #31171 flake, which was fixed in the test only.domain:server(metadata-protocol+rest).findingremoved,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ
Claim: PM loop round 1 · 2026-11-07T18:10Z
Session:
session_01FEkQ5p9eu5KqN5GP7JZAGe(card thread, dev) · seatsession_01FEkQ5o8PE7ZtVjcor51wBZAccount:
os-project-managerBranch:
claude/project-thread-qb6zilWorktree:
objectstack-issue-31196Domain:
domain:serverSeat:
domain:server#5File surface:
packages/metadata-protocol/src/protocol-search-and-cache.ts, possiblypackages/rest/src/meta-item-read-routes.ts, their tests, root.changeset/; ⛔packages/spec/**Container & model: S,
mode:thread,model: default tier(dispatch-gates --tier: no path-derived mandate),effort: thread default(order asked medium; the coordinator sets effort only on the maintainer's word)Clause-②: no —
lastModifiedis already optional in the publishedhttp-cache.zod.ts; omitting it or sourcing the item's own time stays inside itMetadata-protocol: none
Responsibility:
packages/metadata-protocolcached item read (objectstack) | ETag revalidation (no-cache) keeps caching correct | every cachedGET /api/v1/meta/:type/:name(If-Modified-Sincealways answers modified)Thread-read: 6710978221
Premise: holds:
protocol-search-and-cache.ts:147setslastModified: new Date().toISOString()andmeta-item-read-routes.ts:973-974renders it, onorigin/main66bf5b4aSerial constraints cleared: none — no open PR or
pm:dispatchedcard touches either fileScope: Fixes #31196. Order:
/mnt/project-files/pm-orders/server/order-31196.md. Summons: the maintainer's 「server 再开两个座位」「并发都是5」 (this project, 2026-11-07); grading per 「定级你可以自己决定」 is triage's here (graded on the card).objectstack-fleet commentedon Nov 7, 2026
domain:server#5 · os-project-manager · session_01FEkQ5p9eu5KqN5GP7JZAGe
os-dev-report
{
"issue": 31196,
"status": "done",
"branch": "claude/project-thread-qb6zil",
"pr": "#31248",
"session": "session_01FEkQ5p9eu5KqN5GP7JZAGe",
"premise_still_valid": true,
"summary": "getMetaItemCached stamped lastModified with the read time (protocol-search-and-cache.ts); the REST door only renders it. The by-name read (readMetaItem) now records the adopted sys_metadata row's updated_at (created_at fallback, canonicalIsoInstant) on its active envelope as a non-enumerable Symbol.for key (new served-row-changed-at.ts); the cached read answers it, and answers no lastModified key for an item no stored row serves, so the door sends no Last-Modified. ETag, Cache-Control and the published GetMetaItemResponse envelope are unchanged. REST door unchanged; If-Modified-Since was never read by the protocol and still never answers 304 (pinned).",
"tests": "metadata-protocol src/protocol.cached-item-last-modified.test.ts 4/4 (same lastModified on two reads; save and publish each move it, a pending draft does not; code-shipped item has no key; envelope serialisation unchanged; ETag/no-cache CONTROL) and rest src/meta-item-cached-last-modified.test.ts 3/3, both re-run green on 7ff2b9e. Package suites on f59f3fa+565bea38 (later commits test-only): metadata-protocol 323 files passed | 4 skipped, 22531 tests passed | 26 skipped; rest 394 files passed, 7489 passed | 332 skipped; typecheck both packages exit 0 on 7ff2b9e; scoped eslint packages/metadata-protocol packages/rest exit 0 on 7ff2b9e. Ablation via ablation-replace.mjs (src-resolved, no dist): spread replaced by
lastModified: new Date().toISOString(),(anchor 1->0, replacement 0->1, blob c29eebfc->c033ddc6): 3 failed | 1 passed,expected '2026-11-07T08:05:00.000Z' to be '2026-11-07T08:00:00.000Z'andexpected [ Array(5) ] to not include 'lastModified'; restored blob == HEAD, git diff HEAD empty.","gates": "dispatch-gates --commands: 69 families on 7ff2b9e, all run, exit 0 each; --ran: 69 derived accounted for, 69 run, 0 NOT-MEASURED (record /mnt/project-files/pm-orders/server/31196-gates-ran.txt). Earlier rounds red only on the new test doubles, fixed in-test: engine-double-contract (ledger --write), objectql-double-limit, where-matcher, test-source-alias. CI check-runs on PR #31248: in_progress at report time.",
"dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm","mcp_calls": "0",
"api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches → PR #31248); this os-dev-report comment via post-stamped.mjs (POST issues/31196/comments). git push not counted.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: seat · packages/runtime/src/domains/mcp-object-schema-mask.test.ts (PR #31195) comment says the protocol stamps lastModified with the read time; false after this PR for Last-Modified (the Date header half holds), masking harmless; not touched, outside the claimed surface",
"carrier: none · deviation: file surface grew past the claim by protocol-meta-item-reads.ts, new served-row-changed-at.ts, a one-word export in sys-metadata-repository.ts, and scripts/engine-double-contract.pinned.json (the change time is reachable only inside readMetaItem; getMetaItem envelope version is a hash digest)",
"carrier: none · deviation: origin/main merged once (no-op at 66bf5b4); main moved to 30f23fe since, touching none of these files; not re-merged"
]
}
Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ
ACCEPT → PR #31248 comment 6712419529 (Head-sha
7ff2b9e528). Ready, auto-merge armed; the card closes on merge.