@dtmd/temper 0.0.4 → 0.0.7

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 (91) hide show
  1. package/README.md +10 -12
  2. package/bin/temper.js +52 -0
  3. package/dist/src/assembly.d.ts +32 -16
  4. package/dist/src/assembly.js +11 -10
  5. package/dist/src/builtins.d.ts +206 -41
  6. package/dist/src/builtins.js +258 -54
  7. package/dist/src/claude-code.d.ts +7 -9
  8. package/dist/src/claude-code.js +6 -8
  9. package/dist/src/contract.d.ts +47 -24
  10. package/dist/src/contract.js +35 -9
  11. package/dist/src/declarations.d.ts +42 -101
  12. package/dist/src/declarations.js +375 -47
  13. package/dist/src/emit.d.ts +56 -28
  14. package/dist/src/emit.js +177 -54
  15. package/dist/src/generated/AssemblyFactRow.d.ts +29 -0
  16. package/dist/src/generated/AssemblyFactRow.js +2 -0
  17. package/dist/src/generated/BoundRow.d.ts +14 -0
  18. package/dist/src/generated/BoundRow.js +2 -0
  19. package/dist/src/generated/CharsetRow.d.ts +15 -0
  20. package/dist/src/generated/CharsetRow.js +2 -0
  21. package/dist/src/generated/ClauseRow.d.ts +97 -0
  22. package/dist/src/generated/ClauseRow.js +1 -0
  23. package/dist/src/generated/CollectionAddressRow.d.ts +17 -0
  24. package/dist/src/generated/CollectionAddressRow.js +2 -0
  25. package/dist/src/generated/CollectionEntryRow.d.ts +23 -0
  26. package/dist/src/generated/CollectionEntryRow.js +2 -0
  27. package/dist/src/generated/CollectionEntryWire.d.ts +17 -0
  28. package/dist/src/generated/CollectionEntryWire.js +2 -0
  29. package/dist/src/generated/CountBoundRow.d.ts +13 -0
  30. package/dist/src/generated/CountBoundRow.js +2 -0
  31. package/dist/src/generated/Declarations.d.ts +89 -0
  32. package/dist/src/generated/Declarations.js +1 -0
  33. package/dist/src/generated/DegreeBoundRow.d.ts +15 -0
  34. package/dist/src/generated/DegreeBoundRow.js +1 -0
  35. package/dist/src/generated/EdgeBoundRow.d.ts +13 -0
  36. package/dist/src/generated/EdgeBoundRow.js +2 -0
  37. package/dist/src/generated/EmbeddedMember.d.ts +45 -0
  38. package/dist/src/generated/EmbeddedMember.js +1 -0
  39. package/dist/src/generated/EmbeddedMemberCollectionEntry.d.ts +21 -0
  40. package/dist/src/generated/EmbeddedMemberCollectionEntry.js +1 -0
  41. package/dist/src/generated/FeatureValue.d.ts +23 -0
  42. package/dist/src/generated/FeatureValue.js +1 -0
  43. package/dist/src/generated/Features.d.ts +82 -0
  44. package/dist/src/generated/Features.js +1 -0
  45. package/dist/src/generated/FencedBlock.d.ts +24 -0
  46. package/dist/src/generated/FencedBlock.js +2 -0
  47. package/dist/src/generated/IncludeRow.d.ts +18 -0
  48. package/dist/src/generated/IncludeRow.js +2 -0
  49. package/dist/src/generated/KindFactRow.d.ts +65 -0
  50. package/dist/src/generated/KindFactRow.js +1 -0
  51. package/dist/src/generated/LayoutRegionRow.d.ts +29 -0
  52. package/dist/src/generated/LayoutRegionRow.js +2 -0
  53. package/dist/src/generated/LayoutRow.d.ts +12 -0
  54. package/dist/src/generated/LayoutRow.js +1 -0
  55. package/dist/src/generated/MentionRow.d.ts +17 -0
  56. package/dist/src/generated/MentionRow.js +2 -0
  57. package/dist/src/generated/NestedMemberRow.d.ts +39 -0
  58. package/dist/src/generated/NestedMemberRow.js +1 -0
  59. package/dist/src/generated/Payload.d.ts +25 -0
  60. package/dist/src/generated/Payload.js +1 -0
  61. package/dist/src/generated/PayloadMember.d.ts +31 -0
  62. package/dist/src/generated/PayloadMember.js +2 -0
  63. package/dist/src/generated/RangeBoundRow.d.ts +15 -0
  64. package/dist/src/generated/RangeBoundRow.js +2 -0
  65. package/dist/src/generated/RegistrationRow.d.ts +35 -0
  66. package/dist/src/generated/RegistrationRow.js +2 -0
  67. package/dist/src/generated/RequirementRow.d.ts +40 -0
  68. package/dist/src/generated/RequirementRow.js +1 -0
  69. package/dist/src/generated/SatisfiesRow.d.ts +14 -0
  70. package/dist/src/generated/SatisfiesRow.js +2 -0
  71. package/dist/src/generated/Section.d.ts +21 -0
  72. package/dist/src/generated/Section.js +2 -0
  73. package/dist/src/generated/SectionContainsRow.d.ts +14 -0
  74. package/dist/src/generated/SectionContainsRow.js +2 -0
  75. package/dist/src/generated/SettingsRow.d.ts +25 -0
  76. package/dist/src/generated/SettingsRow.js +2 -0
  77. package/dist/src/generated/ValueType.d.ts +9 -0
  78. package/dist/src/generated/ValueType.js +2 -0
  79. package/dist/src/generated/index.d.ts +32 -0
  80. package/dist/src/generated/index.js +1 -0
  81. package/dist/src/index.d.ts +14 -18
  82. package/dist/src/index.js +10 -13
  83. package/dist/src/kind.d.ts +190 -43
  84. package/dist/src/kind.js +34 -30
  85. package/dist/src/needs.d.ts +8 -8
  86. package/dist/src/needs.js +7 -7
  87. package/dist/src/prose.d.ts +75 -28
  88. package/dist/src/prose.js +0 -0
  89. package/package.json +9 -1
  90. package/dist/src/genres.d.ts +0 -38
  91. package/dist/src/genres.js +0 -24
@@ -0,0 +1,35 @@
1
+ /**
2
+ * One fields-only registration member the SDK erased for the manifest write face — a
3
+ * hook, an MCP server — carried across the seam so `emit` routes its host manifest whole
4
+ * through the canonical write face ([`crate::json_manifest::write_manifest`]) rather than
5
+ * the unrepresented in-place splice. `kind`/`key` are the member's identity; `manifest`/
6
+ * `key_path` name the collection address it surfaces at; `fields` are its folded typed
7
+ * fields — the entry value the write face places under `key`.
8
+ *
9
+ * **Seam-inbound with `fields`.** The lock's `registration` declaration family records
10
+ * only the identity and address: the fields live in the projected manifest artifact, never
11
+ * a second copy the engine reads back (0018, "the projection is not the database"), so a
12
+ * row read back off the lock carries an empty `fields`.
13
+ */
14
+ export type RegistrationRow = {
15
+ /**
16
+ * The registration kind's bare name — `hook`, `mcp-server` — joining `declarations.kinds`.
17
+ */
18
+ kind: string;
19
+ /**
20
+ * The member's key among its collection's entries — a hook's event, a server's name.
21
+ */
22
+ key: string;
23
+ /**
24
+ * The host manifest the registration surfaces in (`settings.json`, `.mcp.json`).
25
+ */
26
+ manifest: string;
27
+ /**
28
+ * The manifest key-path label the registration keys at (`hooks.<Event>`, `mcpServers.*`).
29
+ */
30
+ key_path: string;
31
+ /**
32
+ * The member's folded typed fields — seam-inbound only, dropped from the lock row.
33
+ */
34
+ fields: Array<[string, unknown]>;
35
+ };
@@ -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,40 @@
1
+ import type { ClauseRow } from "./ClauseRow.js";
2
+ /**
3
+ * One named requirement's declaration row,
4
+ * carrying the scalar facets plus the requirement's own **clause rows** — the
5
+ * set-scope demands
6
+ * the roster/graph checks range over. No facet columns: a demand's severity,
7
+ * argument, and — for `unique`/`membership` — targeted field ride the nested
8
+ * [`ClauseRow`], the identical row shape a kind's own floor clauses use.
9
+ *
10
+ * Not `Eq`: its nested [`ClauseRow`]s may carry `f64` `range` bounds.
11
+ */
12
+ export type RequirementRow = {
13
+ /**
14
+ * The requirement's name.
15
+ */
16
+ name: string;
17
+ /**
18
+ * The kind that may fill it, when typed by one.
19
+ */
20
+ kind?: string;
21
+ /**
22
+ * Whether an unfilled requirement blocks the gate.
23
+ */
24
+ required: boolean;
25
+ /**
26
+ * The requirement's set-/edge-scope demands, in declaration order — a
27
+ * `count`/`unique`/`membership`/`degree` [`ClauseRow`] per clause, each
28
+ * carrying its own severity. Empty ⇒ no set-scope demand.
29
+ */
30
+ clauses: Array<ClauseRow>;
31
+ /**
32
+ * The external verifier for the behavioral remainder, when declared.
33
+ */
34
+ verified_by?: string;
35
+ /**
36
+ * The authored intent the requirement exists to carry, when declared —
37
+ * carried verbatim, never interpreted.
38
+ */
39
+ prose?: string;
40
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -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,25 @@
1
+ /**
2
+ * One harness-level settings-residue key the SDK erased for the manifest write face — an
3
+ * opaque top-level key of the manifest it names (Claude Code's `settings.json`) with no
4
+ * typed member kind of its own yet. Carried across the seam so `emit` folds it into that
5
+ * manifest's opaque residue beside the collection segments its registration members build.
6
+ *
7
+ * **Seam-inbound with `value`.** Like a composed-prose include, this row is consumed at
8
+ * emit and never written into the lock's declaration table: the value lives in the
9
+ * projected manifest artifact, never a second copy the engine reads back (0018), so a lock
10
+ * round-trip carries none.
11
+ */
12
+ export type SettingsRow = {
13
+ /**
14
+ * The host manifest the residue key surfaces in (`settings.json`).
15
+ */
16
+ manifest: string;
17
+ /**
18
+ * The residue key — an opaque top-level manifest key with no member home.
19
+ */
20
+ key: string;
21
+ /**
22
+ * The key's opaque JSON value, placed verbatim into the manifest's residue.
23
+ */
24
+ value: unknown;
25
+ };
@@ -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,32 @@
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 { CollectionAddressRow } from "./CollectionAddressRow.js";
6
+ export type { CollectionEntryRow } from "./CollectionEntryRow.js";
7
+ export type { CollectionEntryWire } from "./CollectionEntryWire.js";
8
+ export type { CountBoundRow } from "./CountBoundRow.js";
9
+ export type { Declarations } from "./Declarations.js";
10
+ export type { DegreeBoundRow } from "./DegreeBoundRow.js";
11
+ export type { EdgeBoundRow } from "./EdgeBoundRow.js";
12
+ export type { EmbeddedMember } from "./EmbeddedMember.js";
13
+ export type { EmbeddedMemberCollectionEntry } from "./EmbeddedMemberCollectionEntry.js";
14
+ export type { FeatureValue } from "./FeatureValue.js";
15
+ export type { Features } from "./Features.js";
16
+ export type { FencedBlock } from "./FencedBlock.js";
17
+ export type { IncludeRow } from "./IncludeRow.js";
18
+ export type { KindFactRow } from "./KindFactRow.js";
19
+ export type { LayoutRegionRow } from "./LayoutRegionRow.js";
20
+ export type { LayoutRow } from "./LayoutRow.js";
21
+ export type { MentionRow } from "./MentionRow.js";
22
+ export type { NestedMemberRow } from "./NestedMemberRow.js";
23
+ export type { Payload } from "./Payload.js";
24
+ export type { PayloadMember } from "./PayloadMember.js";
25
+ export type { RangeBoundRow } from "./RangeBoundRow.js";
26
+ export type { RegistrationRow } from "./RegistrationRow.js";
27
+ export type { RequirementRow } from "./RequirementRow.js";
28
+ export type { SatisfiesRow } from "./SatisfiesRow.js";
29
+ export type { Section } from "./Section.js";
30
+ export type { SectionContainsRow } from "./SectionContainsRow.js";
31
+ export type { SettingsRow } from "./SettingsRow.js";
32
+ 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 { CollectionAddress, EdgeField, EmbeddedMemberCollectionEntry, EmbeddedMemberValue, Format, KindDefinition, KindFacts, Layout, LayoutRegion, Locus, Member, MemberInit, Registration, Shape, 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, RegistrationFact, 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,36 @@
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,
7
- * 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).
10
- */
11
- import type { Prose } from "./prose.js";
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. A registration kind (a hook,
5
+ * an MCP server) extends the content fact with a fields-only `shape` and a
6
+ * `collectionAddress` naming the host manifest it surfaces in. `tsc` is the keystroke
7
+ * wall; every type erases at the seam, and what a kind leaves behind rides the lock as
8
+ * rows. Identity travels by import, never by string — a `kind` reference is the imported
9
+ * value.
10
+ */
11
+ import type { Prose, Text } from "./prose.js";
12
12
  import type { Capability } from "./needs.js";
13
13
  import type { Requirement } from "./contract.js";
14
14
  /** The shape of the on-disk artifact a member projects to (fact 3, layout). */
15
15
  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
16
  /**
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.
17
+ * Whether a member is a lone file (identity from the stem), a directory with an
18
+ * entry file (identity from the directory name), or a lone file whose identity is
19
+ * read from a declared frontmatter field (`identityField`) instead of derived from
20
+ * the path (an agent's `name`).
21
+ */
22
+ export type UnitShape = "file" | "directory" | "named-field";
23
+ /**
24
+ * One **channel** a kind's registration declares — a documented way a member
25
+ * reaches the world (fact 4, `builtins.md`, "The shipped kinds": "user
26
+ * invocation and description trigger are channels, not rivals"). Reachability
27
+ * is graph reachability from the world node, OR'd across a member's declared
28
+ * channel set — live on any one channel is live.
22
29
  */
23
30
  export type Registration = {
24
31
  readonly via: "always";
32
+ } | {
33
+ readonly via: "user-invoked";
25
34
  } | {
26
35
  readonly via: "description-trigger";
27
36
  readonly field: string;
@@ -42,7 +51,7 @@ export interface EdgeField {
42
51
  }
43
52
  /**
44
53
  * 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 +
54
+ * fenced blocks inside host documents (`embedded`). An `at` locus is split root +
46
55
  * glob so the kind fact row carries `governs_root`/`governs_glob` directly.
47
56
  */
48
57
  export type Locus = {
@@ -50,10 +59,53 @@ export type Locus = {
50
59
  readonly root: string;
51
60
  readonly glob: string;
52
61
  } | {
53
- readonly kind: "genre";
62
+ readonly kind: "embedded";
54
63
  readonly withinHosts: readonly string[];
55
64
  };
56
- /** The five facts of a kind's runtime residue (`15-kinds.md`). */
65
+ /**
66
+ * One region of a kind's **layout** — one of the three corpus primitives over the
67
+ * body's heading tree. `prose` is a verbatim span, or an `import` reference resolving to
68
+ * a file's contents; `field` is a heading whose span fills a named field `slot`;
69
+ * `collection` is a heading whose child headings are each one member of `memberKind`,
70
+ * identity the slugged child heading unless an explicit `key` overrides it.
71
+ */
72
+ export type LayoutRegion = {
73
+ readonly region: "prose";
74
+ readonly import?: string;
75
+ } | {
76
+ readonly region: "field";
77
+ readonly slot: string;
78
+ } | {
79
+ readonly region: "collection";
80
+ readonly memberKind: string;
81
+ readonly key?: string;
82
+ };
83
+ /**
84
+ * A declared **layout** — the ordered regions a `layout`-content kind's body is read as.
85
+ * Declaring one on a kind's `content` makes the kind `layout`-content; leaving `content`
86
+ * absent leaves it `file`-content (one verbatim prose body, the default).
87
+ */
88
+ export interface Layout {
89
+ readonly regions: readonly LayoutRegion[];
90
+ }
91
+ /**
92
+ * A kind's **body shape** marker — `"fields"` for a fields-only kind: no body slot at
93
+ * all, the member its typed fields and edges and nothing more (a hook, an MCP server).
94
+ * Absent leaves the kind body-bearing, its body `file` (the default) or a declared
95
+ * {@link Layout}.
96
+ */
97
+ export type Shape = "fields";
98
+ /**
99
+ * A registration member's **collection address** — where inside a host manifest its
100
+ * registration surfaces: which `manifest` (`settings.json`, `.mcp.json`) and which
101
+ * `keyPath` (`hooks.<Event>`, `mcpServers.*`) it keys at. Carried by a fields-only
102
+ * registration kind; absent for a kind that owns its own file locus.
103
+ */
104
+ export interface CollectionAddress {
105
+ readonly manifest: string;
106
+ readonly keyPath: "hooks.<Event>" | "mcpServers.*";
107
+ }
108
+ /** The six facts of a kind's runtime residue. */
57
109
  export interface KindFacts {
58
110
  /** Fact 1, label — the compiled debug label findings speak; the kind's name. */
59
111
  readonly name: string;
@@ -65,31 +117,44 @@ export interface KindFacts {
65
117
  readonly format?: Format;
66
118
  /** Fact 3b, layout — the on-disk unit shape. */
67
119
  readonly unitShape: UnitShape;
68
- /** Fact 4, registration — the world edge. */
69
- readonly registration: Registration;
120
+ /** Fact 4, registration — the declared channel set naming every documented way
121
+ * the world reaches a member (never rivals — a member is live if any one is). */
122
+ readonly registration: readonly Registration[];
70
123
  /**
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
- */
124
+ * The frontmatter key the member's name writes under. For `unitShape:
125
+ * "named-field"` this is the id **source** — the declared field a member's
126
+ * identity is read from (an agent's `name`), never the filename or directory.
127
+ * For `"directory"` it is a projection-order detail only (a skill's `name`
128
+ * still writes into frontmatter, but identity is the directory name); absent
129
+ * when identity is the file stem and no field carries it (a rule).
130
+ */
75
131
  readonly identityField?: string;
76
132
  /** Fact 5, edge fields — the kind's fields that are references to other members. */
77
133
  readonly edgeFields?: readonly EdgeField[];
134
+ /** Fact 6, content — a declared {@link Layout} over the body's heading tree; absent
135
+ * leaves the kind `file`-content (one verbatim prose body, the default). */
136
+ readonly content?: Layout;
137
+ /** Fact 6b, content — the fields-only body shape (`"fields"`, no body slot); absent
138
+ * leaves the kind body-bearing (`file` or a {@link Layout}). */
139
+ readonly shape?: Shape;
140
+ /** The registration member's {@link CollectionAddress} — which manifest and key path
141
+ * its registration surfaces at; absent for a kind that owns its own file locus. */
142
+ readonly collectionAddress?: CollectionAddress;
78
143
  }
79
144
  /**
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
145
+ * One authored member — a typed value in the library. Kind identity travels by
146
+ * import (`facts`), never by string; the
82
147
  * typed fields are flat at the top level, carried as an ordered pair list so the
83
148
  * projected frontmatter key order is the author's.
84
149
  */
85
150
  export interface Member {
86
151
  /** The kind's name — its declaration-row and lock identity. */
87
152
  readonly kind: string;
88
- /** The kind's five facts — carried for projection and the declaration rows. */
153
+ /** The kind's six facts — carried for projection and the declaration rows. */
89
154
  readonly facts: KindFacts;
90
155
  /** Identity within the kind. */
91
156
  readonly name: string;
92
- /** The member's words (`20-surface.md`, "Prose"). */
157
+ /** The member's words. */
93
158
  readonly prose?: Prose;
94
159
  /** The kind's typed fields, flat and ordered — the projected frontmatter. */
95
160
  readonly fields: ReadonlyArray<readonly [string, unknown]>;
@@ -109,30 +174,112 @@ export type MemberInit<T> = {
109
174
  readonly needs?: readonly Capability[];
110
175
  } & T;
111
176
  /**
112
- * A kind — a callable constructor carrying its five facts. Calling it builds a
177
+ * A kind — a callable constructor carrying its six facts. Calling it builds a
113
178
  * 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").
179
+ * The value *is* the identity — it travels by import, never by string.
115
180
  */
116
181
  export interface KindDefinition<T> {
117
182
  (init: MemberInit<T>): Member;
118
183
  readonly facts: KindFacts;
119
184
  readonly key: string;
185
+ /**
186
+ * An embedded kind's own composed view of one of its values (`representation.md`,
187
+ * "kind": an embedded-locus format is writer-only, so the hook is unconstrained).
188
+ * Every leaf the hook receives is already resolved to its final stored string
189
+ * (`emit.ts`'s `resolveMemberLeaves`) — a hook author never handles a raw `Text`
190
+ * template. Erased at the emit seam — the engine only ever sees the resulting
191
+ * string, never the function. Absent, `blocks()` renders the kind's values with
192
+ * the default `[collection.entry]` TOML view.
193
+ */
194
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
195
+ }
196
+ /** The options `kind()` takes beyond its six facts — today, only the embedded `render` hook. */
197
+ export interface KindOptions {
198
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
120
199
  }
121
200
  /**
122
- * Define a kind (`15-kinds.md`). Returns a constructor over the kind's typed
201
+ * Define a kind. Returns a constructor over the kind's typed
123
202
  * 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.
203
+ * into emit is the six facts plus flat field data. `options.render`, when given,
204
+ * rides alongside `facts`/`key` on the returned constructor — never on the member
205
+ * it builds, since it is erased before a member reaches emit.
125
206
  */
126
- export declare function kind<T extends object>(facts: KindFacts): KindDefinition<T>;
207
+ export declare function kind<T extends object>(facts: KindFacts, options?: KindOptions): KindDefinition<T>;
208
+ /**
209
+ * One entry in a sibling collection: its own key plus its leaf fields
210
+ * (`rejected."baked-projection"`) — an ordered list element, never a positional
211
+ * index; the entry's `key` is what a leaf address carries.
212
+ */
213
+ export interface EmbeddedMemberCollectionEntry {
214
+ /** The entry's key among its collection's siblings. */
215
+ readonly key: string;
216
+ /**
217
+ * The entry's own leaf fields: field name → authored string, or a `Text`
218
+ * template whose mentions resolve the way a member-level `Text` body does.
219
+ */
220
+ readonly leaves: Readonly<Record<string, string | Text>>;
221
+ }
222
+ /**
223
+ * An **embedded member's** composed value (posture 3, passed to `blocks()`):
224
+ * leaves are authored strings keyed by field name; sibling collections are keyed
225
+ * by collection name, each an authored-order list of entries — leaf addresses
226
+ * are structural and keyed. Its
227
+ * facts are declaration rows, captured the same emit pass that renders it —
228
+ * never mined back from the `member.<kind> <key>` fence `blocks()` renders
229
+ * (`pipeline.md`, "Emit"). There is no prescribed child-kind ontology — a
230
+ * corpus that wants one declares its own child kind with the same machinery.
231
+ */
232
+ export interface EmbeddedMemberValue {
233
+ /** The child kind this value instantiates — the fence info string's `member.<kind>`. */
234
+ readonly kind: string;
235
+ /** The value's key — the identity a leaf address carries (`surface-authority`). */
236
+ readonly key: string;
237
+ /**
238
+ * Prose leaves: authored strings, law-5 protected one by one, or a `Text`
239
+ * template carrying its own mentions — a leaf mention lifts into the host's
240
+ * mention rows and resolves the way a member-level `Text` body does.
241
+ */
242
+ readonly leaves: Readonly<Record<string, string | Text>>;
243
+ /** Sibling collections: collection name → its entries, in authored order. */
244
+ readonly collections: Readonly<Record<string, readonly EmbeddedMemberCollectionEntry[]>>;
245
+ /** The originating kind's `render` hook, when declared — resolved once at construction. */
246
+ readonly render?: (value: ResolvedEmbeddedMemberValue) => string;
247
+ }
248
+ /**
249
+ * One resolved sibling-collection entry: its own key plus its leaf fields,
250
+ * already resolved to plain strings — no `Text` template remains.
251
+ */
252
+ export interface ResolvedEmbeddedMemberCollectionEntry {
253
+ /** The entry's key among its collection's siblings. */
254
+ readonly key: string;
255
+ /** The entry's own leaf fields, already resolved to their final strings. */
256
+ readonly leaves: Readonly<Record<string, string>>;
257
+ }
258
+ /**
259
+ * An {@link EmbeddedMemberValue} after every leaf (top-level and each
260
+ * collection entry's) resolves to its final stored string
261
+ * (`emit.ts`'s `resolveMemberLeaves`) — the shape a kind's own `render` hook
262
+ * receives, so a hook author never handles a raw `Text` leaf.
263
+ */
264
+ export interface ResolvedEmbeddedMemberValue {
265
+ /** The child kind this value instantiates. */
266
+ readonly kind: string;
267
+ /** The value's key. */
268
+ readonly key: string;
269
+ /** Prose leaves, already resolved to their final strings. */
270
+ readonly leaves: Readonly<Record<string, string>>;
271
+ /** Sibling collections, each entry's leaves already resolved. */
272
+ readonly collections: Readonly<Record<string, readonly ResolvedEmbeddedMemberCollectionEntry[]>>;
273
+ }
127
274
  /**
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.
275
+ * Compose an embedded member's value for `blocks()` — the shape any project's own
276
+ * child kind uses. `kind` names the child kind: a bare string, or the child kind's
277
+ * own `KindDefinition` — passing the definition carries its `render` hook (when
278
+ * declared) through to emit, with no other change to the composed value's shape.
132
279
  */
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>;
280
+ export declare function embeddedMemberValue(init: {
281
+ kind: string | KindDefinition<any>;
282
+ key: string;
283
+ leaves: Readonly<Record<string, string | Text>>;
284
+ collections?: EmbeddedMemberValue["collections"];
285
+ }): EmbeddedMemberValue;