@spikedpunch/align-core 0.1.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.
Files changed (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -0
  3. package/dist/baseline/fingerprint.d.ts +19 -0
  4. package/dist/baseline/fingerprint.d.ts.map +1 -0
  5. package/dist/baseline/fingerprint.js +0 -0
  6. package/dist/baseline/fingerprint.js.map +1 -0
  7. package/dist/baseline/store.d.ts +81 -0
  8. package/dist/baseline/store.d.ts.map +1 -0
  9. package/dist/baseline/store.js +111 -0
  10. package/dist/baseline/store.js.map +1 -0
  11. package/dist/build/diff.d.ts +22 -0
  12. package/dist/build/diff.d.ts.map +1 -0
  13. package/dist/build/diff.js +61 -0
  14. package/dist/build/diff.js.map +1 -0
  15. package/dist/build/export-ir.d.ts +11 -0
  16. package/dist/build/export-ir.d.ts.map +1 -0
  17. package/dist/build/export-ir.js +4 -0
  18. package/dist/build/export-ir.js.map +1 -0
  19. package/dist/build/ground.d.ts +32 -0
  20. package/dist/build/ground.d.ts.map +1 -0
  21. package/dist/build/ground.js +162 -0
  22. package/dist/build/ground.js.map +1 -0
  23. package/dist/build/hash.d.ts +10 -0
  24. package/dist/build/hash.d.ts.map +1 -0
  25. package/dist/build/hash.js +13 -0
  26. package/dist/build/hash.js.map +1 -0
  27. package/dist/build/impact.d.ts +20 -0
  28. package/dist/build/impact.d.ts.map +1 -0
  29. package/dist/build/impact.js +15 -0
  30. package/dist/build/impact.js.map +1 -0
  31. package/dist/build/index.d.ts +14 -0
  32. package/dist/build/index.d.ts.map +1 -0
  33. package/dist/build/index.js +14 -0
  34. package/dist/build/index.js.map +1 -0
  35. package/dist/build/merge.d.ts +27 -0
  36. package/dist/build/merge.d.ts.map +1 -0
  37. package/dist/build/merge.js +85 -0
  38. package/dist/build/merge.js.map +1 -0
  39. package/dist/build/propose.d.ts +16 -0
  40. package/dist/build/propose.d.ts.map +1 -0
  41. package/dist/build/propose.js +126 -0
  42. package/dist/build/propose.js.map +1 -0
  43. package/dist/build/provenance.d.ts +19 -0
  44. package/dist/build/provenance.d.ts.map +1 -0
  45. package/dist/build/provenance.js +23 -0
  46. package/dist/build/provenance.js.map +1 -0
  47. package/dist/build/schema.d.ts +1825 -0
  48. package/dist/build/schema.d.ts.map +1 -0
  49. package/dist/build/schema.js +128 -0
  50. package/dist/build/schema.js.map +1 -0
  51. package/dist/build/sections.d.ts +30 -0
  52. package/dist/build/sections.d.ts.map +1 -0
  53. package/dist/build/sections.js +58 -0
  54. package/dist/build/sections.js.map +1 -0
  55. package/dist/build/tier1.d.ts +24 -0
  56. package/dist/build/tier1.d.ts.map +1 -0
  57. package/dist/build/tier1.js +68 -0
  58. package/dist/build/tier1.js.map +1 -0
  59. package/dist/build/tier2.d.ts +42 -0
  60. package/dist/build/tier2.d.ts.map +1 -0
  61. package/dist/build/tier2.js +187 -0
  62. package/dist/build/tier2.js.map +1 -0
  63. package/dist/build/types.d.ts +42 -0
  64. package/dist/build/types.d.ts.map +1 -0
  65. package/dist/build/types.js +2 -0
  66. package/dist/build/types.js.map +1 -0
  67. package/dist/components/glob.d.ts +10 -0
  68. package/dist/components/glob.d.ts.map +1 -0
  69. package/dist/components/glob.js +52 -0
  70. package/dist/components/glob.js.map +1 -0
  71. package/dist/components/registry.d.ts +51 -0
  72. package/dist/components/registry.d.ts.map +1 -0
  73. package/dist/components/registry.js +121 -0
  74. package/dist/components/registry.js.map +1 -0
  75. package/dist/dsl/factories.d.ts +86 -0
  76. package/dist/dsl/factories.d.ts.map +1 -0
  77. package/dist/dsl/factories.js +145 -0
  78. package/dist/dsl/factories.js.map +1 -0
  79. package/dist/dsl/index.d.ts +46 -0
  80. package/dist/dsl/index.d.ts.map +1 -0
  81. package/dist/dsl/index.js +67 -0
  82. package/dist/dsl/index.js.map +1 -0
  83. package/dist/dsl/reserved-names.typecheck.d.ts +2 -0
  84. package/dist/dsl/reserved-names.typecheck.d.ts.map +1 -0
  85. package/dist/dsl/reserved-names.typecheck.js +16 -0
  86. package/dist/dsl/reserved-names.typecheck.js.map +1 -0
  87. package/dist/dsl/verb-manifest.d.ts +12 -0
  88. package/dist/dsl/verb-manifest.d.ts.map +1 -0
  89. package/dist/dsl/verb-manifest.js +101 -0
  90. package/dist/dsl/verb-manifest.js.map +1 -0
  91. package/dist/fix/apply.d.ts +67 -0
  92. package/dist/fix/apply.d.ts.map +1 -0
  93. package/dist/fix/apply.js +163 -0
  94. package/dist/fix/apply.js.map +1 -0
  95. package/dist/fix/index.d.ts +3 -0
  96. package/dist/fix/index.d.ts.map +1 -0
  97. package/dist/fix/index.js +3 -0
  98. package/dist/fix/index.js.map +1 -0
  99. package/dist/fix/schema.d.ts +180 -0
  100. package/dist/fix/schema.d.ts.map +1 -0
  101. package/dist/fix/schema.js +41 -0
  102. package/dist/fix/schema.js.map +1 -0
  103. package/dist/gates/advisories.d.ts +11 -0
  104. package/dist/gates/advisories.d.ts.map +1 -0
  105. package/dist/gates/advisories.js +27 -0
  106. package/dist/gates/advisories.js.map +1 -0
  107. package/dist/gates/types.d.ts +36 -0
  108. package/dist/gates/types.d.ts.map +1 -0
  109. package/dist/gates/types.js +8 -0
  110. package/dist/gates/types.js.map +1 -0
  111. package/dist/index.d.ts +17 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +17 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/orchestrator.d.ts +51 -0
  116. package/dist/orchestrator.d.ts.map +1 -0
  117. package/dist/orchestrator.js +304 -0
  118. package/dist/orchestrator.js.map +1 -0
  119. package/dist/payload/builder.d.ts +49 -0
  120. package/dist/payload/builder.d.ts.map +1 -0
  121. package/dist/payload/builder.js +61 -0
  122. package/dist/payload/builder.js.map +1 -0
  123. package/dist/payload/mermaid.d.ts +22 -0
  124. package/dist/payload/mermaid.d.ts.map +1 -0
  125. package/dist/payload/mermaid.js +89 -0
  126. package/dist/payload/mermaid.js.map +1 -0
  127. package/dist/plugin/registry.d.ts +24 -0
  128. package/dist/plugin/registry.d.ts.map +1 -0
  129. package/dist/plugin/registry.js +24 -0
  130. package/dist/plugin/registry.js.map +1 -0
  131. package/dist/rules/component-refs.d.ts +26 -0
  132. package/dist/rules/component-refs.d.ts.map +1 -0
  133. package/dist/rules/component-refs.js +81 -0
  134. package/dist/rules/component-refs.js.map +1 -0
  135. package/dist/rules/evaluators.d.ts +50 -0
  136. package/dist/rules/evaluators.d.ts.map +1 -0
  137. package/dist/rules/evaluators.js +236 -0
  138. package/dist/rules/evaluators.js.map +1 -0
  139. package/dist/rules/host-rules.d.ts +109 -0
  140. package/dist/rules/host-rules.d.ts.map +1 -0
  141. package/dist/rules/host-rules.js +152 -0
  142. package/dist/rules/host-rules.js.map +1 -0
  143. package/dist/rules/index.d.ts +7 -0
  144. package/dist/rules/index.d.ts.map +1 -0
  145. package/dist/rules/index.js +7 -0
  146. package/dist/rules/index.js.map +1 -0
  147. package/dist/rules/manifest-evaluators.d.ts +32 -0
  148. package/dist/rules/manifest-evaluators.d.ts.map +1 -0
  149. package/dist/rules/manifest-evaluators.js +124 -0
  150. package/dist/rules/manifest-evaluators.js.map +1 -0
  151. package/dist/rules/rule-category.d.ts +13 -0
  152. package/dist/rules/rule-category.d.ts.map +1 -0
  153. package/dist/rules/rule-category.js +27 -0
  154. package/dist/rules/rule-category.js.map +1 -0
  155. package/dist/rules/tarjan.d.ts +9 -0
  156. package/dist/rules/tarjan.d.ts.map +1 -0
  157. package/dist/rules/tarjan.js +102 -0
  158. package/dist/rules/tarjan.js.map +1 -0
  159. package/dist/scanner.d.ts +12 -0
  160. package/dist/scanner.d.ts.map +1 -0
  161. package/dist/scanner.js +2 -0
  162. package/dist/scanner.js.map +1 -0
  163. package/dist/telemetry/diff.d.ts +27 -0
  164. package/dist/telemetry/diff.d.ts.map +1 -0
  165. package/dist/telemetry/diff.js +54 -0
  166. package/dist/telemetry/diff.js.map +1 -0
  167. package/dist/telemetry/index.d.ts +4 -0
  168. package/dist/telemetry/index.d.ts.map +1 -0
  169. package/dist/telemetry/index.js +4 -0
  170. package/dist/telemetry/index.js.map +1 -0
  171. package/dist/telemetry/serialize.d.ts +10 -0
  172. package/dist/telemetry/serialize.d.ts.map +1 -0
  173. package/dist/telemetry/serialize.js +11 -0
  174. package/dist/telemetry/serialize.js.map +1 -0
  175. package/dist/telemetry/types.d.ts +138 -0
  176. package/dist/telemetry/types.d.ts.map +1 -0
  177. package/dist/telemetry/types.js +3 -0
  178. package/dist/telemetry/types.js.map +1 -0
  179. package/dist/types/branded.d.ts +26 -0
  180. package/dist/types/branded.d.ts.map +1 -0
  181. package/dist/types/branded.js +24 -0
  182. package/dist/types/branded.js.map +1 -0
  183. package/dist/types/graph.d.ts +46 -0
  184. package/dist/types/graph.d.ts.map +1 -0
  185. package/dist/types/graph.js +2 -0
  186. package/dist/types/graph.js.map +1 -0
  187. package/dist/types/index.d.ts +6 -0
  188. package/dist/types/index.d.ts.map +1 -0
  189. package/dist/types/index.js +6 -0
  190. package/dist/types/index.js.map +1 -0
  191. package/dist/types/ir.d.ts +1747 -0
  192. package/dist/types/ir.d.ts.map +1 -0
  193. package/dist/types/ir.js +120 -0
  194. package/dist/types/ir.js.map +1 -0
  195. package/dist/types/manifest.d.ts +58 -0
  196. package/dist/types/manifest.d.ts.map +1 -0
  197. package/dist/types/manifest.js +2 -0
  198. package/dist/types/manifest.js.map +1 -0
  199. package/dist/types/violation.d.ts +94 -0
  200. package/dist/types/violation.d.ts.map +1 -0
  201. package/dist/types/violation.js +56 -0
  202. package/dist/types/violation.js.map +1 -0
  203. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/build/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAQ7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAQ9D,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAQ1E,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;EAQrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO1B,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAexD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Wire shapes for `align build` (ADR 011): the tier-1/MCP "rule fragment" input format, the
3
+ * `.align/generated-rules.json` file, and the `.align/rules.lock.json` file. Zod-validated per
4
+ * ADR 002's parse-don't-validate discipline — every fragment and every on-disk build artifact is
5
+ * `.parse()`d once, at its boundary.
6
+ */
7
+ import { z } from 'zod';
8
+ import { ruleIRSchema, rulesetIRSchema } from '../types/ir.js';
9
+ const componentRefText = z.string().min(1);
10
+ // ---------------------------------------------------------------------------------------------
11
+ // Rule fragment: the tier-1 ```align block JSON shape (and the MCP `align_propose_rules` proposal
12
+ // input shape) — a RuleIR variant's structural fields, minus `id` and `provenance`. Both of those
13
+ // are always assigned by align's build pipeline, never authored: `id` is a deterministic slug
14
+ // derived from the fragment's own content (ADR 011's rule-level diff minimization depends on ids
15
+ // being content-addressed, not author-assigned) and `provenance` is populated from where the
16
+ // fragment was found in the doc (or, for MCP, from what the client agent reports). A fragment MAY
17
+ // carry an optional `because` override — sourceQuote is auto-populated into the final rule's
18
+ // `because` field either way (ADR 011), but an author can prepend their own rationale text.
19
+ // ---------------------------------------------------------------------------------------------
20
+ const noDependencyFragmentSchema = z.object({
21
+ kind: z.literal('arch.no-dependency'),
22
+ from: componentRefText,
23
+ to: componentRefText,
24
+ because: z.string().optional(),
25
+ });
26
+ const noCyclesFragmentSchema = z.object({
27
+ kind: z.literal('arch.no-cycles'),
28
+ scope: z.union([z.literal('repo'), componentRefText]).optional(),
29
+ includeTypeOnly: z.boolean().optional(),
30
+ because: z.string().optional(),
31
+ });
32
+ const layersFragmentSchema = z.object({
33
+ kind: z.literal('arch.layers'),
34
+ // Exactly one layer entry per fragment (mirrors the DSL's `.layer(x).canOnlyDependOn(...)`,
35
+ // which always produces a single-entry `layers` array) — keeps rule ids content-addressed
36
+ // one-layer-per-id (`arch.layers:<layer>`), the same scheme `dsl/index.ts` uses. A doc
37
+ // expressing constraints for two layers writes two bullets/blocks, not one fragment with two
38
+ // entries.
39
+ layers: z.array(z.object({ layer: componentRefText, canDependOn: z.array(componentRefText) })).length(1),
40
+ because: z.string().optional(),
41
+ });
42
+ const customHostFragmentSchema = z.object({
43
+ kind: z.literal('custom.host'),
44
+ hostRuleName: z.string(),
45
+ because: z.string().optional(),
46
+ });
47
+ // `arch.metric` (max-LOC only, promoted 2026-07-12 on kluster ruleset evidence,
48
+ // IMPLEMENTATION_PLAN.md's Promotion log) — mirrors the DSL's `.maxLinesPerFile(max)` (dsl/index.ts).
49
+ const metricFragmentSchema = z.object({
50
+ kind: z.literal('arch.metric'),
51
+ target: componentRefText,
52
+ metric: z.literal('loc'),
53
+ max: z.number().int().positive(),
54
+ because: z.string().optional(),
55
+ });
56
+ // `security.manifest.*` (ADR 013, promoted 2026-07-12 on spike/MANIFEST_PROBE_REPORT.md probe
57
+ // evidence) — mirrors the DSL's `.sourceHygiene()`/`.newDependencyGate()` (dsl/index.ts). Neither
58
+ // verb takes a target/selector, so the fragment carries only `because`, same shape as
59
+ // `customHostFragmentSchema` minus `hostRuleName`.
60
+ const securityManifestSourceHygieneFragmentSchema = z.object({
61
+ kind: z.literal('security.manifest.source-hygiene'),
62
+ because: z.string().optional(),
63
+ });
64
+ const securityManifestNewDependencyFragmentSchema = z.object({
65
+ kind: z.literal('security.manifest.new-dependency'),
66
+ because: z.string().optional(),
67
+ });
68
+ export const ruleFragmentSchema = z.discriminatedUnion('kind', [
69
+ noDependencyFragmentSchema,
70
+ noCyclesFragmentSchema,
71
+ layersFragmentSchema,
72
+ customHostFragmentSchema,
73
+ metricFragmentSchema,
74
+ securityManifestSourceHygieneFragmentSchema,
75
+ securityManifestNewDependencyFragmentSchema,
76
+ ]);
77
+ // ---------------------------------------------------------------------------------------------
78
+ // `.align/generated-rules.json` — a RuleIR array with full provenance, imported by the config
79
+ // loader (packages/cli/src/config.ts). Deliberately NOT a full RulesetIR: `components` stays
80
+ // authored once in align.config.ts, never duplicated into the generated artifact.
81
+ // ---------------------------------------------------------------------------------------------
82
+ export const generatedRulesFileSchema = z.object({
83
+ irVersion: z.literal('1'),
84
+ docPath: z.string(),
85
+ generatedAt: z.number(),
86
+ rules: z.array(ruleIRSchema),
87
+ });
88
+ // ---------------------------------------------------------------------------------------------
89
+ // `.align/rules.lock.json` — section hashes <-> rule ids, plus the generated-rules.json content
90
+ // hash (divergence detection: a hand-edit to the generated artifact changes this hash without a
91
+ // matching lockfile update).
92
+ // ---------------------------------------------------------------------------------------------
93
+ const lockSectionSchema = z.object({
94
+ anchor: z.string(),
95
+ headingText: z.string(),
96
+ startLine: z.number().int(),
97
+ endLine: z.number().int(),
98
+ contentHash: z.string(),
99
+ tier: z.enum(['verbatim', 'bullet', 'prose', 'empty']),
100
+ ruleIds: z.array(z.string()),
101
+ });
102
+ export const rulesLockSchema = z.object({
103
+ irVersion: z.literal('1'),
104
+ docPath: z.string(),
105
+ docContentHash: z.string(),
106
+ builtAt: z.number(),
107
+ sections: z.array(lockSectionSchema),
108
+ generatedRulesContentHash: z.string(),
109
+ });
110
+ // ---------------------------------------------------------------------------------------------
111
+ // `.align/ruleset-ir.json` (ADR 014) — the untrusted-mode data source. Written once in a trusted
112
+ // context by `align export-ir` and read by `align check --untrusted`/`--ir-only`, which never
113
+ // imports align.config.ts. `ruleset` is exactly a `RulesetIR` (ADR 002: components + rules, both
114
+ // already portable JSON with zero function-valued fields — `defineProject` zod-parses it before
115
+ // this schema ever sees it) — this wrapper adds only what an untrusted scan additionally needs
116
+ // beyond the ruleset itself: the scan-time `excludes` list (plain string data, config.ts's
117
+ // documented `excludes`-is-not-part-of-RulesetIR deviation, ADR 002) and export provenance.
118
+ // Deliberately does NOT carry `hostRules` — predicate functions cannot survive a JSON boundary
119
+ // (ADR 002 amendment) and are categorically unavailable under --untrusted regardless
120
+ // (`assertNoCustomHostRules`, `rules/host-rules.ts`).
121
+ // ---------------------------------------------------------------------------------------------
122
+ export const exportedRulesetSchema = z.object({
123
+ irVersion: z.literal('1'),
124
+ exportedAt: z.number(),
125
+ excludes: z.array(z.string()),
126
+ ruleset: rulesetIRSchema,
127
+ });
128
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/build/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Markdown section model (ADR 011): a doc is parsed into heading-anchored sections with stable
3
+ * content hashes. Every markdown heading (any level, `#`-`######`) starts a new section that runs
4
+ * until the next heading or end of file — a flat model, not a nested tree; `align build`'s
5
+ * change-detection unit is "the section under one heading," which is what ADR 011's acceptance
6
+ * criteria ("one-section reword re-proposes only that section") operates on.
7
+ */
8
+ export interface DocSection {
9
+ /** Stable slug derived from the heading text (github-style), deduped against earlier headings
10
+ * in the same doc so two identically-worded headings don't collide. */
11
+ readonly anchor: string;
12
+ readonly headingText: string;
13
+ readonly level: number;
14
+ /** 1-based, inclusive — the heading line itself. */
15
+ readonly startLine: number;
16
+ /** 1-based, inclusive — the last line of the section's body (before the next heading, or EOF). */
17
+ readonly endLine: number;
18
+ /** Raw body text (excludes the heading line) — the classification/hashing input. */
19
+ readonly bodyText: string;
20
+ /** Content hash of `headingText` + `bodyText` — changes iff the section's own text changes,
21
+ * independent of line-number shifts caused by edits elsewhere in the doc. */
22
+ readonly contentHash: string;
23
+ }
24
+ export interface ParsedDoc {
25
+ readonly lines: readonly string[];
26
+ readonly sections: readonly DocSection[];
27
+ }
28
+ /** Parses a markdown document into heading-anchored sections (ADR 011). Pure — no I/O. */
29
+ export declare function parseMarkdownDoc(doc: string): ParsedDoc;
30
+ //# sourceMappingURL=sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../src/build/sections.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB;2EACuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;iFAC6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAqBD,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA0CvD"}
@@ -0,0 +1,58 @@
1
+ import { sha256Hex } from './hash.js';
2
+ const HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/;
3
+ function slugify(headingText) {
4
+ const base = headingText
5
+ .toLowerCase()
6
+ .trim()
7
+ .replace(/[^a-z0-9\s-]/g, '')
8
+ .replace(/\s+/g, '-')
9
+ .replace(/-+/g, '-')
10
+ .replace(/^-|-$/g, '');
11
+ return base.length > 0 ? base : 'section';
12
+ }
13
+ function dedupeAnchor(base, seen) {
14
+ const count = seen.get(base) ?? 0;
15
+ seen.set(base, count + 1);
16
+ return count === 0 ? base : `${base}-${count + 1}`;
17
+ }
18
+ /** Parses a markdown document into heading-anchored sections (ADR 011). Pure — no I/O. */
19
+ export function parseMarkdownDoc(doc) {
20
+ const lines = doc.split('\n');
21
+ const seenAnchors = new Map();
22
+ const headings = [];
23
+ for (let i = 0; i < lines.length; i += 1) {
24
+ const line = lines[i];
25
+ if (line === undefined)
26
+ continue;
27
+ const match = HEADING_RE.exec(line);
28
+ if (match === null)
29
+ continue;
30
+ const hashes = match[1];
31
+ const headingText = match[2];
32
+ if (hashes === undefined || headingText === undefined)
33
+ continue;
34
+ headings.push({ level: hashes.length, headingText, startLine: i + 1 });
35
+ }
36
+ const sections = [];
37
+ for (let i = 0; i < headings.length; i += 1) {
38
+ const h = headings[i];
39
+ if (h === undefined)
40
+ continue;
41
+ const next = headings[i + 1];
42
+ const endLine = next === undefined ? lines.length : next.startLine - 1;
43
+ const bodyLines = lines.slice(h.startLine, endLine); // excludes the heading line itself
44
+ const bodyText = bodyLines.join('\n');
45
+ const anchor = dedupeAnchor(slugify(h.headingText), seenAnchors);
46
+ sections.push({
47
+ anchor,
48
+ headingText: h.headingText,
49
+ level: h.level,
50
+ startLine: h.startLine,
51
+ endLine,
52
+ bodyText,
53
+ contentHash: sha256Hex(`${h.headingText}\n${bodyText}`),
54
+ });
55
+ }
56
+ return { lines, sections };
57
+ }
58
+ //# sourceMappingURL=sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/build/sections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { RepoRelativePath } from '../types/branded.js';
2
+ import type { SourceRange } from '../types/violation.js';
3
+ import type { DocSection } from './sections.js';
4
+ import { type RuleFragment } from './schema.js';
5
+ import type { FlaggedProposal } from './types.js';
6
+ export interface ExtractedFragment {
7
+ readonly fragment: RuleFragment;
8
+ readonly sourceLineRange: SourceRange;
9
+ /** Tier-1 sourceQuote is the fenced block's own JSON content (trimmed) — there is no separate
10
+ * prose to quote for a verbatim block; the block itself IS the doc's declared intent (an
11
+ * explicit ADR 011 resolution — see the Stage 3 final report's "ambiguities resolved" list). */
12
+ readonly sourceQuote: string;
13
+ }
14
+ /**
15
+ * Tier 1 of the precision ladder (ADR 011): fenced ` ```align ` code blocks compile verbatim,
16
+ * zero LLM involved. Each block's content is a **JSON RuleFragment** (`schema.ts`) — the
17
+ * structural fields of one `RuleIR` variant, minus `id`/`provenance` (both are always assigned by
18
+ * the build pipeline, never authored — see `ground.ts`). Pure — no I/O.
19
+ */
20
+ export declare function extractFencedAlignBlocks(lines: readonly string[], section: DocSection, docPath: RepoRelativePath): {
21
+ readonly fragments: readonly ExtractedFragment[];
22
+ readonly errors: readonly FlaggedProposal[];
23
+ };
24
+ //# sourceMappingURL=tier1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1.d.ts","sourceRoot":"","sources":["../../src/build/tier1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC;IACtC;;oGAEgG;IAChG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAKD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,gBAAgB,GACxB;IAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;CAAE,CA+DnG"}
@@ -0,0 +1,68 @@
1
+ import { ruleFragmentSchema } from './schema.js';
2
+ const FENCE_OPEN_RE = /^```align\s*$/;
3
+ const FENCE_CLOSE_RE = /^```\s*$/;
4
+ /**
5
+ * Tier 1 of the precision ladder (ADR 011): fenced ` ```align ` code blocks compile verbatim,
6
+ * zero LLM involved. Each block's content is a **JSON RuleFragment** (`schema.ts`) — the
7
+ * structural fields of one `RuleIR` variant, minus `id`/`provenance` (both are always assigned by
8
+ * the build pipeline, never authored — see `ground.ts`). Pure — no I/O.
9
+ */
10
+ export function extractFencedAlignBlocks(lines, section, docPath) {
11
+ const fragments = [];
12
+ const errors = [];
13
+ const bodyStart = section.startLine; // 0-indexed first body line (section.startLine is the
14
+ // 1-based heading line; the body's first line is index === that 1-based number)
15
+ const bodyEndExclusive = section.endLine; // 0-indexed exclusive end (section.endLine is 1-based inclusive)
16
+ let i = bodyStart;
17
+ while (i < bodyEndExclusive) {
18
+ const line = lines[i];
19
+ if (line === undefined || !FENCE_OPEN_RE.test(line.trim())) {
20
+ i += 1;
21
+ continue;
22
+ }
23
+ const contentStart = i + 1; // 0-indexed
24
+ let j = contentStart;
25
+ while (j < bodyEndExclusive && !FENCE_CLOSE_RE.test((lines[j] ?? '').trim()))
26
+ j += 1;
27
+ const contentEndExclusive = j;
28
+ const contentLines = lines.slice(contentStart, contentEndExclusive);
29
+ const raw = contentLines.join('\n').trim();
30
+ const range = {
31
+ startLine: contentStart + 1,
32
+ endLine: Math.max(contentStart + 1, contentEndExclusive),
33
+ };
34
+ let parsedJson;
35
+ try {
36
+ parsedJson = JSON.parse(raw);
37
+ }
38
+ catch (err) {
39
+ errors.push({
40
+ section: section.anchor,
41
+ sourceFile: docPath,
42
+ sourceLineRange: range,
43
+ sourceQuote: raw,
44
+ reason: 'invalid-fragment',
45
+ detail: `JSON parse error in \`\`\`align block: ${err instanceof Error ? err.message : String(err)}`,
46
+ });
47
+ i = j + 1;
48
+ continue;
49
+ }
50
+ const result = ruleFragmentSchema.safeParse(parsedJson);
51
+ if (!result.success) {
52
+ errors.push({
53
+ section: section.anchor,
54
+ sourceFile: docPath,
55
+ sourceLineRange: range,
56
+ sourceQuote: raw,
57
+ reason: 'invalid-fragment',
58
+ detail: `Schema validation error: ${result.error.issues.map((iss) => iss.message).join('; ')}`,
59
+ });
60
+ i = j + 1;
61
+ continue;
62
+ }
63
+ fragments.push({ fragment: result.data, sourceLineRange: range, sourceQuote: raw });
64
+ i = j + 1;
65
+ }
66
+ return { fragments, errors };
67
+ }
68
+ //# sourceMappingURL=tier1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1.js","sourceRoot":"","sources":["../../src/build/tier1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { RepoRelativePath } from '../types/branded.js';
2
+ import type { SourceRange } from '../types/violation.js';
3
+ import type { DocSection } from './sections.js';
4
+ import type { RuleFragment } from './schema.js';
5
+ import type { FlaggedProposal } from './types.js';
6
+ export interface ExtractedBullet {
7
+ readonly fragment: RuleFragment;
8
+ readonly sourceLineRange: SourceRange;
9
+ readonly sourceQuote: string;
10
+ }
11
+ /**
12
+ * Parses one bullet's sentence into a `RuleFragment` per ADR 011's constrained grammar: component
13
+ * names, "must not depend on", "no cycles", "layers," "must stay under N lines" (`arch.metric`,
14
+ * max-LOC only). Returns `undefined` for a sentence that
15
+ * doesn't match any known pattern — the caller flags it as `unparsed-bullet` rather than guessing.
16
+ * Deterministic regex matching only — no LLM, no fuzzy matching (this stage's CLI build path is
17
+ * zero-LLM by design; see the Stage 3 report's ADR-011-ambiguity resolutions).
18
+ */
19
+ export declare function parseBulletSentence(sentence: string): RuleFragment | undefined;
20
+ /**
21
+ * Human-readable grammar-form catalog (Stage 5, IMPLEMENTATION_PLAN.md) — the single source
22
+ * `align skill`'s generated bullet-grammar section reads (`packages/cli/src/skill/bullet-
23
+ * grammar.ts`). Each `example` is asserted against the real `parseBulletSentence` in
24
+ * `test/build-tier2-grammar-catalog.test.ts`: if a regex above changes shape and an example stops
25
+ * matching (or starts producing a different rule kind), that test fails — the catalog cannot
26
+ * silently drift from the parser it describes.
27
+ */
28
+ export interface BulletGrammarForm {
29
+ readonly ruleKind: RuleFragment['kind'];
30
+ readonly pattern: string;
31
+ readonly example: string;
32
+ }
33
+ export declare const BULLET_GRAMMAR_FORMS: readonly BulletGrammarForm[];
34
+ /**
35
+ * Tier 2 of the precision ladder (ADR 011): structured `- **Rule**: ...` bullets parse
36
+ * deterministically. Pure — no I/O.
37
+ */
38
+ export declare function extractStructuredBullets(lines: readonly string[], section: DocSection, docPath: RepoRelativePath): {
39
+ readonly bullets: readonly ExtractedBullet[];
40
+ readonly errors: readonly FlaggedProposal[];
41
+ };
42
+ //# sourceMappingURL=tier2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier2.d.ts","sourceRoot":"","sources":["../../src/build/tier2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AA0DD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAsD9E;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAOD,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EA+B5D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,gBAAgB,GACxB;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;CAAE,CAmC/F"}
@@ -0,0 +1,187 @@
1
+ const BULLET_RE = /^\s*-\s+\*\*Rule\*\*:\s*(.+?)\s*$/i;
2
+ const NO_CYCLES_SCOPED_RE = /^no\s+cycles?(?:\s+(?:allowed|permitted))?\s+(?:within|in|for)\s+(.+?)\.?$/i;
3
+ const NO_CYCLES_BARE_RE = /^no\s+cycles?\.?$/i;
4
+ const NO_CYCLES_SUBJECT_RE = /^(.+?)\s+must\s+have\s+no\s+cycles?\.?$/i;
5
+ const NO_DEPENDENCY_RE = /^(.+?)\s+must\s+not\s+depend\s+on\s+(.+?)\.?$/i;
6
+ const LAYERS_RE = /^(.+?)\s+(?:may|can)\s+only\s+depend\s+on\s+(.+?)\.?$/i;
7
+ // `arch.metric` (max-LOC only, promoted 2026-07-12 on kluster ruleset evidence,
8
+ // IMPLEMENTATION_PLAN.md's Promotion log). Mirrors the DSL's `.maxLinesPerFile(max)`
9
+ // (dsl/index.ts) — only the `loc` metric has a tier-2 grammar; fan-in/fan-out/instability stay
10
+ // reserved pending their own evidence and gain their own bullet grammar when promoted.
11
+ const MAX_LOC_RE = /^files\s+in\s+(.+?)\s+must\s+stay\s+under\s+(\d+)\s+lines?\.?$/i;
12
+ // `security.manifest.*` (ADR 013, promoted 2026-07-12 on probe evidence). Bare-sentence forms,
13
+ // same shape as `NO_CYCLES_BARE_RE` — neither rule takes a component target, so there is nothing
14
+ // to capture.
15
+ const SOURCE_HYGIENE_RE = /^dependenc(?:y|ies)\s+(?:sources?\s+)?must\s+be\s+(?:sourced\s+from\s+)?(?:the\s+)?registry(?:[- ]only)?\.?$/i;
16
+ const NEW_DEPENDENCY_GATE_RE = /^new\s+dependenc(?:y|ies)\s+(?:requires?|needs?)\s+baseline\s+(?:approval|acceptance)\.?$/i;
17
+ /** Splits a target-list clause ("`core`, `cli` and `pluginTypescript`") into raw tokens.
18
+ * Backtick/quote stripping happens at grounding time (`ground.ts`), not here — tier 2 stays a
19
+ * pure sentence splitter. */
20
+ function splitTokens(clause) {
21
+ return clause
22
+ .split(/\s*,\s*|\s+and\s+|\s+or\s+/i)
23
+ .map((t) => t.trim())
24
+ .filter((t) => t.length > 0);
25
+ }
26
+ /**
27
+ * R5 (precision-ladder gap, GREENFIELD_TRIAD_REPORT.md §1): tier-2 bullets had no field for an
28
+ * authored rationale — only fenced-JSON blocks (tier 1) could carry `.because()` text, capping the
29
+ * greenfield demo's `.because()` coverage at 75% for no reason other than which tier a rule was
30
+ * authored in. Splits an optional trailing "Because <rationale>." clause off a bullet's rule
31
+ * sentence: "api may only depend on core. Because the API layer must stay headless." -> sentence
32
+ * "api may only depend on core", because "the API layer must stay headless". The result flows
33
+ * straight into `RuleFragment.because` (every fragment variant already has this optional field,
34
+ * `schema.ts` — the same field a tier-1 fenced block's own `"because"` JSON key populates), so
35
+ * `groundFragment`/`buildProvenance` (`ground.ts`/`provenance.ts`) need no changes at all: an
36
+ * authored tier-2 rationale is prepended to the auto-generated "Enforced by <doc>:<line>: '<quote>'"
37
+ * phrase exactly like a tier-1 fragment's `because` is.
38
+ *
39
+ * The literal period-then-"Because" boundary is the deterministic separator — no NLP, and no
40
+ * ambiguity with a rule sentence that happens to use the word "because" without that boundary
41
+ * (which simply isn't matched, and flows through unsplit, same as today).
42
+ */
43
+ const TRAILING_BECAUSE_RE = /^(.*?)\.\s+Because\s+(.+?)\s*\.?$/i;
44
+ function splitBecauseClause(raw) {
45
+ const trimmed = raw.trim();
46
+ const match = TRAILING_BECAUSE_RE.exec(trimmed);
47
+ if (match?.[1] !== undefined && match[2] !== undefined && match[2].length > 0) {
48
+ return { sentence: match[1].trim(), because: match[2].trim() };
49
+ }
50
+ return { sentence: trimmed.replace(/\.$/, '').trim(), because: undefined };
51
+ }
52
+ /**
53
+ * Parses one bullet's sentence into a `RuleFragment` per ADR 011's constrained grammar: component
54
+ * names, "must not depend on", "no cycles", "layers," "must stay under N lines" (`arch.metric`,
55
+ * max-LOC only). Returns `undefined` for a sentence that
56
+ * doesn't match any known pattern — the caller flags it as `unparsed-bullet` rather than guessing.
57
+ * Deterministic regex matching only — no LLM, no fuzzy matching (this stage's CLI build path is
58
+ * zero-LLM by design; see the Stage 3 report's ADR-011-ambiguity resolutions).
59
+ */
60
+ export function parseBulletSentence(sentence) {
61
+ const scopedCycles = NO_CYCLES_SCOPED_RE.exec(sentence);
62
+ if (scopedCycles?.[1] !== undefined) {
63
+ return { kind: 'arch.no-cycles', scope: scopedCycles[1].trim() };
64
+ }
65
+ if (NO_CYCLES_BARE_RE.test(sentence)) {
66
+ return { kind: 'arch.no-cycles', scope: 'repo' };
67
+ }
68
+ const subjectCycles = NO_CYCLES_SUBJECT_RE.exec(sentence);
69
+ if (subjectCycles?.[1] !== undefined) {
70
+ return { kind: 'arch.no-cycles', scope: subjectCycles[1].trim() };
71
+ }
72
+ const noDependency = NO_DEPENDENCY_RE.exec(sentence);
73
+ if (noDependency?.[1] !== undefined && noDependency[2] !== undefined) {
74
+ const from = splitTokens(noDependency[1])[0];
75
+ const targets = splitTokens(noDependency[2]);
76
+ const to = targets[0];
77
+ // Single from -> single to is the only shape a RuleFragment can express (a "from must not
78
+ // depend on A, B" bullet with multiple targets isn't representable as one fragment — the
79
+ // caller sees `undefined` here and flags it as unparsed rather than silently dropping targets;
80
+ // multi-target denylists are `align.layers`'s job, or split into multiple bullets).
81
+ if (from === undefined || to === undefined || targets.length > 1)
82
+ return undefined;
83
+ return { kind: 'arch.no-dependency', from, to };
84
+ }
85
+ const layers = LAYERS_RE.exec(sentence);
86
+ if (layers?.[1] !== undefined && layers[2] !== undefined) {
87
+ const layerTokens = splitTokens(layers[1]);
88
+ const layer = layerTokens[0];
89
+ const canDependOn = splitTokens(layers[2]);
90
+ if (layer === undefined || layerTokens.length > 1 || canDependOn.length === 0)
91
+ return undefined;
92
+ return { kind: 'arch.layers', layers: [{ layer, canDependOn }] };
93
+ }
94
+ const maxLoc = MAX_LOC_RE.exec(sentence);
95
+ if (maxLoc?.[1] !== undefined && maxLoc[2] !== undefined) {
96
+ const targetTokens = splitTokens(maxLoc[1]);
97
+ const target = targetTokens[0];
98
+ const max = Number.parseInt(maxLoc[2], 10);
99
+ // Single target only — same "a RuleFragment can express one grounded target" discipline as
100
+ // `NO_DEPENDENCY_RE`/`LAYERS_RE` above.
101
+ if (target === undefined || targetTokens.length > 1 || !Number.isFinite(max))
102
+ return undefined;
103
+ return { kind: 'arch.metric', target, metric: 'loc', max };
104
+ }
105
+ if (SOURCE_HYGIENE_RE.test(sentence)) {
106
+ return { kind: 'security.manifest.source-hygiene' };
107
+ }
108
+ if (NEW_DEPENDENCY_GATE_RE.test(sentence)) {
109
+ return { kind: 'security.manifest.new-dependency' };
110
+ }
111
+ return undefined;
112
+ }
113
+ /** Appended to every pattern below (R5): any bullet may carry an optional trailing rationale
114
+ * clause, parsed into the rule's `.because()` provenance — a period then the literal word
115
+ * "Because" is the deterministic boundary between the rule sentence and the rationale. */
116
+ const BECAUSE_SUFFIX = ' Optionally followed by " Because <rationale>." to record why (e.g. "... Because the API layer must stay headless.") — parsed into the rule\'s .because() provenance.';
117
+ export const BULLET_GRAMMAR_FORMS = [
118
+ {
119
+ ruleKind: 'arch.no-dependency',
120
+ pattern: `<component> must not depend on <component>.${BECAUSE_SUFFIX}`,
121
+ example: 'api must not depend on ui.',
122
+ },
123
+ {
124
+ ruleKind: 'arch.layers',
125
+ pattern: `<component> may|can only depend on <component>[, <component> and/or <component>...].${BECAUSE_SUFFIX}`,
126
+ example: 'api may only depend on core.',
127
+ },
128
+ {
129
+ ruleKind: 'arch.no-cycles',
130
+ pattern: `no cycles. | no cycles within|in|for <scope>. | <scope> must have no cycles.${BECAUSE_SUFFIX}`,
131
+ example: 'no cycles.',
132
+ },
133
+ {
134
+ ruleKind: 'arch.metric',
135
+ pattern: `files in <component> must stay under <N> lines.${BECAUSE_SUFFIX}`,
136
+ example: 'files in core must stay under 500 lines.',
137
+ },
138
+ {
139
+ ruleKind: 'security.manifest.source-hygiene',
140
+ pattern: `dependency|dependencies (sources) must be (sourced from the) registry(-only).${BECAUSE_SUFFIX}`,
141
+ example: 'dependency sources must be registry-only.',
142
+ },
143
+ {
144
+ ruleKind: 'security.manifest.new-dependency',
145
+ pattern: `new dependency|dependencies requires|needs baseline approval|acceptance.${BECAUSE_SUFFIX}`,
146
+ example: 'new dependency requires baseline approval.',
147
+ },
148
+ ];
149
+ /**
150
+ * Tier 2 of the precision ladder (ADR 011): structured `- **Rule**: ...` bullets parse
151
+ * deterministically. Pure — no I/O.
152
+ */
153
+ export function extractStructuredBullets(lines, section, docPath) {
154
+ const bullets = [];
155
+ const errors = [];
156
+ const bodyStart = section.startLine;
157
+ const bodyEndExclusive = section.endLine;
158
+ for (let i = bodyStart; i < bodyEndExclusive; i += 1) {
159
+ const line = lines[i];
160
+ if (line === undefined)
161
+ continue;
162
+ const match = BULLET_RE.exec(line);
163
+ if (match?.[1] === undefined)
164
+ continue;
165
+ const { sentence, because } = splitBecauseClause(match[1]);
166
+ const range = { startLine: i + 1, endLine: i + 1 };
167
+ const fragment = parseBulletSentence(sentence);
168
+ if (fragment === undefined) {
169
+ errors.push({
170
+ section: section.anchor,
171
+ sourceFile: docPath,
172
+ sourceLineRange: range,
173
+ sourceQuote: line.trim(),
174
+ reason: 'unparsed-bullet',
175
+ detail: `Bullet did not match the tier-2 grammar (component names + "must not depend on" / "no cycles" / "may only depend on" / "must stay under N lines"): "${sentence}"`,
176
+ });
177
+ continue;
178
+ }
179
+ bullets.push({
180
+ fragment: because === undefined ? fragment : { ...fragment, because },
181
+ sourceLineRange: range,
182
+ sourceQuote: line.trim(),
183
+ });
184
+ }
185
+ return { bullets, errors };
186
+ }
187
+ //# sourceMappingURL=tier2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier2.js","sourceRoot":"","sources":["../../src/build/tier2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { RepoRelativePath, RuleId } from '../types/branded.js';
2
+ import type { RuleIR } from '../types/ir.js';
3
+ import type { SourceRange } from '../types/violation.js';
4
+ /** Why a candidate rule was NOT written — ADR 011: "ungroundable -> flagged proposal, never
5
+ * silently written." Every reason is surfaced to the human/agent, never silently dropped. */
6
+ export type FlaggedReason = 'ungroundable-selector' | 'unparsed-bullet' | 'invalid-fragment' | 'conflicting-rule-id' | 'unregistered-host-rule';
7
+ export interface FlaggedProposal {
8
+ readonly section: string;
9
+ readonly sourceFile: RepoRelativePath;
10
+ readonly sourceLineRange: SourceRange;
11
+ readonly sourceQuote: string;
12
+ readonly reason: FlaggedReason;
13
+ readonly detail: string;
14
+ }
15
+ export type SectionTier = 'verbatim' | 'bullet' | 'prose' | 'empty';
16
+ export interface SectionClassification {
17
+ readonly anchor: string;
18
+ readonly headingText: string;
19
+ readonly startLine: number;
20
+ readonly endLine: number;
21
+ readonly contentHash: string;
22
+ readonly tier: SectionTier;
23
+ /** Rule ids produced from this section, post-dedup — empty for 'prose'/'empty' sections. */
24
+ readonly ruleIds: readonly RuleId[];
25
+ }
26
+ /** Pass-1 scaffold for a prose section (ADR 011 two-pass clarification, Stage 3 MCP spec): align
27
+ * never invents concerns — `concerns` is deliberately empty here, for the connected client agent
28
+ * to fill in pass 2. */
29
+ export interface ProseSectionScaffold {
30
+ readonly anchor: string;
31
+ readonly headingText: string;
32
+ readonly startLine: number;
33
+ readonly endLine: number;
34
+ readonly concerns: readonly string[];
35
+ }
36
+ export interface BuildProposal {
37
+ readonly sections: readonly SectionClassification[];
38
+ readonly rules: readonly RuleIR[];
39
+ readonly flagged: readonly FlaggedProposal[];
40
+ readonly proseSections: readonly ProseSectionScaffold[];
41
+ }
42
+ //# sourceMappingURL=types.d.ts.map