@ai-sdlc/orchestrator 0.9.0 → 0.13.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 (172) hide show
  1. package/dist/__test-helpers/git-env.d.ts +40 -0
  2. package/dist/__test-helpers/git-env.js +73 -0
  3. package/dist/adapters.d.ts +42 -3
  4. package/dist/adapters.js +133 -3
  5. package/dist/admission-composite.d.ts +134 -1
  6. package/dist/admission-composite.js +170 -6
  7. package/dist/admission-enrichment.d.ts +12 -3
  8. package/dist/admission-enrichment.js +71 -10
  9. package/dist/admission-hc.d.ts +20 -1
  10. package/dist/admission-hc.js +12 -1
  11. package/dist/admission-score.d.ts +44 -0
  12. package/dist/admission-score.js +11 -2
  13. package/dist/backlog-adapter.d.ts +45 -0
  14. package/dist/backlog-adapter.js +145 -1
  15. package/dist/calibration.d.ts +81 -0
  16. package/dist/calibration.js +76 -0
  17. package/dist/cli/commands/git-remote.d.ts +25 -0
  18. package/dist/cli/commands/git-remote.js +80 -1
  19. package/dist/cli/commands/init-features.d.ts +507 -0
  20. package/dist/cli/commands/init-features.js +1100 -0
  21. package/dist/cli/commands/init-templates.d.ts +301 -0
  22. package/dist/cli/commands/init-templates.js +1341 -0
  23. package/dist/cli/commands/init.d.ts +67 -0
  24. package/dist/cli/commands/init.js +301 -2
  25. package/dist/cli/commands/run.js +9 -1
  26. package/dist/cli/index.d.ts +11 -0
  27. package/dist/cli/index.js +42 -8
  28. package/dist/compliance/composer.d.ts +79 -0
  29. package/dist/compliance/composer.js +258 -0
  30. package/dist/compliance/errors.d.ts +64 -0
  31. package/dist/compliance/errors.js +85 -0
  32. package/dist/compliance/loader.d.ts +52 -0
  33. package/dist/compliance/loader.js +124 -0
  34. package/dist/compliance/types.d.ts +184 -0
  35. package/dist/compliance/types.js +41 -0
  36. package/dist/compliance-clearance.d.ts +269 -0
  37. package/dist/compliance-clearance.js +269 -0
  38. package/dist/config.js +17 -0
  39. package/dist/cost-tracker.d.ts +22 -0
  40. package/dist/cost-tracker.js +41 -0
  41. package/dist/database/adapters/external.js +5 -1
  42. package/dist/design-authority.d.ts +13 -0
  43. package/dist/design-authority.js +13 -0
  44. package/dist/embedding/adapters/openai-text-embedding-3-small.d.ts +71 -0
  45. package/dist/embedding/adapters/openai-text-embedding-3-small.js +190 -0
  46. package/dist/embedding/consumers/tessellation-drift.d.ts +74 -0
  47. package/dist/embedding/consumers/tessellation-drift.js +76 -0
  48. package/dist/embedding/cross-provider.d.ts +78 -0
  49. package/dist/embedding/cross-provider.js +75 -0
  50. package/dist/embedding/deprecation.d.ts +151 -0
  51. package/dist/embedding/deprecation.js +229 -0
  52. package/dist/embedding/errors.d.ts +90 -0
  53. package/dist/embedding/errors.js +150 -0
  54. package/dist/embedding/index.d.ts +29 -0
  55. package/dist/embedding/index.js +24 -0
  56. package/dist/embedding/pipeline-load.d.ts +146 -0
  57. package/dist/embedding/pipeline-load.js +178 -0
  58. package/dist/embedding/registry.d.ts +45 -0
  59. package/dist/embedding/registry.js +61 -0
  60. package/dist/embedding/stale-vector.d.ts +110 -0
  61. package/dist/embedding/stale-vector.js +92 -0
  62. package/dist/embedding/storage/index.d.ts +51 -0
  63. package/dist/embedding/storage/index.js +43 -0
  64. package/dist/embedding/storage/jsonl-backend.d.ts +150 -0
  65. package/dist/embedding/storage/jsonl-backend.js +332 -0
  66. package/dist/embedding/storage/types.d.ts +135 -0
  67. package/dist/embedding/storage/types.js +13 -0
  68. package/dist/embedding/types.d.ts +180 -0
  69. package/dist/embedding/types.js +10 -0
  70. package/dist/execute.d.ts +29 -2
  71. package/dist/execute.js +179 -35
  72. package/dist/index.d.ts +14 -2
  73. package/dist/index.js +19 -2
  74. package/dist/journey/inheritance-validator.d.ts +396 -0
  75. package/dist/journey/inheritance-validator.js +370 -0
  76. package/dist/journey/state-id-drift-rule.d.ts +137 -0
  77. package/dist/journey/state-id-drift-rule.js +245 -0
  78. package/dist/journey-sa2-router.d.ts +395 -0
  79. package/dist/journey-sa2-router.js +308 -0
  80. package/dist/models/classifier.d.ts +3 -1
  81. package/dist/models/classifier.js +61 -5
  82. package/dist/pillar-breakdown.d.ts +23 -1
  83. package/dist/pillar-breakdown.js +9 -0
  84. package/dist/runners/review-agent.js +6 -2
  85. package/dist/runners/runner-registry.d.ts +36 -0
  86. package/dist/runners/runner-registry.js +90 -0
  87. package/dist/runtime/attestations.d.ts +663 -11
  88. package/dist/runtime/attestations.js +971 -24
  89. package/dist/runtime/index.d.ts +1 -1
  90. package/dist/runtime/index.js +1 -1
  91. package/dist/runtime/parallelism-flag.d.ts +21 -3
  92. package/dist/runtime/parallelism-flag.js +27 -6
  93. package/dist/runtime/port-allocator.d.ts +11 -0
  94. package/dist/runtime/port-allocator.js +30 -0
  95. package/dist/sa-scoring/layer3-llm.js +6 -1
  96. package/dist/sa-scoring/revision-proposal-config.d.ts +178 -0
  97. package/dist/sa-scoring/revision-proposal-config.js +198 -0
  98. package/dist/sa-scoring/revision-proposal.d.ts +285 -0
  99. package/dist/sa-scoring/revision-proposal.js +417 -0
  100. package/dist/signal-ingestion/adapters/community-thread.d.ts +43 -0
  101. package/dist/signal-ingestion/adapters/community-thread.js +55 -0
  102. package/dist/signal-ingestion/adapters/in-app-feedback.d.ts +67 -0
  103. package/dist/signal-ingestion/adapters/in-app-feedback.js +51 -0
  104. package/dist/signal-ingestion/adapters/manual.d.ts +78 -0
  105. package/dist/signal-ingestion/adapters/manual.js +112 -0
  106. package/dist/signal-ingestion/adapters/support-ticket.d.ts +47 -0
  107. package/dist/signal-ingestion/adapters/support-ticket.js +51 -0
  108. package/dist/signal-ingestion/classifier.d.ts +205 -0
  109. package/dist/signal-ingestion/classifier.js +494 -0
  110. package/dist/signal-ingestion/clustering-types.d.ts +36 -0
  111. package/dist/signal-ingestion/clustering-types.js +14 -0
  112. package/dist/signal-ingestion/clustering.d.ts +200 -0
  113. package/dist/signal-ingestion/clustering.js +413 -0
  114. package/dist/signal-ingestion/config.d.ts +351 -0
  115. package/dist/signal-ingestion/config.js +587 -0
  116. package/dist/signal-ingestion/d1.d.ts +252 -0
  117. package/dist/signal-ingestion/d1.js +235 -0
  118. package/dist/signal-ingestion/errors.d.ts +73 -0
  119. package/dist/signal-ingestion/errors.js +108 -0
  120. package/dist/signal-ingestion/governance-events.d.ts +181 -0
  121. package/dist/signal-ingestion/governance-events.js +189 -0
  122. package/dist/signal-ingestion/index.d.ts +35 -0
  123. package/dist/signal-ingestion/index.js +53 -0
  124. package/dist/signal-ingestion/manual-share-metric.d.ts +93 -0
  125. package/dist/signal-ingestion/manual-share-metric.js +106 -0
  126. package/dist/signal-ingestion/registry.d.ts +40 -0
  127. package/dist/signal-ingestion/registry.js +137 -0
  128. package/dist/signal-ingestion/residency.d.ts +227 -0
  129. package/dist/signal-ingestion/residency.js +238 -0
  130. package/dist/signal-ingestion/significance.d.ts +554 -0
  131. package/dist/signal-ingestion/significance.js +555 -0
  132. package/dist/signal-ingestion/types.d.ts +191 -0
  133. package/dist/signal-ingestion/types.js +8 -0
  134. package/dist/substrate/drift-composition.d.ts +270 -0
  135. package/dist/substrate/drift-composition.js +306 -0
  136. package/dist/substrate/drift-tui-surface.d.ts +61 -0
  137. package/dist/substrate/drift-tui-surface.js +102 -0
  138. package/dist/substrate/identity-class.d.ts +176 -0
  139. package/dist/substrate/identity-class.js +201 -0
  140. package/dist/tessellation/cross-soul-provenance-rule.d.ts +133 -0
  141. package/dist/tessellation/cross-soul-provenance-rule.js +171 -0
  142. package/dist/tessellation/inter-soul-embedding-distance-rule.d.ts +61 -0
  143. package/dist/tessellation/inter-soul-embedding-distance-rule.js +67 -0
  144. package/dist/tessellation/rule-registry.d.ts +269 -0
  145. package/dist/tessellation/rule-registry.js +92 -0
  146. package/dist/tessellation/soul-slug-ast-scan-rule.d.ts +90 -0
  147. package/dist/tessellation/soul-slug-ast-scan-rule.js +158 -0
  148. package/dist/tessellation-admission.d.ts +162 -0
  149. package/dist/tessellation-admission.js +146 -0
  150. package/dist/tessellation-drift.d.ts +246 -0
  151. package/dist/tessellation-drift.js +250 -0
  152. package/dist/validate-config.js +13 -0
  153. package/dist/validate-issue.js +2 -2
  154. package/dist/variant/cardinality-activation.d.ts +126 -0
  155. package/dist/variant/cardinality-activation.js +101 -0
  156. package/dist/variant/deprecation-lifecycle.d.ts +184 -0
  157. package/dist/variant/deprecation-lifecycle.js +208 -0
  158. package/dist/variant/drift-extension.d.ts +136 -0
  159. package/dist/variant/drift-extension.js +164 -0
  160. package/dist/variant/engineering-review.d.ts +185 -0
  161. package/dist/variant/engineering-review.js +142 -0
  162. package/dist/variant/index.d.ts +32 -0
  163. package/dist/variant/index.js +32 -0
  164. package/dist/variant/inheritance-validator.d.ts +165 -0
  165. package/dist/variant/inheritance-validator.js +139 -0
  166. package/dist/variant/internal-adopter/index.d.ts +11 -0
  167. package/dist/variant/internal-adopter/index.js +10 -0
  168. package/dist/variant/internal-adopter/products.d.ts +156 -0
  169. package/dist/variant/internal-adopter/products.js +366 -0
  170. package/dist/variant-admission.d.ts +316 -0
  171. package/dist/variant-admission.js +247 -0
  172. package/package.json +11 -8
@@ -0,0 +1,162 @@
1
+ /**
2
+ * RFC-0009 Phase 2.1 — Tessellation routing for admission composite.
3
+ *
4
+ * Implements the soul-scope routing algorithm from RFC-0009 §6:
5
+ *
6
+ * resolveAffectedSouls(w) = set of Soul DIDs the work item affects,
7
+ * computed from the dependency graph snapshot (RFC-0014).
8
+ *
9
+ * If tessellation absent on the resolved DID:
10
+ * Behavior unchanged from RFC-0008. Single-DID semantics preserved.
11
+ *
12
+ * Else if |resolveAffectedSouls(w)| == 0:
13
+ * // Pure substrate work touching no soul-importing module
14
+ * Sα(w) = min over ALL souls { Sα(w, soul) } (§6 degenerate case)
15
+ *
16
+ * Else if |resolveAffectedSouls(w)| == 1:
17
+ * Sα(w) = Sα(w, targetSoul) // soul's own DSB
18
+ *
19
+ * Else:
20
+ * Sα(w) = crossSoulScoringRule(w, affectedSouls) // default `min`
21
+ *
22
+ * The same resolution applies to Eρ₄ (Design System Readiness) per §6:
23
+ * "The same soul-resolution applies to Eρ₄ which reads against the
24
+ * targeted soul's DSB rather than the platform-aggregate DSB."
25
+ *
26
+ * @see spec/rfcs/RFC-0009-tessellated-design-intent-documents.md §6 + §10
27
+ */
28
+ import type { Tessellation } from '@ai-sdlc/reference';
29
+ /**
30
+ * A minimal representation of one dep-graph snapshot record's soul scope.
31
+ *
32
+ * Derived from the RFC-0014 snapshot (SnapshotRecord) via the pipeline-cli
33
+ * reader layer. Callers populate this from `snapshot.*.jsonl` records before
34
+ * calling `resolveAffectedSouls`.
35
+ *
36
+ * When `targetedSoulIds` is absent or empty, the work item is treated as
37
+ * substrate-only — affecting the full `min`-over-all-souls degenerate case.
38
+ */
39
+ export interface DepGraphSoulEntry {
40
+ /**
41
+ * Canonical task ID (case-insensitive match used internally). E.g. "AISDLC-313".
42
+ */
43
+ id: string;
44
+ /**
45
+ * Soul slugs (soulId values from the Tessellation manifest) that this
46
+ * work item explicitly targets. Empty or absent = substrate-only change.
47
+ *
48
+ * Populated by the pipeline-cli layer reading the dep-graph snapshot; the
49
+ * soulId values must match `tessellation.souls[].soulId` for the lookup to
50
+ * produce useful results.
51
+ */
52
+ targetedSoulIds?: string[];
53
+ }
54
+ /**
55
+ * Per-soul scoring data used by the tessellated admission composite.
56
+ * One entry per active soul in the tessellation.
57
+ */
58
+ export interface SoulScores {
59
+ /**
60
+ * Soul-specific soul-alignment score in [0, 1].
61
+ * Scored against this soul's DSB and product vertex (§6 + §5.1.1).
62
+ */
63
+ soulAlignment: number;
64
+ /**
65
+ * Soul-specific Eρ₄ Design System Readiness in [0, 1].
66
+ * Reads from the soul's own DSB at `.ai-sdlc/souls/<slug>/design-system-binding.yaml`
67
+ * rather than the platform-aggregate DSB (§6 last para).
68
+ */
69
+ er4: number;
70
+ }
71
+ /**
72
+ * All tessellation-related inputs needed by the admission composite
73
+ * for RFC-0009 Phase 2.1 soul-scope routing.
74
+ *
75
+ * Callers build this once per pipeline tick and pass it to
76
+ * `computeAdmissionComposite` via `AdmissionCompositeOptions.tessellationContext`.
77
+ */
78
+ export interface TessellationContext {
79
+ /**
80
+ * The Tessellated DID's `tessellation` field (from `DesignIntentDocumentSpec`).
81
+ * Carries the soul manifest + `crossSoulScoringRule` + `substrateInvariants`.
82
+ */
83
+ tessellation: Tessellation;
84
+ /**
85
+ * Pre-computed per-soul scores, keyed by `soulId` (matching
86
+ * `tessellation.souls[].soulId`). Must cover at least every active soul.
87
+ *
88
+ * In a full Phase 2 implementation these are computed by reading each
89
+ * soul's DSB at `.ai-sdlc/souls/<slug>/design-system-binding.yaml` and
90
+ * scoring Sα against the soul's product vertex.
91
+ */
92
+ soulScores: Record<string, SoulScores>;
93
+ /**
94
+ * Dep-graph soul scope entries — one per work item in the active backlog.
95
+ * Read from the latest RFC-0014 snapshot via `pipeline-cli`'s snapshot
96
+ * reader before calling the admission composite.
97
+ *
98
+ * When `undefined` or empty, every work item is treated as substrate-only.
99
+ */
100
+ depGraphEntries?: DepGraphSoulEntry[];
101
+ }
102
+ /**
103
+ * Resolve the set of soul IDs affected by a work item.
104
+ *
105
+ * Algorithm (RFC-0009 §6 + OQ-2 sub-decision):
106
+ * 1. Find the work item's dep-graph entry by case-insensitive ID match.
107
+ * 2. Filter its `targetedSoulIds` against souls present in the tessellation.
108
+ * 3. Return the validated intersection.
109
+ * 4. If no entry is found, or `targetedSoulIds` is empty/absent → return `[]`
110
+ * (substrate-only; triggers the `min`-over-all-souls degenerate case in §6).
111
+ *
112
+ * @param workItemId - The work item's canonical ID (e.g. "AISDLC-313").
113
+ * @param depGraphEntries - Soul scope entries from the RFC-0014 snapshot.
114
+ * @param tessellation - The tessellation manifest to validate soul IDs against.
115
+ * @returns Array of valid affected soul IDs (empty = substrate-only).
116
+ */
117
+ export declare function resolveAffectedSouls(workItemId: string, depGraphEntries: DepGraphSoulEntry[] | undefined, tessellation: Tessellation): string[];
118
+ /**
119
+ * Apply `crossSoulScoringRule` over a per-soul score map.
120
+ *
121
+ * Currently implements `min` (default per OQ-2 resolution) and `max`/`mean`
122
+ * escape valves. `weighted-traffic` and `weighted-revenue` require an external
123
+ * data source and are documented as advanced — they fall through to `min` when
124
+ * no weights are available (safe degenerate).
125
+ *
126
+ * @param soulIds - The soul IDs to aggregate over.
127
+ * @param scores - Per-soul score map (keyed by soulId).
128
+ * @param rule - The aggregation rule from the Tessellated DID.
129
+ * @param fallback - Default score when no soul scores are available (0.5).
130
+ */
131
+ export declare function applyCrossSoulRule(soulIds: string[], scores: Record<string, number>, rule: Tessellation['crossSoulScoringRule'], fallback?: number): number;
132
+ /**
133
+ * Result of tessellation-based soul-alignment resolution.
134
+ * Exposes routing path for auditability.
135
+ */
136
+ export interface TessellatedSaResult {
137
+ /** The resolved Sα value in [0, 1]. */
138
+ soulAlignment: number;
139
+ /** The resolved Eρ₄ value in [0, 1]. */
140
+ er4: number;
141
+ /**
142
+ * Routing path taken (matches RFC-0009 §6 case labels).
143
+ *
144
+ * - `'non-tessellated'` — tessellation absent; single-DID path preserved.
145
+ * - `'substrate-only'` — 0 affected souls; `min`-over-ALL-souls degenerate.
146
+ * - `'single-soul'` — 1 affected soul; scored against that soul's DSB.
147
+ * - `'multi-soul'` — N>1 affected souls; crossSoulScoringRule applied.
148
+ */
149
+ routingPath: 'non-tessellated' | 'substrate-only' | 'single-soul' | 'multi-soul';
150
+ /** Soul IDs used in the aggregation (empty for `non-tessellated`). */
151
+ affectedSoulIds: string[];
152
+ }
153
+ /**
154
+ * Compute tessellated Sα + Eρ₄ for a work item, implementing RFC-0009 §6.
155
+ *
156
+ * @param workItemId - The canonical work item ID.
157
+ * @param fallbackSa - SA score to use when tessellation is absent (single-DID path).
158
+ * @param fallbackEr4 - Eρ₄ score to use when tessellation is absent.
159
+ * @param tessellationCtx - Tessellation context, or undefined for non-tessellated DID.
160
+ */
161
+ export declare function computeTessellatedScores(workItemId: string, fallbackSa: number, fallbackEr4: number, tessellationCtx: TessellationContext | undefined): TessellatedSaResult;
162
+ //# sourceMappingURL=tessellation-admission.d.ts.map
@@ -0,0 +1,146 @@
1
+ /**
2
+ * RFC-0009 Phase 2.1 — Tessellation routing for admission composite.
3
+ *
4
+ * Implements the soul-scope routing algorithm from RFC-0009 §6:
5
+ *
6
+ * resolveAffectedSouls(w) = set of Soul DIDs the work item affects,
7
+ * computed from the dependency graph snapshot (RFC-0014).
8
+ *
9
+ * If tessellation absent on the resolved DID:
10
+ * Behavior unchanged from RFC-0008. Single-DID semantics preserved.
11
+ *
12
+ * Else if |resolveAffectedSouls(w)| == 0:
13
+ * // Pure substrate work touching no soul-importing module
14
+ * Sα(w) = min over ALL souls { Sα(w, soul) } (§6 degenerate case)
15
+ *
16
+ * Else if |resolveAffectedSouls(w)| == 1:
17
+ * Sα(w) = Sα(w, targetSoul) // soul's own DSB
18
+ *
19
+ * Else:
20
+ * Sα(w) = crossSoulScoringRule(w, affectedSouls) // default `min`
21
+ *
22
+ * The same resolution applies to Eρ₄ (Design System Readiness) per §6:
23
+ * "The same soul-resolution applies to Eρ₄ which reads against the
24
+ * targeted soul's DSB rather than the platform-aggregate DSB."
25
+ *
26
+ * @see spec/rfcs/RFC-0009-tessellated-design-intent-documents.md §6 + §10
27
+ */
28
+ // ── Core functions ─────────────────────────────────────────────────────
29
+ /**
30
+ * Resolve the set of soul IDs affected by a work item.
31
+ *
32
+ * Algorithm (RFC-0009 §6 + OQ-2 sub-decision):
33
+ * 1. Find the work item's dep-graph entry by case-insensitive ID match.
34
+ * 2. Filter its `targetedSoulIds` against souls present in the tessellation.
35
+ * 3. Return the validated intersection.
36
+ * 4. If no entry is found, or `targetedSoulIds` is empty/absent → return `[]`
37
+ * (substrate-only; triggers the `min`-over-all-souls degenerate case in §6).
38
+ *
39
+ * @param workItemId - The work item's canonical ID (e.g. "AISDLC-313").
40
+ * @param depGraphEntries - Soul scope entries from the RFC-0014 snapshot.
41
+ * @param tessellation - The tessellation manifest to validate soul IDs against.
42
+ * @returns Array of valid affected soul IDs (empty = substrate-only).
43
+ */
44
+ export function resolveAffectedSouls(workItemId, depGraphEntries, tessellation) {
45
+ if (!depGraphEntries || depGraphEntries.length === 0)
46
+ return [];
47
+ const normalizedId = workItemId.toLowerCase();
48
+ const entry = depGraphEntries.find((e) => e.id.toLowerCase() === normalizedId);
49
+ if (!entry || !entry.targetedSoulIds || entry.targetedSoulIds.length === 0)
50
+ return [];
51
+ // Validate each declared soul ID against the tessellation manifest.
52
+ const validSoulIds = new Set(tessellation.souls.map((s) => s.soulId));
53
+ return entry.targetedSoulIds.filter((id) => validSoulIds.has(id));
54
+ }
55
+ /**
56
+ * Apply `crossSoulScoringRule` over a per-soul score map.
57
+ *
58
+ * Currently implements `min` (default per OQ-2 resolution) and `max`/`mean`
59
+ * escape valves. `weighted-traffic` and `weighted-revenue` require an external
60
+ * data source and are documented as advanced — they fall through to `min` when
61
+ * no weights are available (safe degenerate).
62
+ *
63
+ * @param soulIds - The soul IDs to aggregate over.
64
+ * @param scores - Per-soul score map (keyed by soulId).
65
+ * @param rule - The aggregation rule from the Tessellated DID.
66
+ * @param fallback - Default score when no soul scores are available (0.5).
67
+ */
68
+ export function applyCrossSoulRule(soulIds, scores, rule, fallback = 0.5) {
69
+ const values = soulIds.map((id) => scores[id]).filter((v) => v !== undefined);
70
+ if (values.length === 0)
71
+ return fallback;
72
+ switch (rule ?? 'min') {
73
+ case 'min':
74
+ return Math.min(...values);
75
+ case 'max':
76
+ return Math.max(...values);
77
+ case 'mean':
78
+ return values.reduce((sum, v) => sum + v, 0) / values.length;
79
+ case 'weighted-traffic':
80
+ case 'weighted-revenue':
81
+ // Advanced variants require an external data source (per RFC-0009 §5.2 note).
82
+ // Degenerate to `min` when no weight data available — safe, conservative.
83
+ return Math.min(...values);
84
+ }
85
+ }
86
+ /**
87
+ * Compute tessellated Sα + Eρ₄ for a work item, implementing RFC-0009 §6.
88
+ *
89
+ * @param workItemId - The canonical work item ID.
90
+ * @param fallbackSa - SA score to use when tessellation is absent (single-DID path).
91
+ * @param fallbackEr4 - Eρ₄ score to use when tessellation is absent.
92
+ * @param tessellationCtx - Tessellation context, or undefined for non-tessellated DID.
93
+ */
94
+ export function computeTessellatedScores(workItemId, fallbackSa, fallbackEr4, tessellationCtx) {
95
+ // ── Non-tessellated path (RFC-0008 legacy) ─────────────────────
96
+ if (!tessellationCtx) {
97
+ return {
98
+ soulAlignment: fallbackSa,
99
+ er4: fallbackEr4,
100
+ routingPath: 'non-tessellated',
101
+ affectedSoulIds: [],
102
+ };
103
+ }
104
+ const { tessellation, soulScores, depGraphEntries } = tessellationCtx;
105
+ const affectedSoulIds = resolveAffectedSouls(workItemId, depGraphEntries, tessellation);
106
+ // Build per-soul score maps for Sα and Eρ₄.
107
+ const soulSaMap = {};
108
+ const soulEr4Map = {};
109
+ for (const soul of tessellation.souls) {
110
+ const scores = soulScores[soul.soulId];
111
+ if (scores) {
112
+ soulSaMap[soul.soulId] = scores.soulAlignment;
113
+ soulEr4Map[soul.soulId] = scores.er4;
114
+ }
115
+ }
116
+ const rule = tessellation.crossSoulScoringRule ?? 'min';
117
+ const allSoulIds = tessellation.souls.map((s) => s.soulId);
118
+ // ── Substrate-only path (§6 degenerate) ───────────────────────
119
+ if (affectedSoulIds.length === 0) {
120
+ return {
121
+ soulAlignment: applyCrossSoulRule(allSoulIds, soulSaMap, rule, fallbackSa),
122
+ er4: applyCrossSoulRule(allSoulIds, soulEr4Map, rule, fallbackEr4),
123
+ routingPath: 'substrate-only',
124
+ affectedSoulIds: [],
125
+ };
126
+ }
127
+ // ── Single-soul path ───────────────────────────────────────────
128
+ if (affectedSoulIds.length === 1) {
129
+ const soulId = affectedSoulIds[0];
130
+ const scores = soulScores[soulId];
131
+ return {
132
+ soulAlignment: scores?.soulAlignment ?? fallbackSa,
133
+ er4: scores?.er4 ?? fallbackEr4,
134
+ routingPath: 'single-soul',
135
+ affectedSoulIds,
136
+ };
137
+ }
138
+ // ── Multi-soul path (crossSoulScoringRule over affected souls) ─
139
+ return {
140
+ soulAlignment: applyCrossSoulRule(affectedSoulIds, soulSaMap, rule, fallbackSa),
141
+ er4: applyCrossSoulRule(affectedSoulIds, soulEr4Map, rule, fallbackEr4),
142
+ routingPath: 'multi-soul',
143
+ affectedSoulIds,
144
+ };
145
+ }
146
+ //# sourceMappingURL=tessellation-admission.js.map
@@ -0,0 +1,246 @@
1
+ /**
2
+ * RFC-0009 Phase 4.2 — Eτ_tessellation_drift detector (orchestrator-side).
3
+ *
4
+ * Detects design-coherence drift across tessellated souls per RFC-0009 §7.2
5
+ * (OQ-6 resolution: detection is orchestrator-side, not adapter-side).
6
+ *
7
+ * Three detection rules are specified in §7.2:
8
+ *
9
+ * Rule #1 — AST scan for soul-name string literals in shared substrate
10
+ * SHIPS HERE. Static scan over the substrate file set looking for
11
+ * soul-slug string literals and `if (soul === '<slug>')` patterns
12
+ * in modules that are NOT scoped to a single soul.
13
+ *
14
+ * Rule #2 — Embedding distance between Soul DIDs over time
15
+ * EXPLICITLY DEFERRED to RFC-0019 (Embedding Provider Adapter).
16
+ * Not implemented here; would land in a separate detector once
17
+ * `embedDocument(text)` is callable from the orchestrator.
18
+ *
19
+ * Rule #3 — Cross-soul provenance audits
20
+ * SHIPS HERE. Walks the supplied provenance records (RFC-0009 §8.3
21
+ * ProvenanceRecord with `targetedSouls`, `substrateScoped`,
22
+ * `tessellatedSoulRef`, all landed by AISDLC-315) and flags work
23
+ * whose `targetedSouls` set crosses tessellation boundaries
24
+ * without an amendment record; flags substrate work whose
25
+ * downstream provenance shows soul-distinct outcomes diverge.
26
+ *
27
+ * Both shipped rules are gated on adopter opt-in via `enabled` (default
28
+ * `false`) per RFC-0009 §10 Phase 4 promotion convention ("All sub-dimension
29
+ * activations are gated on adopter opt-in initially").
30
+ *
31
+ * Detected drift events emit to `events.jsonl` (the RFC-0015 substrate) via
32
+ * the supplied `emit` callback. Callers wire this to
33
+ * `orchestrator/src/artifacts.appendEvent(artifactsDir, event)`.
34
+ *
35
+ * @see spec/rfcs/RFC-0009-tessellated-design-intent-documents.md §7.2 + §10
36
+ */
37
+ import type { ProvenanceRecord } from '@ai-sdlc/reference';
38
+ import type { Tessellation } from '@ai-sdlc/reference';
39
+ /**
40
+ * Discriminated rule identifier for an emitted drift event.
41
+ *
42
+ * - `'ast-scan'` — Rule #1 (soul-name leakage in substrate).
43
+ * - `'cross-soul-provenance'` — Rule #3 (provenance crosses soul boundaries
44
+ * without amendment, OR substrate
45
+ * provenance shows divergent soul-
46
+ * distinct outcomes).
47
+ *
48
+ * Rule #2 (`'embedding-distance'`) is reserved for the RFC-0019 follow-on
49
+ * detector and is intentionally NOT a member of this union — exporting it
50
+ * here would invite premature consumers. AISDLC-340 will add it.
51
+ */
52
+ export type TessellationDriftRule = 'ast-scan' | 'cross-soul-provenance';
53
+ /**
54
+ * The minimal common shape of every drift event written to events.jsonl.
55
+ *
56
+ * Discriminated by `rule` so consumers (operators grepping events.jsonl,
57
+ * cli-status, TUI analytics) can attribute to the originating detector
58
+ * without re-parsing free-form messages.
59
+ */
60
+ export interface TessellationDriftDetectedEvent {
61
+ type: 'TessellationDriftDetected';
62
+ rule: TessellationDriftRule;
63
+ /** RFC-3339 UTC timestamp at detection time. */
64
+ timestamp: string;
65
+ /**
66
+ * Parent Tessellated DID URI (e.g., `did:platform-x:platform`) the drift
67
+ * was detected against. Sourced from the `tessellation` field's owning
68
+ * DID; callers pass it through so events.jsonl traces back to the DID.
69
+ */
70
+ tessellatedDid: string;
71
+ /**
72
+ * Soul IDs implicated in the drift (for `ast-scan`: souls whose slugs
73
+ * appeared in shared substrate; for `cross-soul-provenance`: souls
74
+ * crossed). Empty if no specific souls are implicated.
75
+ */
76
+ involvedSouls: string[];
77
+ /** Human-readable severity label. Currently a single tier; reserved for future expansion. */
78
+ severity: 'warning';
79
+ /** Free-form one-line summary; safe for operator surfaces (TUI, Slack). */
80
+ message: string;
81
+ /**
82
+ * Rule-specific structured payload. Per-rule discriminator is `rule`
83
+ * above; consumers narrow on that before reading `details`.
84
+ */
85
+ details: AstScanDetails | CrossSoulProvenanceDetails;
86
+ }
87
+ /** Details emitted by Rule #1 (AST scan). */
88
+ export interface AstScanDetails {
89
+ rule: 'ast-scan';
90
+ /** Each finding represents one literal/conditional hit in substrate code. */
91
+ findings: AstScanFinding[];
92
+ }
93
+ /** A single AST-scan finding. */
94
+ export interface AstScanFinding {
95
+ /** Path of the substrate file that contained the soul-leaking literal. */
96
+ filePath: string;
97
+ /** Soul slug whose name leaked into shared substrate. */
98
+ soulSlug: string;
99
+ /** 1-based line number in `filePath`. */
100
+ line: number;
101
+ /**
102
+ * Discriminator for which pattern triggered the finding:
103
+ * - `'string-literal'` — bare `'<slug>'` (or `"<slug>"`) appeared in substrate
104
+ * - `'soul-conditional'` — `if (soul === '<slug>')` / `=== "<slug>"` branched on soul
105
+ */
106
+ pattern: 'string-literal' | 'soul-conditional';
107
+ /** The raw matching substring (trimmed) for operator inspection. */
108
+ excerpt: string;
109
+ }
110
+ /** Details emitted by Rule #3 (cross-soul provenance audit). */
111
+ export interface CrossSoulProvenanceDetails {
112
+ rule: 'cross-soul-provenance';
113
+ /** Each finding represents one provenance record (or substrate-vs-soul divergence) flagged. */
114
+ findings: CrossSoulProvenanceFinding[];
115
+ }
116
+ /** A single cross-soul provenance finding. */
117
+ export interface CrossSoulProvenanceFinding {
118
+ /**
119
+ * Discriminator:
120
+ * - `'cross-boundary-no-amendment'` — provenance's `targetedSouls` spans
121
+ * >=2 souls and no recorded amendment was supplied for the work.
122
+ * - `'substrate-divergent-outcomes'` — `substrateScoped: true` provenance
123
+ * where downstream soul-distinct outcomes diverge sharply (the caller-
124
+ * supplied `outcomeBySoul` map shows ≥`divergenceThreshold` spread).
125
+ */
126
+ kind: 'cross-boundary-no-amendment' | 'substrate-divergent-outcomes';
127
+ /**
128
+ * Stable per-work-item identifier extracted from `promptHash` so operators
129
+ * can grep events.jsonl by work item without exposing soul data.
130
+ */
131
+ workItemRef: string;
132
+ /** Soul IDs crossed (for cross-boundary) or implicated (for substrate-divergent). */
133
+ crossedSouls: string[];
134
+ /**
135
+ * Soul-distinct outcome readings for substrate-divergent findings, keyed
136
+ * by soulId. Absent for cross-boundary findings.
137
+ */
138
+ outcomeBySoul?: Record<string, number>;
139
+ /** Free-form description; safe for operator surfaces. */
140
+ note: string;
141
+ }
142
+ /**
143
+ * A single substrate file's contents for Rule #1 to scan.
144
+ *
145
+ * Callers materialize this from the dependency graph + filesystem before
146
+ * invoking the detector. Only files NOT scoped to a single soul should be
147
+ * passed in (files under `.ai-sdlc/souls/<slug>/` or other soul-scoped
148
+ * trees are by-definition allowed to mention their own soul slug).
149
+ */
150
+ export interface SubstrateFile {
151
+ /** Workspace-relative path (use forward slashes; informational only). */
152
+ path: string;
153
+ /** Full file contents as UTF-8. */
154
+ contents: string;
155
+ }
156
+ /**
157
+ * One provenance record paired with the optional cross-soul amendment ref +
158
+ * the optional downstream soul-outcome readings.
159
+ *
160
+ * `amendmentRecorded` is true when the work item carried an explicit
161
+ * cross-tessellation amendment (operator-acknowledged the cross-soul span).
162
+ * `outcomeBySoul` is the optional downstream calibration cell readout per
163
+ * soul, supplied for substrate-scoped provenance so Rule #3 can detect
164
+ * sharp divergence in soul-distinct outcomes.
165
+ */
166
+ export interface ProvenanceAuditEntry {
167
+ /** The provenance record itself (RFC-0009 §8.3 extended shape). */
168
+ record: ProvenanceRecord;
169
+ /** True iff the operator recorded a cross-tessellation amendment for this work item. */
170
+ amendmentRecorded?: boolean;
171
+ /**
172
+ * Soul-distinct outcome readout, keyed by soulId. Only meaningful when
173
+ * `record.substrateScoped === true`. Values are caller-supplied outcome
174
+ * scores in [0, 1]; the detector flags when the spread exceeds
175
+ * `divergenceThreshold`.
176
+ */
177
+ outcomeBySoul?: Record<string, number>;
178
+ }
179
+ /**
180
+ * Detector configuration. All fields optional with safe defaults; the only
181
+ * required toggle is `enabled` (default `false`, honoring RFC-0009 §10
182
+ * Phase 4 opt-in default).
183
+ */
184
+ export interface TessellationDriftConfig {
185
+ /**
186
+ * Master opt-in switch. Per RFC-0009 §10 Phase 4 "All sub-dimension
187
+ * activations are gated on adopter opt-in initially". Default `false`;
188
+ * the detector short-circuits and emits nothing when disabled.
189
+ */
190
+ enabled?: boolean;
191
+ /**
192
+ * Per-rule kill switches. Useful for staged rollout (e.g., enable rule
193
+ * #1 first, observe noise levels, then enable rule #3). Defaults: both
194
+ * `true` (subject to `enabled` master gate).
195
+ */
196
+ rules?: {
197
+ astScan?: boolean;
198
+ crossSoulProvenance?: boolean;
199
+ };
200
+ /**
201
+ * Spread threshold for substrate-divergent-outcomes detection. When the
202
+ * max-min of `outcomeBySoul` values exceeds this number, the detector
203
+ * emits a `substrate-divergent-outcomes` finding. Defaults to 0.3 (a
204
+ * 30-point spread on a 0..1 outcome scale).
205
+ */
206
+ divergenceThreshold?: number;
207
+ }
208
+ export declare const DEFAULT_DIVERGENCE_THRESHOLD = 0.3;
209
+ export interface TessellationDriftInput {
210
+ /** The Tessellated DID URI the scan runs against (for event provenance). */
211
+ tessellatedDid: string;
212
+ /** The tessellation manifest (souls + substrate invariants). */
213
+ tessellation: Tessellation;
214
+ /** Substrate file contents to scan with Rule #1. Empty/absent = rule #1 no-op. */
215
+ substrateFiles?: SubstrateFile[];
216
+ /** Provenance entries to scan with Rule #3. Empty/absent = rule #3 no-op. */
217
+ provenance?: ProvenanceAuditEntry[];
218
+ }
219
+ export interface TessellationDriftResult {
220
+ /** Every drift event emitted during this run (also forwarded to `emit`). */
221
+ events: TessellationDriftDetectedEvent[];
222
+ /** True when the detector short-circuited because `enabled === false`. */
223
+ optedOut: boolean;
224
+ }
225
+ /**
226
+ * Run Eτ_tessellation_drift detection against the supplied inputs.
227
+ *
228
+ * The detector is **read-only** — it does not mutate the tessellation,
229
+ * the provenance records, or the substrate files. It computes events and
230
+ * forwards each via the optional `emit` callback (callers wire this to
231
+ * `appendEvent(artifactsDir, ev)`).
232
+ *
233
+ * When `config.enabled !== true` the detector short-circuits immediately
234
+ * and returns `{ events: [], optedOut: true }`. This honors the RFC-0009
235
+ * §10 Phase 4 "adopter opt-in initially" convention; the detector exists
236
+ * in the surface but produces zero side effects until explicitly enabled.
237
+ *
238
+ * @param input Detection inputs (tessellation + optional substrate + provenance).
239
+ * @param config Detector configuration (master `enabled` flag + per-rule toggles).
240
+ * @param emit Optional event sink; called once per detected event. Errors
241
+ * from `emit` are propagated to the caller (intentional — the
242
+ * detector is sync-pure with respect to its inputs; the caller
243
+ * decides how to handle event-stream failures).
244
+ */
245
+ export declare function detectTessellationDrift(input: TessellationDriftInput, config?: TessellationDriftConfig, emit?: (event: TessellationDriftDetectedEvent) => Promise<void> | void): Promise<TessellationDriftResult>;
246
+ //# sourceMappingURL=tessellation-drift.d.ts.map