@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,1341 @@
1
+ /**
2
+ * Embedded template strings scaffolded by `ai-sdlc init` (AISDLC-143).
3
+ *
4
+ * Why these live in code instead of being read from disk at runtime:
5
+ * - The orchestrator ships as an npm package; users `npm i -g
6
+ * @ai-sdlc/orchestrator` and run `ai-sdlc init` in a brand new repo.
7
+ * The `dist/` payload would not include arbitrary `*.yml` source
8
+ * fixtures unless we listed each one in `package.json#files` AND
9
+ * plumbed a `__dirname`-based loader through esm import-meta.url.
10
+ * - Embedded strings work identically when invoked via `node ./dist/...`
11
+ * from a checkout, via `npx @ai-sdlc/orchestrator init`, or via a
12
+ * pre-bundled binary, with no runtime filesystem dependency.
13
+ *
14
+ * Drift policy: when the canonical workflow at
15
+ * `.github/workflows/ai-sdlc-gate.yml` (or the audit-only
16
+ * `verify-attestation.yml`) is updated for adopters, mirror the change
17
+ * here. The init-workspace test suite includes a smoke check that the
18
+ * embedded copy at least parses as a YAML mapping; AISDLC-140 sub-3's
19
+ * cutover memo will add a hard byte-equality assertion against the live
20
+ * file once the framework's own copy stabilizes.
21
+ *
22
+ * Q-decisions baked into the templates:
23
+ * - Q1 (prescriptive default): the gate workflow is scaffolded
24
+ * unconditionally — every adopter gets `ai-sdlc/pr-ready` on day one.
25
+ * - Q3 (attestation = audit-only): verify-attestation template is the
26
+ * audit-only variant; signing infrastructure is opt-in via
27
+ * `--with-attestation`.
28
+ * - Q4(b) (interactive default with --yes escape hatch): see
29
+ * `init-features.ts` for the wizard wiring; this module just supplies
30
+ * the byte content.
31
+ */
32
+ /** `.github/workflows/ai-sdlc-gate.yml` — single rollup PR-ready check. */
33
+ export const AI_SDLC_GATE_WORKFLOW = `name: AI-SDLC PR Ready Gate
34
+
35
+ # Single rollup status check \`ai-sdlc/pr-ready\` that aggregates every PR
36
+ # signal AI-SDLC adopters need into ONE branch-protection entry. Replaces
37
+ # the historical pattern of enumerating N required checks by name + app_id,
38
+ # which is brittle against path filters, [skip ci] tokens, matrix changes,
39
+ # and multi-app posters. See \`docs/operations/quality-gate.md\` for the
40
+ # full rationale.
41
+ #
42
+ # Industry pattern: \`re-actors/alls-green\` ("alls-green") is the de facto
43
+ # community fix; named adopters include aiohttp, attrs, conda, setuptools,
44
+ # pytest, pip-tools, Open edX, PyCA, PyPA, Mergify.
45
+
46
+ on:
47
+ # AISDLC-261 PR #480 review fix: include 'ready_for_review' so the gate
48
+ # fires when adopters using the draft-PR flow (AISDLC-218) flip a PR
49
+ # from draft to ready. Without it, ai-sdlc/pr-ready stays unposted on
50
+ # the ready transition and branch protection fails.
51
+ pull_request:
52
+ types: [opened, synchronize, reopened, ready_for_review]
53
+ merge_group:
54
+ types: [checks_requested]
55
+
56
+ concurrency:
57
+ group: ai-sdlc-gate-\${{ github.event.pull_request.number || github.event.merge_group.head_sha || github.ref }}
58
+ cancel-in-progress: true
59
+
60
+ permissions:
61
+ contents: read
62
+ pull-requests: read
63
+ checks: write
64
+
65
+ jobs:
66
+ detect:
67
+ name: Detect Changes
68
+ runs-on: ubuntu-latest
69
+ outputs:
70
+ docs_only: \${{ steps.filter.outputs.docs_only }}
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - id: filter
74
+ uses: dorny/paths-filter@v3
75
+ with:
76
+ predicate-quantifier: 'every'
77
+ filters: |
78
+ docs_only:
79
+ - 'docs/**'
80
+ - '*.md'
81
+
82
+ lint:
83
+ name: Lint & Format
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - uses: actions/checkout@v4
87
+ - uses: pnpm/action-setup@v4
88
+ - uses: actions/setup-node@v4
89
+ with:
90
+ node-version: 22
91
+ cache: pnpm
92
+ - run: pnpm install --frozen-lockfile
93
+ - run: pnpm lint
94
+ - run: pnpm format:check
95
+
96
+ build-test:
97
+ name: Build & Test (Node \${{ matrix.node-version }})
98
+ needs: detect
99
+ if: needs.detect.outputs.docs_only != 'true'
100
+ runs-on: ubuntu-latest
101
+ strategy:
102
+ fail-fast: false
103
+ matrix:
104
+ node-version: [20, 22]
105
+ steps:
106
+ - uses: actions/checkout@v4
107
+ - uses: pnpm/action-setup@v4
108
+ - uses: actions/setup-node@v4
109
+ with:
110
+ node-version: \${{ matrix.node-version }}
111
+ cache: pnpm
112
+ - run: pnpm install --frozen-lockfile
113
+ - run: pnpm build
114
+ - run: pnpm test
115
+
116
+ coverage:
117
+ name: Coverage
118
+ needs: detect
119
+ if: needs.detect.outputs.docs_only != 'true'
120
+ runs-on: ubuntu-latest
121
+ steps:
122
+ - uses: actions/checkout@v4
123
+ - uses: pnpm/action-setup@v4
124
+ - uses: actions/setup-node@v4
125
+ with:
126
+ node-version: 22
127
+ cache: pnpm
128
+ - run: pnpm install --frozen-lockfile
129
+ - run: pnpm build
130
+ - run: pnpm test:coverage
131
+
132
+ pr-ready:
133
+ name: ai-sdlc/pr-ready
134
+ needs: [detect, lint, build-test, coverage]
135
+ if: always()
136
+ runs-on: ubuntu-latest
137
+ steps:
138
+ - name: Aggregate required signals
139
+ uses: re-actors/alls-green@release/v1
140
+ with:
141
+ jobs: \${{ toJSON(needs) }}
142
+ `;
143
+ /**
144
+ * `.github/workflows/verify-attestation.yml` — AUDIT-ONLY verifier.
145
+ *
146
+ * Per Q3 in /tmp/quality-gate-redesign-final.md, attestation infrastructure
147
+ * is opt-in and audit-only. This workflow logs verification results to the
148
+ * action run log but does NOT post a required-status check or block merges.
149
+ * Operators who want to promote attestation to a hard gate can edit the
150
+ * \`Log audit result\` step to write to commit statuses.
151
+ */
152
+ export const VERIFY_ATTESTATION_WORKFLOW = `name: AI-SDLC Verify Review Attestation
153
+
154
+ # Reads the DSSE attestation at .ai-sdlc/attestations/<head-sha>.dsse.json
155
+ # and verifies the signature against any-of-N pubkeys in
156
+ # .ai-sdlc/trusted-reviewers.yaml.
157
+ #
158
+ # AUDIT-ONLY: this workflow logs verification results (success/failure with
159
+ # reason) for forensic purposes but does NOT post a required commit status.
160
+ # The single merge gate is \`ai-sdlc/pr-ready\` from ai-sdlc-gate.yml.
161
+
162
+ on:
163
+ pull_request:
164
+ types: [opened, synchronize, reopened]
165
+ branches: [main]
166
+ paths-ignore:
167
+ - 'docs/**'
168
+ - '*.md'
169
+ merge_group:
170
+ types: [checks_requested]
171
+
172
+ concurrency:
173
+ group: verify-attestation-\${{ github.event.pull_request.number || github.event.merge_group.head_sha }}
174
+ cancel-in-progress: true
175
+
176
+ jobs:
177
+ verify:
178
+ name: Verify attestation
179
+ runs-on: ubuntu-latest
180
+ permissions:
181
+ contents: read
182
+ steps:
183
+ - name: Resolve subject SHA + base SHA from event payload
184
+ id: resolve
185
+ run: |
186
+ if [ "\${{ github.event_name }}" = "merge_group" ]; then
187
+ echo "head_sha=\${{ github.event.merge_group.head_sha }}" >> "$GITHUB_OUTPUT"
188
+ echo "base_sha=\${{ github.event.merge_group.base_sha }}" >> "$GITHUB_OUTPUT"
189
+ else
190
+ echo "head_sha=\${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT"
191
+ echo "base_sha=\${{ github.event.pull_request.base.sha }}" >> "$GITHUB_OUTPUT"
192
+ fi
193
+
194
+ - uses: actions/checkout@v4
195
+ with:
196
+ fetch-depth: 0
197
+ ref: \${{ steps.resolve.outputs.head_sha }}
198
+
199
+ - name: Log audit result
200
+ env:
201
+ HEAD_SHA: \${{ steps.resolve.outputs.head_sha }}
202
+ run: |
203
+ if [ -f ".ai-sdlc/attestations/\${HEAD_SHA}.dsse.json" ]; then
204
+ echo "::notice::ai-sdlc attestation AUDIT — envelope present at \${HEAD_SHA}"
205
+ else
206
+ echo "::notice::ai-sdlc attestation AUDIT — no envelope on \${HEAD_SHA} (audit-only, not blocking)"
207
+ fi
208
+ `;
209
+ /**
210
+ * `.husky/pre-push` snippet that signs an attestation when one is missing
211
+ * for the current HEAD. Installed when `--with-attestation` is opted in;
212
+ * the actual `sign-attestation.mjs` script ships separately with the
213
+ * orchestrator and is referenced by the canonical command stub here.
214
+ *
215
+ * Adopters typically already have a `.husky/pre-push` from their existing
216
+ * tooling; the wizard appends our snippet behind a sentinel so we can
217
+ * extend an existing hook without trampling user content.
218
+ */
219
+ export const HUSKY_PREPUSH_SIGN_SNIPPET = `# ai-sdlc:attestation-sign-block
220
+ # Signs the DSSE attestation envelope for the current HEAD when verdict
221
+ # files exist. Skip with AI_SDLC_SKIP_ATTESTATION_SIGN=1.
222
+ if [ -z "\${AI_SDLC_SKIP_ATTESTATION_SIGN:-}" ] && [ -x "./scripts/check-attestation-sign.sh" ]; then
223
+ ./scripts/check-attestation-sign.sh
224
+ fi
225
+ # end ai-sdlc:attestation-sign-block
226
+ `;
227
+ /**
228
+ * `.ai-sdlc/trusted-reviewers.yaml` stub — empty allowlist with operator
229
+ * instructions. The wizard scaffolds this so adopters have a single file
230
+ * to receive contributor pubkey PRs into; bootstrap a contributor with
231
+ * `/ai-sdlc init-signing-key` and append the printed YAML block.
232
+ */
233
+ export const TRUSTED_REVIEWERS_STUB = `# Trusted contributor signing keys for review attestations.
234
+ #
235
+ # This file is a stub created by \`ai-sdlc init --with-attestation\`. Add
236
+ # entries by running \`/ai-sdlc init-signing-key\` on a contributor's
237
+ # machine and opening a PR that appends the printed YAML block below.
238
+ #
239
+ # Schema:
240
+ # - identity: free-form string (typically email or GitHub handle)
241
+ # - machine: free-form label (lets one identity register multiple keys)
242
+ # - pubkey: PEM-encoded ed25519 public key (multi-line block scalar)
243
+ # - addedAt: ISO 8601 date the entry was added
244
+ # - addedBy: GitHub handle of the maintainer who approved this entry's PR
245
+ #
246
+ # The verifier in CI uses a strict YAML format: every scalar value
247
+ # single-quoted; \`pubkey:\` is a \`|\` block scalar with each PEM line
248
+ # indented exactly 6 spaces; no tab characters anywhere.
249
+
250
+ reviewers: []
251
+ `;
252
+ /**
253
+ * `.ai-sdlc/dor-config.yaml` stub — Definition-of-Ready rubric config.
254
+ *
255
+ * Mirrors the production DoR config used by the framework itself; ships
256
+ * in warn-only mode so a fresh adopter does not get blocked by the rubric
257
+ * while they tune it.
258
+ */
259
+ export const DOR_CONFIG_STUB = `# Definition-of-Ready (DoR) gate configuration.
260
+ #
261
+ # The DoR rubric scores incoming issues + backlog tasks against seven
262
+ # criteria (binary-testable ACs, no wishlist markers, references resolve,
263
+ # bounded scope, surface named, done-state describable, no invisible
264
+ # dependencies). Failing the rubric posts a clarification comment on the
265
+ # issue / PR.
266
+ #
267
+ # Ships in warn-only mode by default — flip to 'enforce' after the soak
268
+ # window confirms the false-positive rate is low.
269
+
270
+ apiVersion: ai-sdlc.io/v1alpha1
271
+ kind: DorConfig
272
+ metadata:
273
+ name: ai-sdlc-dor
274
+ spec:
275
+ rubricVersion: v1
276
+ evaluationMode: warn-only
277
+
278
+ notifications:
279
+ authorChannel: true
280
+ # dedicatedChannel:
281
+ # slack: '#ai-sdlc-dor'
282
+
283
+ staleness:
284
+ warnAfterDays: 14
285
+ closeAfterDays: 28
286
+ closedLabel: 'closed-as-stale-dor'
287
+ `;
288
+ /** `.github/workflows/dor-ingress.yml` — minimal DoR ingress shim. */
289
+ export const DOR_INGRESS_WORKFLOW = `name: AI-SDLC DoR Ingress
290
+
291
+ # Wires the DoR rubric into the GitHub issue + PR lifecycle:
292
+ # - issues:opened / issues:edited → score the issue body, post the
293
+ # idempotent clarification comment when needs-clarification.
294
+ # - pull_request touching backlog/tasks/*.md → score the changed
295
+ # task bodies (the in-repo equivalent of an issue).
296
+ #
297
+ # Ships in warn-only mode (see .ai-sdlc/dor-config.yaml). Flip the
298
+ # config's \`evaluationMode\` to \`enforce\` after the soak window.
299
+
300
+ on:
301
+ issues:
302
+ types: [opened, edited]
303
+ pull_request:
304
+ types: [opened, synchronize, reopened]
305
+ paths:
306
+ - 'backlog/tasks/*.md'
307
+
308
+ concurrency:
309
+ group: dor-ingress-\${{ github.event.issue.number || github.event.pull_request.number }}
310
+ cancel-in-progress: true
311
+
312
+ jobs:
313
+ evaluate:
314
+ name: Evaluate against DoR rubric
315
+ runs-on: ubuntu-latest
316
+ permissions:
317
+ issues: write
318
+ pull-requests: write
319
+ contents: read
320
+ steps:
321
+ - uses: actions/checkout@v4
322
+ - uses: pnpm/action-setup@v4
323
+ - uses: actions/setup-node@v4
324
+ with:
325
+ node-version: 22
326
+ cache: pnpm
327
+ - run: pnpm install --frozen-lockfile
328
+ - name: Evaluate DoR (placeholder — wire to your DoR runner)
329
+ run: |
330
+ echo "::notice::DoR ingress shim invoked. Wire pnpm --filter @ai-sdlc/pipeline-cli evaluate-dor here."
331
+ `;
332
+ /**
333
+ * `.ai-sdlc/review-classifier.yaml` stub — cost-optimized review tiers.
334
+ *
335
+ * The actual classifier code ships via AISDLC-141 (a follow-up). For now
336
+ * the wizard scaffolds the config stub + a pointer to the classifier
337
+ * docs so adopters who opt in via `--with-classifier` are ready to flip
338
+ * on the workflow once AISDLC-141 lands.
339
+ */
340
+ export const REVIEW_CLASSIFIER_STUB = `# Review classifier configuration (AISDLC-141, follow-up).
341
+ #
342
+ # The review classifier inspects a PR diff and decides which review tier
343
+ # to invoke (cheap-pattern-match → mid-tier-LLM → full reviewer fan-out)
344
+ # to keep review costs bounded as PR volume grows.
345
+ #
346
+ # This file is a stub scaffolded by \`ai-sdlc init --with-classifier\`.
347
+ # The classifier runtime ships in AISDLC-141; until then this config is
348
+ # advisory only. See docs/operations/init.md for the migration path.
349
+
350
+ apiVersion: ai-sdlc.io/v1alpha1
351
+ kind: ReviewClassifier
352
+ metadata:
353
+ name: default-classifier
354
+ spec:
355
+ tiers:
356
+ - name: cheap
357
+ maxFilesChanged: 5
358
+ maxLinesChanged: 50
359
+ strategy: pattern-match
360
+ - name: mid
361
+ maxFilesChanged: 20
362
+ maxLinesChanged: 500
363
+ strategy: single-llm-pass
364
+ - name: full
365
+ strategy: full-reviewer-fanout
366
+ routing:
367
+ docsOnly: cheap
368
+ testOnly: cheap
369
+ default: mid
370
+ `;
371
+ /**
372
+ * `.github/workflows/ai-sdlc-review.yml` — CI-side PR review workflow.
373
+ *
374
+ * Posts `Post Review Results` as a commit status so branch-protection can
375
+ * require it. Adopter repos that have not set up `ANTHROPIC_API_KEY` will
376
+ * see the job run but produce advisory-only output — the status check still
377
+ * posts `success` so it does not block merges.
378
+ *
379
+ * This is a simplified adopter-facing template. The AI-SDLC framework's
380
+ * own repo carries a more elaborate version that drives the full review
381
+ * fan-out pipeline (classifier, incremental review, etc.); adopters start
382
+ * here and can progressively opt into those features.
383
+ *
384
+ * Source of truth: `.github/workflows/ai-sdlc-review.yml` in the ai-sdlc
385
+ * framework repo (AISDLC-261). Mirror changes here when the adopter-facing
386
+ * surface evolves.
387
+ */
388
+ export const AI_SDLC_REVIEW_WORKFLOW = `name: AI-SDLC PR Review
389
+
390
+ # Posts \`Post Review Results\` as a required commit status.
391
+ # Docs-only PRs (spec/rfcs/**, docs/**, backlog/**, *.md) are short-circuited
392
+ # with success so they do not block the merge queue.
393
+
394
+ on:
395
+ pull_request:
396
+ types: [opened, synchronize, reopened, ready_for_review]
397
+ branches: [main]
398
+ paths-ignore:
399
+ - 'spec/rfcs/**'
400
+ - 'docs/**'
401
+ - 'backlog/tasks/**'
402
+ - 'backlog/completed/**'
403
+ - '*.md'
404
+ merge_group:
405
+ types: [checks_requested]
406
+
407
+ concurrency:
408
+ group: review-\${{ github.event.pull_request.number || github.event.merge_group.head_sha }}
409
+ cancel-in-progress: true
410
+
411
+ jobs:
412
+ docs-only-check:
413
+ name: Docs-only check
414
+ runs-on: ubuntu-latest
415
+ if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
416
+ permissions:
417
+ contents: read
418
+ statuses: write
419
+ pull-requests: read
420
+ steps:
421
+ - name: Resolve event SHA
422
+ id: resolve
423
+ run: |
424
+ if [ "\${{ github.event_name }}" = "merge_group" ]; then
425
+ echo "head_sha=\${{ github.event.merge_group.head_sha }}" >> "\${GITHUB_OUTPUT}"
426
+ echo "base_sha=\${{ github.event.merge_group.base_sha }}" >> "\${GITHUB_OUTPUT}"
427
+ echo "is_merge_group=true" >> "\${GITHUB_OUTPUT}"
428
+ else
429
+ echo "head_sha=\${{ github.event.pull_request.head.sha }}" >> "\${GITHUB_OUTPUT}"
430
+ echo "is_merge_group=false" >> "\${GITHUB_OUTPUT}"
431
+ fi
432
+
433
+ - uses: actions/checkout@v4
434
+ with:
435
+ fetch-depth: 0
436
+ ref: \${{ steps.resolve.outputs.head_sha }}
437
+
438
+ - name: Detect docs-only changeset
439
+ id: detect
440
+ env:
441
+ GH_TOKEN: \${{ github.token }}
442
+ PR_NUMBER: \${{ github.event.pull_request.number }}
443
+ REPO: \${{ github.repository }}
444
+ IS_MERGE_GROUP: \${{ steps.resolve.outputs.is_merge_group }}
445
+ BASE_SHA: \${{ steps.resolve.outputs.base_sha }}
446
+ HEAD_SHA: \${{ steps.resolve.outputs.head_sha }}
447
+ run: |
448
+ set -euo pipefail
449
+ if [ "\${IS_MERGE_GROUP}" = "true" ]; then
450
+ FILES=$(git -c core.quotePath=false diff --name-only "\${BASE_SHA}...\${HEAD_SHA}")
451
+ else
452
+ FILES=$(gh api "repos/\${REPO}/pulls/\${PR_NUMBER}/files" --paginate --jq '.[].filename')
453
+ fi
454
+ if [ -z "\${FILES}" ]; then
455
+ echo "all_docs=true" >> "\${GITHUB_OUTPUT}"
456
+ exit 0
457
+ fi
458
+ # Simple docs-only check: all files must be in docs, spec/rfcs, backlog, or *.md
459
+ ALL_DOCS=true
460
+ while IFS= read -r f; do
461
+ case "$f" in
462
+ docs/*|spec/rfcs/*|backlog/tasks/*|backlog/completed/*|*.md) ;;
463
+ *) ALL_DOCS=false; break ;;
464
+ esac
465
+ done <<< "\${FILES}"
466
+ echo "all_docs=\${ALL_DOCS}" >> "\${GITHUB_OUTPUT}"
467
+
468
+ - name: Post Review Results (docs-only short-circuit)
469
+ if: steps.detect.outputs.all_docs == 'true'
470
+ env:
471
+ GH_TOKEN: \${{ github.token }}
472
+ REPO: \${{ github.repository }}
473
+ HEAD_SHA: \${{ steps.resolve.outputs.head_sha }}
474
+ run: |
475
+ set -euo pipefail
476
+ gh api "repos/\${REPO}/statuses/\${HEAD_SHA}" \\
477
+ -X POST \\
478
+ -f state=success \\
479
+ -f context='Post Review Results' \\
480
+ -f description='docs-only changeset — review N/A'
481
+ echo "Posted Post Review Results: success (docs-only) on \${HEAD_SHA}"
482
+
483
+ review:
484
+ name: Post Review Results
485
+ runs-on: ubuntu-latest
486
+ if: >-
487
+ github.event_name == 'pull_request' &&
488
+ !startsWith(github.head_ref, 'release-please--') &&
489
+ github.event.pull_request.draft == false
490
+ needs: [docs-only-check]
491
+ permissions:
492
+ contents: read
493
+ pull-requests: write
494
+ statuses: write
495
+ steps:
496
+ - uses: actions/checkout@v4
497
+ with:
498
+ fetch-depth: 0
499
+
500
+ - name: Post Review Results (stub — fails closed by default)
501
+ env:
502
+ GH_TOKEN: \${{ github.token }}
503
+ REPO: \${{ github.repository }}
504
+ HEAD_SHA: \${{ github.event.pull_request.head.sha }}
505
+ # AISDLC-261 PR #480 review fix (CRITICAL): the stub now defaults to
506
+ # FAILURE so adopters who configure 'Post Review Results' as a required
507
+ # branch-protection check + enable auto-merge don't accidentally ship
508
+ # a phantom review gate that auto-merges every PR with zero review.
509
+ # To opt in to auto-pass while wiring your reviewers, set the repo
510
+ # variable AISDLC_REVIEW_STUB_AUTOPASS=true. Real reviewer wiring
511
+ # should replace this entire step.
512
+ AUTOPASS: \${{ vars.AISDLC_REVIEW_STUB_AUTOPASS }}
513
+ run: |
514
+ set -euo pipefail
515
+ if [ "\${AUTOPASS:-}" = "true" ]; then
516
+ STATE=success
517
+ DESC='Review passed (STUB AUTOPASS — wire your reviewers, then unset AISDLC_REVIEW_STUB_AUTOPASS)'
518
+ else
519
+ STATE=failure
520
+ DESC='Review stub not wired. Either replace this workflow step with your reviewers OR set repo var AISDLC_REVIEW_STUB_AUTOPASS=true (acknowledged risk).'
521
+ fi
522
+ gh api "repos/\${REPO}/statuses/\${HEAD_SHA}" \\
523
+ -X POST \\
524
+ -f state="\${STATE}" \\
525
+ -f context='Post Review Results' \\
526
+ -f description="\${DESC}"
527
+ echo "Posted Post Review Results: \${STATE} on \${HEAD_SHA}"
528
+ `;
529
+ /**
530
+ * `.github/workflows/auto-enable-auto-merge.yml` — auto-arms GitHub auto-merge
531
+ * on every new same-repo PR so the PR merges automatically as soon as required
532
+ * checks pass. Release-please PRs are excluded (operator arms manually).
533
+ *
534
+ * Source of truth: `.github/workflows/auto-enable-auto-merge.yml` in the
535
+ * ai-sdlc framework repo (AISDLC-261). Mirror changes here when the
536
+ * auto-merge strategy or exclude rules evolve.
537
+ *
538
+ * Requires:
539
+ * - GitHub repo setting "Allow auto-merge" must be enabled.
540
+ * - \`AI_SDLC_PAT\` secret with write access to the repo (or use
541
+ * \`secrets.GITHUB_TOKEN\` if the repo's default token has write access).
542
+ */
543
+ export const AUTO_ENABLE_AUTO_MERGE_WORKFLOW = `name: Auto-enable auto-merge on PR open
544
+
545
+ # Enables GitHub's auto-merge on every new same-repo PR. Once required
546
+ # checks pass, GitHub adds the PR to the merge queue which rebases + runs
547
+ # CI + merges if green. No human click needed.
548
+ #
549
+ # Requires repo setting "Allow auto-merge" to be enabled (Settings → General).
550
+ # Requires a PAT or GitHub App token with \`pull_requests: write\` stored as
551
+ # the \`AI_SDLC_PAT\` repository secret (or swap for \`github.token\` if your
552
+ # repo grants it write access).
553
+
554
+ on:
555
+ pull_request:
556
+ types: [opened, synchronize, reopened, ready_for_review]
557
+ check_suite:
558
+ types: [completed]
559
+ status:
560
+
561
+ permissions:
562
+ pull-requests: write
563
+ contents: write
564
+
565
+ jobs:
566
+ enable-auto-merge:
567
+ runs-on: ubuntu-latest
568
+ steps:
569
+ - name: Discover PR for this event
570
+ id: discover
571
+ env:
572
+ GH_TOKEN: \${{ secrets.AI_SDLC_PAT }}
573
+ GH_REPO: \${{ github.repository }}
574
+ EVENT_NAME: \${{ github.event_name }}
575
+ PR_NUMBER_FROM_PR_EVENT: \${{ github.event.pull_request.number }}
576
+ HEAD_SHA: \${{ github.event.check_suite.head_sha || github.event.sha || github.sha }}
577
+ run: |
578
+ set -euo pipefail
579
+ if [ "$EVENT_NAME" = "pull_request" ]; then
580
+ echo "pr=$PR_NUMBER_FROM_PR_EVENT" >> "$GITHUB_OUTPUT"
581
+ else
582
+ PR=$(gh api "/repos/$GH_REPO/commits/$HEAD_SHA/pulls" --jq '.[] | select(.state == "open") | .number' | head -1)
583
+ echo "pr=\${PR:-}" >> "$GITHUB_OUTPUT"
584
+ fi
585
+
586
+ - name: Skip when no PR matches
587
+ if: steps.discover.outputs.pr == ''
588
+ run: echo "[auto-enable] no open PR for this event — nothing to arm."
589
+
590
+ - name: Skip drafts, fork PRs, and release-please PRs
591
+ id: guard
592
+ if: steps.discover.outputs.pr != ''
593
+ env:
594
+ GH_TOKEN: \${{ secrets.AI_SDLC_PAT }}
595
+ GH_REPO: \${{ github.repository }}
596
+ PR: \${{ steps.discover.outputs.pr }}
597
+ REPO: \${{ github.repository }}
598
+ run: |
599
+ set -euo pipefail
600
+ PR_INFO=$(gh pr view "$PR" --json isDraft,headRepositoryOwner,headRepository,headRefName \\
601
+ -q '{isDraft: .isDraft, headRefName: .headRefName, headFull: (((.headRepositoryOwner.login // "") + "/" + (.headRepository.name // "")) // "")}')
602
+ IS_DRAFT=$(echo "$PR_INFO" | jq -r '.isDraft')
603
+ HEAD_FULL=$(echo "$PR_INFO" | jq -r '.headFull')
604
+ HEAD_REF=$(echo "$PR_INFO" | jq -r '.headRefName')
605
+ if [ "$IS_DRAFT" = "true" ]; then
606
+ echo "[auto-enable] PR #$PR is draft — skipping."
607
+ echo "skip=true" >> "$GITHUB_OUTPUT"
608
+ elif [ "$HEAD_FULL" = "/" ] || [ -z "$HEAD_FULL" ]; then
609
+ # AISDLC-261 PR #480 review fix: defensive — head repository was
610
+ # deleted or API returned an empty shape. Refuse to arm; operator
611
+ # can re-arm manually if intended.
612
+ echo "[auto-enable] PR #$PR has no resolvable head repository — skipping."
613
+ echo "skip=true" >> "$GITHUB_OUTPUT"
614
+ elif [ "$HEAD_FULL" != "$REPO" ]; then
615
+ echo "[auto-enable] PR #$PR is from a fork ($HEAD_FULL) — skipping."
616
+ echo "skip=true" >> "$GITHUB_OUTPUT"
617
+ elif case "$HEAD_REF" in release-please--*) true ;; *) false ;; esac; then
618
+ echo "[auto-enable] PR #$PR is a release-please PR — skipping. Arm manually when ready."
619
+ echo "skip=true" >> "$GITHUB_OUTPUT"
620
+ else
621
+ echo "skip=false" >> "$GITHUB_OUTPUT"
622
+ fi
623
+
624
+ - name: Refresh auto-merge
625
+ if: steps.discover.outputs.pr != '' && steps.guard.outputs.skip != 'true'
626
+ env:
627
+ GH_TOKEN: \${{ secrets.AI_SDLC_PAT }}
628
+ PR: \${{ steps.discover.outputs.pr }}
629
+ run: |
630
+ # disable-then-arm to clear any stale GitHub auto-merge state.
631
+ gh pr merge --disable-auto "$PR" 2>/dev/null || true
632
+ gh pr merge --auto "$PR"
633
+ `;
634
+ /**
635
+ * `.ai-sdlc/calibration.yaml` — per-org calibration config for the
636
+ * RFC-0031 DIDRevisionProposal mechanism (Refit AISDLC-310).
637
+ *
638
+ * Exposes OQ-12.1 (confidence thresholds) and OQ-12.5 (rejection weights +
639
+ * penalty floor) as per-org configurable defaults. All values default to
640
+ * the operator-affirmed shipped defaults from AISDLC-271 / PR #476.
641
+ *
642
+ * Drift policy: when `parseRevisionProposalCalibrationYaml()` in
643
+ * `orchestrator/src/sa-scoring/revision-proposal-config.ts` gains new
644
+ * config fields, mirror them here. The values in this template MUST match
645
+ * the DEFAULT_* constants exported from that module.
646
+ */
647
+ export const CALIBRATION_YAML_STUB = `# RFC-0031 DIDRevisionProposal calibration config (Refit AISDLC-310).
648
+ #
649
+ # Configures per-org thresholds and weights for the calibration-driven
650
+ # DID revision proposal mechanism. All values below are the shipped
651
+ # defaults (operator-affirmed 2026-05-16 audit). Adjust to tune the
652
+ # mechanism for your SOUL-drift cadence and review culture.
653
+ #
654
+ # Validation rules (enforced at load time by the runtime):
655
+ # - confidenceThresholds.highSampleSize > lowSampleSize > 0
656
+ # - all rejectionPrecedent.weights in [0, 1]
657
+ # - rejectionPrecedent.confidencePenaltyFloor in [0, 1]
658
+
659
+ calibration:
660
+ # Fields that should never receive auto-proposals (OQ-12.3).
661
+ # Add JSON-path identifiers for fields the triad has decided to lock.
662
+ # Operators remove entries from this list to opt back in.
663
+ lockNoProposal: []
664
+ # - $.identityClass.evolving.voiceRegister
665
+ # - $.identityClass.core.soulPurpose.mission
666
+
667
+ # Confidence threshold configuration (OQ-12.1).
668
+ # Sample size = dismissSignals + escalateSignals + driftEvents.
669
+ confidenceThresholds:
670
+ highSampleSize: 20 # sample size >= this → HIGH confidence (if other conditions met)
671
+ lowSampleSize: 5 # sample size < this → LOW confidence (regardless of other conditions)
672
+
673
+ # Rejection precedent configuration (OQ-12.5).
674
+ # When a proposal is rejected, a weight is stored in the rejection record
675
+ # and averaged across prior rejections to suppress future confidence for
676
+ # the same field. Formula: factor = max(floor, 1.0 - avgWeight x 0.5)
677
+ rejectionPrecedent:
678
+ weights:
679
+ highConfidenceRejection: 0.8 # strong disagreement signal
680
+ mediumConfidenceRejection: 0.5 # moderate disagreement
681
+ lowConfidenceRejection: 0.2 # expected noise level; low weight
682
+ confidencePenaltyFloor: 0.2 # max 80% suppression; raise to be more conservative
683
+ `;
684
+ /**
685
+ * `.ai-sdlc/embedding-config.yaml` — per-org embedding-framework defaults
686
+ * per RFC-0019 §15.1 (operator re-walkthrough 2026-05-21). Includes every
687
+ * NEW field surfaced by the re-walkthrough (marked as such inline):
688
+ * - scaleEscalationHeuristic (OQ-1)
689
+ * - perConsumerOverridesAllowed (OQ-2)
690
+ * - crossProviderPolicy split (OQ-3)
691
+ * - catalogDedup milestones (OQ-4)
692
+ * - unifiedCostReport (OQ-6 + OQ-7)
693
+ * - adapterBillingModelRespected (OQ-7)
694
+ *
695
+ * The framework reads this file when `AI_SDLC_EMBEDDING_PROVIDER=on` AND
696
+ * `Pipeline.spec.embedding` is present. Per-pipeline fields in
697
+ * `Pipeline.spec.embedding` override the corresponding per-org defaults here.
698
+ *
699
+ * The file is OPTIONAL — when absent, framework defaults apply (matching
700
+ * the values below). Operators commit this file to make the defaults
701
+ * explicit + reviewable.
702
+ */
703
+ export const EMBEDDING_CONFIG_YAML_STUB = `# Per-org embedding-framework defaults (RFC-0019 §15.1).
704
+ #
705
+ # Read by the framework when AI_SDLC_EMBEDDING_PROVIDER=on. Per-pipeline
706
+ # fields under spec.embedding override these defaults. The file is
707
+ # OPTIONAL — when absent, the framework defaults below apply.
708
+ #
709
+ # Reference: spec/rfcs/RFC-0019-embedding-provider-adapter.md §15.1
710
+ # Runbook: docs/operations/embedding-providers.md
711
+
712
+ embedding:
713
+ provider: openai-text-embedding-3-small # default adapter (OQ-5 + Phase 1)
714
+
715
+ storage: # OQ-1 — JSONL backend + scale-escalation heuristic
716
+ backend: jsonl
717
+ path: \${ARTIFACTS_DIR}/_embeddings/
718
+ gcRetentionDays: 90 # mtime-based GC threshold
719
+ scaleEscalationHeuristic: # NEW (re-walkthrough): operator-visible swap trigger
720
+ maxEntriesPerProvider: 100000 # > 100K → swap to sqlite or vector DB
721
+ maxP95ReadLatencyMs: 250 # OR > 250ms p95 read → swap
722
+ operatorRunbook: docs/operations/embedding-providers.md#scale-escalation
723
+
724
+ staleVectorPolicy: # OQ-2 — per-org default + per-consumer override
725
+ default: lazy-re-embed # alternatives: fail-loud | warn
726
+ logToCatalog: true # log every stale-vector event as Decision
727
+ perConsumerOverridesAllowed: true # NEW (re-walkthrough): consumers may pin policy at API
728
+ # site (e.g., RFC-0009 Eτ drift pins fail-loud regardless
729
+ # of org default to preserve historical-trajectory fidelity)
730
+
731
+ crossProviderPolicy: # OQ-3 — split (re-walkthrough refinement)
732
+ crossProvider: refuse # ALWAYS strict no-op cross-PROVIDER (openai vs cohere)
733
+ # → Decision: cross-provider-comparison-attempted
734
+ crossVersionWithinProvider: delegate-to-staleVectorPolicy
735
+ # cross-VERSION delegates to OQ-2 (resolves v0.2 conflict)
736
+
737
+ deprecation: # OQ-4 — three-layer precedence + catalog dedup
738
+ gracePeriodDays: 90 # framework default; adapter may declare defaultGracePeriodDays
739
+ strictModeAtDeprecatedAt: false
740
+ catalogDedup: # NEW (re-walkthrough): prevent Decision flood under orchestrator
741
+ enabled: true
742
+ milestonesDaysBeforeDeprecatedAt: [89, 60, 30, 7, 1]
743
+ # emit Decisions at milestones, NOT per-load
744
+
745
+ costTracking: # OQ-6 — distinct line item + per-consumer attribution
746
+ lineItem: embeddingTokens
747
+ budgetIntegration: rfc-0004
748
+ consumerLabelRequired: false # NEW (re-walkthrough): optional but recommended;
749
+ # callers pass consumerLabel for per-category attribution
750
+ # (e.g., 'rfc-0009-tessellation-drift', 'rfc-0008-ppa-similarity')
751
+ unifiedCostReport: # NEW (re-walkthrough): cross-substrate finance view
752
+ enabled: true # aggregates embeddingTokens + inputTokens + outputTokens +
753
+ # SubscriptionLedger window cost; tagged by costModel
754
+ costModelLabels:
755
+ - subscription-quota # Claude Code Max / Codex
756
+ - pay-per-token # OpenAI / Cohere / future Anthropic embeddings if launched
757
+
758
+ subscriptionLedgerInteraction: # OQ-7 — separation + per-adapter billingModel
759
+ consumeQuotaDefault: false # default for pay-per-token adapters
760
+ adapterBillingModelRespected: true # NEW (re-walkthrough): adapter declares
761
+ # 'pay-per-token' | 'subscription-quota' in capability matrix;
762
+ # subscription-quota adapters route through SubscriptionLedger
763
+ # (e.g., future Anthropic embeddings if shipped)
764
+ `;
765
+ /**
766
+ * Per-soul DesignSystemBinding template (RFC-0009 Phase 2.2).
767
+ *
768
+ * Scaffolded at `.ai-sdlc/souls/<slug>/design-system-binding.yaml` for
769
+ * each soul in a Tessellated Platform. The `spec.extends` field records
770
+ * the parent platform-root DSB name, implementing the additive inheritance
771
+ * chain described in RFC-0009 §6.
772
+ *
773
+ * Drift policy: when `DesignSystemBindingSpec` gains new required fields,
774
+ * mirror them here so that freshly-scaffolded soul DSBs are immediately valid.
775
+ *
776
+ * @param soulSlug - the soul identifier (e.g. "soul-a"); used in resource name
777
+ * @param platformDsbName - the parent platform-root DSB name (defaults to
778
+ * the literal placeholder `platform-dsb` for adopters to replace)
779
+ */
780
+ export function buildSoulDsbTemplate(soulSlug, platformDsbName = 'platform-dsb') {
781
+ return `apiVersion: ai-sdlc.io/v1alpha1
782
+ kind: DesignSystemBinding
783
+ metadata:
784
+ name: ${soulSlug}-dsb
785
+ labels:
786
+ ai-sdlc/soul: "${soulSlug}"
787
+ ai-sdlc/scope: soul
788
+ spec:
789
+ # Additively extends the platform-root DSB (RFC-0009 §6 resolution rules).
790
+ # Per-soul fields override / extend platform-root fields; absent fields
791
+ # fall through to the platform-root DSB at admission time.
792
+ extends: ${platformDsbName}
793
+
794
+ stewardship:
795
+ designAuthority:
796
+ # Soul-specific design authority — added to the platform-root authority set.
797
+ # Replace with your actual design authority contact(s).
798
+ principals:
799
+ - your-design-authority@example.com
800
+ scope:
801
+ - ${soulSlug}-design-intent
802
+ engineeringAuthority:
803
+ # Replace with your actual engineering authority contact(s).
804
+ principals:
805
+ - your-engineering-authority@example.com
806
+ scope:
807
+ - ${soulSlug}-compliance
808
+
809
+ designToolAuthority: specification
810
+
811
+ tokens:
812
+ provider: tokens-studio
813
+ format: w3c-dtcg
814
+ source:
815
+ repository: your-org/design-tokens
816
+ # Soul-specific token branch — override the platform-root source when
817
+ # this soul maintains divergent token values.
818
+ branch: soul/${soulSlug}
819
+ path: tokens/souls/${soulSlug}/
820
+ versionPolicy: minor
821
+
822
+ catalog:
823
+ provider: storybook
824
+ source:
825
+ # Soul-specific Storybook URL — override platform URL when souls have
826
+ # separate component catalogs.
827
+ storybookUrl: https://${soulSlug}.storybook.your-org.io
828
+
829
+ compliance:
830
+ coverage:
831
+ # Soul-specific coverage threshold (integer percent 0-100) — may be
832
+ # stricter than platform floor.
833
+ minimum: 70
834
+ target: 90
835
+
836
+ designReview:
837
+ required: true
838
+ # Soul-specific reviewers — unioned with platform-root reviewers at
839
+ # admission time per §6.3 additive resolution.
840
+ reviewers: []
841
+ scope:
842
+ - visual-quality
843
+ - accessibility-intent
844
+ `;
845
+ }
846
+ export const DOR_TEMPLATES = {
847
+ files: {
848
+ '.ai-sdlc/dor-config.yaml': DOR_CONFIG_STUB,
849
+ '.github/workflows/dor-ingress.yml': DOR_INGRESS_WORKFLOW,
850
+ },
851
+ };
852
+ export const ATTESTATION_TEMPLATES = {
853
+ files: {
854
+ '.ai-sdlc/trusted-reviewers.yaml': TRUSTED_REVIEWERS_STUB,
855
+ '.github/workflows/verify-attestation.yml': VERIFY_ATTESTATION_WORKFLOW,
856
+ // The .gitkeep ensures the attestations dir is tracked in git so the
857
+ // first PR's envelope lands cleanly without "directory does not exist"
858
+ // errors from the signing script.
859
+ '.ai-sdlc/attestations/.gitkeep': '',
860
+ },
861
+ };
862
+ export const CLASSIFIER_TEMPLATES = {
863
+ files: {
864
+ '.ai-sdlc/review-classifier.yaml': REVIEW_CLASSIFIER_STUB,
865
+ },
866
+ };
867
+ /**
868
+ * `.ai-sdlc/quality-monitoring.yaml` stub — RFC-0025 §13.1 per-org config.
869
+ *
870
+ * AISDLC-305 / Phase 4: ships the documented §13.1 defaults across all
871
+ * resolved OQ surfaces:
872
+ * - OQ-1 confidence-bucketed classifier thresholds
873
+ * - OQ-2 per-axis severity weights
874
+ * - OQ-3 multi-window recurrence
875
+ * - OQ-4 framework-bug suggest-only attribution
876
+ * - OQ-5 upstream reporting (operator-initiated)
877
+ * - OQ-6 coverage-gap response
878
+ * - OQ-7 composite determinism sampling
879
+ * - OQ-9 operator-time-cost instrumentation
880
+ * - OQ-10 vendor-namespace enforcement (strict by default)
881
+ *
882
+ * All values are commented-out so the file is documentation-as-data: the
883
+ * defaults inside `pipeline-cli/src/tui/analytics/quality-monitoring-config.ts`
884
+ * remain the source of truth, but operators get a complete cribsheet of
885
+ * what they can tune by un-commenting and editing.
886
+ */
887
+ export const QUALITY_MONITORING_CONFIG_STUB = `# RFC-0025 Framework Quality Monitoring configuration (§13.1).
888
+ #
889
+ # Per-org overrides for the AI-SDLC framework's failure-mode taxonomy,
890
+ # severity rubric, attribution UX, and self-improvement metrics. Every
891
+ # block below ships with sensible small-to-medium-team defaults
892
+ # (un-commented entries override the defaults).
893
+ #
894
+ # Lifecycle:
895
+ # - Drop this file in \`.ai-sdlc/\` to override defaults org-wide.
896
+ # - Pass \`--severity-weight <axis>=<value>\` on relevant CLIs for a
897
+ # one-shot debugging override (precedence: CLI > YAML > defaults).
898
+ # - The loader rejects un-namespaced custom subclasses by default
899
+ # (OQ-10 strict enforcement); set \`vendor-namespace.enforce: warn\`
900
+ # to downgrade to a soft warning during migration (deprecated).
901
+ #
902
+ # See RFC-0025 §13.1 for the full schema rationale + OQ resolutions.
903
+
904
+ quality:
905
+ # OQ-1 / Phase 2 — Confidence-bucketed classifier (three-tier).
906
+ # classifier:
907
+ # confidenceThresholds:
908
+ # autoClassify: 0.7 # ≥ this → auto-classify into the resolved class
909
+ # ambiguous: 0.3 # ≥ this and < autoClassify → ambiguous;
910
+ # # < this → unclassified, log-only
911
+
912
+ # OQ-2 / Phase 4 — Per-axis severity weights for the §7 composite rubric.
913
+ # Multiplies the qualitative axis (low=0, medium=1, high=2) before the
914
+ # max + frequency bump. A weight of 1.0 is the qualitative-bucket default.
915
+ # severity-weights:
916
+ # operator-time-cost: 1.0
917
+ # framework-recurrence: 1.0
918
+ # blast-radius: 1.0
919
+
920
+ # OQ-3 / Phase 3 — Multi-window recurrence (simultaneously computed).
921
+ # recurrence-windows:
922
+ # - 7d # flap detection
923
+ # - 30d # standard recurrence
924
+ # - 90d # legacy regression
925
+
926
+ # OQ-4 / Phase 4 — Framework-bug attribution UX. Default is suggest-only
927
+ # (small-team-safe per the operator-affirmed OQ-4 resolution). Flip
928
+ # \`autoAttribute: true\` to force-assign the top candidates on creation.
929
+ # framework-bug:
930
+ # autoAttribute: false
931
+ # suggestionCount: 3
932
+ # attributionSources:
933
+ # - codeowners
934
+ # # - git-blame # v2 extension (RFC-0025 §13.1)
935
+ # # - recent-pr # v2 extension
936
+
937
+ # OQ-5 / Phase 6 — Operator-initiated upstream reporting. Set
938
+ # \`repoUrl\` to your framework-repo to enable \`cli-quality report-upstream\`.
939
+ # upstream-reporting:
940
+ # repoUrl: "https://github.com/<org>/<repo>"
941
+ # prefilledIssueTemplate: ".ai-sdlc/templates/framework-bug-report.md"
942
+
943
+ # OQ-6 / Phase 5 — Coverage-gap response. Composes with RFC-0024
944
+ # emergent capture (capture-record with source: framework-coverage-gap).
945
+ # coverage-gap:
946
+ # autoQuarantine: true
947
+ # fileCapture: true
948
+
949
+ # OQ-7 / Phase 5 — Composite determinism-detection sampling. Risk-based
950
+ # concentration via blast-radius matches the framework's deterministic-
951
+ # first preflight ladder (RFC-0035 §5).
952
+ # determinism-detection:
953
+ # defaultSampleRate: 0.02 # 1-in-50 baseline
954
+ # alwaysOnRequiresDeterminism: true
955
+ # alwaysOnTopBlastRadiusDecile: true
956
+
957
+ # OQ-9 / Phase 5 — Operator-time-cost instrumentation. AFK filter zeroes
958
+ # out elapsed-time over inactivity gaps > N minutes (default 30).
959
+ # operator-time-cost:
960
+ # afkInactivityMinutes: 30
961
+
962
+ # OQ-10 / Phase 6 — Vendor-namespace enforcement for custom failure-mode
963
+ # subclasses. Matches Kubernetes CRD / npm scoped / Go module convention.
964
+ # vendor-namespace:
965
+ # enforce: reject # or 'warn' (deprecated) / 'none' (deprecated)
966
+
967
+ # OQ-10 / Phase 6 — Adopter-declared custom failure-mode subclasses.
968
+ # Each entry MUST use a vendor reverse-DNS prefix under the default
969
+ # \`enforce: reject\`. Un-prefixed entries error at resource-load time.
970
+ # customSubclasses:
971
+ # - acme-corp:custom-gate-faulty
972
+ # - acme-corp:billing-timeout
973
+ `;
974
+ /**
975
+ * `.ai-sdlc/templates/framework-bug-report.md` stub — adopter-customisable
976
+ * template for the OQ-5 upstream-reporting CLI (\`cli-quality report-upstream\`).
977
+ *
978
+ * The template uses double-brace placeholders that the
979
+ * \`tui/analytics/upstream-reporter.ts\` module replaces at render time:
980
+ * {{subclass}}, {{severity_composite}}, {{severity_otc}},
981
+ * {{severity_blast}}, {{severity_freq}}, {{ts}}, {{task_id}},
982
+ * {{worker_id}}, {{rationale}}, {{suggested_fix}}, {{related_paths}},
983
+ * {{exit_code}}, {{source}}, {{stderr_tail}}
984
+ *
985
+ * Adopters can re-order sections + add markdown but should keep the
986
+ * placeholder names — the renderer's substitution table is fixed.
987
+ */
988
+ export const FRAMEWORK_BUG_REPORT_TEMPLATE_STUB = `## Framework bug — {{subclass}}
989
+
990
+ **Severity:** {{severity_composite}} (operator-time-cost={{severity_otc}}, blast-radius={{severity_blast}}, frequency={{severity_freq}})
991
+ **Subclass:** \`{{subclass}}\`
992
+ **Reported at (capture timestamp):** {{ts}}
993
+ **Related task:** {{task_id}}
994
+ **Worker:** {{worker_id}}
995
+
996
+ ### What happened
997
+
998
+ The AI-SDLC framework's RFC-0025 quality monitor classified this failure as
999
+ \`framework-misbehaved\` / \`{{subclass}}\`. Per the classifier's rationale:
1000
+
1001
+ > {{rationale}}
1002
+
1003
+ ### Suggested fix (heuristic — please verify)
1004
+
1005
+ {{suggested_fix}}
1006
+
1007
+ ### Related code paths
1008
+
1009
+ {{related_paths}}
1010
+
1011
+ ### Anonymised repro
1012
+
1013
+ The framework anonymised the failure context before this template
1014
+ rendered: absolute home paths were collapsed to \`~/…\`, worktree paths to
1015
+ \`<worktree>\`, and any apparent secret tokens (sk-…, ghp_…, xoxb-…) or
1016
+ email addresses were replaced with \`<REDACTED-…>\`. The operator should
1017
+ still inspect the body before submitting.
1018
+
1019
+ \`\`\`
1020
+ exit code: {{exit_code}}
1021
+ source: {{source}}
1022
+
1023
+ {{stderr_tail}}
1024
+ \`\`\`
1025
+
1026
+ ### Operator checklist (before clicking Submit)
1027
+
1028
+ - [ ] I have reviewed the anonymised repro for any remaining sensitive context.
1029
+ - [ ] The classifier's rationale matches what I observed locally.
1030
+ - [ ] The suggested fix and related paths look correct for this failure.
1031
+ - [ ] I am willing to follow up on the issue if the maintainers ask for more context.
1032
+
1033
+ ---
1034
+
1035
+ _This issue was pre-generated by \`cli-quality report-upstream\` (RFC-0025 §13 OQ-5)._
1036
+ _The operator reviewed and submitted this report. No automatic telemetry was transmitted._
1037
+ `;
1038
+ /**
1039
+ * Quality-monitoring template set scaffolded by the wizard's
1040
+ * \`--with-quality-monitoring\` / \`--add quality-monitoring\` flag
1041
+ * (AISDLC-305). Bundles the OQ-2 + OQ-4 + OQ-5 surfaces:
1042
+ *
1043
+ * 1. \`.ai-sdlc/quality-monitoring.yaml\` — RFC-0025 §13.1 per-org config
1044
+ * with all blocks commented-out (shipping defaults documented inline).
1045
+ * 2. \`.ai-sdlc/templates/framework-bug-report.md\` — adopter-customisable
1046
+ * template for the OQ-5 upstream-reporting CLI.
1047
+ *
1048
+ * Idempotent: files already present at the target paths are skipped by the
1049
+ * dispatcher.
1050
+ */
1051
+ export const QUALITY_MONITORING_TEMPLATES = {
1052
+ files: {
1053
+ '.ai-sdlc/quality-monitoring.yaml': QUALITY_MONITORING_CONFIG_STUB,
1054
+ '.ai-sdlc/templates/framework-bug-report.md': FRAMEWORK_BUG_REPORT_TEMPLATE_STUB,
1055
+ },
1056
+ };
1057
+ /**
1058
+ * `.ai-sdlc/signal-ingestion.yaml` stub — RFC-0030 Signal Ingestion Pipeline.
1059
+ *
1060
+ * AISDLC-348 / Phase 6: ships the full §11 config schema with every block
1061
+ * commented-out under `enabled: false`. The pipeline is OFF until the
1062
+ * operator explicitly flips `enabled: true` AND opts in via the
1063
+ * `AI_SDLC_SIGNAL_INGESTION` flag during the soak window.
1064
+ *
1065
+ * Like `QUALITY_MONITORING_CONFIG_STUB`, this file is documentation-as-data:
1066
+ * the runtime defaults inside `orchestrator/src/signal-ingestion/config.ts`
1067
+ * (DEFAULT_SIGNAL_INGESTION_CONFIG) are the source of truth, but operators
1068
+ * get a complete cribsheet of what they can tune. Tier multipliers, ICP
1069
+ * resonance weights, SA-resonance thresholds, Tier-2 significance gate,
1070
+ * clustering algorithm, D1 composition split, and adapter list are all
1071
+ * documented inline with the shipped defaults.
1072
+ *
1073
+ * Drift policy: when DEFAULT_SIGNAL_INGESTION_CONFIG gains new fields,
1074
+ * mirror them here so freshly-scaffolded configs are immediately complete.
1075
+ * The values in the commented blocks below MUST match the constants in
1076
+ * `config.ts`.
1077
+ *
1078
+ * Configuration changes to this file emit `SignalIngestionConfigChanged`
1079
+ * events to `events.jsonl` (see RFC-0030 §11 closing note + AISDLC-348
1080
+ * governance event logger). Operators should treat tier-multiplier edits,
1081
+ * threshold tweaks, and adapter list changes as governance-relevant: they
1082
+ * change which customer signals the framework treats as load-bearing
1083
+ * demand and therefore affect D1 scoring upstream of the dispatcher.
1084
+ */
1085
+ export const SIGNAL_INGESTION_CONFIG_STUB = `# RFC-0030 Signal Ingestion Pipeline configuration (§11).
1086
+ #
1087
+ # Per-org config for the Demand Sources → D1 pipeline. Pluggable source
1088
+ # adapters fetch raw signals (support tickets, community threads, manual
1089
+ # entries), classify them by tier + ICP + recency, cluster them into
1090
+ # demand themes, filter through SA resonance, and feed D1 cluster-level
1091
+ # demand scores into PPA.
1092
+ #
1093
+ # Ships DISABLED by default. The pipeline is gated by both:
1094
+ # 1. \`spec.enabled: true\` in this file
1095
+ # 2. \`AI_SDLC_SIGNAL_INGESTION\` env flag set to a truthy value during
1096
+ # the soak window (1/true/yes/on). Post-promotion the flag is default-on
1097
+ # and only the YAML toggle matters.
1098
+ #
1099
+ # Configuration changes emit \`SignalIngestionConfigChanged\` governance
1100
+ # events to \`<ARTIFACTS_DIR>/_orchestrator/events-YYYY-MM-DD.jsonl\`. Edits
1101
+ # to tier multipliers, thresholds, or adapter lists are governance-relevant
1102
+ # (RFC-0030 §11 closing note) — log + product-lead review them like any
1103
+ # other DID-adjacent decision.
1104
+ #
1105
+ # Operator runbook: docs/operations/signal-ingestion.md
1106
+ # Promotion runbook: docs/operations/signal-ingestion-promotion.md
1107
+ # Schema: spec/schemas/signal-ingestion-config.v1.schema.json
1108
+ # RFC: spec/rfcs/RFC-0030-signal-ingestion-pipeline.md
1109
+ # Re-walkthrough (2026-05-26): AISDLC-430..434 rolled up OQ-13.1..13.5
1110
+ # refinements onto the shipped Phase 1-6 substrate. All refinements
1111
+ # reflected in this stub and the runbook.
1112
+
1113
+ apiVersion: ai-sdlc.io/v1alpha1
1114
+ kind: SignalIngestionConfig
1115
+ metadata:
1116
+ name: signal-ingestion
1117
+ spec:
1118
+ # Master switch. Flip to \`true\` AFTER:
1119
+ # 1. You have configured at least one working adapter under \`adapters:\`
1120
+ # 2. You have set the \`AI_SDLC_SIGNAL_INGESTION\` env flag (soak window)
1121
+ # 3. You have read docs/operations/signal-ingestion.md for the runbook
1122
+ enabled: false
1123
+
1124
+ # Tier multipliers (RFC-0030 §6.1).
1125
+ # Per-customer-tier weight applied at D1 scoring time. The Churned multiplier
1126
+ # (default 2.0) is intentionally high: churned customers are the strongest
1127
+ # signal of product-market gap. Tune for your deployment heterogeneity —
1128
+ # B2B enterprise platforms typically raise \`enterprise\` (e.g. 5.0) and
1129
+ # flatten \`smb\` / \`free\` (e.g. 0.25). Consumer products typically flatten
1130
+ # all tiers to ~1.0 since tier is less informative.
1131
+ # tierMultipliers:
1132
+ # enterprise: 3.0
1133
+ # mid: 1.5
1134
+ # smb: 1.0
1135
+ # free: 0.5
1136
+ # churned: 2.0
1137
+
1138
+ # ICP resonance weights (RFC-0030 §6.2).
1139
+ # Strong = signal source matches declared ICP segments verbatim.
1140
+ # Partial = adjacent segment (e.g. enterprise but wrong industry vertical).
1141
+ # Weak = peripheral (e.g. student account on a B2B product).
1142
+ # icpResonanceWeights:
1143
+ # strong: 1.5
1144
+ # partial: 1.0
1145
+ # weak: 0.5
1146
+
1147
+ # Recency decay half-life in days (RFC-0030 §6.3).
1148
+ # Exponential decay; signals older than ~6 months contribute < 2% of their
1149
+ # original weight at the default. Shorten (e.g. 14) for rapidly-evolving
1150
+ # products; lengthen (e.g. 60) for products with slow signal cycles.
1151
+ # recencyHalfLifeDays: 30
1152
+
1153
+ # Tier 2 significance threshold (RFC-0030 §8).
1154
+ # Tier 2 signals (community, competitive) only feed D1 once a cluster crosses
1155
+ # ALL of these gates. The \`minTier1SignalCount: 1\` gate is the structural
1156
+ # defense against adversarial flooding (OQ-13.5): community buzz without
1157
+ # any direct customer signal stays in the monitor-only zone.
1158
+ # tier2SignificanceThreshold:
1159
+ # minSignalCount: 5
1160
+ # minUniqueSources: 3
1161
+ # minTier1SignalCount: 1
1162
+ # minClusterAgeDays: 7
1163
+
1164
+ # SA resonance thresholds (RFC-0030 §9).
1165
+ # Per RFC-0029 Principle 4 "The Soul Holds" — high-SA clusters get full
1166
+ # weight, mid-SA discounted, low-SA flagged for review, zero-SA excluded.
1167
+ # When aggregate cluster SA resonance drops below 0.4 sustained for
1168
+ # 3 sprints, the SoulDriftDetected event fires with
1169
+ # \`driftSource: demandMisalignment\`.
1170
+ # saResonanceThresholds:
1171
+ # fullWeight: 0.7
1172
+ # discounted: 0.4
1173
+ # excluded: 0.0
1174
+
1175
+ # Clustering algorithm + similarity threshold (RFC-0030 §7).
1176
+ # \`bm25\` is the deterministic-first default (no external dependencies).
1177
+ # \`embedding\` requires a configured RFC-0019 embedding provider adapter.
1178
+ # Raise \`similarityThreshold\` (closer to 1.0) for stricter clustering;
1179
+ # lower for looser theme aggregation.
1180
+ # clustering:
1181
+ # algorithm: bm25
1182
+ # similarityThreshold: 0.6
1183
+
1184
+ # D1 composition weights (RFC-0030 §10 / AISDLC-347 Phase 5).
1185
+ # Non-replacement: signal-pipeline-derived demand and human-authored
1186
+ # backlog-item demand both feed D1. The composer normalises the pair to
1187
+ # sum to 1; default 50/50 keeps neither stream dominant out of the box.
1188
+ # Raise \`signalPipelineWeight\` after the pipeline has soaked and you
1189
+ # trust its output more than manual translation.
1190
+ # d1Composition:
1191
+ # signalPipelineWeight: 0.5
1192
+ # backlogItemWeight: 0.5
1193
+
1194
+ # Adapter list (RFC-0030 §5 / OQ-13.1 v0.3 re-walkthrough — AISDLC-430).
1195
+ # v1 ships env-var-based adapters ONLY. OAuth-required adapters (full
1196
+ # Salesforce / HubSpot, Zendesk-with-OAuth) wait for the credential-mgmt
1197
+ # RFC. Adapters declaring \`requiresOAuth: true\` are refused at
1198
+ # registration with Decision: adapter-requires-credential-mgmt-rfc.
1199
+ #
1200
+ # Shipped adapters and their credential env vars:
1201
+ # - signal-source-support-ticket → SIGNAL_ZENDESK_PAT
1202
+ # - signal-source-community-thread → SIGNAL_COMMUNITY_BOT_TOKEN
1203
+ # - signal-source-in-app-feedback → SIGNAL_IN_APP_FEEDBACK_API_KEY
1204
+ # - signal-source-manual → no credential (see manualEntry block)
1205
+ #
1206
+ # Credential failure Decisions:
1207
+ # - adapter-credential-not-configured: env var missing → SET the var
1208
+ # - adapter-credential-rejected: env var present but auth failed → ROTATE
1209
+ # Pipeline continues with remaining valid adapters in both cases (G0).
1210
+ # adapters:
1211
+ # - signal-source-support-ticket
1212
+ # - signal-source-community-thread
1213
+ # - signal-source-in-app-feedback
1214
+
1215
+ # Language acceptance (RFC-0030 OQ-13.2 v0.3 re-walkthrough — AISDLC-431).
1216
+ # Detection: \`franc\` library (deterministic; <10ms per signal; JS-native;
1217
+ # MIT-licensed; 95%+ accuracy on text >50 chars). Language detection runs
1218
+ # at the classifier before any clustering step.
1219
+ # Default [en] — English-only. Orgs with non-English customer bases can
1220
+ # add languages: [en, fr, es, de, ja, ...]. Note the documented trade-off:
1221
+ # BM25 clustering degrades ~15-30% precision without per-language
1222
+ # stopwords/stemming (Robertson & Zaragoza §3.5). LLM ICP-resonance and
1223
+ # embedding clustering are native multi-language (no degradation there).
1224
+ # Non-accepted signals: Decision: signal-language-unsupported — dropped and
1225
+ # logged to catalog for visible-gap metric; pipeline continues (G0).
1226
+ # Opt in knowingly — see docs/operations/signal-ingestion.md §2.5.
1227
+ # acceptedLanguages:
1228
+ # - en
1229
+
1230
+ # Per-stage data residency enforcement (RFC-0030 OQ-13.3 v0.3 — AISDLC-432).
1231
+ # RFC-0022 owns regime DECLARATION (compliance.yaml). This block gates
1232
+ # ENFORCEMENT at each signal-pipeline stage. All points default ON when
1233
+ # any regime is declared; disable selectively only when your regime allows it
1234
+ # (rare — every override emits SignalIngestionConfigChanged).
1235
+ # residencyEnforcement:
1236
+ # sourceFromCompliancePosture: true # derive allowedRegions from RFC-0022
1237
+ # enforcementPoints:
1238
+ # fetchSignals: true # refuse out-of-region signals at adapter
1239
+ # clustering: true # prevent cross-region cluster merging
1240
+ # storage: true # persist residencyRegion field; elevate cross-region read audit
1241
+ # unifiedCostReport: true # break out per-region cost attribution
1242
+ # multiPostureBehavior: union # GDPR+HIPAA: strictest of both applies
1243
+
1244
+ # Manual-entry anti-gaming (RFC-0030 OQ-13.4 v0.3 re-walkthrough — AISDLC-430).
1245
+ # RFC-0022 OQ-2 audit trail pattern preserved (forced attestedBy +
1246
+ # auto-filled attestedAt). Three additional anti-gaming hooks:
1247
+ # 1. Per-operator daily rate limit (default 10/day). Above cap:
1248
+ # Decision: manual-signal-rate-limit-exceeded.
1249
+ # 2. Optional evidenceUrl (call recording, ticket URL, transcript link).
1250
+ # When present, audit trail is materially stronger.
1251
+ # 3. Rolling 7d manual-share quality metric. Above 30% sustained:
1252
+ # Decision: manual-signal-share-elevated (warning, not block).
1253
+ # manualEntry:
1254
+ # dailyCapPerOperator: 10 # per-operator per-UTC-day; 0 = disabled
1255
+ # evidenceUrlOptional: true # framework treats evidenceUrl as optional
1256
+ # qualityMetric:
1257
+ # enabled: true
1258
+ # windowDays: 7
1259
+ # shareWarningThreshold: 0.30 # >30% rolling 7d triggers Decision
1260
+
1261
+ # Adversarial-injection defense (RFC-0030 OQ-13.5 v0.3 — AISDLC-433).
1262
+ # Two layers:
1263
+ # 1. Tier 2 significance threshold (§8) — structural floor requiring ≥1
1264
+ # Tier 1 signal per cluster.
1265
+ # 2. Z-score detector — runtime anomaly layer on rolling 7d baseline.
1266
+ # Trigger: volume > 3σ above baseline AND unique sources in window < 3.
1267
+ # Quarantine: flagged signals recorded but NOT fed to D1; auto-expires 24h.
1268
+ # One-click unquarantine logs Decision: signal-flooding-false-positive for
1269
+ # v2 reputation-weighting calibration. Reputation-weighting deferred to v2
1270
+ # (cold-start unsafe — requires 7+ corpus windows of baseline data).
1271
+ # flooding:
1272
+ # detection:
1273
+ # algorithm: z-score # only z-score supported (AISDLC-433)
1274
+ # zScoreThreshold: 3.0
1275
+ # windowMinutes: 60
1276
+ # minUniqueSourcesForSuspicion: 3
1277
+ # baselineDays: 7
1278
+ # quarantine:
1279
+ # enabled: true
1280
+ # durationHours: 24
1281
+ `;
1282
+ /**
1283
+ * Signal-ingestion template set scaffolded by the wizard's
1284
+ * \`--with-signal-ingestion\` / \`--add signal-ingestion\` flag (AISDLC-348).
1285
+ *
1286
+ * Ships the per-org config stub disabled-by-default. The pipeline runtime
1287
+ * lives in \`orchestrator/src/signal-ingestion/\`; this template just gives
1288
+ * adopters the documented config surface to start from.
1289
+ *
1290
+ * Idempotent: existing files at the target paths are skipped by the
1291
+ * dispatcher.
1292
+ */
1293
+ export const SIGNAL_INGESTION_TEMPLATES = {
1294
+ files: {
1295
+ '.ai-sdlc/signal-ingestion.yaml': SIGNAL_INGESTION_CONFIG_STUB,
1296
+ },
1297
+ };
1298
+ /**
1299
+ * Workflow template set scaffolded by `--with-workflows` / `--add workflows`
1300
+ * (AISDLC-261). Bundles all four canonical GitHub Actions workflow files that
1301
+ * an adopter needs for the AI-SDLC framework to function end-to-end:
1302
+ *
1303
+ * 1. `ai-sdlc-gate.yml` — single rollup `ai-sdlc/pr-ready` check (always-on baseline).
1304
+ * 2. `verify-attestation.yml` — DSSE envelope verifier (audit-only).
1305
+ * 3. `ai-sdlc-review.yml` — CI-side reviewer fan-out + `Post Review Results` status.
1306
+ * 4. `auto-enable-auto-merge.yml` — arms auto-merge on every same-repo PR.
1307
+ *
1308
+ * Idempotent: files already present are skipped by default; `--force` overwrites.
1309
+ *
1310
+ * Source of truth: `.github/workflows/` in the ai-sdlc framework repo.
1311
+ * Mirror changes here when the adopter-facing API evolves.
1312
+ */
1313
+ export const WORKFLOWS_TEMPLATES = {
1314
+ files: {
1315
+ '.github/workflows/ai-sdlc-gate.yml': AI_SDLC_GATE_WORKFLOW,
1316
+ '.github/workflows/verify-attestation.yml': VERIFY_ATTESTATION_WORKFLOW,
1317
+ '.github/workflows/ai-sdlc-review.yml': AI_SDLC_REVIEW_WORKFLOW,
1318
+ '.github/workflows/auto-enable-auto-merge.yml': AUTO_ENABLE_AUTO_MERGE_WORKFLOW,
1319
+ },
1320
+ };
1321
+ /**
1322
+ * Always-on baseline workflow templates (regardless of wizard answers).
1323
+ * Matches AC #4 in AISDLC-143: pipeline.yaml + agent-role.yaml +
1324
+ * quality-gate.yaml + autonomy-policy.yaml are scaffolded by `initProject`
1325
+ * (existing logic) and the gate workflow is scaffolded by this map.
1326
+ *
1327
+ * AISDLC-305 / Phase 4 (RFC-0025): the quality-monitoring config + the
1328
+ * upstream-report template are part of the BASELINE because they are pure
1329
+ * documentation-as-data (every block commented-out, shipping defaults
1330
+ * documented inline). Adopters get the §13.1 cribsheet by default; the
1331
+ * `.gitignore`-friendly behavior is to commit it as-is and uncomment
1332
+ * blocks per-org as needed.
1333
+ */
1334
+ export const BASELINE_WORKFLOW_TEMPLATES = {
1335
+ files: {
1336
+ '.github/workflows/ai-sdlc-gate.yml': AI_SDLC_GATE_WORKFLOW,
1337
+ '.ai-sdlc/quality-monitoring.yaml': QUALITY_MONITORING_CONFIG_STUB,
1338
+ '.ai-sdlc/templates/framework-bug-report.md': FRAMEWORK_BUG_REPORT_TEMPLATE_STUB,
1339
+ },
1340
+ };
1341
+ //# sourceMappingURL=init-templates.js.map