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
enforce-or-remove: the declared webhook's label / description keys — are they read anywhere since declared webhooks come from the registry? #24900
Since step 1, a declared webhook is read from the metadata registry (plugin-webhooks/src/declared-webhooks.tsDeclaredWebhookSource) and no longer mirrored into sys_webhook.
The question is whether any runtime or UI surface still reads the declared item's label or description: Setup's webhook list, the delivery log, notifications.
Re-check: git grep -n -E "\.label|\.description" packages/plugins/plugin-webhooks/src plus objectui Setup's webhooks page, and packages/spec/liveness/webhook.jsonprops.label / props.description.
Outcomes
Read somewhere: record the reader in the liveness ledger.
Read nowhere: either enforce it (show it in Setup) or retire the key with a tombstone, per the skill.
Claim: PM loop round 20
Session: session_01D6F9axfoPzR7t8G1J7Ytzz
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-24900-declared-webhook-label-liveness
Worktree: objectstack-issue-24900
Domain: domain:spec
Seat: domain:spec#3 (seat post #18883)
File surface (at origin/main223ae939bb or later; stop on a breach and explain it in the report): packages/spec/liveness/webhook.json (the props.label / props.description rows, with their readers), any generated liveness counts regenerated by repo tooling, and .changeset/24900-*.md if the repo requires one.
Read somewhere: the PR records the reader.
Read nowhere: no code. The dev reports the measurement, and the seat files the enforce-or-retire question as a decision card, because retiring a published key goes to the decision box.
Container & model: S, mode:subagent, model: default (no path-derived mandate)
Clause-②: no
Responsibility: n/a — a liveness measurement (ADR-0049 enforce-or-remove)
Thread-read: none
Serial constraints cleared: read at this act; the dev re-checks open PRs touching webhook.json before opening its own.
Read on origin/main223ae939bb at 2026-10-20T18:22Z: a declared webhook is read from the metadata registry (DeclaredWebhookSource, plugin-webhooks/src/declared-webhooks.ts) and is no longer mirrored into sys_webhook.
{
"issue": 24900,
"status": "blocked",
"branch": "claude/issue-24900-declared-webhook-label-liveness",
"pr": null,
"session": "session_01D6F9axfoPzR7t8G1J7Ytzz",
"premise_still_valid": true,
"summary": "MEASURED: a reader exists for BOTH keys, so the card's 'read somewhere' arm applies and no enforce-or-retire decision is owed. Not in plugin-webhooks (git grep of .label/.description in packages/plugins/plugin-webhooks/src at 223ae939bb: zero non-test, non-translation hits on a declared webhook; auto-enqueuer.ts#projectDeclared reads name/object/triggers/url/method/timeoutMs/secret/headers only; redeliver-guard.ts#judgeDeclared, runtime catalog-activation.ts DECLARATION_LOOKUPS.webhook and the CLI ownership port organization-ownership.ts declaredWebhooks.list read name/packageId/active only; organization-ownership-apply.ts#isSwitchOnlyEdit compares a seeded ROW's label/description to that row's own stored definition_json, a migration read of 18.0 data, not of the authored key). The reader is objectui Studio at the .objectui-sha pin 616df6598b42: ResourceListPage.tsx#defaultColumns:1116/1117 (webhook registers no listColumns/ListPage, so DefaultMetadataList draws label and description via row.item[c.key] at :813) and QuickFind.tsx#MetadataQuickFind:114/115; no webhook preview (registerMetadataPreview('webhook' zero hits) and no Setup catalog (SETUP_CATALOG_TYPES = permission/position/sharing_rule). PRODUCER measured booted: pnpm dev -- --fresh on examples/app-showcase at 223ae939bb with a probe label/description authored on its declared webhook (reverted, hash-verified), dev admin: GET /api/v1/meta/webhook 200, items[0] carried label PROBE_LABEL_24900, description PROBE_DESC_24900, _packageId com.example.showcase; GET /api/v1/meta/types lists webhook; the package is scope project. Committed b5d4eb5ae3 on the branch: both webhook.json rows re-graded dead to live (cross-repo evidence + producer, verifiedAt 2026-10-20, authorHint removed, old note kept as HISTORY, file _note corrected) on the hook.label / email_template.label precedent, and state-counts/webhook.md regenerated with gen:liveness-counts (17/2 to 19/0). BLOCKED on the claim's file surface: the flip necessarily reds packages/lint/src/lint-liveness-properties.test.ts (it runs against the REAL webhook.json and pins label/description as dead warnings), a file outside the declared surface, so per the claim I stopped before opening the PR. Ask: extend the surface to that test file (and optionally the two stale prose sites below); the measured 39-line patch is at /tmp/claude-0/-home-user/0787edf0-b8ce-53dc-b67c-ec25a661356f/scratchpad/issue-24900/lint-test.patch (renames the case to 'stays silent ... label and description included', asserts findings toEqual []). Once extended: apply patch, open draft PR 'Closes #24900', Clause-2 no, skip-changeset (ledger + test only; spec files[] does not ship liveness/ is to be confirmed by the seat or the quick-path rule).",
"tests": "pnpm --filter @objectstack/spec check:liveness EXIT=0 after the re-grade (prints the all-clear line; total 1037 live / 113 dead = 1176 classified). gen:liveness-counts EXIT=0, '1 shard(s) rewritten (webhook.md)'. Lint test against the re-graded ledger, unpatched: os-verify-lock VERDICT command-exit 1, 'x warns on a declared webhook's label and description only', AssertionError expected [] to deeply equal [ ...(2) ], Tests 1 failed / 102 passed. With the scratch patch: VERDICT command-exit 0, Tests 103 passed (103); patch then restored with git checkout HEAD --, git diff HEAD empty, hash-object equals HEAD blob. pnpm check:nul-bytes EXIT=0; check:issue-citations EXIT=0; check:doc-authoring EXIT=0; check:platform-checklist EXIT=0. dispatch-gates --commands --repo objectstack-ai/objectstack at b5d4eb5ae3 derived 58 commands; the rest NOT MEASURED: reason, no PR opened (surface breach stop); the PR round owes them. Builds: showcase closure and full workspace build under the lock (OS_SKIP_DTS=1), VERDICT command-exit 0 both. No ablation (no code change).",
"mcp_calls": "0",
"api_writes": "1 - POST repos/objectstack-ai/objectstack/issues/24900/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). git push x2 of the branch (not REST). No PR, no label write.",
"open_questions": [
{
"question": "The claim's file surface excludes packages/lint/src/lint-liveness-properties.test.ts, which the dead-to-live flip must change (it reads the real ledger). Extend the surface?",
"options": [
"A extend the surface to that test (plus examples/app-showcase/src/automation/webhooks/index.ts comment and docs/qa/platform-checklist/areas/integration-system.json:645, both now stating 'ledger marks both dead'); reopen on this branch, apply the saved patch, open draft PR Closes #24900",
"B keep the surface; the ledger commit stays unshipped and the card waits"
],
"recommendation": "A, because the test edit is the skill's own mechanical step for a ledger flip (CLI advisory lint: update its test to assert non-warn), the measurement is done, and without it the ledger stays wrongly dead and warns every author who labels a declared webhook."
}
],
"out_of_scope_findings": [
"class: a · reach: exception: security (possible data leak); public door measured: GET /api/v1/meta/webhook as the dev admin on a booted examples/app-showcase (223ae939bb) returned the declared webhook's authored signing `secret` verbatim (probe PROBE_SECRET_24900); non-admin reach NOT MEASURED (sign-up answered 403). Seam: spec:WebhookSchema.secret (and .headers) → runtime:packages/rest/src/meta-item-read-gate.ts#createMetaListAnswer, with no `webhook` entry in packages/spec/src/kernel/metadata-type-redaction.ts BUILTIN_METADATA_TYPE_REDACTORS and no registerMetadataTypeRedactor('webhook') anywhere (flow has one: service-automation flow-credential-projection.ts). Contract: webhook.json secret row says the declared key is 'consumed for one HMAC and never persisted'. · dedupe words: meta webhook secret redaction; declared webhook signing secret served; metadata type redactor webhook; GET /api/v1/meta/webhook secret headers",
"carrier: this card's PR once the surface is extended · examples/app-showcase/src/automation/webhooks/index.ts header comment and docs/qa/platform-checklist/areas/integration-system.json:645 both say the ledger marks label/description dead, false after the re-grade · noted, not filed"
]
}
{
"issue": 24900,
"status": "done",
"branch": "claude/issue-24900-declared-webhook-label-liveness",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24972",
"session": "session_01D6F9axfoPzR7t8G1J7Ytzz",
"premise_still_valid": true,
"summary": "Both keys have a reader, so the card's 'read somewhere' arm applies and no enforce-or-retire decision is owed. The reader is objectui Studio at the .objectui-sha pin 616df6598b42: ResourceListPage.tsx#defaultColumns and QuickFind.tsx#MetadataQuickFind. The producer was measured by booting examples/app-showcase: GET /api/v1/meta/webhook serves the authored label and description with _packageId com.example.showcase. The webhook.json rows are re-graded dead to live (cross-repo evidence, producer, verifiedAt 2026-10-20) and the counts shard regenerated (17/2 to 19/0). Per the seat's decision A on the extended surface: the lint test now pins silence; the showcase comment and checklist source line state the live grading. Added a @objectstack/spec patch changeset, because spec files[] ships liveness/ and os lint reads it, so this change publishes and skip-changeset is not allowed. Merged origin/main once (no rebase); the draft PR is assigned to baozhoutao; worktree removed.",
"tests": "At head 5848b7dd99: check:liveness exit 0, check:platform-checklist exit 0. Lint test src/lint-liveness-properties.test.ts: 103 passed (before the test edit, against the re-graded ledger: 1 failed / 102 passed). dispatch-gates: 78 families derived, --ran reconciles 78 of 78, and 76 exited 0. Families 1-70 ran at bf94c93377; the 8 changeset families the changeset commit added ran at 5848b7dd99, and between those heads only .changeset/ changed. NOT MEASURED: check:dts-closure and check:dual-build-cjs-loads. Reason: local dists were built with OS_SKIP_DTS=1 and hold no .d.ts (types, triggers, verify), and the diff touches no package source; CI builds with declarations. No ablation (no code change).",
"mcp_calls": "0",
"api_writes": "3 - POST issues/24900/comments (first report, comment 6298770353); pr_create via the fleet-write relay (POST /pulls draft + POST issues/24972/assignees); POST issues/24900/comments (this report). git push x4 (not REST). No label write: the dispatch named no labels, and skip-changeset does not apply.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: exception: security · declared webhook secret served on GET /api/v1/meta/webhook · filed by the seat as #24966, not acted on here"
]
}
Measured: both keys have a reader, so the card's "read somewhere" arm applies and no enforce-or-retire decision is owed. The reader is objectui Studio at the .objectui-sha pin: ResourceListPage.tsx#defaultColumns and QuickFind.tsx#MetadataQuickFind. The producer was measured by booting the showcase: GET /api/v1/meta/webhook serves the authored values.
webhook.jsonlabel / description are re-graded dead → live, with cross-repo evidence and a producer.
The lint pin now expects silence. The showcase comment and the checklist line state the live grading.
A patch changeset ships for @objectstack/spec, because the published os lint reads liveness/.
No contract review is owed: no packages/spec/src change, Clause-②: no.
Filed from this card:#24966. A declared webhook's secret is served verbatim on GET /api/v1/meta/webhook (security, for triage).
Claim 6298056919 ends here; pm:dispatched is removed in this stroke.
Activity
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 20
Session:
session_01D6F9axfoPzR7t8G1J7YtzzAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-24900-declared-webhook-label-livenessWorktree:
objectstack-issue-24900Domain:
domain:specSeat:
domain:spec#3(seat post #18883)File surface (at
origin/main223ae939bbor later; stop on a breach and explain it in the report):packages/spec/liveness/webhook.json(theprops.label/props.descriptionrows, with their readers), any generated liveness counts regenerated by repo tooling, and.changeset/24900-*.mdif the repo requires one.Container & model:
S,mode:subagent,model: default (no path-derived mandate)Clause-②: no
Responsibility:
n/a — a liveness measurement (ADR-0049 enforce-or-remove)Thread-read: none
Serial constraints cleared: read at this act; the dev re-checks open PRs touching
webhook.jsonbefore opening its own.Read on
origin/main223ae939bbat 2026-10-20T18:22Z: a declared webhook is read from the metadata registry (DeclaredWebhookSource,plugin-webhooks/src/declared-webhooks.ts) and is no longer mirrored intosys_webhook.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 24900, "status": "blocked", "branch": "claude/issue-24900-declared-webhook-label-liveness", "pr": null, "session": "session_01D6F9axfoPzR7t8G1J7Ytzz", "premise_still_valid": true, "summary": "MEASURED: a reader exists for BOTH keys, so the card's 'read somewhere' arm applies and no enforce-or-retire decision is owed. Not in plugin-webhooks (git grep of .label/.description in packages/plugins/plugin-webhooks/src at 223ae939bb: zero non-test, non-translation hits on a declared webhook; auto-enqueuer.ts#projectDeclared reads name/object/triggers/url/method/timeoutMs/secret/headers only; redeliver-guard.ts#judgeDeclared, runtime catalog-activation.ts DECLARATION_LOOKUPS.webhook and the CLI ownership port organization-ownership.ts declaredWebhooks.list read name/packageId/active only; organization-ownership-apply.ts#isSwitchOnlyEdit compares a seeded ROW's label/description to that row's own stored definition_json, a migration read of 18.0 data, not of the authored key). The reader is objectui Studio at the .objectui-sha pin 616df6598b42: ResourceListPage.tsx#defaultColumns:1116/1117 (webhook registers no listColumns/ListPage, so DefaultMetadataList draws label and description via row.item[c.key] at :813) and QuickFind.tsx#MetadataQuickFind:114/115; no webhook preview (registerMetadataPreview('webhook' zero hits) and no Setup catalog (SETUP_CATALOG_TYPES = permission/position/sharing_rule). PRODUCER measured booted: pnpm dev -- --fresh on examples/app-showcase at 223ae939bb with a probe label/description authored on its declared webhook (reverted, hash-verified), dev admin: GET /api/v1/meta/webhook 200, items[0] carried label PROBE_LABEL_24900, description PROBE_DESC_24900, _packageId com.example.showcase; GET /api/v1/meta/types lists webhook; the package is scope project. Committed b5d4eb5ae3 on the branch: both webhook.json rows re-graded dead to live (cross-repo evidence + producer, verifiedAt 2026-10-20, authorHint removed, old note kept as HISTORY, file _note corrected) on the hook.label / email_template.label precedent, and state-counts/webhook.md regenerated with gen:liveness-counts (17/2 to 19/0). BLOCKED on the claim's file surface: the flip necessarily reds packages/lint/src/lint-liveness-properties.test.ts (it runs against the REAL webhook.json and pins label/description as dead warnings), a file outside the declared surface, so per the claim I stopped before opening the PR. Ask: extend the surface to that test file (and optionally the two stale prose sites below); the measured 39-line patch is at /tmp/claude-0/-home-user/0787edf0-b8ce-53dc-b67c-ec25a661356f/scratchpad/issue-24900/lint-test.patch (renames the case to 'stays silent ... label and description included', asserts findings toEqual []). Once extended: apply patch, open draft PR 'Closes #24900', Clause-2 no, skip-changeset (ledger + test only; spec files[] does not ship liveness/ is to be confirmed by the seat or the quick-path rule).", "tests": "pnpm --filter @objectstack/spec check:liveness EXIT=0 after the re-grade (prints the all-clear line; total 1037 live / 113 dead = 1176 classified). gen:liveness-counts EXIT=0, '1 shard(s) rewritten (webhook.md)'. Lint test against the re-graded ledger, unpatched: os-verify-lock VERDICT command-exit 1, 'x warns on a declared webhook's label and description only', AssertionError expected [] to deeply equal [ ...(2) ], Tests 1 failed / 102 passed. With the scratch patch: VERDICT command-exit 0, Tests 103 passed (103); patch then restored with git checkout HEAD --, git diff HEAD empty, hash-object equals HEAD blob. pnpm check:nul-bytes EXIT=0; check:issue-citations EXIT=0; check:doc-authoring EXIT=0; check:platform-checklist EXIT=0. dispatch-gates --commands --repo objectstack-ai/objectstack at b5d4eb5ae3 derived 58 commands; the rest NOT MEASURED: reason, no PR opened (surface breach stop); the PR round owes them. Builds: showcase closure and full workspace build under the lock (OS_SKIP_DTS=1), VERDICT command-exit 0 both. No ablation (no code change).", "mcp_calls": "0", "api_writes": "1 - POST repos/objectstack-ai/objectstack/issues/24900/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). git push x2 of the branch (not REST). No PR, no label write.", "open_questions": [ { "question": "The claim's file surface excludes packages/lint/src/lint-liveness-properties.test.ts, which the dead-to-live flip must change (it reads the real ledger). Extend the surface?", "options": [ "A extend the surface to that test (plus examples/app-showcase/src/automation/webhooks/index.ts comment and docs/qa/platform-checklist/areas/integration-system.json:645, both now stating 'ledger marks both dead'); reopen on this branch, apply the saved patch, open draft PR Closes #24900", "B keep the surface; the ledger commit stays unshipped and the card waits" ], "recommendation": "A, because the test edit is the skill's own mechanical step for a ledger flip (CLI advisory lint: update its test to assert non-warn), the measurement is done, and without it the ledger stays wrongly dead and warns every author who labels a declared webhook." } ], "out_of_scope_findings": [ "class: a · reach: exception: security (possible data leak); public door measured: GET /api/v1/meta/webhook as the dev admin on a booted examples/app-showcase (223ae939bb) returned the declared webhook's authored signing `secret` verbatim (probe PROBE_SECRET_24900); non-admin reach NOT MEASURED (sign-up answered 403). Seam: spec:WebhookSchema.secret (and .headers) → runtime:packages/rest/src/meta-item-read-gate.ts#createMetaListAnswer, with no `webhook` entry in packages/spec/src/kernel/metadata-type-redaction.ts BUILTIN_METADATA_TYPE_REDACTORS and no registerMetadataTypeRedactor('webhook') anywhere (flow has one: service-automation flow-credential-projection.ts). Contract: webhook.json secret row says the declared key is 'consumed for one HMAC and never persisted'. · dedupe words: meta webhook secret redaction; declared webhook signing secret served; metadata type redactor webhook; GET /api/v1/meta/webhook secret headers", "carrier: this card's PR once the surface is extended · examples/app-showcase/src/automation/webhooks/index.ts header comment and docs/qa/platform-checklist/areas/integration-system.json:645 both say the ledger marks label/description dead, false after the re-grade · noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 24900, "status": "done", "branch": "claude/issue-24900-declared-webhook-label-liveness", "pr": "https://github.com/objectstack-ai/objectstack/pull/24972", "session": "session_01D6F9axfoPzR7t8G1J7Ytzz", "premise_still_valid": true, "summary": "Both keys have a reader, so the card's 'read somewhere' arm applies and no enforce-or-retire decision is owed. The reader is objectui Studio at the .objectui-sha pin 616df6598b42: ResourceListPage.tsx#defaultColumns and QuickFind.tsx#MetadataQuickFind. The producer was measured by booting examples/app-showcase: GET /api/v1/meta/webhook serves the authored label and description with _packageId com.example.showcase. The webhook.json rows are re-graded dead to live (cross-repo evidence, producer, verifiedAt 2026-10-20) and the counts shard regenerated (17/2 to 19/0). Per the seat's decision A on the extended surface: the lint test now pins silence; the showcase comment and checklist source line state the live grading. Added a @objectstack/spec patch changeset, because spec files[] ships liveness/ and os lint reads it, so this change publishes and skip-changeset is not allowed. Merged origin/main once (no rebase); the draft PR is assigned to baozhoutao; worktree removed.", "tests": "At head 5848b7dd99: check:liveness exit 0, check:platform-checklist exit 0. Lint test src/lint-liveness-properties.test.ts: 103 passed (before the test edit, against the re-graded ledger: 1 failed / 102 passed). dispatch-gates: 78 families derived, --ran reconciles 78 of 78, and 76 exited 0. Families 1-70 ran at bf94c93377; the 8 changeset families the changeset commit added ran at 5848b7dd99, and between those heads only .changeset/ changed. NOT MEASURED: check:dts-closure and check:dual-build-cjs-loads. Reason: local dists were built with OS_SKIP_DTS=1 and hold no .d.ts (types, triggers, verify), and the diff touches no package source; CI builds with declarations. No ablation (no code change).", "mcp_calls": "0", "api_writes": "3 - POST issues/24900/comments (first report, comment 6298770353); pr_create via the fleet-write relay (POST /pulls draft + POST issues/24972/assignees); POST issues/24900/comments (this report). git push x4 (not REST). No label write: the dispatch named no labels, and skip-changeset does not apply.", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: exception: security · declared webhook secret served on GET /api/v1/meta/webhook · filed by the seat as #24966, not acted on here" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:specseat 3 ·baozhoutao· sessionsession_01D6F9axfoPzR7t8G1J7Ytzz· 2026-10-20T22:25Z0715face7dthrough the merge queue. Verified onorigin/main: single parent, and thegit diff C^ Cpatch-id equals the reviewed head5848b7dd99's against its merge base (1c65316a4d)..objectui-shapin:ResourceListPage.tsx#defaultColumnsandQuickFind.tsx#MetadataQuickFind. The producer was measured by booting the showcase:GET /api/v1/meta/webhookserves the authored values.webhook.jsonlabel/descriptionare re-gradeddead→live, with cross-repo evidence and a producer.@objectstack/spec, because the publishedos lintreadsliveness/.packages/spec/srcchange,Clause-②: no.Filed from this card: #24966. A declared webhook's
secretis served verbatim onGET /api/v1/meta/webhook(security, for triage).Claim
6298056919ends here;pm:dispatchedis removed in this stroke.Generated by Claude Code