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
object.titleFormat has no effect when the object authors no nameField: the registry stamps a derived nameField that outranks the template, so the record title ignores it #29007
Filing gate: ① a product defect, a QA run clause fail (studio-authoring.no-entry-property-matrix acceptance[1]).
Business reason: an author (or AI agent) who writes titleFormat: '{code} @ {city}' on an object gets a save and a publish that both succeed, then a record page and list that show only code. The key is deprecated (ADR-0079) but still accepted, so today it is a silent no-op: either it should apply when no nameField is authored, or it should be refused at save with its prescription.
Reader who acts: the triage seat, then the domain:spec lane (decide honour vs refuse per ADR-0079 / ADR-0049), with the ui half in ui/packages/components/src/renderers/layout/containers.tsx if it is honoured. QA suggestion only: p3.
Duplicate search: titleFormat → 71 hits (closed included). The near ones are closed and different: #24087 (search palette rendered titleFormat before nameField), #25129 / #25071 (docs and lint steering composite titles), #20059 (system objects declaring titleFormat and no pointer). titleFormat inert nameField stamped → 5 hits, none about this.
Batch-of: release-18.3.0-w4-c3b1 — 16 cards from QA run #29002 (subject 7fa9873f; the implementer re-checks the landing site on current main).
Reproduction
As admin, on a writable package: PUT /api/v1/meta/object/qar8_tf2?mode=draft&package=PKG with {name:'qar8_tf2', sharingModel:'public_read_write', titleFormat:'{code} @ {city}', fields:{code:{type:'text'}, city:{type:'text'}}} (no nameField), then POST /api/v1/packages/PKG/publish-drafts → published.
GET /api/v1/meta/object/qar8_tf2 → titleFormat "{code} @ {city}" and a stamped nameField: "code" (the stored draft has none).
POST /api/v1/data/qar8_tf2 {code:'ZX-42', city:'Lyon'}; open the record page and the list in the console.
Expected: the H1 and the list primary read "ZX-42 @ Lyon" (or the save refuses titleFormat). Actual: "ZX-42". The same with '{name} · {code}' on another object → only the name. Reproduced 3 times, fresh browser and sign-in each.
Mechanism (suspected)
packages/spec/src/data/display-name.tsprovisionPrimary stamps a derived nameField at registration, so "no nameField was authored" is lost; containers.tsx (about L2795–2830) ranks nameField / displayNameField above titleFormat, and packages/metadata-protocol/src/protocol-record-reads.ts says "a stamped pointer outranks the template too". The spec describe says only that "an explicit nameField now takes precedence".
Read fresh. provisionPrimary in packages/spec/src/data/display-name.ts stamps a derived nameField, which outranks titleFormat, so the deprecated key is a silent no-op; domain:spec, with a ui half in containers.tsx only if it is honoured. ADR-0079 D3 chose to keep parsing titleFormat with an advisory lint, so whether to honour it when no nameField is authored or to refuse it at save reopens that ADR choice; needs-user-decision. A silent no-op on a saved key is a user-visible defect, p2.
Director seat (第 56 场). This card is presented to the maintainer as batch #454 item 1 in the 总监决裁 thread; the ruling comment follows the maintainer's answer. ⛔ Not a claim.
Ruling: batch #454 item 1 · letter B · maintainer 「454 同意」 2026-11-02T10:04Z
What the ruling binds
titleFormat is refused at the metadata save gate and by os validate on an object definition that carries it. The refusal text is the prescription the describe and the title-format-retired lint already carry: a single-field title is nameField; a composed title is a stored formula field pointed at by nameField. No new wording.
Not honoured (option A refused): provisionPrimary keeps stamping the derived pointer, the console keeps pointer-over-template ordering (objectui#9436 C1), ADR-0079 D3/D9 stay closed.
Not deleted from the schema (option C refused): a stored object that already carries the key still parses and reads; it is refused only when it is next saved or validated. No conversion drops it.
The describe on object.zod.ts ≈L3389 gains one sentence saying the key is refused at save and validate.
S on domain:spec: the save gate, os validate, tests, the describe sentence, the grep sweep. Clause-②: no (narrowing); Metadata-protocol: semantic (an accepted document becomes refused on save). One CONTRACT_REVIEW_TIER review before landing; the record goes to this seat.
Claim: PM loop round 1 · 2026-11-02T13:55Z
Session: session_01ADHkmPi25XXKx92Xmg4viS (seat); dev = card thread session_01ADHkmQaszscubbRkbhxD9k
Account: os-steve
Branch: claude/project-thread-ejw6q8
Worktree: the card thread's own checkout of objectstack-ai/objectstack
Domain: domain:spec
Seat: domain:spec#1
File surface: packages/spec/src/data/object.zod.ts (the titleFormat describe sentence) and its tests; the metadata save door's object-definition refusal (packages/metadata-protocol/src/**, the save-door refusal module) and the os validate door that runs title-format-retired, with their tests; every titleFormat hit in examples, templates and system objects (moved to nameField); root .changeset/; not objectql, not ui, no schema deletion and no conversion (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); one CONTRACT_REVIEW_TIER review (a narrowing on the published schema face) before landing, effort: high
Clause-②: no (narrowing)
Metadata-protocol: semantic
Responsibility: packages/spec object.zod.ts titleFormat | ADR-0079 deprecated the key but every door still accepts it, and a stamped nameField outranks it | authors and agents whose titleFormat saves and publishes, then shows only nameField
Thread-read: 6574393684
Premise: holds (QA run #29002 reproduced it three times; the ruling binds refuse-at-save-and-validate)
Serial constraints cleared: PR #29331 merged (3fb74b6d30, same file); #28205 follows this card on object.zod.ts
Ruling-ref: director 6574393684, letter B, maintainer 「454 同意」 — refused at the metadata save gate and by os validate with the existing prescription; still parses on read; not honoured, not deleted, no conversion; describe gains one sentence; every repo titleFormat hit moves to nameField in the same PR. The dev measures the claim pair offline with --event and reports what the gate accepts.
{
"issue": 29007,
"status": "done",
"branch": "claude/project-thread-ejw6q8",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29499",
"session": "session_01ADHkmQaszscubbRkbhxD9k",
"premise_still_valid": true,
"summary": "Ruling 6574393684 letter B. title-format-retired moves out of the advisory validateRecordTitle into a new gating registry rule, validateTitleFormatRetired (CLI_AND_RUNTIME, runtimeTypes ['object']), so os validate/build/lint and the metadata save gate (active save, promotion, restore: 422 INVALID_METADATA) refuse an object that declares titleFormat, with the existing prescription byte-identical. The key stays in the schema and a stored object still parses and loads; the describe gains one sentence; a new D3 semantic entry object-title-format-refused is registered. All 68 code-shipped system objects drop titleFormat (65 already had nameField; sys_attachment, sys_audience_binding_suggestion, sys_notification_template now declare the field the registry already stamped). No example or template declared it.",
"tests": "head 0885931864 under os-verify-lock: lint 7834 passed; spec 23451 passed + 1 todo; platform-objects 1505; plugin-approvals 1381; plugin-audit, plugin-security, plugin-sharing, plugin-webhooks, service-automation, service-mailbox, service-messaging, service-realtime, service-storage, metadata-protocol all command-exit 0; cli 6871 passed / 9 skipped (unit + integration). typecheck green for all 15 touched packages (cli test layer needed the CI heap --max-old-space-size=4136; default heap OOM). New pins: lint validate-record-title + runtime-gate.object-writes (refusal, re-save of stored row refused, healed control), metadata-protocol draft-publish-verdict (stored row loads, next save 422, nameField control), cli validate-title-format-retired integration (exit 1 / control exit 0), platform-objects repo-wide no-titleFormat sweep with red fixture. Ablation: severity 'error' -> 'warning' with dist preflight confirmed: lint 5 red, metadata-protocol 2 red, cli 1 red; restored, --absent preflight passed, tree clean.",
"gates": "dispatch-gates --commands on 0885931864: 113 derived; dispatch-gates --ran: 113 run, 0 NOT-MEASURED (derived zero), 0 non-zero. First pass reds fixed in-PR: check:docs-transcript-drift (4 CLI transcripts printed 'author-time rules (60)'; the new gating rule makes 61) and check-plugin-teardown-shape --self-test exit 3 (shallow clone; green after fetching pinned 621a4876). check-changeset-no-major --event on the PR body: exit 0 (no (narrowing) + semantic accepted). check-nul-bytes OK. CI check-runs not yet read.",
"dogfood_battery": "0885931864 (suite run on 904c42f7; the only later commit edits four .mdx transcript lines, no package source) · os-verify-lock: VERDICT command-exit 0 · held the lock 1775s · Test Files 393 passed | 3 skipped (396) · Tests 3243 passed | 28 skipped (3271) · no failures",
"mcp_calls": "2 — mcp__github__issue_read (get), mcp__github__issue_read (get_comments); no write tools",
"api_writes": "3 relay writes via fleet-write dispatch: pr_create #29499 (run 41482642352); issue_patch #29499 body (run 41482837189, fixes a shell-mangled docs bullet from my own heredoc); this os-dev-report comment. Plus git pushes to the branch.",
"files_changed": "101 files: 68 *.object.ts (titleFormat dropped, 3 gain nameField, comments rewritten); lint src validate-record-title.ts, authoring-rules.ts, index.ts, rule-explanations.ts; spec object.zod.ts describe, migrations/entries/semantic/18.object-title-format-refused.ts, liveness/sharing_rule.json; 9 forced test edits (8 display-title tests -> local RETIRED_TITLE_TEMPLATES map; sys-approval-request-title.integration asserts undefined); 4 pin test files + new packages/cli/test/validate-title-format-retired.test.ts; docs objects.mdx, schema-design.mdx, building-crud-app.mdx, crm-development-standards.mdx, 4 CLI transcript .mdx, 3 regenerated references; .changeset/29007-object-title-format-refused.md",
"line_budget": "+728 / -273 (993 changed vs 3000 human-merge threshold): tests +414/-38, object files +146/-190, references +4/-4, other +164/-41",
"deviations": [
"Draft saves are not refused: the publish-gate contract (#4463 D1) leaves draft saves ungated; they store with _diagnostics valid:false and their promotion is refused. Read the ruling's 'save gate' as the existing gate (open question 1).",
"Composite titles: the 3 objects without nameField got the already-stamped field, and composites were not converted to stored computed fields (new columns would be null on existing rows); only the blank-pointer fallback text changes (open question 2).",
"skills/objectstack-data/SKILL.md line 90 still says 'Deprecated, not removed': governed path, left out of this PR.",
"Commits 1-3 carry wip: subjects; intended for squash merge."
],
"open_questions": [
{ "question": "Should a DRAFT save of an object carrying titleFormat be refused too, not only active save / promotion / restore?", "options": ["A keep the #4463 D1 contract: draft stores with valid:false, publish refused", "B add a draft-door refusal for this rule only (a gate-wide exception)"], "recommendation": "A, because the gate contract is uniform for every gating rule and a draft cannot go live anyway" },
{ "question": "Should system objects whose retired template was a composite gain a stored computed title field?", "options": ["A no: nameField already titles them and the old template rendered only as a blank-pointer fallback", "B yes: add expression fields and backfill"], "recommendation": "A, because new stored columns would be null on existing rows and need a backfill the ruling did not ask for" }
],
"security_findings": "withheld",
"out_of_scope_findings": ["class: b · reach: named producer skills/objectstack-data/SKILL.md:90 ('Deprecated, not removed') now understates a refusal · evidence: grep titleFormat skills/ · dedupe words: titleFormat skill prose refused", "carrier: seat · noted, not filed"]
}
Claim amendment on #29007 (amends claim 6578956474) · 2026-11-02T16:48Z
Metadata-protocol: semantic becomes Metadata-protocol: narrowed. Under AGENTS.md checklist 3, a value refused is narrowed, and "several ⇒ narrowed over semantic". The refusal of an authored titleFormat at the save gate and in os validate is an accept-set narrowing.
This corrects the seat's own claim line, so it is not a deviation by the implementer. Clause-②: no (narrowing) is unchanged and the level stays minor. The PR body and the changeset take the corrected line in round 2 (contract review FAIL on 08859318, must-fix B).
pm:dispatched is removed. The seat ACCEPTed, with the claim amended to Clause-②: no (narrowing) / Metadata-protocol: narrowed. The CONTRACT_REVIEW_TIER review FAILed round 1 (transcripts, protocol kind) and then passed on the round-2 delta. A′, the main race on the rule count, was closed by merge-only head 63417d56 (transcripts 63).
What changed: an object that declares titleFormat is refused at the save door and by os validate, with the nameField prescription. The D3 semantic entry is object-title-format-refused (ADR-0087).
Still owed, non-blocking: governed finding #29506 covers the two skills lines and the ADR-0079 D3 note. Next on the same files is #28205, which is free for another spec seat.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: studio-authoring.no-entry-property-matrix
Triage:
domain:spec· p2 ·needs-user-decision· 2026-11-02T07:28Z⛔ Not a claim.
Generated by Claude Code
zhuangjianguo commentedon Nov 2, 2026
director#1 · zhuangjianguo · session_01QsR2jV5sBSzCYNEDgpYLJw
Brief-claimed-by: session_01QsR2jV5sBSzCYNEDgpYLJw · batch #454 · 2026-11-02T09:27Z
Director seat (第 56 场). This card is presented to the maintainer as batch #454 item 1 in the 总监决裁 thread; the ruling comment follows the maintainer's answer. ⛔ Not a claim.
Generated by Claude Code
zhuangjianguo commentedon Nov 2, 2026
director#1 · zhuangjianguo · session_01QsR2jV5sBSzCYNEDgpYLJw
Ruling: batch #454 item 1 · letter B · maintainer 「454 同意」 2026-11-02T10:04Z
What the ruling binds
titleFormatis refused at the metadata save gate and byos validateon an object definition that carries it. The refusal text is the prescription the describe and thetitle-format-retiredlint already carry: a single-field title isnameField; a composed title is a stored formula field pointed at bynameField. No new wording.provisionPrimarykeeps stamping the derived pointer, the console keeps pointer-over-template ordering (objectui#9436 C1), ADR-0079 D3/D9 stay closed.object.zod.ts≈L3389 gains one sentence saying the key is refused at save and validate.titleFormatin examples, templates and system objects (the card names platform-objects: ten system objects declaretitleFormatand no pointer, so the registry stampsnameField: idand a renderer honouring the declared pointer shows the raw record id as the title — the engine half of #20044 #20059's system objects); every hit moves tonameFieldin the same PR.Workload of the letter
S on
domain:spec: the save gate,os validate, tests, the describe sentence, the grep sweep.Clause-②: no (narrowing);Metadata-protocol: semantic(an accepted document becomes refused on save). One CONTRACT_REVIEW_TIER review before landing; the record goes to this seat.Execution
domain:specseat takes the card; serial with field.searchable: true has no reader: $search skips the field and $searchFields naming it answers 400 "is not searchable" while the served schema says searchable: true #29008 on the same lane.needs-user-decision→pm:queue) is the lane seat's.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS
Claim: PM loop round 1 · 2026-11-02T13:55Z
Session:
session_01ADHkmPi25XXKx92Xmg4viS(seat); dev = card threadsession_01ADHkmQaszscubbRkbhxD9kAccount:
os-steveBranch:
claude/project-thread-ejw6q8Worktree: the card thread's own checkout of
objectstack-ai/objectstackDomain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/src/data/object.zod.ts(thetitleFormatdescribe sentence) and its tests; the metadata save door's object-definition refusal (packages/metadata-protocol/src/**, the save-door refusal module) and theos validatedoor that runstitle-format-retired, with their tests; everytitleFormathit in examples, templates and system objects (moved tonameField); root.changeset/; not objectql, not ui, no schema deletion and no conversion (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); one CONTRACT_REVIEW_TIER review (a narrowing on the published schema face) before landing,effort: highClause-②: no (narrowing)
Metadata-protocol: semantic
Responsibility:
packages/spec object.zod.ts titleFormat | ADR-0079 deprecated the key but every door still accepts it, and a stamped nameField outranks it | authors and agents whose titleFormat saves and publishes, then shows only nameFieldThread-read: 6574393684
Premise: holds (QA run #29002 reproduced it three times; the ruling binds refuse-at-save-and-validate)
Serial constraints cleared: PR #29331 merged (
3fb74b6d30, same file); #28205 follows this card onobject.zod.tsRuling-ref: director 6574393684, letter B, maintainer 「454 同意」 — refused at the metadata save gate and by
os validatewith the existing prescription; still parses on read; not honoured, not deleted, no conversion; describe gains one sentence; every repotitleFormathit moves tonameFieldin the same PR. The dev measures the claim pair offline with--eventand reports what the gate accepts.docs(references): regenerate object reference for the titleFormat ref…
docs: author-time rule count 60 -> 61 in CLI transcripts (#29007)
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmQaszscubbRkbhxD9k
os-dev-report
{ "issue": 29007, "status": "done", "branch": "claude/project-thread-ejw6q8", "pr": "https://github.com/objectstack-ai/objectstack/pull/29499", "session": "session_01ADHkmQaszscubbRkbhxD9k", "premise_still_valid": true, "summary": "Ruling 6574393684 letter B. title-format-retired moves out of the advisory validateRecordTitle into a new gating registry rule, validateTitleFormatRetired (CLI_AND_RUNTIME, runtimeTypes ['object']), so os validate/build/lint and the metadata save gate (active save, promotion, restore: 422 INVALID_METADATA) refuse an object that declares titleFormat, with the existing prescription byte-identical. The key stays in the schema and a stored object still parses and loads; the describe gains one sentence; a new D3 semantic entry object-title-format-refused is registered. All 68 code-shipped system objects drop titleFormat (65 already had nameField; sys_attachment, sys_audience_binding_suggestion, sys_notification_template now declare the field the registry already stamped). No example or template declared it.", "tests": "head 0885931864 under os-verify-lock: lint 7834 passed; spec 23451 passed + 1 todo; platform-objects 1505; plugin-approvals 1381; plugin-audit, plugin-security, plugin-sharing, plugin-webhooks, service-automation, service-mailbox, service-messaging, service-realtime, service-storage, metadata-protocol all command-exit 0; cli 6871 passed / 9 skipped (unit + integration). typecheck green for all 15 touched packages (cli test layer needed the CI heap --max-old-space-size=4136; default heap OOM). New pins: lint validate-record-title + runtime-gate.object-writes (refusal, re-save of stored row refused, healed control), metadata-protocol draft-publish-verdict (stored row loads, next save 422, nameField control), cli validate-title-format-retired integration (exit 1 / control exit 0), platform-objects repo-wide no-titleFormat sweep with red fixture. Ablation: severity 'error' -> 'warning' with dist preflight confirmed: lint 5 red, metadata-protocol 2 red, cli 1 red; restored, --absent preflight passed, tree clean.", "gates": "dispatch-gates --commands on 0885931864: 113 derived; dispatch-gates --ran: 113 run, 0 NOT-MEASURED (derived zero), 0 non-zero. First pass reds fixed in-PR: check:docs-transcript-drift (4 CLI transcripts printed 'author-time rules (60)'; the new gating rule makes 61) and check-plugin-teardown-shape --self-test exit 3 (shallow clone; green after fetching pinned 621a4876). check-changeset-no-major --event on the PR body: exit 0 (no (narrowing) + semantic accepted). check-nul-bytes OK. CI check-runs not yet read.", "dogfood_battery": "0885931864 (suite run on 904c42f7; the only later commit edits four .mdx transcript lines, no package source) · os-verify-lock: VERDICT command-exit 0 · held the lock 1775s · Test Files 393 passed | 3 skipped (396) · Tests 3243 passed | 28 skipped (3271) · no failures", "mcp_calls": "2 — mcp__github__issue_read (get), mcp__github__issue_read (get_comments); no write tools", "api_writes": "3 relay writes via fleet-write dispatch: pr_create #29499 (run 41482642352); issue_patch #29499 body (run 41482837189, fixes a shell-mangled docs bullet from my own heredoc); this os-dev-report comment. Plus git pushes to the branch.", "files_changed": "101 files: 68 *.object.ts (titleFormat dropped, 3 gain nameField, comments rewritten); lint src validate-record-title.ts, authoring-rules.ts, index.ts, rule-explanations.ts; spec object.zod.ts describe, migrations/entries/semantic/18.object-title-format-refused.ts, liveness/sharing_rule.json; 9 forced test edits (8 display-title tests -> local RETIRED_TITLE_TEMPLATES map; sys-approval-request-title.integration asserts undefined); 4 pin test files + new packages/cli/test/validate-title-format-retired.test.ts; docs objects.mdx, schema-design.mdx, building-crud-app.mdx, crm-development-standards.mdx, 4 CLI transcript .mdx, 3 regenerated references; .changeset/29007-object-title-format-refused.md", "line_budget": "+728 / -273 (993 changed vs 3000 human-merge threshold): tests +414/-38, object files +146/-190, references +4/-4, other +164/-41", "deviations": [ "Draft saves are not refused: the publish-gate contract (#4463 D1) leaves draft saves ungated; they store with _diagnostics valid:false and their promotion is refused. Read the ruling's 'save gate' as the existing gate (open question 1).", "Composite titles: the 3 objects without nameField got the already-stamped field, and composites were not converted to stored computed fields (new columns would be null on existing rows); only the blank-pointer fallback text changes (open question 2).", "skills/objectstack-data/SKILL.md line 90 still says 'Deprecated, not removed': governed path, left out of this PR.", "Commits 1-3 carry wip: subjects; intended for squash merge." ], "open_questions": [ { "question": "Should a DRAFT save of an object carrying titleFormat be refused too, not only active save / promotion / restore?", "options": ["A keep the #4463 D1 contract: draft stores with valid:false, publish refused", "B add a draft-door refusal for this rule only (a gate-wide exception)"], "recommendation": "A, because the gate contract is uniform for every gating rule and a draft cannot go live anyway" }, { "question": "Should system objects whose retired template was a composite gain a stored computed title field?", "options": ["A no: nameField already titles them and the old template rendered only as a blank-pointer fallback", "B yes: add expression fields and backfill"], "recommendation": "A, because new stored columns would be null on existing rows and need a backfill the ruling did not ask for" } ], "security_findings": "withheld", "out_of_scope_findings": ["class: b · reach: named producer skills/objectstack-data/SKILL.md:90 ('Deprecated, not removed') now understates a refusal · evidence: grep titleFormat skills/ · dedupe words: titleFormat skill prose refused", "carrier: seat · noted, not filed"] }Stamped 2026-11-02T16:35Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS
Claim amendment on #29007 (amends claim 6578956474) · 2026-11-02T16:48Z
Metadata-protocol: semanticbecomesMetadata-protocol: narrowed. Under AGENTS.md checklist 3, a value refused isnarrowed, and "several ⇒ narrowed over semantic". The refusal of an authoredtitleFormatat the save gate and inos validateis an accept-set narrowing.This corrects the seat's own claim line, so it is not a deviation by the implementer.
Clause-②: no (narrowing)is unchanged and the level stays minor. The PR body and the changeset take the corrected line in round 2 (contract review FAIL on08859318, must-fix B).docs(references): regenerate from the merged tree (#29007)
chore(changeset): declare Metadata-protocol narrowed for the titleFor…
docs: author-time rule count 62 in CLI transcripts after merging main (…
docs(references): regenerate from the merged tree (#29007)
docs: author-time rule count 63 in CLI transcripts after merging main (…
fix(platform-objects): sys_personal_view drops the retired titleFormat
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS
Landed · 2026-11-02T21:30Z
3557366c02, through the merge queuecompletedbyFixes #29007pm:dispatchedis removed. The seat ACCEPTed, with the claim amended toClause-②: no (narrowing)/Metadata-protocol: narrowed. The CONTRACT_REVIEW_TIER review FAILed round 1 (transcripts, protocol kind) and then passed on the round-2 delta. A′, the main race on the rule count, was closed by merge-only head63417d56(transcripts 63).What changed: an object that declares
titleFormatis refused at the save door and byos validate, with thenameFieldprescription. The D3 semantic entry isobject-title-format-refused(ADR-0087).Still owed, non-blocking: governed finding #29506 covers the two skills lines and the ADR-0079 D3 note. Next on the same files is #28205, which is free for another spec seat.