amsd-pipeline-workflow 0.1.15 → 0.1.17

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.
@@ -0,0 +1,112 @@
1
+ {
2
+ "component": {
3
+ "name": "amsd-pipeline-workflow",
4
+ "package": "amsd-pipeline-workflow",
5
+ "description": "the AMSD pipeline as Claude workflows: the driver, the workflow generators, the hooks and the launch tools"
6
+ },
7
+ "scope": {
8
+ "repairDirs": [
9
+ "driver",
10
+ "generator",
11
+ "hooks",
12
+ "mcp"
13
+ ],
14
+ "testDirs": [
15
+ "test"
16
+ ],
17
+ "testFile": "^test/.*\\.test\\.js$",
18
+ "forbiddenTests": [
19
+ "(^|/)driver-[^/]*\\.test\\.js$"
20
+ ]
21
+ },
22
+ "test": {
23
+ "command": [
24
+ "{node}",
25
+ "--test",
26
+ "{files}"
27
+ ],
28
+ "envUnset": [
29
+ "NODE_TEST_CONTEXT"
30
+ ],
31
+ "greenPatterns": [
32
+ "ℹ pass [1-9]",
33
+ "ℹ fail 0",
34
+ "✔ (?!\\S+\\.js \\()"
35
+ ],
36
+ "failedPattern": "ℹ fail [1-9]"
37
+ },
38
+ "install": {
39
+ "dest": "claude-workflows",
40
+ "requires": [
41
+ "orchestrations/scripts",
42
+ "orchestrations/projects"
43
+ ],
44
+ "command": [
45
+ "{node}",
46
+ "{worktree}/bin/amsd-pipeline-workflow.js",
47
+ "install",
48
+ "--into",
49
+ "{install}"
50
+ ],
51
+ "manifest": "package.json#files",
52
+ "patchRecord": "doctor-patches.json"
53
+ },
54
+ "crash": {
55
+ "file": "crash.json"
56
+ },
57
+ "classify": {
58
+ "runtime": "node",
59
+ "refusals": [
60
+ "never works a real codeline",
61
+ "cannot resume run",
62
+ "operator's yes",
63
+ "needs the operator"
64
+ ]
65
+ },
66
+ "settings": {
67
+ "on": "EPAM_PIPELINE_DOCTOR",
68
+ "restarts": "EPAM_PIPELINE_DOCTOR_RESTARTS",
69
+ "repo": "EPAM_PIPELINE_DOCTOR_REPO",
70
+ "budget": "EPAM_PIPELINE_DOCTOR_BUDGET_USD"
71
+ },
72
+ "restart": {
73
+ "args": [
74
+ "--resume"
75
+ ]
76
+ },
77
+ "model": {
78
+ "family": "sonnet",
79
+ "config": "{install}/orchestrations/config/llm-defaults.claude.json"
80
+ },
81
+ "logs": {
82
+ "dir": "doctor",
83
+ "alerts": "abort-alerts.log",
84
+ "evidence": [
85
+ "driver.log"
86
+ ],
87
+ "evidenceTailLines": 200
88
+ },
89
+ "branch": {
90
+ "prefix": "doctor/"
91
+ },
92
+ "boundaries": [
93
+ "the ticket (any AMSD-… story) and its Jira content",
94
+ "every client repository and every codeline copy the run works in (cx-shared, gotransit, metrolinx, upexpress and any other)",
95
+ "the bash pipeline (the install's orchestrations/ folder) — a defect there is reported, never repaired",
96
+ "package.json, bin/, docs/ and everything outside the repairable directories",
97
+ "the pipeline's own prompt templates, agent roster, seams, ladders and system instructions in the install's orchestrations/ folder (the generators' prompts in generator/ are the agentic layer the doctor may repair)"
98
+ ],
99
+ "agentic": {
100
+ "dirs": [
101
+ "generator",
102
+ "hooks"
103
+ ],
104
+ "abortSignatures": [
105
+ "session's answer is not JSON",
106
+ "the detective gave none",
107
+ "the step runner gave no result"
108
+ ],
109
+ "autoApply": true,
110
+ "description": "the workflow generators' prompts, system instructions and answer schemas (generator/), and the hooks that hand one agent's result to the next (hooks/)"
111
+ }
112
+ }
@@ -46,13 +46,13 @@ async function runReleaseLines(ctx, lane, clPrd, laneLog, laneEnv, canonical, ph
46
46
  // A RESUMED LINE'S COMMITTED WORK IS NOT REWRITTEN (operator, 2026-10-20): its story completed by its commit, as a lane's is
47
47
  if (env.EPAM_RESUME_RUN && fs.existsSync(linePrd)) {
48
48
  const id = (JSON.parse(fs.readFileSync(linePrd, 'utf8')).stories[0] || {}).id;
49
- if (id) completeLineByCommit(env, wt, lineLog, linePrd, `${env.EPAM_BRANCH_PREFIX || ''}AI-${id}-${slug}`, log);
49
+ if (id) completeLineByCommit(env, wt, lineLog, linePrd, lineBranch(env, id, slug), log);
50
50
  }
51
51
  const done = lineIsDone(linePrd);
52
52
  if (bash(env, 'resume_preserves', ['completed-stories']).status === 0 && done
53
53
  && !handler(env, 'spec-predates-plan', [linePrd, canonical || clPrd]).stdout.trim()) { // :96–106
54
54
  rerun = [];
55
- const lb = `${env.EPAM_BRANCH_PREFIX || ''}AI-${JSON.parse(fs.readFileSync(linePrd, 'utf8')).stories[0].id}-${slug}`;
55
+ const lb = lineBranch(env, JSON.parse(fs.readFileSync(linePrd, 'utf8')).stories[0].id, slug);
56
56
  if (git(wt, 'checkout', '-q', lb).status !== 0) log(`[orch] Codeline '${cl}': could not check out ${lb} for its review`);
57
57
  handler(env, 'carry-plan', [linePrd, canonical || clPrd], { log });
58
58
  log(`[orch] Codeline '${cl}' — release line ${line} completed in this run — its reviewer judges it again against the story's plan`);
@@ -94,6 +94,16 @@ async function runReleaseLines(ctx, lane, clPrd, laneLog, laneEnv, canonical, ph
94
94
  }
95
95
  }
96
96
 
97
+ /**
98
+ * A RELEASE LINE'S BRANCH NAME — the shared run-state core's ONE rule (story_branch_name, lib/git-ops.sh; backlog B75, finding RS-10), asked of the install's own
99
+ * function: the driver keeps no second copy of the rule. An install that predates it is said, loudly.
100
+ */
101
+ function lineBranch(env, id, slug) {
102
+ const r = bash(env, 'story_branch_name', [id, `-${slug}`]);
103
+ if (r.status !== 0 || !r.stdout.trim()) throw new Error(`the install's lib/git-ops.sh has no story_branch_name (exit ${r.status}) — it needs amsd-pipeline-shared >= 0.5.2 (amsd-pipeline-shared install --into <install>)`);
104
+ return r.stdout.trim();
105
+ }
106
+
97
107
  /**
98
108
  * A RESUMED RELEASE LINE (LIVE-AMSD-2974-11): the line's branch checked out and the pipeline's own
99
109
  * story_resume_completed_by_commit run on the line's log and PRD. The pipeline applies it to lanes only, so a line whose
@@ -120,4 +130,4 @@ function lineIsDone(linePrd) {
120
130
  return (p.stories || []).length > 0 && p.stories.every((s) => s.status === 'completed');
121
131
  }
122
132
 
123
- module.exports = { runReleaseLines, completeLineByCommit, lineIsDone };
133
+ module.exports = { runReleaseLines, completeLineByCommit, lineIsDone, lineBranch };
package/driver/run.js CHANGED
@@ -578,6 +578,17 @@ if (require.main === module) {
578
578
  if (r.error) { process.stderr.write(`the stand-in runtime could not drop the network (unshare -rn): ${r.error.message}\n`); process.exit(1); }
579
579
  process.exit(r.status === null ? 1 : r.status);
580
580
  }
581
+ // THE CRASH LISTENER is the shared component's (lib/doctor/crash-record.js), loaded from the install this driver runs against, writing the file this port's
582
+ // profile names: a throw nothing caught leaves that record and a `crashed` answer, and the launcher decides from it whether the failure is a defect in this
583
+ // code (the shared doctor's classifier). An install that predates the shared doctor is SAID, loudly — never silently unlistened.
584
+ const crash = (() => {
585
+ const f = path.join(path.resolve(a0.install || '.'), 'orchestrations', 'scripts', 'lib', 'doctor', 'crash-record.js');
586
+ try {
587
+ const lib = require(f); // eslint-disable-line global-require, import/no-dynamic-require
588
+ if (a0.out) lib.install({ runDir: path.resolve(a0.out), file: JSON.parse(fs.readFileSync(process.env.AMSD_DOCTOR_PROFILE || path.join(__dirname, '..', 'doctor', 'profile.json'), 'utf8')).crash.file });
589
+ return lib;
590
+ } catch (e) { process.stderr.write(`[driver] crash listener unavailable: ${e.code === 'MODULE_NOT_FOUND' ? `the install has no ${f} — it needs amsd-pipeline-shared >= 0.5.0 (amsd-pipeline-shared install --into <install>)` : e.message}\n`); return null; }
591
+ })();
581
592
  main(a0).then((o) => { process.stdout.write(`${JSON.stringify(o)}\n`); process.exit(o.exit || 0); })
582
- .catch((e) => { process.stderr.write(`${e.stack || e.message}\n`); process.exit(1); });
593
+ .catch((e) => { process.stderr.write(`${e.stack || e.message}\n`); if (crash) crash.die(e); else process.exit(1); });
583
594
  }
@@ -39,7 +39,7 @@ while IFS= read -r _f; do
39
39
  while IFS= read -r _pkg; do
40
40
  [ -z "$_pkg" ] && continue
41
41
  _vc="$PROJECT_ROOT/.contracts/vendor-${_pkg}.md"
42
- [ -f "$_vc" ] || _generate_vendor_contract "$PROJECT_ROOT" "$_pkg" 2>/dev/null
42
+ [ -f "$_vc" ] || _generate_vendor_contract "$PROJECT_ROOT" "$_pkg" >/dev/null 2>/dev/null
43
43
  [ -f "$_vc" ] && dependency_contracts="${dependency_contracts}
44
44
  ### Vendor package: ${_pkg}
45
45
  $(cat "$_vc")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amsd-pipeline-workflow",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "The AMSD pipeline as Claude workflows. Installed by the amsd-pipeline installer: install.sh --workflows",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "driver/",
12
12
  "generator/",
13
13
  "hooks/",
14
+ "doctor/",
14
15
  "mcp/",
15
16
  "test/layer1/harness.js",
16
17
  "test/layer1/hook-harness.js",