amsd-pipeline-workflow 0.1.9 → 0.1.11

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.
@@ -17,6 +17,9 @@ function applyGateStamps(story, res) {
17
17
  else if (uit && uit.passed === true) { del('suiteState'); del('suiteStateStep'); }
18
18
  const gate = res && res.gate;
19
19
  if (gate && gate.ran !== false && gate.passed === false) { set('reviewStatus', 'escalated'); set('reproGate', 'failed'); }
20
+ // A REAL APPROVAL CLEARS AN EARLIER ATTEMPT'S ESCALATION (lib/review-cycle.sh ~:180–195, the pipeline's own: reviewStatus
21
+ // "escalated" → null). A Writer result of 'done' comes only after the review approved. B65: the stale stamp blocked the gate.
22
+ else if (res && res.status === 'done' && story.reviewStatus === 'escalated') set('reviewStatus', null);
20
23
  return changed;
21
24
  }
22
25
 
@@ -384,10 +384,14 @@ async function reproStep(prep) {
384
384
  if (!source) return { committed: false, reason: 'no testable source file in the change' }
385
385
  const cand = prep.candidates[source]
386
386
  const fb = { typecheck: '', assertions: '', commit_rejected: '' }
387
+ // the answer names the source the workflow chose, and only that (B61: unexplained, the model named the codeline, then the test)
388
+ const schema = { ...SCHEMAS.repro, properties: { ...SCHEMAS.repro.properties,
389
+ source: { type: 'string', enum: [source], description: 'the source file your test covers: exactly this path' },
390
+ test: { type: 'string', description: \`the path of the test file you wrote, relative to the codeline root (planned: \${cand.target})\` } } }
387
391
  for (let i = 0; i < PLAN.repro.maxAttempts; i++) {
388
392
  const model = PLAN.repro.ladder[Math.min(i, PLAN.repro.ladder.length - 1)]
389
393
  const a = await agentCall(relativize(cand.prompt) + fb.typecheck + fb.assertions + fb.commit_rejected,
390
- { agentType: PLAN.agents.reproWriter, model, schema: SCHEMAS.repro, label: \`repro test #\${i + 1}\`, phase: 'Writer' })
394
+ { agentType: PLAN.agents.reproWriter, model, schema, label: \`repro test #\${i + 1}\`, phase: 'Writer' })
391
395
  const v = (a && a.validation) || { valid: false, committed: false, class: 'no_file', feedback: '', reason: a ? 'the answer carries no validation' : 'the agent ended without an answer' }
392
396
  if (v.valid) return { committed: !!v.committed, attempts: i + 1, test: a.test, reason: v.reason }
393
397
  const slot = v.class === 'unchanged' ? 'commit_rejected' : v.class
@@ -20,7 +20,10 @@ function args(argv) { const a = {}; for (let i = 0; i < argv.length; i += 2) a[a
20
20
  function judge(a, input) {
21
21
  const pj = JSON.parse(fs.readFileSync(a.pipeline, 'utf8'));
22
22
  const prep = JSON.parse(fs.readFileSync(path.join(a.state, 'repro-prep.json'), 'utf8'));
23
- const source = String(input.source || ''); const test = String(input.test || '');
23
+ const source = String(input.source || '');
24
+ // a test named by its absolute path inside the codeline is that codeline-relative path (B61); anything else stays as named
25
+ const named = String(input.test || ''); const rel = path.isAbsolute(named) ? path.relative(pj.codeline, named) : named;
26
+ const test = rel && !rel.startsWith('..') && !path.isAbsolute(rel) ? rel : named;
24
27
  const cand = (prep.candidates || {})[source];
25
28
  if (!cand) return { valid: false, committed: false, class: 'no_file', feedback: '', reason: `'${source}' is not a source this change offered for a test` };
26
29
  const allowed = new Set([cand.target]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amsd-pipeline-workflow",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
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": {