Skip to content

Commit fa18f81

Browse files
dmealingclaude
andcommitted
fix(requirements): viewWeb promised a control; view.web is an abstract base
The ledger's L4 for view.web said "a rich-content control declares that a value is edited as formatted web content". It is not a control. Its own registry description reads "Abstract base for web-rendered views" and the constant naming it carries the same comment; nothing extends it and no generator dispatches on it. The finding worth keeping is that nothing could have caught this. Two shipped artifacts call it an abstract base while a third — registry-manifest-exclusions, which I edited in this same program — counts it among "the 13 generic view.* controls". And STRUCTURALLY it is indistinguishable from a concrete control: no entry in that provider carries an abstract flag, so a base and a control differ only in prose. The coverage gate checks that a name derives a registered subtype and can never check what the requirement SAYS about it — the gap between spelling and meaning that this whole program is about, found inside the program's own output. The entry now describes an abstract base and records the contradiction in notes. The exclusions comment is corrected to "13 generic view.* entries — 12 controls plus the web abstract base", which is what the count actually covers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NynrRND6ZUwGvq3ZUTCfxG
1 parent 7935582 commit fa18f81

7 files changed

Lines changed: 33 additions & 18 deletions

File tree

‎fixtures/requirement-harness/csharp/RequirementHarnessTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ public void declare_presentation_viewText() { /* metaobjects.declare.presentatio
308308
[Fact(Skip = "unfilled slot — write an assertion that fails when: A paragraph edited through a one-line control, so the author cannot see what they have written.")]
309309
public void declare_presentation_viewTextarea() { /* metaobjects.declare.presentation.viewTextarea */ }
310310

311-
// Rich content — A rich-content control declares that a value is edited as formatted web content rather than as plain text.
312-
[Fact(Skip = "unfilled slot — write an assertion that fails when: Formatted content edited as plain text, so its markup is shown to the author instead of applied.")]
311+
// Web-rendered view base — An abstract base groups the views that render in a browser, so what they share is declared once rather than on each of them.
312+
[Fact(Skip = "unfilled slot — write an assertion that fails when: A property common to every browser-rendered view restated on each one, where adding a view means remembering to restate it again.")]
313313
public void declare_presentation_viewWeb() { /* metaobjects.declare.presentation.viewWeb */ }
314314

315315
// Aggregation — An aggregation declares that one object groups others which outlive it.

‎fixtures/requirement-harness/java/RequirementHarnessTest.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,9 @@ void declare_presentation_viewText() { /* metaobjects.declare.presentation.viewT
382382
@Disabled("unfilled slot — write an assertion that fails when: A paragraph edited through a one-line control, so the author cannot see what they have written.")
383383
void declare_presentation_viewTextarea() { /* metaobjects.declare.presentation.viewTextarea */ }
384384

385-
// Rich content — A rich-content control declares that a value is edited as formatted web content rather than as plain text.
385+
// Web-rendered view base — An abstract base groups the views that render in a browser, so what they share is declared once rather than on each of them.
386386
@Test
387-
@Disabled("unfilled slot — write an assertion that fails when: Formatted content edited as plain text, so its markup is shown to the author instead of applied.")
387+
@Disabled("unfilled slot — write an assertion that fails when: A property common to every browser-rendered view restated on each one, where adding a view means remembering to restate it again.")
388388
void declare_presentation_viewWeb() { /* metaobjects.declare.presentation.viewWeb */ }
389389

390390
// Aggregation — An aggregation declares that one object groups others which outlive it.

‎fixtures/requirement-harness/kotlin/RequirementHarnessTest.kt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,9 @@ class RequirementHarnessTest {
382382
@Disabled("unfilled slot — write an assertion that fails when: A paragraph edited through a one-line control, so the author cannot see what they have written.")
383383
fun declare_presentation_viewTextarea() { /* metaobjects.declare.presentation.viewTextarea */ }
384384

385-
// Rich content — A rich-content control declares that a value is edited as formatted web content rather than as plain text.
385+
// Web-rendered view base — An abstract base groups the views that render in a browser, so what they share is declared once rather than on each of them.
386386
@Test
387-
@Disabled("unfilled slot — write an assertion that fails when: Formatted content edited as plain text, so its markup is shown to the author instead of applied.")
387+
@Disabled("unfilled slot — write an assertion that fails when: A property common to every browser-rendered view restated on each one, where adding a view means remembering to restate it again.")
388388
fun declare_presentation_viewWeb() { /* metaobjects.declare.presentation.viewWeb */ }
389389

390390
// Aggregation — An aggregation declares that one object groups others which outlive it.

‎fixtures/requirement-harness/python/test_requirement_harness.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,8 @@ def test_declare_presentation_viewText():
377377
def test_declare_presentation_viewTextarea():
378378
"""metaobjects.declare.presentation.viewTextarea"""
379379

380-
# Rich content — A rich-content control declares that a value is edited as formatted web content rather than as plain text.
381-
@pytest.mark.skip(reason="unfilled slot — write an assertion that fails when: Formatted content edited as plain text, so its markup is shown to the author instead of applied.")
380+
# Web-rendered view base — An abstract base groups the views that render in a browser, so what they share is declared once rather than on each of them.
381+
@pytest.mark.skip(reason="unfilled slot — write an assertion that fails when: A property common to every browser-rendered view restated on each one, where adding a view means remembering to restate it again.")
382382
def test_declare_presentation_viewWeb():
383383
"""metaobjects.declare.presentation.viewWeb"""
384384

‎fixtures/requirement-harness/typescript/requirement-harness.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,9 @@ test.skip("metaobjects.declare.presentation.viewTextarea", () => {
377377
// unfilled slot — write an assertion that fails when: A paragraph edited through a one-line control, so the author cannot see what they have written.
378378
});
379379

380-
// Rich content — A rich-content control declares that a value is edited as formatted web content rather than as plain text.
380+
// Web-rendered view base — An abstract base groups the views that render in a browser, so what they share is declared once rather than on each of them.
381381
test.skip("metaobjects.declare.presentation.viewWeb", () => {
382-
// unfilled slot — write an assertion that fails when: Formatted content edited as plain text, so its markup is shown to the author instead of applied.
382+
// unfilled slot — write an assertion that fails when: A property common to every browser-rendered view restated on each one, where adding a view means remembering to restate it again.
383383
});
384384

385385
// Aggregation — An aggregation declares that one object groups others which outlive it.

‎metaobjects/meta.requirements.yaml‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,16 +1475,29 @@ metadata.root:
14751475
submit because there was no way to carry it.
14761476
- requirement.functional:
14771477
name: viewWeb
1478-
title: Rich content
1478+
title: Web-rendered view base
14791479
level: 4
14801480
status: live
14811481
statement: >-
1482-
A rich-content control declares that a value is
1483-
edited as formatted web content rather than as
1484-
plain text.
1482+
An abstract base groups the views that render in a
1483+
browser, so what they share is declared once rather
1484+
than on each of them.
14851485
counterexample: >-
1486-
Formatted content edited as plain text, so its
1487-
markup is shown to the author instead of applied.
1486+
A property common to every browser-rendered view
1487+
restated on each one, where adding a view means
1488+
remembering to restate it again.
1489+
notes: >-
1490+
First authored as a rich-content control, which is
1491+
wrong, and the mistake is recorded because nothing
1492+
could have caught it. Two shipped artifacts call this
1493+
an abstract base — its own registry description and
1494+
the constant naming it — while a third counts it
1495+
among the generic view controls, and STRUCTURALLY it
1496+
is indistinguishable from a concrete one: no entry in
1497+
this provider carries an abstract flag, so a base and
1498+
a control differ only in prose. The coverage gate
1499+
checks that a name derives a registered subtype and
1500+
can never check what the requirement SAYS about it.
14881501
- requirement.functional:
14891502
name: viewImage
14901503
title: Image upload

‎server/typescript/packages/metadata/src/registry-manifest-exclusions.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
// - INHERITANCE_ANCHOR the `metadata.base` per-port abstract anchor (the
3434
// deferred `inheritsFrom` facet; other ports register
3535
// only the concrete `metadata.root`).
36-
// - PRESENTATION_ONLY the 13 generic `view.*` controls (checkbox/date/…)
36+
// - PRESENTATION_ONLY the 13 generic `view.*` entries — 12 controls
37+
// (checkbox/date/…) plus the `web` abstract base
3738
// — a TS-web presentation facet (TS web client + TS
3839
// form codegen consume them; zero backend/codegen/
3940
// render consumers in any port), like the TS-only `D1`
@@ -127,7 +128,8 @@ export const EXCLUDED_PER_TYPE_ATTRS: ReadonlyMap<string, ExclusionReason> = new
127128
/**
128129
* `(type, subType)` rows carved OUT of the agreed vocabulary, with reason.
129130
* `metadata.base` is the per-port inheritance anchor (INHERITANCE_ANCHOR); the
130-
* 13 generic `view.*` controls are TS-web-presentation-only (PRESENTATION_ONLY).
131+
* 13 generic `view.*` entries — 12 controls plus the `web` abstract base — are
132+
* TS-web-presentation-only (PRESENTATION_ONLY).
131133
* Returns the reason, or `undefined` for an INCLUDED (logical) row.
132134
*/
133135
export function classifyTypeSubType(

0 commit comments

Comments
 (0)