amsd-pipeline-workflow 0.1.29 → 0.1.31
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/driver/run.js +11 -2
- package/generator/generate.js +11 -0
- package/generator/writer-workflow.js +2 -2
- package/package.json +1 -1
package/driver/run.js
CHANGED
|
@@ -469,8 +469,17 @@ async function phaseRunner(ctx, lane, laneEnv, { prd, phase, args, tag, lineSlug
|
|
|
469
469
|
// reviewed, locked (operator, 2026-10-20); an approved one is locked and not touched
|
|
470
470
|
const toReview = env.EPAM_RESUME_RUN ? ((p.implementationOrder || {})[phase] || []).map((id) => p.stories.find((s) => s.id === id))
|
|
471
471
|
.filter((s) => s && s.completed === true && s.status !== 'deprecated' && s.agentRole !== 'review-agent')
|
|
472
|
-
.filter((s) => {
|
|
473
|
-
|
|
472
|
+
.filter((s) => {
|
|
473
|
+
const rec = reviewRecord(ctx, lane, env, s.id, lineSlug); if (!(rec && rec.verdict === 'approved')) return true;
|
|
474
|
+
// THE OPERATOR LIFTS THE LOCK (2026-10-21: "yes rewrite it is not good code"): approved work is judged again by the current
|
|
475
|
+
// reviewer; a rejection sends it back to the writer with the findings, as any rejection does
|
|
476
|
+
if (env.EPAM_REREVIEW_APPROVED === '1') { s.rereview = rec.from; return true; }
|
|
477
|
+
return false;
|
|
478
|
+
}) : [];
|
|
479
|
+
for (const s of toReview) {
|
|
480
|
+
log(s.rereview ? `[driver] ${s.id}: approved earlier — judged again by the current reviewer (EPAM_REREVIEW_APPROVED=1, ${s.rereview}); a rejection goes back to the writer`
|
|
481
|
+
: `[driver] ${s.id}: committed but never reviewed — its review judges the committed change; nothing is rewritten`);
|
|
482
|
+
}
|
|
474
483
|
if (order.length && env.EPAM_BROWNFIELD === '1') bash(env, 'ensure_story_branch', [lane.wt, order[0].id, env.JIRA_BASELINE_BRANCH || ''], { log });
|
|
475
484
|
// RAO:2653–2654 — THE LANE'S PHASE BASELINE (lib/qa-gate-evidence.sh qa_record_phase_baseline: the fork point from the
|
|
476
485
|
// base branch) in the lane's log, where the release lines read the main line's change from (lib/release-lines.sh:69–74)
|
package/generator/generate.js
CHANGED
|
@@ -313,6 +313,16 @@ function main(a) {
|
|
|
313
313
|
// retry budget plus one more per review cycle (lib/review-cycle.sh), each on every model the ladder can reach — has its
|
|
314
314
|
// own copy of the writer, the failure analyst and the rung-entry step runner, identical but for the values their hooks
|
|
315
315
|
// are given (the copy's retry; the writer's model; the model the previous attempt ran on).
|
|
316
|
+
// THE MODEL THE REVIEW RUNS ON: the shared policy (config/reviewer-policy.json), read by the SAME reader the bash reviewer calls (lib/reviewer-model.js in the install —
|
|
317
|
+
// team-lead-review.sh reviewer_model_for), so the two pipelines cannot differ. null = the writer's rung model (policy 'writer-rung', or an install without the policy).
|
|
318
|
+
// Run 11 (2026-10-21): on the writer's Sonnet rung the reviewer rated a thin and a rich delivery alike (9, 9); on Opus it separated them (6, 7.5).
|
|
319
|
+
const reviewerModel = (() => {
|
|
320
|
+
const lib = path.join(a.install, 'orchestrations', 'scripts', 'lib', 'reviewer-model.js');
|
|
321
|
+
if (!fs.existsSync(lib)) return null;
|
|
322
|
+
const r = spawnSync(process.execPath, [lib, ''], { encoding: 'utf8', env: { ...process.env, ...launchValues(a.launchEnv || {}), EPAM_PROVIDER_SET: a.set || 'claude' } });
|
|
323
|
+
if (r.status !== 0) { process.stderr.write(`[generate] the reviewer's model policy could not be read — reviewing on the writer's model: ${(r.stderr || '').trim()}\n`); return null; }
|
|
324
|
+
return r.stdout.trim() || null;
|
|
325
|
+
})();
|
|
316
326
|
const reviewMaxCycles = maxRetries + 3;
|
|
317
327
|
const lastAttempt = maxRetries + reviewMaxCycles;
|
|
318
328
|
const models = [...new Set([lad.start.model, ...Object.values(lad.steps).map((v) => v.model)])];
|
|
@@ -562,6 +572,7 @@ function main(a) {
|
|
|
562
572
|
where: "this workflow run's journal (it records the full prompt of every attempt)" },
|
|
563
573
|
// lib/review-cycle.sh: REVIEW_MAX_CYCLES defaults to EPAM_MAX_RETRIES + 3.
|
|
564
574
|
reviewMaxCycles,
|
|
575
|
+
reviewerModel,
|
|
565
576
|
prompts: {
|
|
566
577
|
'writer.first': fs.readFileSync(path.join(a.out, 'prompts', 'writer.first.md'), 'utf8'),
|
|
567
578
|
'writer.retry': fs.readFileSync(path.join(a.out, 'prompts', 'writer.retry.md'), 'utf8'),
|
|
@@ -972,8 +972,8 @@ for (; attempt <= budget; attempt++) {
|
|
|
972
972
|
for (;;) {
|
|
973
973
|
r = await agentCall(fill(PLAN.prompts.reviewer, { ...base, story_acs: noTrail(criteriaBlock(state.acs, 'ACCEPTANCE CRITERIA:')),
|
|
974
974
|
prior_review: priorReviews(), story_diff: checks.storyDiff, test_files: checks.testFiles, uncovered_vc_block: uncoveredVc !== null ? uncoveredVc : checks.uncoveredVc }),
|
|
975
|
-
// team-lead-review.sh:
|
|
976
|
-
{ agentType: PLAN.agents.reviewer, model: rung.model, schema: SCHEMAS.review, label: \`review #\${reviews.length + 1}\`, phase: 'Review' })
|
|
975
|
+
// team-lead-review.sh reviewer_model_for: the shared policy's model (PLAN.reviewerModel — the reader the bash reviewer calls), else the writer's model (the rung that produced this work); effort stays the reviewer's own.
|
|
976
|
+
{ agentType: PLAN.agents.reviewer, model: PLAN.reviewerModel || rung.model, schema: SCHEMAS.review, label: \`review #\${reviews.length + 1}\`, phase: 'Review' })
|
|
977
977
|
if (r !== null) { noVerdict = 0; reviews.push({ verdict: r.verdict, issues: r.issues || [] }); break }
|
|
978
978
|
reviews.push({ reviewIncomplete: true })
|
|
979
979
|
noVerdict++
|
package/package.json
CHANGED