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
Job body sandbox has no Intl, so a job that needs time-zone date maths cannot migrate from the deprecated handler key to body #28898
The spec marks a job's handler key DEPRECATED in favour of body. duly's dispatch job cannot make that move. Inside the job body sandbox (QuickJS), typeof Intl === 'undefined', and ctx carries only object, recordId, api, log, crypto and title.
The dispatcher computes each duty's current period in that duty's own IANA time zone, which needs Intl.DateTimeFormat with a timeZone option. Without Intl, or a platform date helper on ctx that takes a time zone, body cannot express the job. So the app keeps handler.
On 18.2.0 the deprecation no longer prints an author-time warning, so nothing tells the author about the dead end until the key is removed.
What would unblock it
One of these:
expose Intl (at least DateTimeFormat with timeZone) in the job body sandbox, or
give ctx a date helper that resolves a calendar date and period boundaries in a named IANA zone.
Then document which one it is in the handler → body migration message.
Until then, handler should not be removed while a job's maths depends on time zones.
Read fresh (filed from duly, measured on 18.2.0). The job body sandbox has no Intl, and ctx has no time-zone date helper, so a job that needs per-zone periods cannot leave the deprecated handler key. Platform first: domain:server, p2.
⚠️ Exposing Intl in the sandbox is runtime. Adding a date helper to the job ctx changes the job context contract, which is a protocol addition. If the lane picks that, it raises it before building, and the card goes to p1.
Claim: PM loop round 4 · card thread · 2026-11-02T04:37Z
Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5paXMpX75J4HCKYU6Z
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-n1omdg (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#2
Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. With 2026-11-01T12:11Z 「定级你可以自己决定」; triage graded p2. Seat's route: runtime only — Intl.DateTimeFormat in the sandbox, no ctx helper, so the job context contract is unchanged.
File surface: the job body sandbox runner (and hook/action bodies only if they share it); the handler-to-body migration text; their tests and one dogfood pin; changeset
Container & model: M, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: medium
Clause-②: no expected (a runtime capability, no published member or schema); the dev measures and declares
Metadata-protocol: none (expected; the dev measures and declares)
Responsibility: the dev exposes a host-backed Intl.DateTimeFormat in the body sandbox without leaking host objects, updates the migration text, red first with ablation; the seat reviews and lands
Thread-read: none
Premise: measured by duly#147 on 18.2.0; triaged p2 with the ctx-helper warning
Serial constraints cleared: none; overlap re-read before pr_create
Resume-from: none — fresh from origin/main
State: → pm:dispatched, assigned to os-project-manager, recorded by this claim.
domain:server#2 · os-project-manager · session_01FEkQ5paXMpX75J4HCKYU6Z
os-dev-report
{
"issue": 28898,
"status": "done",
"branch": "claude/project-thread-n1omdg",
"pr": "#29031",
"session": "session_01FEkQ5paXMpX75J4HCKYU6Z",
"premise_still_valid": true,
"summary": "Runtime-only route as ruled: the QuickJS sandbox gets globalThis.Intl with one member, a whole host-backed Intl.DateTimeFormat (constructor with or without new, supportedLocalesOf, format getter, formatToParts, formatRange, formatRangeToParts, resolvedOptions); only plain values cross (op + one JSON string + up to two numbers in, one JSON string out parsed in the VM), the bridge is a closure argument, now comes from the VM clock, no ctx helper and no job-context change. Hooks, actions and jobs share QuickJSScriptRunner.execute(), so all three get it (one seam). The cli lowering allowlist now judges Intl per member (MEMBER_JUDGED_GLOBALS; Intl.DateTimeFormat lowers, every other Intl member and the bare name stay host-only and bundled), forced because the sandbox-globals probe measures the runtime and would red otherwise. The job handler deprecation text (spec describe + docblock, regenerated job.mdx) and the jobs guide say time-zone date maths moves to body through Intl.DateTimeFormat.",
"tests": "Red on base a364093: new sandbox-intl.test.ts 12 failed (12), each ReferenceError: 'Intl' is not defined. Green: runtime src/sandbox 35/35 files, 341/341 tests; pnpm --filter @objectstack/runtime test 514/514 files, 8279 passed 19 skipped; cli unit tier 366 + 2 published-subpath pins after cli build = 368/368 files; runtime and cli typecheck exit 0 (check:test-typecheck OK); eslint on 11 changed files exit 0. Ablations (scripts/ablation-replace.mjs, restored blob == HEAD, git diff HEAD empty each): runtime call deleted -> 12 failed | 329 passed, exactly the Intl cases; cli 'Intl.DateTimeFormat' removed from SANDBOX_GLOBALS -> 4 failed | 136 passed; dogfood on rebuilt runtime dist (call replaced by void, preflight 'marker absent from all 12 built files') -> 1 failed, job threw ReferenceError: 'Intl' is not defined, read {}; restore leg rebuilt, preflight present in 2 files + tree clean, 1 passed. New dogfood job-body-time-zone-date.dogfood.test.ts 1/1 green on built dist.",
"gates": "Local: dispatch-gates --commands on aed5e29, 108 families, each exit captured before any pipe, all 108 exit 0; --ran: 108 derived, 108 run, 0 NOT-MEASURED (a DERIVED zero). Record pm-orders/server/28898-gates-ran.txt. First pass on b4099da read 4 at exit 3 (prerequisites: teardown self-test pinned commit, unrelated builds), cleared before the final pass. CI on PR #29031 head aed5e29 at report time: 19 in_progress, 1 queued, 2 skipped, none concluded (in_progress is the honest value).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub calls (reads via gh api REST; hearthbot thread tools only)",
"api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create, PR #29031, read-back 14723 bytes identical); POST /repos//issues/28898/comments (this report, via post-stamped). git push x2 is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: QuickJS Date.prototype.toLocaleString(locale, { timeZone }) exists in the sandbox and ignores its arguments, so a handler using it lowers and formats in the server zone; read-only observation, no measured public-door reach · dedupe words: toLocaleString timeZone sandbox ignored · carrier: none",
"noted, not filed: resolvedOptions() of a default-constructed formatter tells a body the server's default locale and time zone (values, not objects) · carrier: seat 2 review"
]
}
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:server·area:automation·pm:queue· 2026-11-02T03:54Z⛔ Not a claim.
bodysandbox has noIntl, andctxhas no time-zone date helper, so a job that needs per-zone periods cannot leave the deprecatedhandlerkey. Platform first:domain:server, p2.Intlin the sandbox is runtime. Adding a date helper to the jobctxchanges the job context contract, which is a protocol addition. If the lane picks that, it raises it before building, and the card goes to p1.Generated by Claude Code
Clear the 18 field-no-consumers warnings by grouping every field on i…
objectstack-fleet commentedon Nov 2, 2026
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
Claim: PM loop round 4 · card thread · 2026-11-02T04:37Z
Session:
session_0186vfjHHMsRXC9EUT9hTFMo(the seat); the card thread issession_01FEkQ5paXMpX75J4HCKYU6ZAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-n1omdg(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#2Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. With 2026-11-01T12:11Z 「定级你可以自己决定」; triage graded p2. Seat's route: runtime only —
Intl.DateTimeFormatin the sandbox, no ctx helper, so the job context contract is unchanged.File surface: the job body sandbox runner (and hook/action bodies only if they share it); the handler-to-body migration text; their tests and one dogfood pin; changeset
Container & model:
M,mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: mediumClause-②: no expected (a runtime capability, no published member or schema); the dev measures and declares
Metadata-protocol: none (expected; the dev measures and declares)
Responsibility: the dev exposes a host-backed
Intl.DateTimeFormatin the body sandbox without leaking host objects, updates the migration text, red first with ablation; the seat reviews and landsThread-read: none
Premise: measured by duly#147 on 18.2.0; triaged p2 with the ctx-helper warning
Serial constraints cleared: none; overlap re-read before pr_create
Resume-from: none — fresh from
origin/mainState: →
pm:dispatched, assigned toos-project-manager, recorded by this claim.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#2 · os-project-manager · session_01FEkQ5paXMpX75J4HCKYU6Z
os-dev-report
{
"issue": 28898,
"status": "done",
"branch": "claude/project-thread-n1omdg",
"pr": "#29031",
"session": "session_01FEkQ5paXMpX75J4HCKYU6Z",
"premise_still_valid": true,
"summary": "Runtime-only route as ruled: the QuickJS sandbox gets globalThis.Intl with one member, a whole host-backed Intl.DateTimeFormat (constructor with or without new, supportedLocalesOf, format getter, formatToParts, formatRange, formatRangeToParts, resolvedOptions); only plain values cross (op + one JSON string + up to two numbers in, one JSON string out parsed in the VM), the bridge is a closure argument, now comes from the VM clock, no ctx helper and no job-context change. Hooks, actions and jobs share QuickJSScriptRunner.execute(), so all three get it (one seam). The cli lowering allowlist now judges Intl per member (MEMBER_JUDGED_GLOBALS; Intl.DateTimeFormat lowers, every other Intl member and the bare name stay host-only and bundled), forced because the sandbox-globals probe measures the runtime and would red otherwise. The job handler deprecation text (spec describe + docblock, regenerated job.mdx) and the jobs guide say time-zone date maths moves to body through Intl.DateTimeFormat.",
"tests": "Red on base a364093: new sandbox-intl.test.ts 12 failed (12), each ReferenceError: 'Intl' is not defined. Green: runtime src/sandbox 35/35 files, 341/341 tests; pnpm --filter @objectstack/runtime test 514/514 files, 8279 passed 19 skipped; cli unit tier 366 + 2 published-subpath pins after cli build = 368/368 files; runtime and cli typecheck exit 0 (check:test-typecheck OK); eslint on 11 changed files exit 0. Ablations (scripts/ablation-replace.mjs, restored blob == HEAD, git diff HEAD empty each): runtime call deleted -> 12 failed | 329 passed, exactly the Intl cases; cli 'Intl.DateTimeFormat' removed from SANDBOX_GLOBALS -> 4 failed | 136 passed; dogfood on rebuilt runtime dist (call replaced by void, preflight 'marker absent from all 12 built files') -> 1 failed, job threw ReferenceError: 'Intl' is not defined, read {}; restore leg rebuilt, preflight present in 2 files + tree clean, 1 passed. New dogfood job-body-time-zone-date.dogfood.test.ts 1/1 green on built dist.",
"gates": "Local: dispatch-gates --commands on aed5e29, 108 families, each exit captured before any pipe, all 108 exit 0; --ran: 108 derived, 108 run, 0 NOT-MEASURED (a DERIVED zero). Record pm-orders/server/28898-gates-ran.txt. First pass on b4099da read 4 at exit 3 (prerequisites: teardown self-test pinned commit, unrelated builds), cleared before the final pass. CI on PR #29031 head aed5e29 at report time: 19 in_progress, 1 queued, 2 skipped, none concluded (in_progress is the honest value).",
"dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm","mcp_calls": "0 — no MCP GitHub calls (reads via gh api REST; hearthbot thread tools only)",
"api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create, PR #29031, read-back 14723 bytes identical); POST /repos//issues/28898/comments (this report, via post-stamped). git push x2 is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: QuickJS Date.prototype.toLocaleString(locale, { timeZone }) exists in the sandbox and ignores its arguments, so a handler using it lowers and formats in the server zone; read-only observation, no measured public-door reach · dedupe words: toLocaleString timeZone sandbox ignored · carrier: none",
"noted, not filed: resolvedOptions() of a default-constructed formatter tells a body the server's default locale and time zone (values, not objects) · carrier: seat 2 review"
]
}
Generated by Claude Code