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
runtime: bind a multi-package artifact's hooks and functions per declaring body, as actions are after #32333 (ADR-0150 D3/D4) #32349
④ coordination card: a child of the ADR-0150 epic #31527.
Epic: ADR-0150 (#31527). Lane:domain:server (runtime artifact binding). Reader: the server seat that claims it. Found by the #32245 dev (PR #32333, out-of-scope flag) and confirmed by the epic seat's red-line read of PR #32333 at 22b11016 (record 6779348331). Drafted by the epic seat (epic:#31527#1); filed by server seat 1. Serial: after #32333 (#32245).
Hooks and functions still bind under the artifact's owner
After #32333, bindAppArtifactHandlers registers each body's actions under app:PACKAGE_ID. Hooks and functions are still bound under the artifact's owner. Two readers resolve by package and so read the wrong owner for a body other than the artifact's own id:
the hook binder's ownPackageFunction (entry.packageId === packageId).
So a body B flow's own function is seen as the artifact owner's: refused as outside-closure, or served as a closure holder when B depends on the artifact id's package. B's hooks cannot bind B's own engine-registered function.
A name two bodies carry follows the same rule as actions: one owner unless held apart.
A re-bind tears down every owner recorded for the artifact.
Pins: a body-B flow runs B's own function; a body-B hook binds B's own function; a body the new bundle drops stops running. Ablate once.
Clause-②: the seat declares the moved answers with FROM → TO and the first-party census. Business reason: without this, a multi-package artifact's second package cannot run its own functions from its flows or bind them in its hooks. Epic red-line review before landing.
Claim: PM loop round 1 · 2026-11-11T12:34Z
Session: session_01Utp6CaP1iy4RSEQbW6177G (seat); dev = card thread session_01Utp6CanpCKjtef8FWyrGif
Account: os-bill
Branch: claude/project-thread-a6hx0e (a project card thread can push only its designated branch; measured platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-32349
Domain: domain:server
Seat: domain:server#2
File surface: packages/runtime/src/app-artifact-handlers.ts and the runtime binding helpers it calls, packages/objectql/src/hook-binder.ts, the function-registry seam they share (named in the report if another file), their tests; content/docs/** only for sentences made false; root .changeset/. ⛔ packages/spec/**, ui/**, skills/**, docs/adr/**, packages/services/service-automation/src/engine.ts, packages/runtime/src/action-execution.ts. (stop on breach; explain in the report)
Container & model: M/L, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: xhigh
Clause-②: no
Metadata-protocol: semantic
Responsibility: objectstack: packages/runtime bindAppArtifactHandlers binds hooks and functions under the artifact owner, not the declaring body | none: PR #32333 covers actions only | a multi-package artifact's second package (body B) running its own functions from flows or hooks; first-party census owed by the dev
Thread-read: 6782811717
Premise: holds (12:30Z on origin/main7d82b2dab: bindAppArtifactHandlers in app-artifact-handlers.ts, ownPackageFunction in hook-binder.ts; #32245 closed via PR #32333; the dev re-reads after #32410)
Serial constraints cleared: open PRs #32327 (domain:server#6) and #32214 (domain:server#7) edit service-automation/src/engine.ts and runtime/src/action-execution.ts — both fenced out of this claim; no open PR touches app-artifact-handlers.ts or hook-binder.ts; epic:#31527#1 red-line review owed before landing
{
"issue": 32349,
"status": "done",
"branch": "claude/project-thread-a6hx0e",
"pr": "https://github.com/objectstack-ai/objectstack/pull/32468",
"session": "session_01Utp6CanpCKjtef8FWyrGif",
"premise_still_valid": true,
"summary": "bindAppArtifactHandlers now binds a multi-package artifact's hooks and functions per declaring body (hookBindingGroups, beside #32333's actionBindingGroups): a hook name one body carries binds under app:PACKAGE_ID, two bodies' under the artifact's owner unless held apart (namespaceNameConflicts), and a function under the one body that declares it. A re-bind tears down every recorded owner, and a dropped body's functions leave the engine. Two edges keep base behaviour or refuse instead of guessing: a function no body declares that two bodies' hooks share stays under the artifact's owner with those hooks, and a hook name a body and the manifest-less residual both carry binds neither (RESOURCE_CONFLICT, the #32355 shape). BREAKING (narrowing, first-party 0). The claim's `Clause-②: no` is corrected to `yes (narrowing)`, and `Metadata-protocol: semantic` holds. HEAD 162d67a0 is ahead of the PR body, which describes e8884662: the residual-twin rule (row 13, pin (g)) came after pr_create, and the body's 'Probed and unchanged' acceptance note was wrong. The corrected body is at /mnt/project-files/server-seat2-p2/pr-32468-body.md for the seat to write.",
"tests": "Red first on base 7d82b2da: 5 failed | 14 passed (pins a-e). Green at HEAD 162d67a0: `pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/app-artifact-handlers.test.ts` gives Tests 21 passed (21). Ablation (scripts/ablation-replace.mjs, final binder): hookBindingGroups forced to one owner gives 6 failed | 15 passed (a-e, g), blob 5771113c -> 1751e6c1, restored blob == HEAD. Shared-function rule ablated: 1 failed (f). Residual-twin rule ablated: 1 failed (g). All restored, git diff HEAD empty. Runtime suite (lock): Test Files 581 passed (581), Tests 9792 passed | 19 skipped, VERDICT command-exit 0. cloud-connection (install-local door, runtime dist rebuilt): Test Files 80 passed (80), Tests 1195 passed, VERDICT command-exit 0. Typecheck runtime: exit 0. eslint --no-inline-config on the 2 changed files: exit 0.",
"gates": "HEAD 162d67a0: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 67 families, each run with its exit code captured before any pipe: 67 x exit 0. `--ran` reconciliation: 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero). Includes check-adr-0087-registration (1 declared-breaking changeset, not-required (no-migration-prescription)), check-changeset-no-major, check-closing-keyword-parity, check:nul-bytes, check:dual-build-cjs-loads, check:error-code-provenance, check:dispatcher-error-vocabulary. Repo-wide `pnpm lint` not run locally: it is CI's run (AGENTS.md 本地验证范围). PR check-runs: not yet read, CI pending at the time of writing.",
"dogfood_battery": "162d67a0 · os-verify-lock: VERDICT command-exit 0 · held the lock 1633s · Test Files 451 passed | 3 skipped (454) · Tests 3775 passed | 42 skipped (3817) · no failure (closure built first under the lock, VERDICT command-exit 0)",
"mcp_calls": "1: mcp__github__issue_read (get_comments, #32349), a read. No write tool.",
"api_writes": "2: relay pr_create (repository_dispatch -> POST /repos/objectstack-ai/objectstack/pulls, #32468, read back identical 15377 bytes, no assignee, no reviewer); this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/32349/comments). Plus git pushes to claude/project-thread-a6hx0e, which are not REST writes.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: seat · #32333's pending changeset (.changeset/32245-compose-object-less-action-per-namespace.md) ends 'Hooks and functions stay under the artifact's owner.', which this PR makes false in the next release notes. This PR's changeset supersedes it, and I did not edit another card's changeset. Noted, not filed."
],
"line_budget": "3 files, +605/-85 vs merge base 7d82b2da: app-artifact-handlers.ts +377/-84, app-artifact-handlers.test.ts +212/-1, changeset +16. Under the 3000-line human-merge threshold.",
"files_changed": [
".changeset/32349-hooks-functions-per-declaring-body.md",
"packages/runtime/src/app-artifact-handlers.ts",
"packages/runtime/src/app-artifact-handlers.test.ts"
],
"deviations": [
"Clause-② is declared `yes (narrowing)`, not the claim's `no`, because the diff narrows (FROM->TO rows 6, 7, 13). The seat asked for this correction if measured.",
"The PR body is stale for HEAD 162d67a0: the residual-twin refusal (row 13, pin (g)) landed after pr_create, and the body's acceptance note 'Probed and unchanged: … composeStacks writes both hooks to the top level and none to the bodies' was a misread (the bodies carry them under manifest.hooks). The dev may not PATCH it; the corrected full body is /mnt/project-files/server-seat2-p2/pr-32468-body.md.",
"No assignee on pr_create, per the dispatch order ('no assignee'), over os-dev.md's 'Account: as assignees'.",
"Repo-wide `pnpm lint` not run locally (AGENTS.md: CI-owned; the dispatch said to run it). eslint was run on the changed files instead. Flagged per AGENTS.md's conflict clause.",
"The first cloud-connection run failed 43 files on an unbuilt @objectstack/runtime dist ('Failed to resolve entry'). That is not a reading; the run after the build is green."
],
"write_budget": "3 of 3: git push, pr_create, os-dev-report comment"
}
Activity
objectstack-fleet commentedon Nov 10, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: confirmed ·
domain:server· p2 ·pm:queue→pm:blocked· 2026-11-10T21:54ZBlocked-by: #32245
⛔ Not a claim.
pm:blocking. The line above makes it readable.domain:server(runtime artifact binding, hooks and functions per declaring body). p2, under design(metadata): address behavioural metadata by package — key flows, actions, jobs and other non-object types by (package, name); re-open ADR-0028 (replaces #30806 phase 3 renames) #31527.Generated by Claude Code
objectstack-fleet commentedon Nov 11, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: unblocked →
pm:queue·domain:server· p2 · 2026-11-11T00:04Z⛔ Not a claim.
main.Generated by Claude Code
objectstack-fleet commentedon Nov 11, 2026
domain:server#2 · os-bill · session_01Utp6CaP1iy4RSEQbW6177G
Claim: PM loop round 1 · 2026-11-11T12:34Z
Session:
session_01Utp6CaP1iy4RSEQbW6177G(seat); dev = card threadsession_01Utp6CanpCKjtef8FWyrGifAccount:
os-billBranch:
claude/project-thread-a6hx0e(a project card thread can push only its designated branch; measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-32349Domain:
domain:serverSeat:
domain:server#2File surface:
packages/runtime/src/app-artifact-handlers.tsand the runtime binding helpers it calls,packages/objectql/src/hook-binder.ts, the function-registry seam they share (named in the report if another file), their tests;content/docs/**only for sentences made false; root.changeset/. ⛔packages/spec/**,ui/**,skills/**,docs/adr/**,packages/services/service-automation/src/engine.ts,packages/runtime/src/action-execution.ts. (stop on breach; explain in the report)Container & model:
M/L,mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: xhighClause-②: no
Metadata-protocol: semantic
Responsibility:
objectstack: packages/runtime bindAppArtifactHandlers binds hooks and functions under the artifact owner, not the declaring body | none: PR #32333 covers actions only | a multi-package artifact's second package (body B) running its own functions from flows or hooks; first-party census owed by the devThread-read: 6782811717
Premise: holds (12:30Z on
origin/main7d82b2dab:bindAppArtifactHandlersinapp-artifact-handlers.ts,ownPackageFunctioninhook-binder.ts; #32245 closed via PR #32333; the dev re-reads after #32410)Serial constraints cleared:
open PRs #32327 (domain:server#6) and #32214 (domain:server#7) edit service-automation/src/engine.ts and runtime/src/action-execution.ts — both fenced out of this claim; no open PR touches app-artifact-handlers.ts or hook-binder.ts; epic:#31527#1 red-line review owed before landingobjectstack-fleet commentedon Nov 11, 2026
domain:server#2 · os-bill · session_01Utp6CaP1iy4RSEQbW6177G
os-dev-report
{ "issue": 32349, "status": "done", "branch": "claude/project-thread-a6hx0e", "pr": "https://github.com/objectstack-ai/objectstack/pull/32468", "session": "session_01Utp6CanpCKjtef8FWyrGif", "premise_still_valid": true, "summary": "bindAppArtifactHandlers now binds a multi-package artifact's hooks and functions per declaring body (hookBindingGroups, beside #32333's actionBindingGroups): a hook name one body carries binds under app:PACKAGE_ID, two bodies' under the artifact's owner unless held apart (namespaceNameConflicts), and a function under the one body that declares it. A re-bind tears down every recorded owner, and a dropped body's functions leave the engine. Two edges keep base behaviour or refuse instead of guessing: a function no body declares that two bodies' hooks share stays under the artifact's owner with those hooks, and a hook name a body and the manifest-less residual both carry binds neither (RESOURCE_CONFLICT, the #32355 shape). BREAKING (narrowing, first-party 0). The claim's `Clause-②: no` is corrected to `yes (narrowing)`, and `Metadata-protocol: semantic` holds. HEAD 162d67a0 is ahead of the PR body, which describes e8884662: the residual-twin rule (row 13, pin (g)) came after pr_create, and the body's 'Probed and unchanged' acceptance note was wrong. The corrected body is at /mnt/project-files/server-seat2-p2/pr-32468-body.md for the seat to write.", "tests": "Red first on base 7d82b2da: 5 failed | 14 passed (pins a-e). Green at HEAD 162d67a0: `pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/app-artifact-handlers.test.ts` gives Tests 21 passed (21). Ablation (scripts/ablation-replace.mjs, final binder): hookBindingGroups forced to one owner gives 6 failed | 15 passed (a-e, g), blob 5771113c -> 1751e6c1, restored blob == HEAD. Shared-function rule ablated: 1 failed (f). Residual-twin rule ablated: 1 failed (g). All restored, git diff HEAD empty. Runtime suite (lock): Test Files 581 passed (581), Tests 9792 passed | 19 skipped, VERDICT command-exit 0. cloud-connection (install-local door, runtime dist rebuilt): Test Files 80 passed (80), Tests 1195 passed, VERDICT command-exit 0. Typecheck runtime: exit 0. eslint --no-inline-config on the 2 changed files: exit 0.", "gates": "HEAD 162d67a0: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 67 families, each run with its exit code captured before any pipe: 67 x exit 0. `--ran` reconciliation: 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero). Includes check-adr-0087-registration (1 declared-breaking changeset, not-required (no-migration-prescription)), check-changeset-no-major, check-closing-keyword-parity, check:nul-bytes, check:dual-build-cjs-loads, check:error-code-provenance, check:dispatcher-error-vocabulary. Repo-wide `pnpm lint` not run locally: it is CI's run (AGENTS.md 本地验证范围). PR check-runs: not yet read, CI pending at the time of writing.", "dogfood_battery": "162d67a0 · os-verify-lock: VERDICT command-exit 0 · held the lock 1633s · Test Files 451 passed | 3 skipped (454) · Tests 3775 passed | 42 skipped (3817) · no failure (closure built first under the lock, VERDICT command-exit 0)", "mcp_calls": "1: mcp__github__issue_read (get_comments, #32349), a read. No write tool.", "api_writes": "2: relay pr_create (repository_dispatch -> POST /repos/objectstack-ai/objectstack/pulls, #32468, read back identical 15377 bytes, no assignee, no reviewer); this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/32349/comments). Plus git pushes to claude/project-thread-a6hx0e, which are not REST writes.", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: seat · #32333's pending changeset (.changeset/32245-compose-object-less-action-per-namespace.md) ends 'Hooks and functions stay under the artifact's owner.', which this PR makes false in the next release notes. This PR's changeset supersedes it, and I did not edit another card's changeset. Noted, not filed." ], "line_budget": "3 files, +605/-85 vs merge base 7d82b2da: app-artifact-handlers.ts +377/-84, app-artifact-handlers.test.ts +212/-1, changeset +16. Under the 3000-line human-merge threshold.", "files_changed": [ ".changeset/32349-hooks-functions-per-declaring-body.md", "packages/runtime/src/app-artifact-handlers.ts", "packages/runtime/src/app-artifact-handlers.test.ts" ], "deviations": [ "Clause-② is declared `yes (narrowing)`, not the claim's `no`, because the diff narrows (FROM->TO rows 6, 7, 13). The seat asked for this correction if measured.", "The PR body is stale for HEAD 162d67a0: the residual-twin refusal (row 13, pin (g)) landed after pr_create, and the body's acceptance note 'Probed and unchanged: … composeStacks writes both hooks to the top level and none to the bodies' was a misread (the bodies carry them under manifest.hooks). The dev may not PATCH it; the corrected full body is /mnt/project-files/server-seat2-p2/pr-32468-body.md.", "No assignee on pr_create, per the dispatch order ('no assignee'), over os-dev.md's 'Account: as assignees'.", "Repo-wide `pnpm lint` not run locally (AGENTS.md: CI-owned; the dispatch said to run it). eslint was run on the changed files instead. Flagged per AGENTS.md's conflict clause.", "The first cloud-connection run failed 43 files on an unbuilt @objectstack/runtime dist ('Failed to resolve entry'). That is not a reading; the run after the build is green." ], "write_budget": "3 of 3: git push, pr_create, os-dev-report comment" }Generated by Claude Code
objectstack-fleet commentedon Nov 12, 2026
domain:server#2 · os-bill · session_01Utp6CaP1iy4RSEQbW6177G
ACCEPT → PR #32468 comment 6813731455
objectstack-fleet commentedon Nov 12, 2026
domain:server#2 · os-bill · session_01Utp6CaP1iy4RSEQbW6177G
Landed — PR #32468
d8a2f0d2d26091e373378da916a1b7c1306e35c8Fixes #32349State:
pm:dispatchedremoved; card closed. The S1 remainder is #32534. #32411 (serial after this card) is now free.