@rsaglobaltech/specgate 0.27.8 → 1.0.0-rc.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/CHANGELOG.md +47 -0
- package/dist/packages/core/src/application/ValidateChangeUseCase.js +19 -3
- package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -1
- package/dist/packages/core/src/domain/ApiContract.js +157 -0
- package/dist/packages/core/src/domain/ApiContract.js.map +1 -0
- package/dist/packages/core/src/domain/Approvals.js +127 -0
- package/dist/packages/core/src/domain/Approvals.js.map +1 -0
- package/dist/packages/core/src/domain/ChangeLayers.js +281 -0
- package/dist/packages/core/src/domain/ChangeLayers.js.map +1 -0
- package/dist/packages/core/src/domain/DraftChecklist.js +15 -2
- package/dist/packages/core/src/domain/DraftChecklist.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessGaps.js +182 -0
- package/dist/packages/core/src/domain/HarnessGaps.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessReport.js +16 -1
- package/dist/packages/core/src/domain/HarnessReport.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
- package/dist/packages/core/src/domain/Principles.js +119 -0
- package/dist/packages/core/src/domain/Principles.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementGraph.js +12 -1
- package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -1
- package/dist/packages/core/src/domain/Workspace.js +150 -0
- package/dist/packages/core/src/domain/Workspace.js.map +1 -0
- package/dist/packages/core/src/index.js +1 -0
- package/dist/packages/core/src/index.js.map +1 -1
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +12 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
- package/dist/packages/mcp-spec-driven/src/tools.js +18 -0
- package/dist/packages/mcp-spec-driven/src/tools.js.map +1 -1
- package/dist/scripts/alm/cli.js +45 -4
- package/dist/scripts/alm/cli.js.map +1 -1
- package/dist/scripts/alm/clients.js +3 -1
- package/dist/scripts/alm/clients.js.map +1 -1
- package/dist/scripts/alm/phases.js +279 -0
- package/dist/scripts/alm/phases.js.map +1 -0
- package/dist/scripts/alm/port.js +33 -5
- package/dist/scripts/alm/port.js.map +1 -1
- package/dist/scripts/alm/providers/azure.js +72 -11
- package/dist/scripts/alm/providers/azure.js.map +1 -1
- package/dist/scripts/alm/providers/github.js +67 -7
- package/dist/scripts/alm/providers/github.js.map +1 -1
- package/dist/scripts/alm/providers/index.js +8 -2
- package/dist/scripts/alm/providers/index.js.map +1 -1
- package/dist/scripts/alm/providers/jira.js +86 -8
- package/dist/scripts/alm/providers/jira.js.map +1 -1
- package/dist/scripts/alm/providers/linear.js +167 -0
- package/dist/scripts/alm/providers/linear.js.map +1 -0
- package/dist/scripts/change/artifacts.js +15 -1
- package/dist/scripts/change/artifacts.js.map +1 -1
- package/dist/scripts/change/instructions.js +39 -5
- package/dist/scripts/change/instructions.js.map +1 -1
- package/dist/scripts/cli/commands/alm/PhaseCommand.js +153 -0
- package/dist/scripts/cli/commands/alm/PhaseCommand.js.map +1 -0
- package/dist/scripts/cli/commands/alm/PullCommand.js +33 -2
- package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -1
- package/dist/scripts/cli/commands/alm/pull-back.js +104 -0
- package/dist/scripts/cli/commands/alm/pull-back.js.map +1 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js +92 -14
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/change/TicketCommand.js +20 -7
- package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
- package/dist/scripts/cli/commands/config/ConfigSetCommand.js +2 -1
- package/dist/scripts/cli/commands/config/ConfigSetCommand.js.map +1 -1
- package/dist/scripts/cli/commands/harness/RunCommand.js +85 -21
- package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/AdoptCommand.js +44 -4
- package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/MigrateCommand.js +166 -0
- package/dist/scripts/cli/commands/project/MigrateCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/OnboardCommand.js +23 -5
- package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/CheckCommand.js +25 -0
- package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +15 -0
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/ContractCommand.js +117 -0
- package/dist/scripts/cli/commands/spec/ContractCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/DraftCommand.js +22 -8
- package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/DriftCommand.js +128 -0
- package/dist/scripts/cli/commands/spec/DriftCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js +12 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js +43 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js +485 -0
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js.map +1 -0
- package/dist/scripts/contract.js +10 -0
- package/dist/scripts/contract.js.map +1 -0
- package/dist/scripts/docs/nav.js +16 -1
- package/dist/scripts/docs/nav.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +6 -0
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/draft/ticket-guide.js +5 -0
- package/dist/scripts/draft/ticket-guide.js.map +1 -1
- package/dist/scripts/drift.js +10 -0
- package/dist/scripts/drift.js.map +1 -0
- package/dist/scripts/harness/gap-evidence.js +149 -0
- package/dist/scripts/harness/gap-evidence.js.map +1 -0
- package/dist/scripts/harness/prompt.js +5 -1
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/harness/report.js +104 -5
- package/dist/scripts/harness/report.js.map +1 -1
- package/dist/scripts/lib/agent-permission.js +19 -0
- package/dist/scripts/lib/agent-permission.js.map +1 -1
- package/dist/scripts/lib/approvals.js +243 -0
- package/dist/scripts/lib/approvals.js.map +1 -0
- package/dist/scripts/lib/change-review.js +19 -11
- package/dist/scripts/lib/change-review.js.map +1 -1
- package/dist/scripts/lib/contracts.js +211 -0
- package/dist/scripts/lib/contracts.js.map +1 -0
- package/dist/scripts/lib/drift.js +80 -0
- package/dist/scripts/lib/drift.js.map +1 -0
- package/dist/scripts/lib/harness-environment.js +118 -0
- package/dist/scripts/lib/harness-environment.js.map +1 -0
- package/dist/scripts/lib/live-model.js +1 -0
- package/dist/scripts/lib/live-model.js.map +1 -1
- package/dist/scripts/lib/migrate.js +264 -0
- package/dist/scripts/lib/migrate.js.map +1 -0
- package/dist/scripts/lib/quality-run.js +3 -1
- package/dist/scripts/lib/quality-run.js.map +1 -1
- package/dist/scripts/lib/role-packages.js +230 -0
- package/dist/scripts/lib/role-packages.js.map +1 -0
- package/dist/scripts/lib/steering.js +180 -0
- package/dist/scripts/lib/steering.js.map +1 -0
- package/dist/scripts/lib/studio-app-page.js +28 -5
- package/dist/scripts/lib/studio-app-page.js.map +1 -1
- package/dist/scripts/lib/studio-app.js +42 -0
- package/dist/scripts/lib/studio-app.js.map +1 -1
- package/dist/scripts/lib/studio-route.js +54 -8
- package/dist/scripts/lib/studio-route.js.map +1 -1
- package/dist/scripts/lib/surface.js +55 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/lib/workspace-live-page.js +90 -0
- package/dist/scripts/lib/workspace-live-page.js.map +1 -0
- package/dist/scripts/lib/workspace-live.js +216 -0
- package/dist/scripts/lib/workspace-live.js.map +1 -0
- package/dist/scripts/lib/workspace.js +406 -0
- package/dist/scripts/lib/workspace.js.map +1 -0
- package/dist/scripts/migrate.js +10 -0
- package/dist/scripts/migrate.js.map +1 -0
- package/dist/scripts/schema/registry.js +12 -0
- package/dist/scripts/schema/registry.js.map +1 -1
- package/dist/scripts/workspace.js +10 -0
- package/dist/scripts/workspace.js.map +1 -0
- package/package.json +1 -1
|
@@ -62,6 +62,7 @@ exports.promptInFlight = promptInFlight;
|
|
|
62
62
|
exports.setJsonMode = setJsonMode;
|
|
63
63
|
exports.error = error;
|
|
64
64
|
exports.parseArgs = parseArgs;
|
|
65
|
+
exports.baselineProblem = baselineProblem;
|
|
65
66
|
exports.isRegeneratedMatrix = isRegeneratedMatrix;
|
|
66
67
|
exports.publishBranch = publishBranch;
|
|
67
68
|
exports.printReport = printReport;
|
|
@@ -82,11 +83,19 @@ const prompt_1 = require("../../../harness/prompt");
|
|
|
82
83
|
const agent_permission_1 = require("../../../lib/agent-permission");
|
|
83
84
|
const init_1 = require("../../../harness/init");
|
|
84
85
|
const in_flight_1 = require("../../../lib/in-flight");
|
|
86
|
+
const approvals_1 = require("../../../lib/approvals");
|
|
87
|
+
const role_packages_1 = require("../../../lib/role-packages");
|
|
88
|
+
/**
|
|
89
|
+
* REQ-317: the role packages each requirement's prompts carried in this run,
|
|
90
|
+
* recorded on its result — the report counts them across runs.
|
|
91
|
+
*/
|
|
92
|
+
const packagesUsed = new Map();
|
|
85
93
|
const harness_events_1 = require("../../../lib/harness-events");
|
|
86
94
|
const clarification_1 = require("../../../lib/clarification");
|
|
87
95
|
const screen_requirements_1 = require("../../../lib/screen-requirements");
|
|
88
96
|
const harness_guard_1 = require("../../../lib/harness-guard");
|
|
89
97
|
const quality_run_1 = require("../../../lib/quality-run");
|
|
98
|
+
const harness_environment_1 = require("../../../lib/harness-environment");
|
|
90
99
|
const HarnessEvents_1 = require("../../../../packages/core/src/domain/HarnessEvents");
|
|
91
100
|
/**
|
|
92
101
|
* `read` against the project as it will be after its open changes are
|
|
@@ -659,6 +668,17 @@ function runGate(worktreeDir, testCmd, timeoutMs, req = {}, settings = {}, repor
|
|
|
659
668
|
...(0, HarnessEvents_1.testCounts)(`${test.stdout || ""}${test.stderr || ""}`),
|
|
660
669
|
ms: Date.now() - testStart,
|
|
661
670
|
});
|
|
671
|
+
// REQ-279: a test command that could not reach Docker failed for the
|
|
672
|
+
// machine, not the code; the person starts Docker, the agent cannot.
|
|
673
|
+
const missing = test.status !== 0 ? (0, harness_environment_1.environmentFailure)(`${test.stdout || ""}${test.stderr || ""}`) : null;
|
|
674
|
+
if (missing) {
|
|
675
|
+
return {
|
|
676
|
+
ok: false,
|
|
677
|
+
stage: `test command: ${resolved}`,
|
|
678
|
+
output: `${test.stdout || ""}${test.stderr || ""}`,
|
|
679
|
+
couldNotRun: missing,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
662
682
|
if (test.status !== 0) {
|
|
663
683
|
// Name the command. A gate that silently does the wrong thing — running
|
|
664
684
|
// the whole suite because a filter did not apply, say — produces a
|
|
@@ -890,7 +910,10 @@ function agentChecks(worktreeDir, req, settings, timeoutMs, testCmd) {
|
|
|
890
910
|
said = runAgentOnce(worktreeDir, command, promptFor(`Review only; change no file. Compare the change below with ${req.requirement}, its ` +
|
|
891
911
|
"statement and every scenario. Answer with a first line `VERDICT: PASS` when the " +
|
|
892
912
|
"change does what the requirement says and nothing it forbids, or `VERDICT: FAIL` " +
|
|
893
|
-
"followed by each reason as `- path:line — what is wrong
|
|
913
|
+
"followed by each reason as `- path:line — what is wrong`." +
|
|
914
|
+
// REQ-318: one advice line per role package; it never decides the verdict.
|
|
915
|
+
(0, role_packages_1.reviewAdvice)(judged(worktreeDir, (d) => (0, role_packages_1.packagesFor)(d, String(req.requirement || "")))) +
|
|
916
|
+
"\n\n```diff\n" +
|
|
894
917
|
diff +
|
|
895
918
|
"\n```"), timeoutMs, "review");
|
|
896
919
|
}
|
|
@@ -1258,7 +1281,7 @@ function attemptRequirement(req, ctx) {
|
|
|
1258
1281
|
let agentMs = 0;
|
|
1259
1282
|
/** Which roles ran this attempt, in order — the run record's answer to "who did this". */
|
|
1260
1283
|
const profilesUsed = [];
|
|
1261
|
-
const record = (stage) => {
|
|
1284
|
+
const record = (stage, gateStage) => {
|
|
1262
1285
|
event({
|
|
1263
1286
|
type: "attempt",
|
|
1264
1287
|
state: "end",
|
|
@@ -1271,6 +1294,8 @@ function attemptRequirement(req, ctx) {
|
|
|
1271
1294
|
agentMs,
|
|
1272
1295
|
totalMs: Date.now() - attemptStart,
|
|
1273
1296
|
profiles: [...profilesUsed],
|
|
1297
|
+
// REQ-301: which stage rejected it is what says what to strengthen.
|
|
1298
|
+
...(gateStage ? { gateStage } : {}),
|
|
1274
1299
|
});
|
|
1275
1300
|
ledgerAttempts(attemptLog);
|
|
1276
1301
|
};
|
|
@@ -1288,21 +1313,31 @@ function attemptRequirement(req, ctx) {
|
|
|
1288
1313
|
// implementing step that follows must see what it said. Building once
|
|
1289
1314
|
// up front meant findings only ever reached the *next* attempt, which
|
|
1290
1315
|
// is not what a reviewer is for.
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
:
|
|
1305
|
-
|
|
1316
|
+
let stepPackages = [];
|
|
1317
|
+
const prompt = judged(worktreeDir, (dir) => {
|
|
1318
|
+
stepPackages = (0, role_packages_1.packagesFor)(dir, req.requirement).map((p) => p.id);
|
|
1319
|
+
return (0, prompt_1.buildPrompt)(req, dir, {
|
|
1320
|
+
promptPrefix: settings.promptPrefix,
|
|
1321
|
+
hint,
|
|
1322
|
+
previousFailure: previousFailure || undefined,
|
|
1323
|
+
reviewFindings: step.advisory ? undefined : reviewFindings || undefined,
|
|
1324
|
+
attempt,
|
|
1325
|
+
maxAttempts: settings.maxAttempts,
|
|
1326
|
+
// Read from the worktree, which carries the matrix at the base
|
|
1327
|
+
// commit — the precedent must be work already accepted, not a
|
|
1328
|
+
// sibling requirement this same run happens to be writing.
|
|
1329
|
+
withPrecedents: settings.promptPrecedents === true,
|
|
1330
|
+
e2eDir: settings.e2eDir && (0, screen_requirements_1.onScreen)(worktreeDir, req.requirement)
|
|
1331
|
+
? settings.e2eDir
|
|
1332
|
+
: undefined,
|
|
1333
|
+
});
|
|
1334
|
+
});
|
|
1335
|
+
if (stepPackages.length > 0) {
|
|
1336
|
+
const seen = packagesUsed.get(req.requirement) || new Set();
|
|
1337
|
+
for (const id of stepPackages)
|
|
1338
|
+
seen.add(id);
|
|
1339
|
+
packagesUsed.set(req.requirement, seen);
|
|
1340
|
+
}
|
|
1306
1341
|
const promptFile = path.join(os.tmpdir(), `specgate-harness-prompt-${req.requirement}-${crypto.randomBytes(4).toString("hex")}.md`);
|
|
1307
1342
|
fs.writeFileSync(promptFile, prompt, "utf8");
|
|
1308
1343
|
archivePrompt(worktreeDir, req.requirement, attempt, step, prompt);
|
|
@@ -1313,6 +1348,8 @@ function attemptRequirement(req, ctx) {
|
|
|
1313
1348
|
role: step.profile || (step.advisory ? "reviewer" : "agent"),
|
|
1314
1349
|
chars: prompt.length,
|
|
1315
1350
|
lines: prompt.split("\n").length,
|
|
1351
|
+
// REQ-317: which role packages it carried.
|
|
1352
|
+
...(stepPackages.length > 0 ? { packages: stepPackages } : {}),
|
|
1316
1353
|
});
|
|
1317
1354
|
// D1: a profile chosen by matching this requirement, when one matches.
|
|
1318
1355
|
// The role ladder still wins — `attempt_profiles` names a profile for
|
|
@@ -1461,8 +1498,10 @@ function attemptRequirement(req, ctx) {
|
|
|
1461
1498
|
warn(`${req.requirement}: ${gate.couldNotRun}`);
|
|
1462
1499
|
for (const line of gate.output.trim().split("\n").slice(-5))
|
|
1463
1500
|
warn(` ${line}`);
|
|
1464
|
-
warn(
|
|
1465
|
-
|
|
1501
|
+
warn(gate.stage.startsWith("quality check")
|
|
1502
|
+
? ` not retrying: fix the check (harness.config.yaml) and run it again`
|
|
1503
|
+
: ` not retrying: the agent cannot fix the machine`);
|
|
1504
|
+
record("check", gate.stage);
|
|
1466
1505
|
stopRetrying = true;
|
|
1467
1506
|
break;
|
|
1468
1507
|
}
|
|
@@ -1486,11 +1525,11 @@ function attemptRequirement(req, ctx) {
|
|
|
1486
1525
|
previousFailure;
|
|
1487
1526
|
warn(`${req.requirement}: the failure is in ${specFiles.join(", ")}, which the agent may not edit`);
|
|
1488
1527
|
warn(` not retrying; fix the specification and run it again`);
|
|
1489
|
-
record("spec");
|
|
1528
|
+
record("spec", gate.stage);
|
|
1490
1529
|
stopRetrying = true;
|
|
1491
1530
|
break;
|
|
1492
1531
|
}
|
|
1493
|
-
record("gate");
|
|
1532
|
+
record("gate", gate.stage);
|
|
1494
1533
|
continue;
|
|
1495
1534
|
}
|
|
1496
1535
|
// Green — but does the diff contain what the row promised? (A2)
|
|
@@ -2053,6 +2092,9 @@ function processRequirement(req, ctx) {
|
|
|
2053
2092
|
ledgerWrite();
|
|
2054
2093
|
}
|
|
2055
2094
|
const result = processOneRequirement(req, ctx);
|
|
2095
|
+
const used = packagesUsed.get(req.requirement);
|
|
2096
|
+
if (used && used.size > 0)
|
|
2097
|
+
result.packages = [...used];
|
|
2056
2098
|
if (ledger) {
|
|
2057
2099
|
ledger.record.results.push(result);
|
|
2058
2100
|
delete ledger.record.running;
|
|
@@ -2074,6 +2116,22 @@ function processOneRequirement(req, ctx) {
|
|
|
2074
2116
|
});
|
|
2075
2117
|
if (matchedProfile)
|
|
2076
2118
|
info(`${req.requirement}: profile '${matchedProfile}' matched`);
|
|
2119
|
+
// REQ-315: a requirement of an open change waits for its approvals — the 1.0
|
|
2120
|
+
// default for a layered change — before any worktree or agent.
|
|
2121
|
+
const owning = (0, in_flight_1.inFlightRequirements)(projectDir).find((r) => r.id === req.requirement);
|
|
2122
|
+
const unapproved = owning ? (0, approvals_1.missingApprovals)(projectDir, owning.change) : null;
|
|
2123
|
+
if (unapproved) {
|
|
2124
|
+
error(`${req.requirement}: ${unapproved.message} [harness_not_approved]`);
|
|
2125
|
+
warn(` fix: ${unapproved.fix}`);
|
|
2126
|
+
return {
|
|
2127
|
+
requirement: req.requirement,
|
|
2128
|
+
category: req.category,
|
|
2129
|
+
result: "skipped",
|
|
2130
|
+
attempts: 0,
|
|
2131
|
+
branch,
|
|
2132
|
+
error: `harness_not_approved: ${unapproved.message} Fix: ${unapproved.fix}`,
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2077
2135
|
const readiness = readinessOf(projectDir, req);
|
|
2078
2136
|
const unrunnable = readiness.blockers.find((b) => b.code === "requirement_scenario_unrunnable");
|
|
2079
2137
|
const hardStop = unrunnable || (ctx.skipNotReady && !readiness.ready);
|
|
@@ -2953,6 +3011,12 @@ class RunCommand extends command_1.BaseCommand {
|
|
|
2953
3011
|
const identity = gitIdentityProblem(projectDir);
|
|
2954
3012
|
if (identity)
|
|
2955
3013
|
throw new Error(identity);
|
|
3014
|
+
// REQ-279: a stopped Docker fails every attempt in the tests or the
|
|
3015
|
+
// checks, and the agent cannot start it (truck-flote S61: three attempts).
|
|
3016
|
+
const needsDocker = (0, harness_environment_1.dockerNeed)(projectDir, settings.quality || null);
|
|
3017
|
+
const noDocker = needsDocker ? (0, quality_run_1.dockerWhyNot)() : null;
|
|
3018
|
+
if (noDocker)
|
|
3019
|
+
throw new Error(`${noDocker} This project needs it: ${needsDocker}.`);
|
|
2956
3020
|
if (args.chain) {
|
|
2957
3021
|
if (args.baseBranch) {
|
|
2958
3022
|
throw new Error("--chain merges into the branch you are on: check that branch out instead of --base-branch.");
|