contract-driven-delivery 1.8.1 → 1.10.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.
@@ -1,23 +1,26 @@
1
- # Technical Design
1
+ ---
2
+ change-id: <id>
3
+ schema-version: 0.1.0
4
+ last-changed: <date>
5
+ ---
2
6
 
3
- ## Architecture Summary
7
+ # Design: <change-id>
4
8
 
5
- ## Affected Components
6
-
7
- ## API Design
9
+ ## Summary
8
10
 
9
- ## Data / Schema Design
11
+ (1 paragraph: what changes architecturally and why)
10
12
 
11
- ## UI / UX Design
13
+ ## Affected Components
12
14
 
13
- ## Env / Config Design
15
+ | component | file path(s) | nature of change |
16
+ |---|---|---|
14
17
 
15
- ## Error Handling
18
+ ## Key Decisions
16
19
 
17
- ## Performance Considerations
20
+ - **Decision**: rationale — rejected alternative: reason rejected
18
21
 
19
- ## Security Considerations
22
+ ## Migration / Rollback
20
23
 
21
- ## Deployment / Rollback
24
+ (Prose description. SQL and code go in migration files, not here.)
22
25
 
23
- ## Architecture Decision Notes
26
+ ## Open Risks
@@ -1,31 +1,25 @@
1
- # Test Plan
1
+ ---
2
+ change-id: <id>
3
+ schema-version: 0.1.0
4
+ last-changed: <date>
5
+ risk: low | medium | high
6
+ tier: 0 | 1 | 2 | 3 | 4 | 5
7
+ ---
2
8
 
3
- ## Acceptance Criteria Mapping
4
- | requirement | test family | planned file/spec | expected evidence |
5
- |---|---|---|---|
6
-
7
- ## Unit Tests
8
-
9
- ## Contract Tests
10
-
11
- ## Integration Tests
9
+ # Test Plan: <change-id>
12
10
 
13
- ## E2E Tests
11
+ ## Acceptance Criteria → Test Mapping
14
12
 
15
- ## Visual Tests / Review
16
-
17
- ## Data Boundary Tests
18
-
19
- ## Resilience Tests
20
-
21
- ## Fuzz / Monkey Operation Tests
13
+ | criterion id | test family | test file path | tier |
14
+ |---|---|---|---|
15
+ | AC-1 | unit | tests/unit/test_xxx.py | 0 |
22
16
 
23
- ## Stress Tests
17
+ ## Test Families Required
24
18
 
25
- ## Soak Tests
19
+ Mark all that apply: unit / contract / integration / e2e / data-boundary / resilience / monkey / stress / soak
26
20
 
27
- ## Mutation Checks
21
+ ## Out of Scope
28
22
 
29
- ## Commands
23
+ ## Notes
30
24
 
31
- ## CI/CD Gate Mapping
25
+ (Keep this section under 10 lines. Implementation detail belongs in the test files themselves.)
package/dist/cli/index.js CHANGED
@@ -26,6 +26,7 @@ var ASSET = {
26
26
  specsTemplates: join(ASSETS_DIR, "specs-templates"),
27
27
  testsTemplates: join(ASSETS_DIR, "tests-templates"),
28
28
  ci: join(ASSETS_DIR, "ci"),
29
+ githubWorkflows: join(ASSETS_DIR, "github-workflows"),
29
30
  hooks: join(ASSETS_DIR, "hooks"),
30
31
  claudeTemplate: join(ASSETS_DIR, "CLAUDE.template.md"),
31
32
  agentsTemplate: join(ASSETS_DIR, "AGENTS.template.md")
@@ -224,6 +225,18 @@ function detectStack(repoRoot) {
224
225
  }
225
226
 
226
227
  // src/commands/init.ts
228
+ function readCondaEnvName(cwd) {
229
+ const envYml = join4(cwd, "environment.yml");
230
+ if (!existsSync3(envYml))
231
+ return "base";
232
+ try {
233
+ const content = readFileSync2(envYml, "utf8");
234
+ const match = content.match(/^name:\s*(.+)$/m);
235
+ return match ? match[1].trim() : "base";
236
+ } catch {
237
+ return "base";
238
+ }
239
+ }
227
240
  function loadCiTemplate(stack) {
228
241
  const templatePath = join4(ASSETS_DIR, "ci-templates", `${stack}.yml`);
229
242
  if (!existsSync3(templatePath))
@@ -326,6 +339,13 @@ async function init(opts) {
326
339
  );
327
340
  track(ciCreated);
328
341
  log.ok(`ci/ \u2014 ${ciCount} file(s) written.`);
342
+ const { count: wfCount, created: wfCreated } = copyDirTracked(
343
+ ASSET.githubWorkflows,
344
+ join4(cwd, ".github", "workflows"),
345
+ { overwrite: opts.force, label: ".github/workflows" }
346
+ );
347
+ track(wfCreated);
348
+ log.ok(`.github/workflows/ \u2014 ${wfCount} file(s) written.`);
329
349
  const detection = detectStack(cwd);
330
350
  if (detection.polyglot) {
331
351
  const PYTHON_STACKS = ["conda", "poetry", "uv", "pip"];
@@ -345,12 +365,17 @@ async function init(opts) {
345
365
  } else {
346
366
  log.warn("Could not detect stack \u2014 CI placeholder left in place.");
347
367
  }
348
- const ciYmlDest = join4(cwd, "ci", "github-actions", "contract-driven-gates.yml");
368
+ const ciYmlDest = join4(cwd, ".github", "workflows", "contract-driven-gates.yml");
349
369
  if (existsSync3(ciYmlDest)) {
350
370
  const template = loadCiTemplate(detection.primary);
351
371
  if (template) {
352
372
  const original = readFileSync2(ciYmlDest, "utf8");
353
- const patched = patchFastGateYml(original, template, detection.primary);
373
+ let patched = patchFastGateYml(original, template, detection.primary);
374
+ if (detection.primary === "conda" && patched.includes("{{conda-env-name}}")) {
375
+ const envName = readCondaEnvName(cwd);
376
+ patched = patched.replace(/\{\{conda-env-name\}\}/g, envName);
377
+ log.ok(`Conda environment name set to: ${envName}`);
378
+ }
354
379
  if (patched !== original) {
355
380
  writeFileSync(ciYmlDest, patched, "utf8");
356
381
  log.ok(`CI fast-gate patched for stack: ${detection.primary}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contract-driven-delivery",
3
- "version": "1.8.1",
3
+ "version": "1.10.0",
4
4
  "description": "Contract-driven delivery kit CLI — spec-first, test-first AI-assisted delivery for brownfield systems",
5
5
  "keywords": [
6
6
  "contract-driven",