@terpjs/spec 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,17 +67,28 @@ The artifacts:
67
67
  extensions, deep-import segments). The portable prohibition rules cite it
68
68
  structurally (the `restricted_surface` catalog field); which sanctioned
69
69
  component answers each primitive is per-stack configuration.
70
- 7. **The residual ratchet** (`corpus/RESIDUALS.json`) — the statically-erased
70
+ 7. **The layout declaration** (`layout-declaration.schema.json`) — the
71
+ stack-neutral, normative schema for the document an app checks in to declare
72
+ which slot-typed page contract it opts into, which palette it starts on, and
73
+ how its application shell is shaped (content measure, density, navigation
74
+ placement, the navigation groups a module's items name by id, and the mark
75
+ the app is recognised by). One document, so a build-time checker and the running app read the
76
+ same bytes and neither can hold a different answer — and so a tool that edits
77
+ files rather than code can read and rewrite those choices. Naming the contract
78
+ and naming a palette are the app's to do and their values are per-stack, hence
79
+ plain strings; the shell's vocabulary is fixed normatively, and the reference
80
+ stack's resolver is parity-tested against it.
81
+ 8. **The residual ratchet** (`corpus/RESIDUALS.json`) — the statically-erased
71
82
  or renamed forms deliberately outside the corpus contract, per rule, as
72
83
  shrink-only data (see "Detector boundaries" below).
73
- 8. **The scorecard format** (`scorecard.schema.json`) — the machine-readable
84
+ 9. **The scorecard format** (`scorecard.schema.json`) — the machine-readable
74
85
  certification summary a conformant checker emits (spec version, per-rule
75
86
  verdicts over the corpus, residuals claimed), so "certified against spec
76
87
  X.Y.Z" is a verifiable artifact instead of a claim.
77
- 9. **The changelog** (`CHANGELOG.md`) — the change history keyed to `VERSION`
88
+ 10. **The changelog** (`CHANGELOG.md`) — the change history keyed to `VERSION`
78
89
  (the top entry must match, held by the spec suite), so a checker certified
79
90
  against an earlier version can see exactly what changed since.
80
- 10. **The rule pages** (`docs/rules/`) — plain-language documentation generated
91
+ 11. **The rule pages** (`docs/rules/`) — plain-language documentation generated
81
92
  from the catalog (`tools/generate_rule_docs.py`; regenerate-and-compare
82
93
  parity in the spec suite, so the pages cannot drift from the data).
83
94
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.25.0
1
+ 0.26.0
@@ -2,7 +2,7 @@
2
2
  "id": "frontend/layout-contract",
3
3
  "surface": "frontend",
4
4
  "title": "An opted-in app's archetype body slots accept only the contract's components",
5
- "intent": "With a checked-in layout contract, each page archetype's body slot is constrained to the contract's sanctioned components, so screens stay structurally consistent and the failure message tells an agent exactly how to build the screen. Paired with the fail-closed runtime check on the rendered slot.",
5
+ "intent": "With a checked-in layout declaration, each page archetype's body slot is constrained to the contract's sanctioned components, so screens stay structurally consistent and the failure message tells an agent exactly how to build the screen. Paired with the fail-closed runtime check on the rendered slot. The declaration is the single source for the opt-in, for the palette the app opens on, and for the shell's own shape down to the navigation groups a module's items name by id and the mark the app is recognised by (layout-declaration.schema.json): a build-time checker and the running app read the same document, so neither can enforce a contract the other does not, and a key declared both in the document and in the app's own code is refused rather than resolved by an invisible precedence.",
6
6
  "layer": "static-bespoke",
7
7
  "enforcement": [
8
8
  {
@@ -18,7 +18,7 @@
18
18
  }
19
19
  ],
20
20
  "opt_out": "// terp-allow-layout-contract: <reason>",
21
- "reference": "frontend/layout-contract.json + the layoutContract bootstrap option (ADR 0079); verifySlotChildren in @terpjs/react-core is the runtime DOM check.",
21
+ "reference": "frontend/layout-contract.json, the document layout-declaration.schema.json describes (ADR 0079); the app imports it and the reference stack's bootstrap resolves it, refusing an unknown key, a value outside its enum, and any key declared twice. The per-stack values: contracts are the keys of LAYOUT_CONTRACTS in @terpjs/react-core, and defaultTheme names one of the palettes @terpjs/contract compiles or the reserved system. Neither list is written out here: the contract ids and the palette names both live in @terpjs/react-core's published layout.manifest.json, with the values filled in for the release an app is pinned to, and every copy of them in that stack is gated against it. A fourth copy in this field would be the one nothing checks, and it would sit in the very field this schema points a reader at for the truth. shell.navGroups is groupNav's group table in @terpjs/react-core, whose NavItem.group references it; shell.brand names paths Vite serves from the app's own frontend/public, rendered into AppShell's logo and logoDark slots. verifySlotChildren in @terpjs/react-core is the runtime DOM check.",
22
22
  "runtime": {
23
23
  "applicability": "required"
24
24
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terpjs/spec",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "The Terp Standard — stack-neutral rule catalog, violation corpus, finding format, and refused-surface declaration (ADRs 0080/0081; packaged per ADR 0082, published per ADR 0086). Data only: consumers resolve the spec root via require.resolve('@terpjs/spec/package.json').",
5
5
  "files": [
6
6
  "VERSION",