spec-controller 0.1.0-alpha.2 → 0.1.0-alpha.4
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/dist/deferralTags.d.ts +2 -2
- package/dist/deferralTags.js +2 -2
- package/dist/ingest/gherkinValidation.d.ts +6 -5
- package/dist/ingest/gherkinValidation.d.ts.map +1 -1
- package/dist/ingest/gherkinValidation.js +6 -5
- package/dist/ingest/gherkinValidation.js.map +1 -1
- package/dist/mutation-ratchet/index.d.ts +11 -6
- package/dist/mutation-ratchet/index.d.ts.map +1 -1
- package/dist/mutation-ratchet/index.js +11 -6
- package/dist/mutation-ratchet/index.js.map +1 -1
- package/dist/run-management/resolveRunInputs.d.ts +24 -11
- package/dist/run-management/resolveRunInputs.d.ts.map +1 -1
- package/dist/run-management/resolveRunInputs.js +49 -13
- package/dist/run-management/resolveRunInputs.js.map +1 -1
- package/package.json +2 -7
package/dist/deferralTags.d.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* established Cucumber deferral conventions.
|
|
6
6
|
*
|
|
7
7
|
* This is **product policy, not a core-domain invariant** — an evolvable list of tag
|
|
8
|
-
* strings, so it lives in the application layer, NOT on the
|
|
9
|
-
*
|
|
8
|
+
* strings, so it lives in the application layer, NOT on the v1 core barrel.
|
|
9
|
+
* The core `parseScenarios` recognises only the deferral set it is
|
|
10
10
|
* handed (its default is `[]`, a policy-free pure core); the app is the single source
|
|
11
11
|
* of the starter policy and always passes the resolved set (starter ∪ configured) into
|
|
12
12
|
* the parser at the ingest edge. Both `resolveDeferralTags` (the `@SCN-PND-021` config
|
package/dist/deferralTags.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* established Cucumber deferral conventions.
|
|
6
6
|
*
|
|
7
7
|
* This is **product policy, not a core-domain invariant** — an evolvable list of tag
|
|
8
|
-
* strings, so it lives in the application layer, NOT on the
|
|
9
|
-
*
|
|
8
|
+
* strings, so it lives in the application layer, NOT on the v1 core barrel.
|
|
9
|
+
* The core `parseScenarios` recognises only the deferral set it is
|
|
10
10
|
* handed (its default is `[]`, a policy-free pure core); the app is the single source
|
|
11
11
|
* of the starter policy and always passes the resolved set (starter ∪ configured) into
|
|
12
12
|
* the parser at the ingest edge. Both `resolveDeferralTags` (the `@SCN-PND-021` config
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
* PURE: `string → parse errors`. No fs, no process — the file READ lives beside it at the ingest
|
|
24
24
|
* edge, as it does for every other input.
|
|
25
25
|
*
|
|
26
|
-
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and the
|
|
26
|
+
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the v1 contract surface downstream consumers
|
|
27
|
+
* build on. Since 3F-3449 nothing reds when a symbol is added there — the guard that reconciled it
|
|
28
|
+
* both directions is gone — so keeping it narrow is a discipline rather than a gate. This validator
|
|
29
|
+
* is an INGEST concern (it decides whether an input can be read at all), not part of the
|
|
30
|
+
* reconciliation contract, so it belongs with the other readers at the app edge and the v1 surface
|
|
31
|
+
* stays untouched.
|
|
31
32
|
*/
|
|
32
33
|
/** A Gherkin parse failure: the file could not be read as Gherkin at all. */
|
|
33
34
|
export interface GherkinParseError {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gherkinValidation.d.ts","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gherkinValidation.d.ts","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAa/E;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;gBAElC,MAAM,EAAE,SAAS,iBAAiB,EAAE;CAUjD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,SAAS,EAAE,MAAM;CAK9B"}
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
* PURE: `string → parse errors`. No fs, no process — the file READ lives beside it at the ingest
|
|
24
24
|
* edge, as it does for every other input.
|
|
25
25
|
*
|
|
26
|
-
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and the
|
|
26
|
+
* WHY IT LIVES IN THE APP, NOT CORE. Core's barrel is the v1 contract surface downstream consumers
|
|
27
|
+
* build on. Since 3F-3449 nothing reds when a symbol is added there — the guard that reconciled it
|
|
28
|
+
* both directions is gone — so keeping it narrow is a discipline rather than a gate. This validator
|
|
29
|
+
* is an INGEST concern (it decides whether an input can be read at all), not part of the
|
|
30
|
+
* reconciliation contract, so it belongs with the other readers at the app edge and the v1 surface
|
|
31
|
+
* stays untouched.
|
|
31
32
|
*/
|
|
32
33
|
import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
|
|
33
34
|
import { IdGenerator } from "@cucumber/messages";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gherkinValidation.js","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gherkinValidation.js","sourceRoot":"","sources":["../../src/ingest/gherkinValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUjD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAc;IACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,0BAA0B,EAAE,CAAC,CAAC;IAEhG,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0FAA0F;QAC1F,sFAAsF;QACtF,0FAA0F;QAC1F,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAC5C,MAAM,CAA+B;IAE9C,YAAY,MAAoC;QAC9C,KAAK,CACH;YACE,yEAAyE;YACzE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC;SAC5D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,8FAA8F;IACrF,SAAS,CAAS;IAE3B,YAAY,SAAiB;QAC3B,KAAK,CAAC,gDAAgD,SAAS,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -34,12 +34,17 @@
|
|
|
34
34
|
* several kinds it is not, so it crosses this line under the fuller name. The aliasing is
|
|
35
35
|
* deliberate and one-directional: the internal spelling stays internal.
|
|
36
36
|
*
|
|
37
|
-
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
37
|
+
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION. 3F-2859
|
|
38
|
+
* stopped publishing this barrel: no manifest key resolves here, and no caller outside this
|
|
39
|
+
* repository can spell the specifier at all. Freezing the list would make every refactor behind it
|
|
40
|
+
* a change to a contract nobody holds.
|
|
41
|
+
*
|
|
42
|
+
* THE COMPARISON THIS PARAGRAPH USED TO DRAW IS GONE, AND SAYING SO IS THE POINT. It read: the
|
|
43
|
+
* sibling core package's barrel IS reflected and compared against a frozen list in both directions,
|
|
44
|
+
* so a symbol quietly added or dropped reds — that being what a PUBLISHED surface is owed, and this
|
|
45
|
+
* one is not published. At 3F-3449 that arm was deleted with the rest of the packaging checks this
|
|
46
|
+
* repository wrote for itself, so NEITHER barrel is guarded now and the contrast no longer carries
|
|
47
|
+
* the argument. What still carries it is the second sentence above, which never depended on it.
|
|
43
48
|
*/
|
|
44
49
|
export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, type GateRecord as MutationGateRecord, } from "./record.js";
|
|
45
50
|
export { measurementFromReport, readMutationReport, type MutationMeasurement, type MutationReportRead, } from "./report.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,KAAK,UAAU,IAAI,kBAAkB,GACtC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC"}
|
|
@@ -34,12 +34,17 @@
|
|
|
34
34
|
* several kinds it is not, so it crosses this line under the fuller name. The aliasing is
|
|
35
35
|
* deliberate and one-directional: the internal spelling stays internal.
|
|
36
36
|
*
|
|
37
|
-
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
37
|
+
* AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION RATHER THAN AN OPEN QUESTION. 3F-2859
|
|
38
|
+
* stopped publishing this barrel: no manifest key resolves here, and no caller outside this
|
|
39
|
+
* repository can spell the specifier at all. Freezing the list would make every refactor behind it
|
|
40
|
+
* a change to a contract nobody holds.
|
|
41
|
+
*
|
|
42
|
+
* THE COMPARISON THIS PARAGRAPH USED TO DRAW IS GONE, AND SAYING SO IS THE POINT. It read: the
|
|
43
|
+
* sibling core package's barrel IS reflected and compared against a frozen list in both directions,
|
|
44
|
+
* so a symbol quietly added or dropped reds — that being what a PUBLISHED surface is owed, and this
|
|
45
|
+
* one is not published. At 3F-3449 that arm was deleted with the rest of the packaging checks this
|
|
46
|
+
* repository wrote for itself, so NEITHER barrel is guarded now and the contrast no longer carries
|
|
47
|
+
* the argument. What still carries it is the second sentence above, which never depended on it.
|
|
43
48
|
*/
|
|
44
49
|
export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, RECORD_FILE, } from "./record.js";
|
|
45
50
|
export { measurementFromReport, readMutationReport, } from "./report.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GAEZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,aAAa,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* CLI (cli-balance/cli.ts) calls these once to build the RunContext.
|
|
7
7
|
*
|
|
8
8
|
* Scenarios: @SCN-RPT-001 (the run-provenance slice); the --source-sha override;
|
|
9
|
-
* @SCN-RPT-016 (target-root derivation).
|
|
9
|
+
* @SCN-RPT-016 (target-root derivation); @SCN-RPT-026 / @SCN-RPT-029 (the tool's own identity).
|
|
10
10
|
*/
|
|
11
11
|
/**
|
|
12
12
|
* Resolve the target's source SHA (project design §4). An explicit non-empty
|
|
@@ -32,17 +32,30 @@ export interface ToolIdentity {
|
|
|
32
32
|
* distinct from the TARGET's `sourceSha`. Two facts, one call, threaded to both the
|
|
33
33
|
* report provenance (RunContext) and the run.yaml manifest.
|
|
34
34
|
*
|
|
35
|
-
* **
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* OWN dir>`, derived from `import.meta.url`, never cwd.
|
|
35
|
+
* **TWO TRAPS, AND THIS DOCBLOCK ONLY NAMED THE FIRST FOR ELEVEN WEEKS** (@SCN-RPT-029,
|
|
36
|
+
* 3F-3418). Nothing typechecks a comment, and the sentence below — true, and the whole of
|
|
37
|
+
* what was written here — is what made the second trap read as already-handled.
|
|
39
38
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* `
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
39
|
+
* **Trap one, cwd:** at run time the process cwd is the TARGET repo (reconcile runs
|
|
40
|
+
* there), so a bare `git rev-parse HEAD` would re-record the TARGET's SHA. So the SHA is
|
|
41
|
+
* read `git -C <the tool's OWN dir>`, derived from `import.meta.url`, never cwd (3F-1916).
|
|
42
|
+
*
|
|
43
|
+
* **Trap two, which the `-C` guard could not see:** the tool's own dir is ITSELF inside the
|
|
44
|
+
* target. For an installed package that dir is `<consumer>/node_modules/…`, which is inside
|
|
45
|
+
* the consumer's worktree, so `git -C` walks up to the consumer's `.git` and answers with
|
|
46
|
+
* the consumer's HEAD — being `.gitignore`d makes no difference, git does not stop at
|
|
47
|
+
* ignored directories. That is not an absent tool SHA, it is a WRONG one, and nothing on
|
|
48
|
+
* the rendered report distinguishes it from a genuine one. It is also the only case a
|
|
49
|
+
* consumer ever sees: every adopter installs into a git repository. `resolveToolSha`
|
|
50
|
+
* therefore answers a `node_modules` SEGMENT before it asks git at all.
|
|
51
|
+
*
|
|
52
|
+
* `toolSha` is `null` for a tool resolved out of `node_modules`, and otherwise
|
|
53
|
+
* `git -C <toolDir> rev-parse HEAD` (trimmed) or `null` on any throw — no `.git` above the
|
|
54
|
+
* tool, git absent, or an empty answer — mirroring `resolveSourceSha`'s fail-soft.
|
|
55
|
+
* `toolVersion` is read from the tool's own `package.json` (walked up from `toolDir`), or
|
|
56
|
+
* `"unknown"` when none is found — so a run stays attributable by version even when no SHA
|
|
57
|
+
* can be read. `toolDir` / `packageJsonPath` are injectable for the `@unit` teeth
|
|
58
|
+
* (@SCN-RPT-026, @SCN-RPT-029).
|
|
46
59
|
*/
|
|
47
60
|
export declare function resolveToolIdentity(opts?: {
|
|
48
61
|
toolDir?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveRunInputs.d.ts","sourceRoot":"","sources":["../../src/run-management/resolveRunInputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAiBhG;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,mGAAmG;IACnG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"resolveRunInputs.d.ts","sourceRoot":"","sources":["../../src/run-management/resolveRunInputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAiBhG;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,mGAAmG;IACnG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAQ3G;AAiED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAerE"}
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* CLI (cli-balance/cli.ts) calls these once to build the RunContext.
|
|
7
7
|
*
|
|
8
8
|
* Scenarios: @SCN-RPT-001 (the run-provenance slice); the --source-sha override;
|
|
9
|
-
* @SCN-RPT-016 (target-root derivation).
|
|
9
|
+
* @SCN-RPT-016 (target-root derivation); @SCN-RPT-026 / @SCN-RPT-029 (the tool's own identity).
|
|
10
10
|
*/
|
|
11
11
|
import { execFileSync } from "node:child_process";
|
|
12
12
|
import { readFileSync } from "node:fs";
|
|
13
|
-
import { dirname, join } from "node:path";
|
|
13
|
+
import { dirname, join, sep } from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
/**
|
|
16
16
|
* Resolve the target's source SHA (project design §4). An explicit non-empty
|
|
@@ -44,17 +44,30 @@ export function resolveSourceSha(opts) {
|
|
|
44
44
|
* distinct from the TARGET's `sourceSha`. Two facts, one call, threaded to both the
|
|
45
45
|
* report provenance (RunContext) and the run.yaml manifest.
|
|
46
46
|
*
|
|
47
|
-
* **
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* OWN dir>`, derived from `import.meta.url`, never cwd.
|
|
47
|
+
* **TWO TRAPS, AND THIS DOCBLOCK ONLY NAMED THE FIRST FOR ELEVEN WEEKS** (@SCN-RPT-029,
|
|
48
|
+
* 3F-3418). Nothing typechecks a comment, and the sentence below — true, and the whole of
|
|
49
|
+
* what was written here — is what made the second trap read as already-handled.
|
|
51
50
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* `
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
51
|
+
* **Trap one, cwd:** at run time the process cwd is the TARGET repo (reconcile runs
|
|
52
|
+
* there), so a bare `git rev-parse HEAD` would re-record the TARGET's SHA. So the SHA is
|
|
53
|
+
* read `git -C <the tool's OWN dir>`, derived from `import.meta.url`, never cwd (3F-1916).
|
|
54
|
+
*
|
|
55
|
+
* **Trap two, which the `-C` guard could not see:** the tool's own dir is ITSELF inside the
|
|
56
|
+
* target. For an installed package that dir is `<consumer>/node_modules/…`, which is inside
|
|
57
|
+
* the consumer's worktree, so `git -C` walks up to the consumer's `.git` and answers with
|
|
58
|
+
* the consumer's HEAD — being `.gitignore`d makes no difference, git does not stop at
|
|
59
|
+
* ignored directories. That is not an absent tool SHA, it is a WRONG one, and nothing on
|
|
60
|
+
* the rendered report distinguishes it from a genuine one. It is also the only case a
|
|
61
|
+
* consumer ever sees: every adopter installs into a git repository. `resolveToolSha`
|
|
62
|
+
* therefore answers a `node_modules` SEGMENT before it asks git at all.
|
|
63
|
+
*
|
|
64
|
+
* `toolSha` is `null` for a tool resolved out of `node_modules`, and otherwise
|
|
65
|
+
* `git -C <toolDir> rev-parse HEAD` (trimmed) or `null` on any throw — no `.git` above the
|
|
66
|
+
* tool, git absent, or an empty answer — mirroring `resolveSourceSha`'s fail-soft.
|
|
67
|
+
* `toolVersion` is read from the tool's own `package.json` (walked up from `toolDir`), or
|
|
68
|
+
* `"unknown"` when none is found — so a run stays attributable by version even when no SHA
|
|
69
|
+
* can be read. `toolDir` / `packageJsonPath` are injectable for the `@unit` teeth
|
|
70
|
+
* (@SCN-RPT-026, @SCN-RPT-029).
|
|
58
71
|
*/
|
|
59
72
|
export function resolveToolIdentity(opts = {}) {
|
|
60
73
|
const toolDir = opts.toolDir !== undefined && opts.toolDir.trim() !== ""
|
|
@@ -65,8 +78,31 @@ export function resolveToolIdentity(opts = {}) {
|
|
|
65
78
|
toolVersion: resolveToolVersion(opts.packageJsonPath ?? findPackageJson(toolDir)),
|
|
66
79
|
};
|
|
67
80
|
}
|
|
68
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* The tool's own git HEAD, read `-C <toolDir>` (never cwd), null on any throw — and null
|
|
83
|
+
* without asking at all for a tool resolved out of `node_modules` (@SCN-RPT-029).
|
|
84
|
+
*
|
|
85
|
+
* A SEGMENT, NEVER A SUBSTRING. A directory honestly named `my_node_modules_backup` is not an
|
|
86
|
+
* install, and a checkout living under a directory literally named `node_modules` reporting null is
|
|
87
|
+
* the pathological trade every tool making this distinction takes.
|
|
88
|
+
*
|
|
89
|
+
* `sep`, NOT A REGEX OVER BOTH SEPARATORS. `[/\\]` would carry a branch no arm on this platform can
|
|
90
|
+
* reach, so a mutant deleting its second half would survive the mutation gate while nothing was
|
|
91
|
+
* worse. `sep` is what `fileURLToPath` produces on each platform, which is the only thing `toolDir`
|
|
92
|
+
* is ever built from.
|
|
93
|
+
*
|
|
94
|
+
* IT ANSWERS BEFORE THE `try`, NOT INSIDE IT. Returning null from a thrown git read and returning
|
|
95
|
+
* null because the tool is an install are the same recorded answer and not the same fact, and only
|
|
96
|
+
* the first of them is allowed to depend on git being present.
|
|
97
|
+
*
|
|
98
|
+
* WHAT IT DOES NOT CLAIM. Under `--preserve-symlinks` Node reports the symlink path rather than the
|
|
99
|
+
* realpath, so a linked development checkout would carry a `node_modules` segment and report null.
|
|
100
|
+
* That is a strictly safer wrong answer than today's, nothing in this repository passes the flag,
|
|
101
|
+
* and no arm covers it — named rather than guarded.
|
|
102
|
+
*/
|
|
69
103
|
function resolveToolSha(toolDir) {
|
|
104
|
+
if (toolDir.split(sep).includes("node_modules"))
|
|
105
|
+
return null;
|
|
70
106
|
try {
|
|
71
107
|
const out = execFileSync("git", ["-C", toolDir, "rev-parse", "HEAD"], {
|
|
72
108
|
encoding: "utf8",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveRunInputs.js","sourceRoot":"","sources":["../../src/run-management/resolveRunInputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resolveRunInputs.js","sourceRoot":"","sources":["../../src/run-management/resolveRunInputs.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-controller",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
4
|
"description": "Reconcile the behaviour your scenarios name against the evidence that actually ran — the deterministic `balance` CLI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"reconciliation",
|
|
@@ -10,11 +10,6 @@
|
|
|
10
10
|
"double-entry",
|
|
11
11
|
"cli"
|
|
12
12
|
],
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/3f-consulting/spec-controller.git",
|
|
16
|
-
"directory": "packages/spec-controller"
|
|
17
|
-
},
|
|
18
13
|
"license": "MIT",
|
|
19
14
|
"type": "module",
|
|
20
15
|
"engines": {
|
|
@@ -30,7 +25,7 @@
|
|
|
30
25
|
"@cucumber/gherkin": "^41.0.0",
|
|
31
26
|
"@cucumber/messages": "^34.0.1",
|
|
32
27
|
"yaml": "^2.9.0",
|
|
33
|
-
"@3f-consulting/spec-controller-core": "0.1.0-alpha.
|
|
28
|
+
"@3f-consulting/spec-controller-core": "0.1.0-alpha.4"
|
|
34
29
|
},
|
|
35
30
|
"publishConfig": {
|
|
36
31
|
"access": "public"
|