⛔ 分级与路由(domain:* / priority:* / type)属分诊,本卡由执行席 domain:spec 不带分级立卡。⛔ Filed unassigned.
Surfaced by the at-tier contract review of PR #16862 (card #16714) as its finding N1, rated non-blocking by that reviewer and not ridden on that PR — the ruling for #16714 named only the filters docblock, and its item 3 explicitly preserves the tolerance this sentence misdescribes.
The defect
packages/spec/src/ui/app.zod.ts, the recordId field's docblock (locate by text, ⛔ not by line number):
Mutually exclusive with viewName (viewName is ignored if both are set).
The guard does not refuse that pair. Measured through NavigationItemSchema at bf41b3f60: recordId + viewName parses clean. It is the one combination objectNavTargetExclusivity deliberately tolerates, and the guard's own docblock says so in as many words — "The legacy recordId + viewName combination stays tolerated".
⇒ Two docblocks in one file describe the same rule and disagree: the guard's is right, recordId's is wrong. The parenthetical is the tell — "viewName is ignored if both are set" describes a precedence, not a refusal, so the sentence's own second clause contradicts its first.
⭐ Why this is worth a card and not a note
This is the same defect class as #16714, one field over, in the same file — prose that asserts a stricter contract than the code enforces. #16714 existed because a precedence sentence sat a few lines above a sentence declaring the combination unrepresentable; this is that shape again, inverted: a refusal sentence sitting above a rule that tolerates.
⚠️ And the harm direction is the one this file family keeps producing: an author (or an agent) who reads "mutually exclusive" will avoid a combination the platform accepts, or will file a bug when it parses. The failure is silent in both directions.
What bounds it — measured, so the card does not overstate itself
⇒ single-file, single-sentence, no consumer, no generated output. Fact layer only.
Shape of a fix (⛔ not a ruling — the tolerance itself is settled and stays)
Rewrite the sentence to describe what the code does. The reviewer's suggestion, recorded rather than mandated:
Tolerated, not refused: viewName is ignored when both are set.
⛔ Do not "unify" the asymmetry. Triage's ruling on #16714 item 3 keeps recordId + viewName tolerated, and PR #16862's ablation M2 exists precisely to make that tolerance go red if someone makes the fields pairwise exclusive. This card corrects the prose; the behaviour is deliberate and pinned.
⭐ Worth pinning the sentence too, if cheap: app-nav-target-exclusivity-export.test.ts already asserts recordId + viewName accepts, so a docblock assertion beside it would close the drift rather than just fix today's copy.
Dedup
Whole domain:spec lane enumerated to the last page at 2026-09-08T12:31Z — 141 returned against totalCount 141, so the enumeration is complete, not a sample — and no open card covers this sentence; #16714 is the only neighbour and it is the filters docblock.
⚠️ Limit of that check, stated rather than hidden: it is an enumeration of the domain:spec lane, so a bare/untriaged duplicate outside the lane would not appear in it. ⛔ Keyword search was deliberately not used as the control: search_issues returns total_count: 0 for camelCase identifiers in this repo (recorded on #16779), and every useful term here — recordId, viewName, objectNavTargetExclusivity — is camelCase, so a zero from that channel would be a tokenizer artefact and not a reading.
Refs: #16714 (the parent card) · PR #16862 (where N1 was found; the review is comment 5585289881).
⛔ 分级与路由(
domain:*/priority:*/type)属分诊,本卡由执行席domain:spec不带分级立卡。⛔ Filed unassigned.Surfaced by the at-tier contract review of PR #16862 (card #16714) as its finding N1, rated non-blocking by that reviewer and not ridden on that PR — the ruling for #16714 named only the
filtersdocblock, and its item 3 explicitly preserves the tolerance this sentence misdescribes.The defect
packages/spec/src/ui/app.zod.ts, therecordIdfield's docblock (locate by text, ⛔ not by line number):The guard does not refuse that pair. Measured through
NavigationItemSchemaatbf41b3f60:recordId+viewNameparses clean. It is the one combinationobjectNavTargetExclusivitydeliberately tolerates, and the guard's own docblock says so in as many words — "The legacyrecordId+viewNamecombination stays tolerated".⇒ Two docblocks in one file describe the same rule and disagree: the guard's is right,
recordId's is wrong. The parenthetical is the tell — "viewName is ignored if both are set" describes a precedence, not a refusal, so the sentence's own second clause contradicts its first.⭐ Why this is worth a card and not a note
This is the same defect class as #16714, one field over, in the same file — prose that asserts a stricter contract than the code enforces. #16714 existed because a precedence sentence sat a few lines above a sentence declaring the combination unrepresentable; this is that shape again, inverted: a refusal sentence sitting above a rule that tolerates.
What bounds it — measured, so the card does not overstate itself
recordIddescribe carries no "mutually exclusive" phrase at three shas — the pinned.objectui-sha53ded82b,3f775ee, and objectuiorigin/maine411c3e. (Contrast thefiltersprecedence sentence, which was copied verbatim into objectui and is exactly why objectui's hand-written NavigationItemSchema never re-implements objectNavTargetExclusivity — its door acceptsfilters+recordIdtogether, which spec refuses #16714 was a two-repo problem.).describe()string, andbuild-docs.tsreads no field JSDoc — socontent/docs/references/**does not carry it.⇒ single-file, single-sentence, no consumer, no generated output. Fact layer only.
Shape of a fix (⛔ not a ruling — the tolerance itself is settled and stays)
Rewrite the sentence to describe what the code does. The reviewer's suggestion, recorded rather than mandated:
⛔ Do not "unify" the asymmetry. Triage's ruling on #16714 item 3 keeps
recordId+viewNametolerated, and PR #16862's ablation M2 exists precisely to make that tolerance go red if someone makes the fields pairwise exclusive. This card corrects the prose; the behaviour is deliberate and pinned.⭐ Worth pinning the sentence too, if cheap:
app-nav-target-exclusivity-export.test.tsalready assertsrecordId + viewNameaccepts, so a docblock assertion beside it would close the drift rather than just fix today's copy.Dedup
Whole
domain:speclane enumerated to the last page at 2026-09-08T12:31Z — 141 returned againsttotalCount141, so the enumeration is complete, not a sample — and no open card covers this sentence; #16714 is the only neighbour and it is thefiltersdocblock.domain:speclane, so a bare/untriaged duplicate outside the lane would not appear in it. ⛔ Keyword search was deliberately not used as the control:search_issuesreturnstotal_count: 0for camelCase identifiers in this repo (recorded on #16779), and every useful term here —recordId,viewName,objectNavTargetExclusivity— is camelCase, so a zero from that channel would be a tokenizer artefact and not a reading.Refs: #16714 (the parent card) · PR #16862 (where N1 was found; the review is comment
5585289881).