@dtmd/temper 0.0.4 → 0.0.6

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.
Files changed (84) hide show
  1. package/README.md +10 -12
  2. package/dist/src/assembly.d.ts +32 -16
  3. package/dist/src/assembly.js +11 -10
  4. package/dist/src/builtins.d.ts +104 -40
  5. package/dist/src/builtins.js +130 -53
  6. package/dist/src/claude-code.d.ts +7 -9
  7. package/dist/src/claude-code.js +6 -8
  8. package/dist/src/contract.d.ts +47 -24
  9. package/dist/src/contract.js +35 -9
  10. package/dist/src/declarations.d.ts +25 -103
  11. package/dist/src/declarations.js +311 -47
  12. package/dist/src/emit.d.ts +13 -32
  13. package/dist/src/emit.js +136 -53
  14. package/dist/src/generated/AssemblyFactRow.d.ts +29 -0
  15. package/dist/src/generated/AssemblyFactRow.js +2 -0
  16. package/dist/src/generated/BoundRow.d.ts +14 -0
  17. package/dist/src/generated/BoundRow.js +2 -0
  18. package/dist/src/generated/CharsetRow.d.ts +15 -0
  19. package/dist/src/generated/CharsetRow.js +2 -0
  20. package/dist/src/generated/ClauseRow.d.ts +97 -0
  21. package/dist/src/generated/ClauseRow.js +1 -0
  22. package/dist/src/generated/CollectionEntryRow.d.ts +23 -0
  23. package/dist/src/generated/CollectionEntryRow.js +2 -0
  24. package/dist/src/generated/CollectionEntryWire.d.ts +17 -0
  25. package/dist/src/generated/CollectionEntryWire.js +2 -0
  26. package/dist/src/generated/CountBoundRow.d.ts +13 -0
  27. package/dist/src/generated/CountBoundRow.js +2 -0
  28. package/dist/src/generated/Declarations.d.ts +72 -0
  29. package/dist/src/generated/Declarations.js +1 -0
  30. package/dist/src/generated/DegreeBoundRow.d.ts +15 -0
  31. package/dist/src/generated/DegreeBoundRow.js +1 -0
  32. package/dist/src/generated/EdgeBoundRow.d.ts +13 -0
  33. package/dist/src/generated/EdgeBoundRow.js +2 -0
  34. package/dist/src/generated/EmbeddedMember.d.ts +45 -0
  35. package/dist/src/generated/EmbeddedMember.js +1 -0
  36. package/dist/src/generated/EmbeddedMemberCollectionEntry.d.ts +21 -0
  37. package/dist/src/generated/EmbeddedMemberCollectionEntry.js +1 -0
  38. package/dist/src/generated/FeatureValue.d.ts +23 -0
  39. package/dist/src/generated/FeatureValue.js +1 -0
  40. package/dist/src/generated/Features.d.ts +82 -0
  41. package/dist/src/generated/Features.js +1 -0
  42. package/dist/src/generated/FencedBlock.d.ts +24 -0
  43. package/dist/src/generated/FencedBlock.js +2 -0
  44. package/dist/src/generated/IncludeRow.d.ts +18 -0
  45. package/dist/src/generated/IncludeRow.js +2 -0
  46. package/dist/src/generated/KindFactRow.d.ts +51 -0
  47. package/dist/src/generated/KindFactRow.js +1 -0
  48. package/dist/src/generated/LayoutRegionRow.d.ts +29 -0
  49. package/dist/src/generated/LayoutRegionRow.js +2 -0
  50. package/dist/src/generated/LayoutRow.d.ts +12 -0
  51. package/dist/src/generated/LayoutRow.js +1 -0
  52. package/dist/src/generated/MentionRow.d.ts +17 -0
  53. package/dist/src/generated/MentionRow.js +2 -0
  54. package/dist/src/generated/NestedMemberRow.d.ts +39 -0
  55. package/dist/src/generated/NestedMemberRow.js +1 -0
  56. package/dist/src/generated/Payload.d.ts +25 -0
  57. package/dist/src/generated/Payload.js +1 -0
  58. package/dist/src/generated/PayloadMember.d.ts +31 -0
  59. package/dist/src/generated/PayloadMember.js +2 -0
  60. package/dist/src/generated/RangeBoundRow.d.ts +15 -0
  61. package/dist/src/generated/RangeBoundRow.js +2 -0
  62. package/dist/src/generated/RequirementRow.d.ts +40 -0
  63. package/dist/src/generated/RequirementRow.js +1 -0
  64. package/dist/src/generated/SatisfiesRow.d.ts +14 -0
  65. package/dist/src/generated/SatisfiesRow.js +2 -0
  66. package/dist/src/generated/Section.d.ts +21 -0
  67. package/dist/src/generated/Section.js +2 -0
  68. package/dist/src/generated/SectionContainsRow.d.ts +14 -0
  69. package/dist/src/generated/SectionContainsRow.js +2 -0
  70. package/dist/src/generated/ValueType.d.ts +9 -0
  71. package/dist/src/generated/ValueType.js +2 -0
  72. package/dist/src/generated/index.d.ts +29 -0
  73. package/dist/src/generated/index.js +1 -0
  74. package/dist/src/index.d.ts +14 -18
  75. package/dist/src/index.js +10 -13
  76. package/dist/src/kind.d.ts +163 -41
  77. package/dist/src/kind.js +24 -24
  78. package/dist/src/needs.d.ts +8 -8
  79. package/dist/src/needs.js +7 -7
  80. package/dist/src/prose.d.ts +75 -28
  81. package/dist/src/prose.js +0 -0
  82. package/package.json +1 -1
  83. package/dist/src/genres.d.ts +0 -38
  84. package/dist/src/genres.js +0 -24
@@ -0,0 +1,14 @@
1
+ /**
2
+ * One member→requirement fill edge's declaration row — the `satisfies` join the
3
+ * roster/coverage tiers need, carried on the lock rather than re-imported.
4
+ */
5
+ export type SatisfiesRow = {
6
+ /**
7
+ * The filling member's id.
8
+ */
9
+ member: string;
10
+ /**
11
+ * The requirement key the member opts into filling.
12
+ */
13
+ requirement: string;
14
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * One ATX **section** of a markdown body: a heading paired with the body span
3
+ * beneath it, up to the next heading of the same or a shallower level. The
4
+ * feature a `section_contains` clause decides over — its [`heading`](Section::heading) is
5
+ * matched by the clause's declared prefix, its [`body`](Section::body) searched
6
+ * for the declared marker. Surface-decidable like every other feature: a heading
7
+ * inside a fenced code block opens no section (the same exclusion
8
+ * [`body_headings`] makes), so a section is never a guess.
9
+ */
10
+ export type Section = {
11
+ /**
12
+ * The heading text, with its `#` markers stripped exactly as
13
+ * [`body_headings`] strips them.
14
+ */
15
+ heading: string;
16
+ /**
17
+ * The body span beneath the heading — the intervening lines rejoined with
18
+ * `\n`, the text a `section_contains` marker check searches.
19
+ */
20
+ body: string;
21
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A `section_contains` clause row's arguments — the heading-text prefix selecting the
3
+ * governed sections and the marker every governed section's body must carry.
4
+ */
5
+ export type SectionContainsRow = {
6
+ /**
7
+ * The heading-text prefix that selects the sections the clause governs.
8
+ */
9
+ heading: string;
10
+ /**
11
+ * The marker text every governed section's body must contain.
12
+ */
13
+ marker: string;
14
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A field's parsed source kind — the closed scalar/container lattice a kind's
3
+ * field schema ranges over. Taken from the *parsed*
4
+ * YAML/JSON value, not its stringified form: a sound `type` check needs the
5
+ * extractor to preserve the source kind rather than collapse every scalar to a
6
+ * bare string (the slice-1 shortcut this entry corrects). The five scalar kinds
7
+ * answer [`FeatureValue::as_scalar`]; the two container kinds do not.
8
+ */
9
+ export type ValueType = "String" | "Integer" | "Number" | "Boolean" | "Null" | "List" | "Map";
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -0,0 +1,29 @@
1
+ export type { AssemblyFactRow } from "./AssemblyFactRow.js";
2
+ export type { BoundRow } from "./BoundRow.js";
3
+ export type { CharsetRow } from "./CharsetRow.js";
4
+ export type { ClauseRow } from "./ClauseRow.js";
5
+ export type { CollectionEntryRow } from "./CollectionEntryRow.js";
6
+ export type { CollectionEntryWire } from "./CollectionEntryWire.js";
7
+ export type { CountBoundRow } from "./CountBoundRow.js";
8
+ export type { Declarations } from "./Declarations.js";
9
+ export type { DegreeBoundRow } from "./DegreeBoundRow.js";
10
+ export type { EdgeBoundRow } from "./EdgeBoundRow.js";
11
+ export type { EmbeddedMember } from "./EmbeddedMember.js";
12
+ export type { EmbeddedMemberCollectionEntry } from "./EmbeddedMemberCollectionEntry.js";
13
+ export type { FeatureValue } from "./FeatureValue.js";
14
+ export type { Features } from "./Features.js";
15
+ export type { FencedBlock } from "./FencedBlock.js";
16
+ export type { IncludeRow } from "./IncludeRow.js";
17
+ export type { KindFactRow } from "./KindFactRow.js";
18
+ export type { LayoutRegionRow } from "./LayoutRegionRow.js";
19
+ export type { LayoutRow } from "./LayoutRow.js";
20
+ export type { MentionRow } from "./MentionRow.js";
21
+ export type { NestedMemberRow } from "./NestedMemberRow.js";
22
+ export type { Payload } from "./Payload.js";
23
+ export type { PayloadMember } from "./PayloadMember.js";
24
+ export type { RangeBoundRow } from "./RangeBoundRow.js";
25
+ export type { RequirementRow } from "./RequirementRow.js";
26
+ export type { SatisfiesRow } from "./SatisfiesRow.js";
27
+ export type { Section } from "./Section.js";
28
+ export type { SectionContainsRow } from "./SectionContainsRow.js";
29
+ export type { ValueType } from "./ValueType.js";
@@ -0,0 +1 @@
1
+ export {};
@@ -1,32 +1,28 @@
1
1
  /**
2
- * temper's authoring face — the six-noun core as a typed module library
3
- * (`specs/intent/00-intent.md`, the SDK Decision; `specs/architecture/20-surface.md`).
4
- * A harness author imports plain nouns — `harness()`, the generic `kind`/`genre`
5
- * constructors, the clause and requirement constructors, `needs`, and the three
2
+ * temper's authoring face — the six-noun core as a typed module library.
3
+ * A harness author imports plain nouns — `harness()`, the generic `kind`
4
+ * constructor, the clause and requirement constructors, `needs`, and the three
6
5
  * prose constructors — and composes members as typed values. `emit` compiles the
7
6
  * whole into the declaration rows and the projected members' erased payload —
8
7
  * the JSON pipe printed to stdout; the engine is the sole compiler of every
9
- * projection and the whole lock (`20-surface.md`, "The seam — one
10
- * implementation"). Every type erases at the seam, and Turing-completeness
8
+ * projection and the whole lock.
9
+ * Every type erases at the seam, and Turing-completeness
11
10
  * stays quarantined at authoring time.
12
11
  *
13
12
  * The first-party Claude Code provider face — the built-in `skill`/`rule`/
14
- * `memory` kinds — lives at the `./claude-code` subpath, never here
15
- * (`specs/architecture/50-distribution.md`, "Decision: one SDK package").
13
+ * `memory` kinds — lives at the `./claude-code` subpath, never here.
16
14
  */
17
- export type { Blocks, File, Mention, Mentionable, Prose, Text } from "./prose.js";
18
- export { blocks, file, renderText, text } from "./prose.js";
19
- export type { GenreValue } from "./genres.js";
20
- export { genreValue } from "./genres.js";
15
+ export type { Blocks, File, Include, Mention, Mentionable, Prose, Reference, Text } from "./prose.js";
16
+ export { blocks, file, include, renderText, text } from "./prose.js";
21
17
  export type { Capability } from "./needs.js";
22
18
  export { bash, capability, permissionUnion } from "./needs.js";
23
19
  export type { Charset, Clause, Predicate, Requirement, Severity } from "./contract.js";
24
- export { allowedChars, clause, count, degree, deny, forbiddenKeys, maxLen, maxLines, membership, minLen, nameMatchesDir, required, requireSections, requirement, type, unique, } from "./contract.js";
25
- export type { EdgeField, Format, KindDefinition, KindFacts, Locus, Member, MemberInit, Registration, UnitShape, } from "./kind.js";
26
- export { genre, kind } from "./kind.js";
27
- export type { ExpectBinding, Harness } from "./assembly.js";
20
+ export { allowedChars, clause, count, degree, deny, enumOf, forbiddenKeys, maxLen, maxLines, membership, minLen, mustDefine, nameMatchesDir, optional, range, required, requireSections, requirement, sectionContains, type, unique, uniqueName, } from "./contract.js";
21
+ export type { EdgeField, EmbeddedMemberCollectionEntry, EmbeddedMemberValue, Format, KindDefinition, KindFacts, Layout, LayoutRegion, Locus, Member, MemberInit, Registration, UnitShape, } from "./kind.js";
22
+ export { embeddedMemberValue, kind } from "./kind.js";
23
+ export type { EnforcementMode, ExpectBinding, Harness } from "./assembly.js";
28
24
  export { harness } from "./assembly.js";
29
25
  export type { AssemblyFactRow, ClauseRow, Declarations, KindFactRow, RequirementRow, SatisfiesRow, } from "./declarations.js";
30
- export { SEAM_VERSION, compileDeclarations, declarationsToJson } from "./declarations.js";
31
- export type { EmitOptions, EmitResult, PayloadMember, ResolveOptions } from "./emit.js";
26
+ export { SEAM_VERSION, compileDeclarations } from "./declarations.js";
27
+ export type { EmitResult, PayloadMember, ResolveOptions } from "./emit.js";
32
28
  export { emit } from "./emit.js";
package/dist/src/index.js CHANGED
@@ -1,24 +1,21 @@
1
1
  /**
2
- * temper's authoring face — the six-noun core as a typed module library
3
- * (`specs/intent/00-intent.md`, the SDK Decision; `specs/architecture/20-surface.md`).
4
- * A harness author imports plain nouns — `harness()`, the generic `kind`/`genre`
5
- * constructors, the clause and requirement constructors, `needs`, and the three
2
+ * temper's authoring face — the six-noun core as a typed module library.
3
+ * A harness author imports plain nouns — `harness()`, the generic `kind`
4
+ * constructor, the clause and requirement constructors, `needs`, and the three
6
5
  * prose constructors — and composes members as typed values. `emit` compiles the
7
6
  * whole into the declaration rows and the projected members' erased payload —
8
7
  * the JSON pipe printed to stdout; the engine is the sole compiler of every
9
- * projection and the whole lock (`20-surface.md`, "The seam — one
10
- * implementation"). Every type erases at the seam, and Turing-completeness
8
+ * projection and the whole lock.
9
+ * Every type erases at the seam, and Turing-completeness
11
10
  * stays quarantined at authoring time.
12
11
  *
13
12
  * The first-party Claude Code provider face — the built-in `skill`/`rule`/
14
- * `memory` kinds — lives at the `./claude-code` subpath, never here
15
- * (`specs/architecture/50-distribution.md`, "Decision: one SDK package").
13
+ * `memory` kinds — lives at the `./claude-code` subpath, never here.
16
14
  */
17
- export { blocks, file, renderText, text } from "./prose.js";
18
- export { genreValue } from "./genres.js";
15
+ export { blocks, file, include, renderText, text } from "./prose.js";
19
16
  export { bash, capability, permissionUnion } from "./needs.js";
20
- export { allowedChars, clause, count, degree, deny, forbiddenKeys, maxLen, maxLines, membership, minLen, nameMatchesDir, required, requireSections, requirement, type, unique, } from "./contract.js";
21
- export { genre, kind } from "./kind.js";
17
+ export { allowedChars, clause, count, degree, deny, enumOf, forbiddenKeys, maxLen, maxLines, membership, minLen, mustDefine, nameMatchesDir, optional, range, required, requireSections, requirement, sectionContains, type, unique, uniqueName, } from "./contract.js";
18
+ export { embeddedMemberValue, kind } from "./kind.js";
22
19
  export { harness } from "./assembly.js";
23
- export { SEAM_VERSION, compileDeclarations, declarationsToJson } from "./declarations.js";
20
+ export { SEAM_VERSION, compileDeclarations } from "./declarations.js";
24
21
  export { emit } from "./emit.js";
@@ -1,27 +1,34 @@
1
1
  /**
2
- * Kinds — the engine room (`specs/architecture/15-kinds.md`, "A kind is a
3
- * constructor plus five facts"). A kind is a plain typed surface — an interface
4
- * `T` and a constructor `kind<T>()` — plus five facts of runtime residue: label,
5
- * locus, layout, registration, and edge fields. `tsc` is the keystroke wall; every
6
- * type erases at the seam, and what a kind leaves behind is those five facts,
2
+ * Kinds — the engine room. A kind is a plain typed surface — an interface
3
+ * `T` and a constructor `kind<T>()` — plus six facts of runtime residue: label,
4
+ * locus, layout, registration, edge fields, and content. `tsc` is the keystroke wall;
5
+ * every type erases at the seam, and what a kind leaves behind is those six facts,
7
6
  * riding the lock as rows. Identity travels by import, never by string — a `kind`
8
- * reference is the imported value (`15-kinds.md`, the built-ins-are-a-module
9
- * Decision).
7
+ * reference is the imported value.
10
8
  */
11
- import type { Prose } from "./prose.js";
9
+ import type { Prose, Text } from "./prose.js";
12
10
  import type { Capability } from "./needs.js";
13
11
  import type { Requirement } from "./contract.js";
14
12
  /** The shape of the on-disk artifact a member projects to (fact 3, layout). */
15
13
  export type Format = "yaml-frontmatter";
16
- /** Whether a member is a lone file (identity from the stem) or a directory with an entry file. */
17
- export type UnitShape = "file" | "directory";
18
14
  /**
19
- * A kind's **registration** — the declared edge between a member and the world
20
- * (fact 4, `15-kinds.md`, "Registration"). Reachability is graph reachability
21
- * from the world node over these edges.
15
+ * Whether a member is a lone file (identity from the stem), a directory with an
16
+ * entry file (identity from the directory name), or a lone file whose identity is
17
+ * read from a declared frontmatter field (`identityField`) instead of derived from
18
+ * the path (an agent's `name`).
19
+ */
20
+ export type UnitShape = "file" | "directory" | "named-field";
21
+ /**
22
+ * One **channel** a kind's registration declares — a documented way a member
23
+ * reaches the world (fact 4, `builtins.md`, "The shipped kinds": "user
24
+ * invocation and description trigger are channels, not rivals"). Reachability
25
+ * is graph reachability from the world node, OR'd across a member's declared
26
+ * channel set — live on any one channel is live.
22
27
  */
23
28
  export type Registration = {
24
29
  readonly via: "always";
30
+ } | {
31
+ readonly via: "user-invoked";
25
32
  } | {
26
33
  readonly via: "description-trigger";
27
34
  readonly field: string;
@@ -42,7 +49,7 @@ export interface EdgeField {
42
49
  }
43
50
  /**
44
51
  * A kind's **locus** (fact 2): members live at path globs (`at`) or as typed
45
- * fenced blocks inside host documents (`genre`). An `at` locus is split root +
52
+ * fenced blocks inside host documents (`embedded`). An `at` locus is split root +
46
53
  * glob so the kind fact row carries `governs_root`/`governs_glob` directly.
47
54
  */
48
55
  export type Locus = {
@@ -50,10 +57,36 @@ export type Locus = {
50
57
  readonly root: string;
51
58
  readonly glob: string;
52
59
  } | {
53
- readonly kind: "genre";
60
+ readonly kind: "embedded";
54
61
  readonly withinHosts: readonly string[];
55
62
  };
56
- /** The five facts of a kind's runtime residue (`15-kinds.md`). */
63
+ /**
64
+ * One region of a kind's **layout** — one of the three corpus primitives over the
65
+ * body's heading tree. `prose` is a verbatim span, or an `import` reference resolving to
66
+ * a file's contents; `field` is a heading whose span fills a named field `slot`;
67
+ * `collection` is a heading whose child headings are each one member of `memberKind`,
68
+ * identity the slugged child heading unless an explicit `key` overrides it.
69
+ */
70
+ export type LayoutRegion = {
71
+ readonly region: "prose";
72
+ readonly import?: string;
73
+ } | {
74
+ readonly region: "field";
75
+ readonly slot: string;
76
+ } | {
77
+ readonly region: "collection";
78
+ readonly memberKind: string;
79
+ readonly key?: string;
80
+ };
81
+ /**
82
+ * A declared **layout** — the ordered regions a `layout`-content kind's body is read as.
83
+ * Declaring one on a kind's `content` makes the kind `layout`-content; leaving `content`
84
+ * absent leaves it `file`-content (one verbatim prose body, the default).
85
+ */
86
+ export interface Layout {
87
+ readonly regions: readonly LayoutRegion[];
88
+ }
89
+ /** The six facts of a kind's runtime residue. */
57
90
  export interface KindFacts {
58
91
  /** Fact 1, label — the compiled debug label findings speak; the kind's name. */
59
92
  readonly name: string;
@@ -65,31 +98,38 @@ export interface KindFacts {
65
98
  readonly format?: Format;
66
99
  /** Fact 3b, layout — the on-disk unit shape. */
67
100
  readonly unitShape: UnitShape;
68
- /** Fact 4, registration — the world edge. */
69
- readonly registration: Registration;
101
+ /** Fact 4, registration — the declared channel set naming every documented way
102
+ * the world reaches a member (never rivals — a member is live if any one is). */
103
+ readonly registration: readonly Registration[];
70
104
  /**
71
- * The frontmatter key the member's name writes under (a skill's `name`), or
72
- * absent when identity is the file stem (a rule). A layout detail: it shapes
73
- * the projected frontmatter, never the model.
74
- */
105
+ * The frontmatter key the member's name writes under. For `unitShape:
106
+ * "named-field"` this is the id **source** — the declared field a member's
107
+ * identity is read from (an agent's `name`), never the filename or directory.
108
+ * For `"directory"` it is a projection-order detail only (a skill's `name`
109
+ * still writes into frontmatter, but identity is the directory name); absent
110
+ * when identity is the file stem and no field carries it (a rule).
111
+ */
75
112
  readonly identityField?: string;
76
113
  /** Fact 5, edge fields — the kind's fields that are references to other members. */
77
114
  readonly edgeFields?: readonly EdgeField[];
115
+ /** Fact 6, content — a declared {@link Layout} over the body's heading tree; absent
116
+ * leaves the kind `file`-content (one verbatim prose body, the default). */
117
+ readonly content?: Layout;
78
118
  }
79
119
  /**
80
- * One authored member — a typed value in the library (`20-surface.md`, "The
81
- * member"). Kind identity travels by import (`facts`), never by string; the
120
+ * One authored member — a typed value in the library. Kind identity travels by
121
+ * import (`facts`), never by string; the
82
122
  * typed fields are flat at the top level, carried as an ordered pair list so the
83
123
  * projected frontmatter key order is the author's.
84
124
  */
85
125
  export interface Member {
86
126
  /** The kind's name — its declaration-row and lock identity. */
87
127
  readonly kind: string;
88
- /** The kind's five facts — carried for projection and the declaration rows. */
128
+ /** The kind's six facts — carried for projection and the declaration rows. */
89
129
  readonly facts: KindFacts;
90
130
  /** Identity within the kind. */
91
131
  readonly name: string;
92
- /** The member's words (`20-surface.md`, "Prose"). */
132
+ /** The member's words. */
93
133
  readonly prose?: Prose;
94
134
  /** The kind's typed fields, flat and ordered — the projected frontmatter. */
95
135
  readonly fields: ReadonlyArray<readonly [string, unknown]>;
@@ -109,30 +149,112 @@ export type MemberInit<T> = {
109
149
  readonly needs?: readonly Capability[];
110
150
  } & T;
111
151
  /**
112
- * A kind — a callable constructor carrying its five facts. Calling it builds a
152
+ * A kind — a callable constructor carrying its six facts. Calling it builds a
113
153
  * member; `key` (its name) keys `expect` and a `kind` reference in a requirement.
114
- * The value *is* the identity (`15-kinds.md`, "identity travels by import").
154
+ * The value *is* the identity — it travels by import, never by string.
115
155
  */
116
156
  export interface KindDefinition<T> {
117
157
  (init: MemberInit<T>): Member;
118
158
  readonly facts: KindFacts;
119
159
  readonly key: string;
160
+ /**
161
+ * An embedded kind's own composed view of one of its values (`representation.md`,
162
+ * "kind": an embedded-locus format is writer-only, so the hook is unconstrained).
163
+ * Every leaf the hook receives is already resolved to its final stored string
164
+ * (`emit.ts`'s `resolveMemberLeaves`) — a hook author never handles a raw `Text`
165
+ * template. Erased at the emit seam — the engine only ever sees the resulting
166
+ * string, never the function. Absent, `blocks()` renders the kind's values with
167
+ * the default `[collection.entry]` TOML view.
168
+ */
169
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
170
+ }
171
+ /** The options `kind()` takes beyond its six facts — today, only the embedded `render` hook. */
172
+ export interface KindOptions {
173
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
120
174
  }
121
175
  /**
122
- * Define a kind (`15-kinds.md`). Returns a constructor over the kind's typed
176
+ * Define a kind. Returns a constructor over the kind's typed
123
177
  * fields `T`; every type erases at the seam, so what the returned member carries
124
- * into emit is the five facts plus flat field data.
178
+ * into emit is the six facts plus flat field data. `options.render`, when given,
179
+ * rides alongside `facts`/`key` on the returned constructor — never on the member
180
+ * it builds, since it is erased before a member reaches emit.
125
181
  */
126
- export declare function kind<T extends object>(facts: KindFacts): KindDefinition<T>;
182
+ export declare function kind<T extends object>(facts: KindFacts, options?: KindOptions): KindDefinition<T>;
183
+ /**
184
+ * One entry in a sibling collection: its own key plus its leaf fields
185
+ * (`rejected."baked-projection"`) — an ordered list element, never a positional
186
+ * index; the entry's `key` is what a leaf address carries.
187
+ */
188
+ export interface EmbeddedMemberCollectionEntry {
189
+ /** The entry's key among its collection's siblings. */
190
+ readonly key: string;
191
+ /**
192
+ * The entry's own leaf fields: field name → authored string, or a `Text`
193
+ * template whose mentions resolve the way a member-level `Text` body does.
194
+ */
195
+ readonly leaves: Readonly<Record<string, string | Text>>;
196
+ }
197
+ /**
198
+ * An **embedded member's** composed value (posture 3, passed to `blocks()`):
199
+ * leaves are authored strings keyed by field name; sibling collections are keyed
200
+ * by collection name, each an authored-order list of entries — leaf addresses
201
+ * are structural and keyed. Its
202
+ * facts are declaration rows, captured the same emit pass that renders it —
203
+ * never mined back from the `member.<kind> <key>` fence `blocks()` renders
204
+ * (`pipeline.md`, "Emit"). There is no prescribed child-kind ontology — a
205
+ * corpus that wants one declares its own child kind with the same machinery.
206
+ */
207
+ export interface EmbeddedMemberValue {
208
+ /** The child kind this value instantiates — the fence info string's `member.<kind>`. */
209
+ readonly kind: string;
210
+ /** The value's key — the identity a leaf address carries (`surface-authority`). */
211
+ readonly key: string;
212
+ /**
213
+ * Prose leaves: authored strings, law-5 protected one by one, or a `Text`
214
+ * template carrying its own mentions — a leaf mention lifts into the host's
215
+ * mention rows and resolves the way a member-level `Text` body does.
216
+ */
217
+ readonly leaves: Readonly<Record<string, string | Text>>;
218
+ /** Sibling collections: collection name → its entries, in authored order. */
219
+ readonly collections: Readonly<Record<string, readonly EmbeddedMemberCollectionEntry[]>>;
220
+ /** The originating kind's `render` hook, when declared — resolved once at construction. */
221
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
222
+ }
223
+ /**
224
+ * One resolved sibling-collection entry: its own key plus its leaf fields,
225
+ * already resolved to plain strings — no `Text` template remains.
226
+ */
227
+ export interface ResolvedEmbeddedMemberCollectionEntry {
228
+ /** The entry's key among its collection's siblings. */
229
+ readonly key: string;
230
+ /** The entry's own leaf fields, already resolved to their final strings. */
231
+ readonly leaves: Readonly<Record<string, string>>;
232
+ }
233
+ /**
234
+ * An {@link EmbeddedMemberValue} after every leaf (top-level and each
235
+ * collection entry's) resolves to its final stored string
236
+ * (`emit.ts`'s `resolveMemberLeaves`) — the shape a kind's own `render` hook
237
+ * receives, so a hook author never handles a raw `Text` leaf.
238
+ */
239
+ export interface ResolvedEmbeddedMemberValue {
240
+ /** The child kind this value instantiates. */
241
+ readonly kind: string;
242
+ /** The value's key. */
243
+ readonly key: string;
244
+ /** Prose leaves, already resolved to their final strings. */
245
+ readonly leaves: Readonly<Record<string, string>>;
246
+ /** Sibling collections, each entry's leaves already resolved. */
247
+ readonly collections: Readonly<Record<string, readonly ResolvedEmbeddedMemberCollectionEntry[]>>;
248
+ }
127
249
  /**
128
- * Define a **genre** — a kind whose locus is `genre(within hosts)`: its members
129
- * live as typed fenced blocks inside host documents instead of at their own
130
- * paths (`15-kinds.md`, "A genre is a kind at the block locus"). Registration
131
- * inherits through the host, so a genre carries no world edge of its own.
250
+ * Compose an embedded member's value for `blocks()` — the shape any project's own
251
+ * child kind uses. `kind` names the child kind: a bare string, or the child kind's
252
+ * own `KindDefinition` — passing the definition carries its `render` hook (when
253
+ * declared) through to emit, with no other change to the composed value's shape.
132
254
  */
133
- export declare function genre<T extends object>(facts: {
134
- name: string;
135
- provider?: string;
136
- withinHosts: readonly string[];
137
- edgeFields?: readonly EdgeField[];
138
- }): KindDefinition<T>;
255
+ export declare function embeddedMemberValue(init: {
256
+ kind: string | KindDefinition<any>;
257
+ key: string;
258
+ leaves: Readonly<Record<string, string | Text>>;
259
+ collections?: EmbeddedMemberValue["collections"];
260
+ }): EmbeddedMemberValue;
package/dist/src/kind.js CHANGED
@@ -1,12 +1,10 @@
1
1
  /**
2
- * Kinds — the engine room (`specs/architecture/15-kinds.md`, "A kind is a
3
- * constructor plus five facts"). A kind is a plain typed surface — an interface
4
- * `T` and a constructor `kind<T>()` — plus five facts of runtime residue: label,
5
- * locus, layout, registration, and edge fields. `tsc` is the keystroke wall; every
6
- * type erases at the seam, and what a kind leaves behind is those five facts,
2
+ * Kinds — the engine room. A kind is a plain typed surface — an interface
3
+ * `T` and a constructor `kind<T>()` — plus six facts of runtime residue: label,
4
+ * locus, layout, registration, edge fields, and content. `tsc` is the keystroke wall;
5
+ * every type erases at the seam, and what a kind leaves behind is those six facts,
7
6
  * riding the lock as rows. Identity travels by import, never by string — a `kind`
8
- * reference is the imported value (`15-kinds.md`, the built-ins-are-a-module
9
- * Decision).
7
+ * reference is the imported value.
10
8
  */
11
9
  /** The framework keys of a member init — everything else is a typed field (flat). */
12
10
  const FRAMEWORK_KEYS = new Set(["name", "prose", "satisfies", "requires", "needs"]);
@@ -28,11 +26,13 @@ function orderedFields(facts, init) {
28
26
  return [...head, ...typed];
29
27
  }
30
28
  /**
31
- * Define a kind (`15-kinds.md`). Returns a constructor over the kind's typed
29
+ * Define a kind. Returns a constructor over the kind's typed
32
30
  * fields `T`; every type erases at the seam, so what the returned member carries
33
- * into emit is the five facts plus flat field data.
31
+ * into emit is the six facts plus flat field data. `options.render`, when given,
32
+ * rides alongside `facts`/`key` on the returned constructor — never on the member
33
+ * it builds, since it is erased before a member reaches emit.
34
34
  */
35
- export function kind(facts) {
35
+ export function kind(facts, options = {}) {
36
36
  const construct = (init) => ({
37
37
  kind: facts.name,
38
38
  facts,
@@ -43,21 +43,21 @@ export function kind(facts) {
43
43
  requires: init.requires ?? {},
44
44
  needs: init.needs ?? [],
45
45
  });
46
- return Object.assign(construct, { facts, key: facts.name });
46
+ return Object.assign(construct, { facts, key: facts.name, render: options.render });
47
47
  }
48
48
  /**
49
- * Define a **genre** — a kind whose locus is `genre(within hosts)`: its members
50
- * live as typed fenced blocks inside host documents instead of at their own
51
- * paths (`15-kinds.md`, "A genre is a kind at the block locus"). Registration
52
- * inherits through the host, so a genre carries no world edge of its own.
49
+ * Compose an embedded member's value for `blocks()` — the shape any project's own
50
+ * child kind uses. `kind` names the child kind: a bare string, or the child kind's
51
+ * own `KindDefinition` — passing the definition carries its `render` hook (when
52
+ * declared) through to emit, with no other change to the composed value's shape.
53
53
  */
54
- export function genre(facts) {
55
- return kind({
56
- name: facts.name,
57
- provider: facts.provider,
58
- locus: { kind: "genre", withinHosts: facts.withinHosts },
59
- unitShape: "file",
60
- registration: { via: "always" },
61
- edgeFields: facts.edgeFields,
62
- });
54
+ export function embeddedMemberValue(init) {
55
+ const [kindName, render] = typeof init.kind === "string" ? [init.kind, undefined] : [init.kind.key, init.kind.render];
56
+ return {
57
+ kind: kindName,
58
+ key: init.key,
59
+ leaves: init.leaves,
60
+ collections: init.collections ?? {},
61
+ ...(render !== undefined ? { render } : {}),
62
+ };
63
63
  }
@@ -1,31 +1,31 @@
1
1
  /**
2
- * Needs — the capabilities a member's behavior uses, declared as typed values
3
- * (`specs/architecture/20-surface.md`, "The member"; "Emit — total"). Emit derives
2
+ * Needs — the capabilities a member's behavior uses, declared as typed values.
3
+ * Emit derives
4
4
  * the settings permission list from their union, so a permission is never authored
5
5
  * twice: `permissions.allow` is the union of the members' declared `needs`, and a
6
- * permission with no member is visible as exactly that (the derived-list Decision).
6
+ * permission with no member is visible as exactly that.
7
7
  */
8
8
  /** A declared capability — its `permission` is the entry it derives in the union. */
9
9
  export interface Capability {
10
10
  /**
11
11
  * The permission-list entry this capability derives. The union of every
12
12
  * member's needs is the settings `permissions.allow` — the fold hooks and MCP
13
- * members ride into once those kinds land (`20-surface.md`, "Emit — total").
13
+ * members ride into once those kinds land.
14
14
  */
15
15
  readonly permission: string;
16
16
  }
17
17
  /**
18
18
  * A shell-command capability. Its derived permission is the Claude Code allow
19
19
  * entry `Bash(<command>)` (code.claude.com/docs/en/settings, retrieved
20
- * 2026-07-04) — the port scene's `bash("git diff")` (`20-surface.md`).
20
+ * 2026-07-04) — e.g. `bash("git diff")`.
21
21
  */
22
22
  export declare function bash(command: string): Capability;
23
23
  /** Any capability whose permission entry the author states verbatim. */
24
24
  export declare function capability(permission: string): Capability;
25
25
  /**
26
26
  * The derived permission list — the union of every capability's entry, deduped
27
- * and sorted so the derived artifact is byte-stable across runs (law 5). The
28
- * permission is derived here, never authored (`20-surface.md`, the derived-list
29
- * Decision).
27
+ * and sorted so the derived artifact is byte-stable across runs.
28
+ * The
29
+ * permission is derived here, never authored.
30
30
  */
31
31
  export declare function permissionUnion(needs: readonly Capability[]): string[];
package/dist/src/needs.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Needs — the capabilities a member's behavior uses, declared as typed values
3
- * (`specs/architecture/20-surface.md`, "The member"; "Emit — total"). Emit derives
2
+ * Needs — the capabilities a member's behavior uses, declared as typed values.
3
+ * Emit derives
4
4
  * the settings permission list from their union, so a permission is never authored
5
5
  * twice: `permissions.allow` is the union of the members' declared `needs`, and a
6
- * permission with no member is visible as exactly that (the derived-list Decision).
6
+ * permission with no member is visible as exactly that.
7
7
  */
8
8
  /**
9
9
  * A shell-command capability. Its derived permission is the Claude Code allow
10
10
  * entry `Bash(<command>)` (code.claude.com/docs/en/settings, retrieved
11
- * 2026-07-04) — the port scene's `bash("git diff")` (`20-surface.md`).
11
+ * 2026-07-04) — e.g. `bash("git diff")`.
12
12
  */
13
13
  export function bash(command) {
14
14
  return { permission: `Bash(${command})` };
@@ -19,9 +19,9 @@ export function capability(permission) {
19
19
  }
20
20
  /**
21
21
  * The derived permission list — the union of every capability's entry, deduped
22
- * and sorted so the derived artifact is byte-stable across runs (law 5). The
23
- * permission is derived here, never authored (`20-surface.md`, the derived-list
24
- * Decision).
22
+ * and sorted so the derived artifact is byte-stable across runs.
23
+ * The
24
+ * permission is derived here, never authored.
25
25
  */
26
26
  export function permissionUnion(needs) {
27
27
  return [...new Set(needs.map((need) => need.permission))].sort();