shapeup-sdlc 3.14.0 → 3.14.1
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/.claude-plugin/plugin.json +1 -1
- package/kernel/compile.mjs +55 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shapeup-sdlc-plugin",
|
|
3
3
|
"displayName": "ShapeUp SDLC Plugin",
|
|
4
|
-
"version": "3.14.
|
|
4
|
+
"version": "3.14.1",
|
|
5
5
|
"description": "Shape Up SDLC harness for Claude Code: shaping, intake, orient, scope-mapping, building (T0-verified, sandboxed, scope-contracted), evaluation and QA skills orchestrated by a tech-lead.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Liberty Nguyen",
|
package/kernel/compile.mjs
CHANGED
|
@@ -527,6 +527,44 @@ export function verdictBugs(cwd, slug, round) {
|
|
|
527
527
|
return v.bugs.filter((b) => !refuted.has(String(b?.id)) && !refuted.has(String(b?.criterion)));
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
/**
|
|
531
|
+
* Who owns the row a bug or a failed criterion is about — by use case, not by file.
|
|
532
|
+
*
|
|
533
|
+
* A bug names a code location, and electing its owner from that location is right when one scope
|
|
534
|
+
* writes the file. Screens are shared: on a live run two bugs about rows of UC-05 and UC-07 both
|
|
535
|
+
* named screen files that three scopes could write, both were elected to a third scope that owned
|
|
536
|
+
* neither row, and that scope could not write the row's check and escalated. The criterion says
|
|
537
|
+
* which row it is; the row's use case says which scope owns it. Read from the name directly
|
|
538
|
+
* (`UC-05 …`), else from the spec's use-case file whose Test Surface lists the row id.
|
|
539
|
+
*
|
|
540
|
+
* @param {string} cwd - Project root.
|
|
541
|
+
* @param {string} slug - Feature slug.
|
|
542
|
+
* @returns {function(string): (string|undefined)} Criterion text → owning scope_id, or undefined
|
|
543
|
+
* when no use case can be read off it or no scope lists that use case.
|
|
544
|
+
*/
|
|
545
|
+
export function rowOwner(cwd, slug) {
|
|
546
|
+
const owners = new Map();
|
|
547
|
+
for (const { contract, id } of readAllContracts(scopesDir(cwd, slug))) {
|
|
548
|
+
const sid = contract?.scope_id || id;
|
|
549
|
+
for (const uc of Array.isArray(contract?.use_cases) ? contract.use_cases : []) if (!owners.has(uc)) owners.set(uc, sid);
|
|
550
|
+
}
|
|
551
|
+
const rowUc = new Map();
|
|
552
|
+
const ucDir = join(defaultSpecDir(cwd, slug), "usecases");
|
|
553
|
+
let files = [];
|
|
554
|
+
try { files = readdirSync(ucDir).filter((f) => /^UC-.*\.md$/.test(f)); } catch { /* no spec tree */ }
|
|
555
|
+
for (const f of files) {
|
|
556
|
+
const uc = f.replace(/\.md$/, "");
|
|
557
|
+
let text = "";
|
|
558
|
+
try { text = readFileSync(join(ucDir, f), "utf8"); } catch { continue; }
|
|
559
|
+
for (const m of text.matchAll(/^\|\s*(TS-[A-Za-z0-9_-]+)\s*\|/gm)) if (!rowUc.has(m[1])) rowUc.set(m[1], uc);
|
|
560
|
+
}
|
|
561
|
+
return (criterion) => {
|
|
562
|
+
const s = String(criterion ?? "");
|
|
563
|
+
const uc = (s.match(/\bUC-[A-Za-z0-9_-]+/) || [])[0] || rowUc.get((s.match(/\bTS-[A-Za-z0-9_-]+/) || [])[0]);
|
|
564
|
+
return uc ? owners.get(uc) : undefined;
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
|
|
530
568
|
/**
|
|
531
569
|
* The previous round's FAILED CRITERIA that the judge filed no bug for, as bug entries.
|
|
532
570
|
*
|
|
@@ -578,6 +616,22 @@ export function criteriaBugs(cwd, slug, round) {
|
|
|
578
616
|
return out;
|
|
579
617
|
}
|
|
580
618
|
|
|
619
|
+
/**
|
|
620
|
+
* Stamp each verdict bug with the scope that owns the row it names, where one can be read. A bug
|
|
621
|
+
* that already carries a scope, or names no row a scope owns, is left to the file election.
|
|
622
|
+
*
|
|
623
|
+
* @param {Array<object>} bugs - Verdict and criterion bugs.
|
|
624
|
+
* @param {function(string): (string|undefined)} owner - From {@link rowOwner}.
|
|
625
|
+
* @returns {Array<object>} The same bugs, `scope_id` added where the row's owner is known.
|
|
626
|
+
*/
|
|
627
|
+
export function byRow(bugs, owner) {
|
|
628
|
+
return (bugs || []).map((b) => {
|
|
629
|
+
if (b?.scope_id) return b;
|
|
630
|
+
const sid = owner(b?.criterion);
|
|
631
|
+
return sid ? { ...b, scope_id: sid } : b;
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
581
635
|
/**
|
|
582
636
|
* The previous round's RED BUILD GATE, as bug entries the fix round can act on.
|
|
583
637
|
*
|
|
@@ -1099,7 +1153,7 @@ export async function cli(rawArgv) {
|
|
|
1099
1153
|
// this line, and none of them can pass a payload to a build order (see the banner above).
|
|
1100
1154
|
// Two sources, one channel: the judge's cited defects and the build gate's failing steps.
|
|
1101
1155
|
const bugs = scope
|
|
1102
|
-
? bugsForScope([...verdictBugs(cwd, slug, round), ...criteriaBugs(cwd, slug, round),
|
|
1156
|
+
? bugsForScope(byRow([...verdictBugs(cwd, slug, round), ...criteriaBugs(cwd, slug, round)], rowOwner(cwd, slug)).concat(buildBugs(cwd, slug, round)), scope.scope_id, scopeSubstrates(cwd, slug))
|
|
1103
1157
|
: [];
|
|
1104
1158
|
|
|
1105
1159
|
// A ROUND CARRYING CITED DEFECTS IS A `fix`, AND THE ORDER HAS TO SAY SO.
|
package/package.json
CHANGED