@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":"ir.d.ts","sourceRoot":"","sources":["../../src/types/ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Ruleset IR (`irVersion: "1"`) — docs/ir-schema.md, ADR 002.
3
+ *
4
+ * Parse, don't validate (CODING_BEST_PRACTICES.md §12): the zod schema IS the type. Every
5
+ * RulesetIR in the system passes through `.parse()` once, at the DSL->IR boundary; nothing
6
+ * downstream re-validates it.
7
+ */
8
+ import { z } from 'zod';
9
+ const componentName = z
10
+ .string()
11
+ .regex(/^[A-Za-z][A-Za-z0-9_-]*$/, 'component names must match ^[A-Za-z][A-Za-z0-9_-]*$');
12
+ const fileSelectorSchema = z.discriminatedUnion('kind', [
13
+ z.object({ kind: z.literal('glob'), patterns: z.array(z.string()).min(1) }),
14
+ z.object({ kind: z.literal('package'), packageNames: z.array(z.string()).min(1) }),
15
+ ]);
16
+ // Greenfield mode (IMPLEMENTATION_PLAN.md Design Reserve "Greenfield mode", ADR 003 amendment):
17
+ // a component's empty-selector policy is a 3-state discriminant, not the old boolean `allowEmpty`.
18
+ // - 'fail' (default): a component matching zero files is a load-time error (ADR 003's
19
+ // empty-selector-fails-by-default doctrine, unchanged).
20
+ // - 'allow': empty tolerated permanently — the old `allowEmpty: true` behavior, now additionally
21
+ // surfaced as an `ungrounded-component` advisory (`components/registry.ts`'s
22
+ // `findUngroundedComponents`) instead of being silently indistinguishable from real compliance
23
+ // (ADR 008 amendment: the reference-validity invariant's sanctioned exception, made visible).
24
+ // - 'until-populated': empty tolerated + surfaced the same way, but self-heals — once the
25
+ // component has >=1 classified file, the empty-check simply stops triggering (no separate
26
+ // "armed" state to track) and its rules evaluate normally. Documents greenfield intent
27
+ // ("this WILL be built") instead of a permanent, easy-to-forget opt-out.
28
+ const emptyPolicySchema = z.enum(['fail', 'allow', 'until-populated']);
29
+ const componentDefinitionSchema = z.object({
30
+ name: componentName,
31
+ selector: fileSelectorSchema,
32
+ empty: emptyPolicySchema.default('fail'),
33
+ });
34
+ const componentRef = componentName;
35
+ const sourceLineRangeSchema = z.object({
36
+ startLine: z.number().int().min(1),
37
+ endLine: z.number().int().min(1),
38
+ });
39
+ const ruleProvenanceSchema = z.object({
40
+ because: z.string().optional(),
41
+ sourceFile: z.string().optional(),
42
+ sourceLineRange: sourceLineRangeSchema.optional(),
43
+ sourceQuote: z.string().optional(),
44
+ });
45
+ const ruleId = z.string();
46
+ const archNoDependencySchema = z.object({
47
+ kind: z.literal('arch.no-dependency'),
48
+ id: ruleId,
49
+ from: componentRef,
50
+ to: componentRef,
51
+ provenance: ruleProvenanceSchema,
52
+ });
53
+ const archNoCyclesSchema = z.object({
54
+ kind: z.literal('arch.no-cycles'),
55
+ id: ruleId,
56
+ scope: z.union([z.literal('repo'), componentRef]),
57
+ includeTypeOnly: z.boolean(),
58
+ provenance: ruleProvenanceSchema,
59
+ });
60
+ const archLayersSchema = z.object({
61
+ kind: z.literal('arch.layers'),
62
+ id: ruleId,
63
+ layers: z
64
+ .array(z.object({
65
+ layer: componentRef,
66
+ canDependOn: z.array(componentRef),
67
+ }))
68
+ .min(1),
69
+ provenance: ruleProvenanceSchema,
70
+ });
71
+ const customHostSchema = z.object({
72
+ kind: z.literal('custom.host'),
73
+ id: ruleId,
74
+ hostRuleName: z.string(),
75
+ portable: z.literal(false),
76
+ provenance: ruleProvenanceSchema,
77
+ });
78
+ // `metric` is a single literal today (`'loc'` only — promoted 2026-07-12 on kluster ruleset
79
+ // evidence, IMPLEMENTATION_PLAN.md's Promotion log). `fan-in`/`fan-out`/`instability` remain
80
+ // reserved (docs/ir-schema.md) pending their own evidence; this is written as a growable
81
+ // discriminant (`z.literal('loc')` now, `z.union([...])` when a second metric is promoted) rather
82
+ // than a bare `z.string()`, so adding one is additive, never a retrofit of this shape.
83
+ const archMetricSchema = z.object({
84
+ kind: z.literal('arch.metric'),
85
+ id: ruleId,
86
+ target: componentRef,
87
+ metric: z.literal('loc'),
88
+ max: z.number().int().positive(),
89
+ provenance: ruleProvenanceSchema,
90
+ });
91
+ // `security.manifest.*` (ADR 013, promoted 2026-07-12 on spike/MANIFEST_PROBE_REPORT.md probe
92
+ // evidence — probe Rules 1 and 7). Both are repo-wide (no `ComponentRef`, same shape as
93
+ // `custom.host` — see `rules/component-refs.ts`'s `componentRefsOf`), because the manifest scan
94
+ // domain (root + workspace package.json + pnpm-lock.yaml) has no notion of align's
95
+ // file-classified components at all.
96
+ const securityManifestSourceHygieneSchema = z.object({
97
+ kind: z.literal('security.manifest.source-hygiene'),
98
+ id: ruleId,
99
+ provenance: ruleProvenanceSchema,
100
+ });
101
+ const securityManifestNewDependencySchema = z.object({
102
+ kind: z.literal('security.manifest.new-dependency'),
103
+ id: ruleId,
104
+ provenance: ruleProvenanceSchema,
105
+ });
106
+ export const ruleIRSchema = z.discriminatedUnion('kind', [
107
+ archNoDependencySchema,
108
+ archNoCyclesSchema,
109
+ archLayersSchema,
110
+ customHostSchema,
111
+ archMetricSchema,
112
+ securityManifestSourceHygieneSchema,
113
+ securityManifestNewDependencySchema,
114
+ ]);
115
+ export const rulesetIRSchema = z.object({
116
+ irVersion: z.literal('1'),
117
+ components: z.record(componentName, componentDefinitionSchema),
118
+ rules: z.array(ruleIRSchema),
119
+ });
120
+ //# sourceMappingURL=ir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.js","sourceRoot":"","sources":["../../src/types/ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Manifest scan domain (ADR 013): a genuinely different input class from everything
3
+ * `plugin-typescript`'s TS-source scanner produces (`DependencyGraph`) — package.json/pnpm-lock.yaml
4
+ * text, not parsed TypeScript. Core defines only the shape and the injection seam
5
+ * (`ManifestScanner`); the concrete pnpm/Node-ecosystem reader lives in `@spikedpunch/align-plugin-typescript`
6
+ * (ADR 013's placement decision), wired in at the CLI composition root exactly like
7
+ * `LanguagePlugin`/`TypeScriptPlugin` already is — core never imports plugin-typescript directly
8
+ * (ARCHITECTURE.md §5).
9
+ */
10
+ import type { RepoRelativePath } from './branded.js';
11
+ /** `optionalDependencies` is scanned (source-hygiene cares about any non-registry specifier
12
+ * regardless of field) but deliberately excluded from `security.manifest.new-dependency`'s
13
+ * name-level gating (ADR 013: runtime + dev only — an optional dep's absence/presence is a
14
+ * different risk shape, out of scope for this promotion). `peerDependencies` is never collected at
15
+ * all: it never resolves to an installable artifact of its own (ADR 004's precedent — align's
16
+ * existing lockfile-drift probe rule hit exactly this false-positive class). */
17
+ export type ManifestDepField = 'dependencies' | 'devDependencies' | 'optionalDependencies';
18
+ export interface ManifestDependency {
19
+ readonly name: string;
20
+ /** The effective specifier: lockfile-resolved (`pnpm-lock.yaml` importer entry) when a lockfile
21
+ * is present, else the raw `package.json` value. Lockfile resolution is what makes a
22
+ * `catalog:`-managed dependency's real specifier visible (spike/MANIFEST_PROBE_REPORT.md Rule 1's
23
+ * documented reason for reading the lockfile at all, not just package.json). */
24
+ readonly specifier: string;
25
+ readonly field: ManifestDepField;
26
+ /** Best-effort 1-based line number of this dependency's raw-text declaration in `raw`, for
27
+ * `Violation.range`/`snippet`. `undefined` when the raw text couldn't be located (should not
28
+ * happen for well-formed JSON, but read-only survey posture never throws on it). */
29
+ readonly line?: number;
30
+ }
31
+ export interface ManifestRecord {
32
+ /** Repo-relative path to the declaring `package.json` (root or a workspace member). */
33
+ readonly file: RepoRelativePath;
34
+ /** Exact source text — the `Violation.snippet` extraction source (ADR 007: snippet is required,
35
+ * never synthesized prose). */
36
+ readonly raw: string;
37
+ readonly dependencies: readonly ManifestDependency[];
38
+ }
39
+ export interface ManifestInventory {
40
+ readonly manifests: readonly ManifestRecord[];
41
+ /** Whether `pnpm-lock.yaml` was found and parsed — informational only in v1 (no rule currently
42
+ * branches on it), kept on the inventory since a future lockfile-dependent rule (e.g. Rule 5's
43
+ * registry-provenance check, rejected on evidence per ADR 013) would need it. */
44
+ readonly lockfilePresent: boolean;
45
+ }
46
+ export declare const EMPTY_MANIFEST_INVENTORY: ManifestInventory;
47
+ export interface ManifestScanOptions {
48
+ readonly rootDir: string;
49
+ readonly excludes: readonly string[];
50
+ }
51
+ /** Injection seam (mirrors `Scanner`/`LanguagePlugin`, `scanner.ts`/`plugin/registry.ts`): core
52
+ * only ever sees this interface. `GateOrchestrator` defaults to a no-op implementation returning
53
+ * `EMPTY_MANIFEST_INVENTORY` so every existing caller/test that doesn't care about the security
54
+ * gate keeps working unchanged (same default-injection convention as `hostPredicates`). */
55
+ export interface ManifestScanner {
56
+ scan(options: ManifestScanOptions): Promise<ManifestInventory> | ManifestInventory;
57
+ }
58
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/types/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;gFAKgF;AAChF,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,iBAAiB,GAAG,sBAAsB,CAAC;AAE3F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;oFAGgF;IAChF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC;;wFAEoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC;mCAC+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C;;qFAEiF;IACjF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAED,eAAO,MAAM,wBAAwB,EAAE,iBAA6D,CAAC;AAErG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;2FAG2F;AAC3F,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,CAAC;CACpF"}
@@ -0,0 +1,2 @@
1
+ export const EMPTY_MANIFEST_INVENTORY = { manifests: [], lockfilePresent: false };
2
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/types/manifest.ts"],"names":[],"mappings":"AAkDA,MAAM,CAAC,MAAM,wBAAwB,GAAsB,EAAE,SAAS,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC"}
@@ -0,0 +1,94 @@
1
+ import type { ComponentName, RepoRelativePath, RuleId, ViolationId } from './branded.js';
2
+ export declare const CATEGORIES: readonly ["architecture", "security", "types", "lint", "format"];
3
+ export type Category = (typeof CATEGORIES)[number];
4
+ export type Severity = 'error' | 'warning' | 'info';
5
+ export interface SourceRange {
6
+ readonly startLine: number;
7
+ readonly endLine: number;
8
+ }
9
+ export interface CycleEdge {
10
+ readonly from: RepoRelativePath;
11
+ readonly to: RepoRelativePath;
12
+ readonly specifier: string;
13
+ readonly line: number;
14
+ }
15
+ export type FixHint = {
16
+ readonly code: 'remove-import';
17
+ readonly file: RepoRelativePath;
18
+ readonly line: number;
19
+ } | {
20
+ readonly code: 'relocate-shared-code';
21
+ readonly from: ComponentName;
22
+ readonly to: ComponentName;
23
+ } | {
24
+ readonly code: 'invert-dependency';
25
+ readonly owner: ComponentName;
26
+ } | {
27
+ readonly code: 'break-cycle-edge';
28
+ readonly suggestedEdge: CycleEdge;
29
+ } | {
30
+ readonly code: 'manual-review';
31
+ } | {
32
+ readonly code: 'split-file';
33
+ readonly file: RepoRelativePath;
34
+ };
35
+ interface ViolationBase {
36
+ readonly id: ViolationId;
37
+ readonly ruleId: RuleId;
38
+ readonly category: Category;
39
+ readonly severity: Severity;
40
+ readonly file: RepoRelativePath;
41
+ readonly range: SourceRange;
42
+ readonly snippet: string;
43
+ readonly fixHint: FixHint;
44
+ readonly because?: string;
45
+ }
46
+ export type Violation = (ViolationBase & {
47
+ readonly kind: 'no-dependency';
48
+ readonly fromFile: RepoRelativePath;
49
+ readonly toFile: RepoRelativePath;
50
+ readonly fromComponent: ComponentName;
51
+ readonly toComponent: ComponentName;
52
+ readonly specifier: string;
53
+ readonly line: number;
54
+ }) | (ViolationBase & {
55
+ readonly kind: 'no-cycles';
56
+ readonly chain: readonly CycleEdge[];
57
+ readonly suggestedBreakEdge: CycleEdge;
58
+ }) | (ViolationBase & {
59
+ readonly kind: 'layers';
60
+ readonly fromLayer: ComponentName;
61
+ readonly toLayer: ComponentName;
62
+ readonly fromFile: RepoRelativePath;
63
+ readonly toFile: RepoRelativePath;
64
+ readonly specifier: string;
65
+ readonly line: number;
66
+ }) | (ViolationBase & {
67
+ readonly kind: 'metric';
68
+ readonly metric: 'loc';
69
+ readonly component: ComponentName;
70
+ readonly value: number;
71
+ readonly threshold: number;
72
+ }) | (ViolationBase & {
73
+ readonly kind: 'custom';
74
+ readonly hostRuleName: string;
75
+ readonly detail: string;
76
+ }) | (ViolationBase & {
77
+ readonly kind: 'manifest-source-hygiene';
78
+ readonly depName: string;
79
+ readonly specifier: string;
80
+ readonly sourceType: 'git' | 'http' | 'file' | 'link';
81
+ }) | (ViolationBase & {
82
+ readonly kind: 'manifest-new-dependency';
83
+ readonly depName: string;
84
+ readonly specifier: string;
85
+ readonly depField: 'dependencies' | 'devDependencies';
86
+ });
87
+ /**
88
+ * Human-facing prose is rendered at the surface, never stored on the model (ADR 007 rule 2:
89
+ * measured 3.6x token reduction, 182 -> 51 tokens/violation, by keeping this out of the machine
90
+ * payload entirely).
91
+ */
92
+ export declare function renderViolationMessage(v: Violation): string;
93
+ export {};
94
+ //# sourceMappingURL=violation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../../src/types/violation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ // v1 executes 'architecture' and 'security' gates only ('types'/'lint'/'format' are the Stage 5
2
+ // tool-wrapping growth path, IMPLEMENTATION_PLAN.md); the union is fixed now so ADR 007/008's
3
+ // priority ordering and GateResult shape don't change when later gates add categories.
4
+ // CATEGORIES is the single source of truth (CODING_BEST_PRACTICES.md §12 "parse, don't
5
+ // validate" applied to a const-derived union instead of a zod schema) — `Category` is *derived*
6
+ // from the array, never hand-duplicated, so anything enumerating categories at runtime (e.g.
7
+ // `align skill`'s generated gate-list section, packages/cli/src/skill/gates.ts) reads the same
8
+ // array the type itself is built from and cannot silently drift from it.
9
+ export const CATEGORIES = ['architecture', 'security', 'types', 'lint', 'format'];
10
+ // Reserved variant (arrives with its rule kind — reserve pending evidence, docs/ir-schema.md):
11
+ // 'naming' { actual, pattern }
12
+ /**
13
+ * Human-facing prose is rendered at the surface, never stored on the model (ADR 007 rule 2:
14
+ * measured 3.6x token reduction, 182 -> 51 tokens/violation, by keeping this out of the machine
15
+ * payload entirely).
16
+ */
17
+ export function renderViolationMessage(v) {
18
+ switch (v.kind) {
19
+ case 'no-dependency':
20
+ return (`${v.fromFile} (component '${v.fromComponent}') imports ${v.toFile} ` +
21
+ `(component '${v.toComponent}') via '${v.specifier}' at line ${v.line}, which rule ` +
22
+ `'${v.ruleId}' forbids.` + (v.because !== undefined ? ` ${v.because}` : ''));
23
+ case 'no-cycles': {
24
+ const lastHop = v.chain[v.chain.length - 1];
25
+ const nodeNames = v.chain.map((e) => String(e.from));
26
+ if (lastHop !== undefined)
27
+ nodeNames.push(String(lastHop.to));
28
+ const path = nodeNames.join(' -> ');
29
+ return (`Import cycle of ${v.chain.length} edge(s) detected: ${path}.` +
30
+ (v.because !== undefined ? ` ${v.because}` : ''));
31
+ }
32
+ case 'layers':
33
+ return (`${v.fromFile} (layer '${v.fromLayer}') imports ${v.toFile} (layer '${v.toLayer}') via ` +
34
+ `'${v.specifier}' at line ${v.line}, which rule '${v.ruleId}' forbids.` +
35
+ (v.because !== undefined ? ` ${v.because}` : ''));
36
+ case 'metric':
37
+ return (`${v.file} (component '${v.component}') is ${v.value} lines, exceeding rule '${v.ruleId}'s ` +
38
+ `max-${v.metric} limit of ${v.threshold} lines.` + (v.because !== undefined ? ` ${v.because}` : ''));
39
+ case 'custom':
40
+ return (`${v.file}: ${v.detail} (rule '${v.ruleId}', host predicate '${v.hostRuleName}').` +
41
+ (v.because !== undefined ? ` ${v.because}` : ''));
42
+ case 'manifest-source-hygiene':
43
+ return (`${v.file} declares '${v.depName}' via a non-registry (${v.sourceType}) specifier ` +
44
+ `'${v.specifier}', which rule '${v.ruleId}' flags for human sign-off.` +
45
+ (v.because !== undefined ? ` ${v.because}` : ''));
46
+ case 'manifest-new-dependency':
47
+ return (`${v.file} declares dependency '${v.depName}' (${v.depField}) via '${v.specifier}', not yet ` +
48
+ `accepted into the baseline, which rule '${v.ruleId}' flags.` +
49
+ (v.because !== undefined ? ` ${v.because}` : ''));
50
+ default: {
51
+ const exhaustive = v;
52
+ throw new Error(`unhandled violation kind: ${JSON.stringify(exhaustive)}`);
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=violation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation.js","sourceRoot":"","sources":["../../src/types/violation.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@spikedpunch/align-core",
3
+ "version": "0.1.0",
4
+ "description": "Zero-dependency architecture-conformance rule engine for align: the DSL, JSON IR schema, gate stack, and baseline.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/SpikedPunchVictim/align",
9
+ "directory": "packages/core"
10
+ },
11
+ "keywords": [
12
+ "align",
13
+ "architecture",
14
+ "conformance",
15
+ "dependency-graph",
16
+ "dependency-direction",
17
+ "import-cycle",
18
+ "static-analysis",
19
+ "dsl",
20
+ "typescript"
21
+ ],
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ },
28
+ "./dsl": {
29
+ "types": "./dist/dsl/index.d.ts",
30
+ "default": "./dist/dsl/index.js"
31
+ },
32
+ "./fix": {
33
+ "types": "./dist/fix/index.d.ts",
34
+ "default": "./dist/fix/index.js"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "engines": {
44
+ "node": ">=20"
45
+ },
46
+ "dependencies": {
47
+ "zod": "^3.23.8"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "^5.6.3",
51
+ "vitest": "^2.1.4"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.json",
55
+ "test": "vitest run",
56
+ "typecheck": "tsc -p tsconfig.json --noEmit"
57
+ }
58
+ }