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.
- package/doctor/profile.json +112 -0
- package/driver/release-lines.js +13 -3
- package/driver/run.js +12 -1
- package/generator/analyst-values.sh +1 -1
- package/package.json +2 -1
|
@@ -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
|
+
}
|
package/driver/release-lines.js
CHANGED
|
@@ -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,
|
|
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 =
|
|
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.
|
|
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",
|