@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
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The two gaps a context harness is measured by (REQ-300..REQ-303).
|
|
4
|
+
*
|
|
5
|
+
* The 1.0 line takes them from the InfoQ article on enterprise spec-driven
|
|
6
|
+
* development (docs/specs/enterprise-sdd-gap.md, 6):
|
|
7
|
+
*
|
|
8
|
+
* - **spec → implementation**: the spec was clear and the code diverged. The
|
|
9
|
+
* fix is stronger validation and constraints — the check that caught it.
|
|
10
|
+
* - **intent → spec**: a detail of the use case was missed while talking. The
|
|
11
|
+
* fix is better elicitation — the module whose questions came late.
|
|
12
|
+
*
|
|
13
|
+
* A person's classification is the truth. What the harness recorded only
|
|
14
|
+
* suggests one: a rejection the agent fixed on a later attempt reads as the
|
|
15
|
+
* code diverging, and a requirement that changed after review — an answered
|
|
16
|
+
* question, a note, a modified delta — as intent the spec had missed. Pure
|
|
17
|
+
* arithmetic over records, like the rest of the report.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.GAPS = void 0;
|
|
21
|
+
exports.checkName = checkName;
|
|
22
|
+
exports.summariseGaps = summariseGaps;
|
|
23
|
+
exports.parseGapMarks = parseGapMarks;
|
|
24
|
+
exports.GAPS = Object.freeze(["spec-impl", "intent-spec"]);
|
|
25
|
+
/** "quality check: pmd" → "pmd"; "test command: npm test" → "test command". */
|
|
26
|
+
function checkName(stage) {
|
|
27
|
+
const s = (stage || "").trim();
|
|
28
|
+
const quality = /^quality check:\s*(\S+)/.exec(s);
|
|
29
|
+
if (quality)
|
|
30
|
+
return quality[1];
|
|
31
|
+
const colon = s.indexOf(":");
|
|
32
|
+
return colon > 0 ? s.slice(0, colon).trim() : s || "gate";
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Every requirement's gap, if it has one, and the rates.
|
|
36
|
+
*
|
|
37
|
+
* `attemptsOf` holds each requirement's attempts across every run, oldest
|
|
38
|
+
* first; `requirements` the ones the ledger records, in any order.
|
|
39
|
+
*/
|
|
40
|
+
function summariseGaps(requirements, attemptsOf, input = {}) {
|
|
41
|
+
const moduleOf = (id) => (input.moduleOf && input.moduleOf[id]) || "spec";
|
|
42
|
+
const marks = new Map();
|
|
43
|
+
for (const m of input.marks ?? [])
|
|
44
|
+
marks.set(m.requirement, m); // the latest wins
|
|
45
|
+
const evidence = new Map();
|
|
46
|
+
for (const e of input.evidence ?? [])
|
|
47
|
+
if (!evidence.has(e.requirement))
|
|
48
|
+
evidence.set(e.requirement, e);
|
|
49
|
+
const ids = [...new Set([...requirements, ...marks.keys()])].sort();
|
|
50
|
+
const rows = [];
|
|
51
|
+
const when = new Map();
|
|
52
|
+
for (const id of ids) {
|
|
53
|
+
const mark = marks.get(id);
|
|
54
|
+
if (mark) {
|
|
55
|
+
rows.push({
|
|
56
|
+
requirement: id,
|
|
57
|
+
gap: mark.gap,
|
|
58
|
+
source: "person",
|
|
59
|
+
why: mark.reason,
|
|
60
|
+
module: moduleOf(id),
|
|
61
|
+
});
|
|
62
|
+
when.set(id, mark.markedAt);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const log = attemptsOf.get(id) ?? [];
|
|
66
|
+
const onSpec = log.some((a) => a.endedAt === "spec");
|
|
67
|
+
const said = evidence.get(id);
|
|
68
|
+
if (said || onSpec) {
|
|
69
|
+
rows.push({
|
|
70
|
+
requirement: id,
|
|
71
|
+
gap: "intent-spec",
|
|
72
|
+
source: "suggested",
|
|
73
|
+
why: said ? said.why : "the gate failed on the specification",
|
|
74
|
+
module: moduleOf(id),
|
|
75
|
+
});
|
|
76
|
+
if (said && said.at)
|
|
77
|
+
when.set(id, said.at);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// A rejection followed by a pass: the agent got there, the code had diverged.
|
|
81
|
+
const fixed = log.findIndex((a, i) => a.endedAt === "gate" && log.slice(i + 1).some((b) => b.endedAt === "pass"));
|
|
82
|
+
if (fixed >= 0) {
|
|
83
|
+
const check = checkName(log[fixed].gateStage || "");
|
|
84
|
+
rows.push({
|
|
85
|
+
requirement: id,
|
|
86
|
+
gap: "spec-impl",
|
|
87
|
+
source: "suggested",
|
|
88
|
+
why: `rejected at ${log[fixed].gateStage || "the gate"}, then passed`,
|
|
89
|
+
check,
|
|
90
|
+
module: moduleOf(id),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const total = requirements.length;
|
|
95
|
+
const count = (g) => rows.filter((r) => r.gap === g).length;
|
|
96
|
+
const rate = (n) => (total > 0 ? n / total : null);
|
|
97
|
+
const modules = new Map();
|
|
98
|
+
for (const id of requirements) {
|
|
99
|
+
const name = moduleOf(id);
|
|
100
|
+
const m = modules.get(name) || { module: name, requirements: 0, specImpl: 0, intentSpec: 0 };
|
|
101
|
+
m.requirements += 1;
|
|
102
|
+
modules.set(name, m);
|
|
103
|
+
}
|
|
104
|
+
for (const r of rows) {
|
|
105
|
+
const m = modules.get(r.module) || {
|
|
106
|
+
module: r.module,
|
|
107
|
+
requirements: 0,
|
|
108
|
+
specImpl: 0,
|
|
109
|
+
intentSpec: 0,
|
|
110
|
+
};
|
|
111
|
+
if (r.gap === "spec-impl")
|
|
112
|
+
m.specImpl += 1;
|
|
113
|
+
else
|
|
114
|
+
m.intentSpec += 1;
|
|
115
|
+
modules.set(r.module, m);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
requirements: total,
|
|
119
|
+
specImpl: { count: count("spec-impl"), rate: rate(count("spec-impl")) },
|
|
120
|
+
intentSpec: { count: count("intent-spec"), rate: rate(count("intent-spec")) },
|
|
121
|
+
byModule: [...modules.values()].sort((a, b) => a.module.localeCompare(b.module)),
|
|
122
|
+
strengthen: {
|
|
123
|
+
specImpl: commonest(rows.filter((r) => r.gap === "spec-impl" && r.check).map((r) => r.check)),
|
|
124
|
+
intentSpec: newestOfCommonest(rows.filter((r) => r.gap === "intent-spec").map((r) => r.module), rows
|
|
125
|
+
.filter((r) => r.gap === "intent-spec")
|
|
126
|
+
.map((r) => [r.module, when.get(r.requirement) || ""])),
|
|
127
|
+
},
|
|
128
|
+
marked: rows.filter((r) => r.source === "person").length,
|
|
129
|
+
suggested: rows.filter((r) => r.source === "suggested").length,
|
|
130
|
+
rows,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function tally(names) {
|
|
134
|
+
const n = new Map();
|
|
135
|
+
for (const name of names)
|
|
136
|
+
n.set(name, (n.get(name) ?? 0) + 1);
|
|
137
|
+
return n;
|
|
138
|
+
}
|
|
139
|
+
/** The commonest name; a tie goes to the first alphabetically. */
|
|
140
|
+
function commonest(names) {
|
|
141
|
+
const best = [...tally(names).entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
|
|
142
|
+
return best.length ? best[0][0] : null;
|
|
143
|
+
}
|
|
144
|
+
/** The commonest name; a tie goes to the one seen most recently. */
|
|
145
|
+
function newestOfCommonest(names, dated) {
|
|
146
|
+
const counts = tally(names);
|
|
147
|
+
if (counts.size === 0)
|
|
148
|
+
return null;
|
|
149
|
+
const top = Math.max(...counts.values());
|
|
150
|
+
const latest = new Map();
|
|
151
|
+
for (const [name, at] of dated)
|
|
152
|
+
if (at > (latest.get(name) ?? ""))
|
|
153
|
+
latest.set(name, at);
|
|
154
|
+
return [...counts.entries()]
|
|
155
|
+
.filter(([, n]) => n === top)
|
|
156
|
+
.map(([name]) => name)
|
|
157
|
+
.sort((a, b) => (latest.get(b) ?? "").localeCompare(latest.get(a) ?? "") || a.localeCompare(b))[0];
|
|
158
|
+
}
|
|
159
|
+
/** The ledger of classifications, one JSON object per line (REQ-300). */
|
|
160
|
+
function parseGapMarks(jsonl) {
|
|
161
|
+
const marks = [];
|
|
162
|
+
for (const line of (jsonl || "").split("\n")) {
|
|
163
|
+
if (!line.trim())
|
|
164
|
+
continue;
|
|
165
|
+
try {
|
|
166
|
+
const p = JSON.parse(line);
|
|
167
|
+
if (p && typeof p.requirement === "string" && exports.GAPS.includes(p.gap)) {
|
|
168
|
+
marks.push({
|
|
169
|
+
requirement: p.requirement,
|
|
170
|
+
gap: p.gap,
|
|
171
|
+
reason: String(p.reason ?? ""),
|
|
172
|
+
markedAt: String(p.markedAt ?? ""),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// A half-written line is what a killed process leaves; skip it.
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return marks;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=HarnessGaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HarnessGaps.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/HarnessGaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,6 +35,7 @@ exports.parseFalseFailures = parseFalseFailures;
|
|
|
35
35
|
exports.sparkline = sparkline;
|
|
36
36
|
const QualitySummary_1 = require("./QualitySummary");
|
|
37
37
|
const RunBudget_1 = require("./RunBudget");
|
|
38
|
+
const HarnessGaps_1 = require("./HarnessGaps");
|
|
38
39
|
/**
|
|
39
40
|
* A run's rows, with the requirement it was on reported as stopped when the
|
|
40
41
|
* run never finished: killed, its record still says what it was doing.
|
|
@@ -70,7 +71,7 @@ exports.STAGE_LABELS = Object.freeze({
|
|
|
70
71
|
done: "`specgate done` failed",
|
|
71
72
|
commit: "commit failed",
|
|
72
73
|
});
|
|
73
|
-
function summariseRuns(runs, falseFailures = [], costPerRunHint = {}) {
|
|
74
|
+
function summariseRuns(runs, falseFailures = [], costPerRunHint = {}, gapInput = {}) {
|
|
74
75
|
// REQ-269: every run's time counts, each requirement once, at its latest
|
|
75
76
|
// outcome. Two runs of REQ-002 — failed, then passed — read "1 of 2 passed"
|
|
76
77
|
// and listed REQ-002 as delivering nothing (truck-flote, S55).
|
|
@@ -161,8 +162,22 @@ function summariseRuns(runs, falseFailures = [], costPerRunHint = {}) {
|
|
|
161
162
|
? (failedRows.length - falseCount) / failedRows.length
|
|
162
163
|
: null,
|
|
163
164
|
quality: (0, QualitySummary_1.summariseQuality)(runs),
|
|
165
|
+
gaps: (0, HarnessGaps_1.summariseGaps)(current.map((r) => r.requirement), attemptsByRequirement(rows), gapInput),
|
|
164
166
|
};
|
|
165
167
|
}
|
|
168
|
+
/** Each requirement's attempts across every run, oldest first. */
|
|
169
|
+
function attemptsByRequirement(rows) {
|
|
170
|
+
const out = new Map();
|
|
171
|
+
for (const row of rows) {
|
|
172
|
+
const list = out.get(row.requirement) ?? [];
|
|
173
|
+
for (const a of row.attemptLog ?? []) {
|
|
174
|
+
if (a && a.endedAt)
|
|
175
|
+
list.push({ endedAt: a.endedAt, gateStage: a.gateStage });
|
|
176
|
+
}
|
|
177
|
+
out.set(row.requirement, list);
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
166
181
|
/** The ledger of human marks, one JSON object per line. */
|
|
167
182
|
function parseFalseFailures(jsonl) {
|
|
168
183
|
const marks = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HarnessReport.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/HarnessReport.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;
|
|
1
|
+
{"version":3,"file":"HarnessReport.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/HarnessReport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HarnessRun.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/HarnessRun.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAwBH,wDAQC;AA6BD,0CAKC;AAED,sDASC;
|
|
1
|
+
{"version":3,"file":"HarnessRun.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/HarnessRun.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The organization's principles (REQ-330..332): `docs/specs/principles.md`,
|
|
4
|
+
* the version a repository follows, and the principles the gate can check.
|
|
5
|
+
*
|
|
6
|
+
* ---
|
|
7
|
+
* principles_version: 1.2.0
|
|
8
|
+
* source: ../workspace/principles.md # or pack:<pack_id>
|
|
9
|
+
* ---
|
|
10
|
+
* ## P1 — No credentials in code
|
|
11
|
+
* <!-- specgate:principle forbid="password\s*=" in="src/**" -->
|
|
12
|
+
*
|
|
13
|
+
* Pure: text in, model out. Reading the source and running the checks is the
|
|
14
|
+
* command layer's.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.PRINCIPLES_FILE = void 0;
|
|
18
|
+
exports.parsePrinciples = parsePrinciples;
|
|
19
|
+
exports.compareVersions = compareVersions;
|
|
20
|
+
exports.globToRegExp = globToRegExp;
|
|
21
|
+
exports.PRINCIPLES_FILE = "docs/specs/principles.md";
|
|
22
|
+
const HEADING = /^#{2,4}\s+(.+?)\s*$/;
|
|
23
|
+
const PRINCIPLE_COMMENT = /<!--\s*specgate:principle\b([\s\S]*?)-->/;
|
|
24
|
+
/** `key="value with \" escapes"` or `key=value`, as a principle comment writes them. */
|
|
25
|
+
function attributes(body) {
|
|
26
|
+
const out = {};
|
|
27
|
+
const re = /([A-Za-z_][\w-]*)=(?:"((?:[^"\\]|\\.)*)"|(\S+))/g;
|
|
28
|
+
for (const m of body.matchAll(re)) {
|
|
29
|
+
out[m[1].toLowerCase()] = m[2] !== undefined ? m[2].replace(/\\"/g, '"') : m[3];
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
function frontMatter(text) {
|
|
34
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
|
|
35
|
+
if (!m)
|
|
36
|
+
return { fields: {}, body: text };
|
|
37
|
+
const fields = {};
|
|
38
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
39
|
+
const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*?)\s*$/.exec(line);
|
|
40
|
+
if (kv)
|
|
41
|
+
fields[kv[1]] = kv[2].replace(/^["']|["']$/g, "");
|
|
42
|
+
}
|
|
43
|
+
return { fields, body: text.slice(m[0].length) };
|
|
44
|
+
}
|
|
45
|
+
function parsePrinciples(text) {
|
|
46
|
+
const { fields, body } = frontMatter(text);
|
|
47
|
+
const principles = [];
|
|
48
|
+
let current = null;
|
|
49
|
+
for (const line of body.split(/\r?\n/)) {
|
|
50
|
+
const h = HEADING.exec(line);
|
|
51
|
+
if (h) {
|
|
52
|
+
const [, label] = h;
|
|
53
|
+
const idMatch = /^([A-Z][A-Z0-9-]*\d)\b\s*[—:-]?\s*(.*)$/.exec(label);
|
|
54
|
+
current = {
|
|
55
|
+
id: idMatch ? idMatch[1] : label.split(/\s+/)[0],
|
|
56
|
+
title: idMatch ? idMatch[2] || label : label,
|
|
57
|
+
level: "error",
|
|
58
|
+
};
|
|
59
|
+
principles.push(current);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const c = PRINCIPLE_COMMENT.exec(line);
|
|
63
|
+
if (c && current) {
|
|
64
|
+
const a = attributes(c[1]);
|
|
65
|
+
if (a.run)
|
|
66
|
+
current.run = a.run;
|
|
67
|
+
if (a.forbid)
|
|
68
|
+
current.forbid = a.forbid;
|
|
69
|
+
if (a.in)
|
|
70
|
+
current.in = a.in;
|
|
71
|
+
if (a.level === "warn")
|
|
72
|
+
current.level = "warn";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
version: fields.principles_version || "",
|
|
77
|
+
source: fields.source || "",
|
|
78
|
+
// Only a heading with a rule, or one under the title, is a principle.
|
|
79
|
+
principles: principles.filter((p) => p.run || p.forbid || /^[A-Z][A-Z0-9-]*\d$/.test(p.id)),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** -1, 0 or 1, comparing dotted versions numerically (`1.10` after `1.9`). */
|
|
83
|
+
function compareVersions(a, b) {
|
|
84
|
+
const parts = (v) => String(v || "")
|
|
85
|
+
.replace(/^v/, "")
|
|
86
|
+
.split(/[.-]/)
|
|
87
|
+
.map((p) => (/^\d+$/.test(p) ? Number(p) : 0));
|
|
88
|
+
const x = parts(a);
|
|
89
|
+
const y = parts(b);
|
|
90
|
+
for (let i = 0; i < Math.max(x.length, y.length); i++) {
|
|
91
|
+
const d = (x[i] || 0) - (y[i] || 0);
|
|
92
|
+
if (d !== 0)
|
|
93
|
+
return d > 0 ? 1 : -1;
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
/** A glob (`src/**`, `*.ts`, `apps/*\/src/**`) as a regular expression on `/` paths. */
|
|
98
|
+
function globToRegExp(glob) {
|
|
99
|
+
let re = "";
|
|
100
|
+
for (let i = 0; i < glob.length; i++) {
|
|
101
|
+
const ch = glob[i];
|
|
102
|
+
if (ch === "*") {
|
|
103
|
+
if (glob[i + 1] === "*") {
|
|
104
|
+
re += ".*";
|
|
105
|
+
i++;
|
|
106
|
+
if (glob[i + 1] === "/")
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
else
|
|
110
|
+
re += "[^/]*";
|
|
111
|
+
}
|
|
112
|
+
else if (ch === "?")
|
|
113
|
+
re += "[^/]";
|
|
114
|
+
else
|
|
115
|
+
re += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
116
|
+
}
|
|
117
|
+
return new RegExp(`^${re}$`);
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=Principles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Principles.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Principles.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,6 +51,12 @@ class RequirementGraph {
|
|
|
51
51
|
dependents;
|
|
52
52
|
unknown;
|
|
53
53
|
selfReferential;
|
|
54
|
+
/**
|
|
55
|
+
* REQ-294: `depends=contracts:REQ-003` names a requirement of another
|
|
56
|
+
* repository of the workspace. The repository cannot judge it — the
|
|
57
|
+
* workspace does (`workspace check`) — so it is neither unknown nor an edge.
|
|
58
|
+
*/
|
|
59
|
+
external;
|
|
54
60
|
ids;
|
|
55
61
|
constructor(requirementIds, declared) {
|
|
56
62
|
this.ids = requirementIds.map((id) => String(id).toUpperCase());
|
|
@@ -63,11 +69,15 @@ class RequirementGraph {
|
|
|
63
69
|
}
|
|
64
70
|
const unknown = [];
|
|
65
71
|
const selfReferential = [];
|
|
72
|
+
const external = [];
|
|
66
73
|
for (const [requirement, deps] of Object.entries(declared)) {
|
|
67
74
|
if (!known.has(requirement))
|
|
68
75
|
continue; // declared for a REQ not in this project
|
|
69
76
|
for (const dependency of deps) {
|
|
70
|
-
if (dependency
|
|
77
|
+
if (dependency.includes(":")) {
|
|
78
|
+
external.push({ requirement, dependency });
|
|
79
|
+
}
|
|
80
|
+
else if (dependency === requirement) {
|
|
71
81
|
selfReferential.push(requirement);
|
|
72
82
|
}
|
|
73
83
|
else if (!known.has(dependency)) {
|
|
@@ -83,6 +93,7 @@ class RequirementGraph {
|
|
|
83
93
|
this.dependents = dependents;
|
|
84
94
|
this.unknown = unknown;
|
|
85
95
|
this.selfReferential = selfReferential;
|
|
96
|
+
this.external = external;
|
|
86
97
|
}
|
|
87
98
|
/** Build from an adjacency map the caller already has — the harness has one. */
|
|
88
99
|
static fromDependencies(requirementIds, declared) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAYH,8CAOC;AARD,sFAAsF;AACtF,SAAgB,iBAAiB,CAAC,GAAW;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAa,gBAAgB;IAClB,SAAS,CAAqC;IAC9C,UAAU,CAAqC;IAC/C,OAAO,CAA+B;IACtC,eAAe,CAAoB;
|
|
1
|
+
{"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A workspace: the repositories of one product, named in one file (ADR-0041).
|
|
4
|
+
*
|
|
5
|
+
* Specgate's gate is a repository's. A product made of services, a web app and
|
|
6
|
+
* a contracts repository needs a place that knows them all: which repositories
|
|
7
|
+
* there are, which requirement of one another depends on, and which business
|
|
8
|
+
* story is split into a change in each. That place is a workspace repository
|
|
9
|
+
* holding `specgate.workspace.yaml`. Inside a member, `REQ-012` stays the id;
|
|
10
|
+
* across the workspace it is `fleet:REQ-012`.
|
|
11
|
+
*
|
|
12
|
+
* Pure domain: parsing and the id grammar. Reading the members is
|
|
13
|
+
* `scripts/lib/workspace.ts`.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.REPO_NAME = exports.WORKSPACE_ROLES = exports.STORIES_DIR = exports.WORKSPACE_FILE = void 0;
|
|
17
|
+
exports.qualifiedRefs = qualifiedRefs;
|
|
18
|
+
exports.splitQualified = splitQualified;
|
|
19
|
+
exports.readWorkspace = readWorkspace;
|
|
20
|
+
exports.renderWorkspace = renderWorkspace;
|
|
21
|
+
exports.readStory = readStory;
|
|
22
|
+
exports.renderStory = renderStory;
|
|
23
|
+
const YamlLite_1 = require("./YamlLite");
|
|
24
|
+
exports.WORKSPACE_FILE = "specgate.workspace.yaml";
|
|
25
|
+
/** Where a workspace keeps its business stories. */
|
|
26
|
+
exports.STORIES_DIR = "docs/stories";
|
|
27
|
+
/** What a member is to the product. `contracts` holds the APIs others depend on. */
|
|
28
|
+
exports.WORKSPACE_ROLES = ["service", "web", "library", "contracts"];
|
|
29
|
+
/** A member name: what a qualified id can carry before its colon. */
|
|
30
|
+
exports.REPO_NAME = /^[a-z][a-z0-9-]*$/;
|
|
31
|
+
/** `fleet:REQ-012` anywhere in a text. */
|
|
32
|
+
const QUALIFIED_ID = /(?<![\w./-])([a-z][a-z0-9-]*):(REQ-\d+)\b/g;
|
|
33
|
+
/** Every qualified id a text mentions, with its line (1-based). */
|
|
34
|
+
function qualifiedRefs(text) {
|
|
35
|
+
const out = [];
|
|
36
|
+
const lines = text.split(/\r?\n/);
|
|
37
|
+
lines.forEach((line, i) => {
|
|
38
|
+
for (const m of line.matchAll(QUALIFIED_ID))
|
|
39
|
+
out.push({ repo: m[1], id: m[2], line: i + 1 });
|
|
40
|
+
});
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* `contracts:REQ-003` as a `depends=` entry reads it, upper-cased by
|
|
45
|
+
* `splitDependencies`: the repository and the id, or null for a plain id.
|
|
46
|
+
*/
|
|
47
|
+
function splitQualified(dep) {
|
|
48
|
+
const m = /^([A-Za-z][A-Za-z0-9-]*):(REQ-\d+)$/i.exec(dep.trim());
|
|
49
|
+
return m ? { repo: m[1].toLowerCase(), id: m[2].toUpperCase() } : null;
|
|
50
|
+
}
|
|
51
|
+
/** The workspace file, checked: every member named once, with a path and a known role. */
|
|
52
|
+
function readWorkspace(text) {
|
|
53
|
+
const problems = [];
|
|
54
|
+
let doc;
|
|
55
|
+
try {
|
|
56
|
+
doc = (0, YamlLite_1.parseYamlLite)(text) || {};
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return {
|
|
60
|
+
config: null,
|
|
61
|
+
problems: [`${exports.WORKSPACE_FILE} does not parse: ${e.message}`],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const version = doc.workspace_version;
|
|
65
|
+
if (version !== 1 && version !== "1") {
|
|
66
|
+
problems.push(`${exports.WORKSPACE_FILE} needs workspace_version: 1.`);
|
|
67
|
+
}
|
|
68
|
+
const name = String(doc.name || "").trim();
|
|
69
|
+
if (!name)
|
|
70
|
+
problems.push(`${exports.WORKSPACE_FILE} needs a name.`);
|
|
71
|
+
const rawRepos = Array.isArray(doc.repos) ? doc.repos : [];
|
|
72
|
+
if (rawRepos.length === 0)
|
|
73
|
+
problems.push(`${exports.WORKSPACE_FILE} lists no repos.`);
|
|
74
|
+
const repos = [];
|
|
75
|
+
const seen = new Set();
|
|
76
|
+
for (const raw of rawRepos) {
|
|
77
|
+
const repoName = String((raw && raw.name) || "").trim();
|
|
78
|
+
if (!exports.REPO_NAME.test(repoName)) {
|
|
79
|
+
problems.push(`A repo is named "${repoName}": a name is lower-case letters, digits and dashes, as in fleet.`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (seen.has(repoName)) {
|
|
83
|
+
problems.push(`The repo ${repoName} is listed twice.`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
seen.add(repoName);
|
|
87
|
+
const repoPath = String(raw.path || "").trim();
|
|
88
|
+
if (!repoPath)
|
|
89
|
+
problems.push(`The repo ${repoName} has no path.`);
|
|
90
|
+
const role = String(raw.role || "service").trim();
|
|
91
|
+
if (!exports.WORKSPACE_ROLES.includes(role)) {
|
|
92
|
+
problems.push(`The repo ${repoName} has the role ${role}: a role is ${exports.WORKSPACE_ROLES.join(", ")}.`);
|
|
93
|
+
}
|
|
94
|
+
const caps = raw.capabilities;
|
|
95
|
+
repos.push({
|
|
96
|
+
name: repoName,
|
|
97
|
+
path: repoPath,
|
|
98
|
+
...(raw.url ? { url: String(raw.url) } : {}),
|
|
99
|
+
role,
|
|
100
|
+
capabilities: Array.isArray(caps) ? caps.map(String) : caps ? [String(caps)] : [],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return { config: problems.length ? null : { name, repos }, problems };
|
|
104
|
+
}
|
|
105
|
+
/** The workspace file as `workspace init` writes it. */
|
|
106
|
+
function renderWorkspace(config) {
|
|
107
|
+
const lines = [
|
|
108
|
+
"# The repositories of one product (ADR-0041). Across them a requirement is",
|
|
109
|
+
"# <repo>:REQ-NNN; inside a repository REQ-NNN stays its id.",
|
|
110
|
+
"workspace_version: 1",
|
|
111
|
+
`name: ${config.name}`,
|
|
112
|
+
"repos:",
|
|
113
|
+
];
|
|
114
|
+
for (const r of config.repos) {
|
|
115
|
+
lines.push(` - name: ${r.name}`, ` path: ${r.path}`);
|
|
116
|
+
if (r.url)
|
|
117
|
+
lines.push(` url: ${r.url}`);
|
|
118
|
+
lines.push(` role: ${r.role}`);
|
|
119
|
+
lines.push(` capabilities: [${r.capabilities.join(", ")}]`);
|
|
120
|
+
}
|
|
121
|
+
return lines.join("\n") + "\n";
|
|
122
|
+
}
|
|
123
|
+
/** `story.yaml` of a workspace story. */
|
|
124
|
+
function readStory(text) {
|
|
125
|
+
let doc;
|
|
126
|
+
try {
|
|
127
|
+
doc = (0, YamlLite_1.parseYamlLite)(text) || {};
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const id = String(doc.story || "").trim();
|
|
133
|
+
if (!id)
|
|
134
|
+
return null;
|
|
135
|
+
const subs = Array.isArray(doc.subchanges) ? doc.subchanges : [];
|
|
136
|
+
return {
|
|
137
|
+
id,
|
|
138
|
+
title: String(doc.title || id),
|
|
139
|
+
subchanges: subs
|
|
140
|
+
.map((s) => ({ repo: String(s.repo || ""), change: String(s.change || id) }))
|
|
141
|
+
.filter((s) => s.repo),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function renderStory(story) {
|
|
145
|
+
const lines = ["story_version: 1", `story: ${story.id}`, `title: ${story.title}`, "subchanges:"];
|
|
146
|
+
for (const s of story.subchanges)
|
|
147
|
+
lines.push(` - repo: ${s.repo}`, ` change: ${s.change}`);
|
|
148
|
+
return lines.join("\n") + "\n";
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=Workspace.js.map
|