spec-controller 0.1.0-alpha.1 → 0.1.0-alpha.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.
Files changed (69) hide show
  1. package/README.md +112 -0
  2. package/dist/cli-args.d.ts +73 -0
  3. package/dist/cli-args.d.ts.map +1 -0
  4. package/dist/cli-args.js +114 -0
  5. package/dist/cli-args.js.map +1 -0
  6. package/dist/cli-balance/cli.d.ts +20 -20
  7. package/dist/cli-balance/cli.d.ts.map +1 -1
  8. package/dist/cli-balance/cli.js +221 -202
  9. package/dist/cli-balance/cli.js.map +1 -1
  10. package/dist/cli-balance/emit/writer.d.ts +1 -1
  11. package/dist/cli-registry.d.ts +35 -12
  12. package/dist/cli-registry.d.ts.map +1 -1
  13. package/dist/cli-registry.js +95 -36
  14. package/dist/cli-registry.js.map +1 -1
  15. package/dist/cli.d.ts +5 -3
  16. package/dist/cli.d.ts.map +1 -1
  17. package/dist/cli.js +9 -3
  18. package/dist/cli.js.map +1 -1
  19. package/dist/corpus/cli.d.ts +34 -0
  20. package/dist/corpus/cli.d.ts.map +1 -0
  21. package/dist/corpus/cli.js +125 -0
  22. package/dist/corpus/cli.js.map +1 -0
  23. package/dist/deferralTags.d.ts +3 -3
  24. package/dist/deferralTags.js +3 -3
  25. package/dist/ingest/gherkinValidation.d.ts +29 -5
  26. package/dist/ingest/gherkinValidation.d.ts.map +1 -1
  27. package/dist/ingest/gherkinValidation.js +33 -5
  28. package/dist/ingest/gherkinValidation.js.map +1 -1
  29. package/dist/ingest/ingestQualityChecks.d.ts +15 -25
  30. package/dist/ingest/ingestQualityChecks.d.ts.map +1 -1
  31. package/dist/ingest/ingestQualityChecks.js +87 -104
  32. package/dist/ingest/ingestQualityChecks.js.map +1 -1
  33. package/dist/ingest/ingestScenarios.d.ts +2 -1
  34. package/dist/ingest/ingestScenarios.d.ts.map +1 -1
  35. package/dist/ingest/ingestScenarios.js +32 -3
  36. package/dist/ingest/ingestScenarios.js.map +1 -1
  37. package/dist/run-management/resolveRunInputs.d.ts +24 -11
  38. package/dist/run-management/resolveRunInputs.d.ts.map +1 -1
  39. package/dist/run-management/resolveRunInputs.js +49 -13
  40. package/dist/run-management/resolveRunInputs.js.map +1 -1
  41. package/package.json +2 -2
  42. package/dist/mutation-ratchet/index.d.ts +0 -48
  43. package/dist/mutation-ratchet/index.d.ts.map +0 -1
  44. package/dist/mutation-ratchet/index.js +0 -48
  45. package/dist/mutation-ratchet/index.js.map +0 -1
  46. package/dist/mutation-ratchet/ratchet.d.ts +0 -129
  47. package/dist/mutation-ratchet/ratchet.d.ts.map +0 -1
  48. package/dist/mutation-ratchet/ratchet.js +0 -222
  49. package/dist/mutation-ratchet/ratchet.js.map +0 -1
  50. package/dist/mutation-ratchet/ratchetCli.d.ts +0 -57
  51. package/dist/mutation-ratchet/ratchetCli.d.ts.map +0 -1
  52. package/dist/mutation-ratchet/ratchetCli.js +0 -139
  53. package/dist/mutation-ratchet/ratchetCli.js.map +0 -1
  54. package/dist/mutation-ratchet/reconcile.d.ts +0 -82
  55. package/dist/mutation-ratchet/reconcile.d.ts.map +0 -1
  56. package/dist/mutation-ratchet/reconcile.js +0 -67
  57. package/dist/mutation-ratchet/reconcile.js.map +0 -1
  58. package/dist/mutation-ratchet/record.d.ts +0 -210
  59. package/dist/mutation-ratchet/record.d.ts.map +0 -1
  60. package/dist/mutation-ratchet/record.js +0 -330
  61. package/dist/mutation-ratchet/record.js.map +0 -1
  62. package/dist/mutation-ratchet/report.d.ts +0 -83
  63. package/dist/mutation-ratchet/report.d.ts.map +0 -1
  64. package/dist/mutation-ratchet/report.js +0 -148
  65. package/dist/mutation-ratchet/report.js.map +0 -1
  66. package/dist/mutation-ratchet/verdict.d.ts +0 -177
  67. package/dist/mutation-ratchet/verdict.d.ts.map +0 -1
  68. package/dist/mutation-ratchet/verdict.js +0 -387
  69. package/dist/mutation-ratchet/verdict.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ingestScenarios.js","sourceRoot":"","sources":["../../src/ingest/ingestScenarios.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ingestScenarios.js","sourceRoot":"","sources":["../../src/ingest/ingestScenarios.ts"],"names":[],"mappings":"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"}
@@ -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
- * **The correctness trap this exists to avoid:** at run time the process cwd is the
36
- * TARGET repo (reconcile runs there), so a bare `git rev-parse HEAD` would re-record the
37
- * TARGET's SHA — the exact bug this ticket fixes. So the SHA is read `git -C <the tool's
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
- * `toolSha` is `git -C <toolDir> rev-parse HEAD` (trimmed), or `null` on any throw — the
41
- * tool installed as a package with no `.git`, git absent, or an empty answer — mirroring
42
- * `resolveSourceSha`'s fail-soft. `toolVersion` is read from the tool's own
43
- * `package.json` (walked up from `toolDir`), or `"unknown"` when none is found — so a run
44
- * stays attributable by version even when no SHA can be read. `toolDir` /
45
- * `packageJsonPath` are injectable for the `@unit` teeth (@SCN-RPT-026).
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;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAQ3G;AA2CD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAerE"}
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
- * **The correctness trap this exists to avoid:** at run time the process cwd is the
48
- * TARGET repo (reconcile runs there), so a bare `git rev-parse HEAD` would re-record the
49
- * TARGET's SHA — the exact bug this ticket fixes. So the SHA is read `git -C <the tool's
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
- * `toolSha` is `git -C <toolDir> rev-parse HEAD` (trimmed), or `null` on any throw — the
53
- * tool installed as a package with no `.git`, git absent, or an empty answer — mirroring
54
- * `resolveSourceSha`'s fail-soft. `toolVersion` is read from the tool's own
55
- * `package.json` (walked up from `toolDir`), or `"unknown"` when none is found — so a run
56
- * stays attributable by version even when no SHA can be read. `toolDir` /
57
- * `packageJsonPath` are injectable for the `@unit` teeth (@SCN-RPT-026).
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
- /** The tool's own git HEAD, read `-C <toolDir>` (never cwd), null on any throw. */
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":"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"}
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.1",
3
+ "version": "0.1.0-alpha.11",
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",
@@ -25,7 +25,7 @@
25
25
  "@cucumber/gherkin": "^41.0.0",
26
26
  "@cucumber/messages": "^34.0.1",
27
27
  "yaml": "^2.9.0",
28
- "@3f-consulting/spec-controller-core": "0.1.0-alpha.1"
28
+ "@3f-consulting/spec-controller-core": "0.1.0-alpha.11"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
@@ -1,48 +0,0 @@
1
- /**
2
- * THE MODULE'S OWN SURFACE — curated symbol by symbol, never a re-export of the tree behind it
3
- * (@SCN-RAT-014, 3F-2804).
4
- *
5
- * A BARREL THAT RE-EXPORTED EVERY MODULE WOULD BE A CONTRACT NOBODY WROTE. Each module below
6
- * exports what its own siblings need from it, and sibling-visibility is a much wider set than
7
- * consumer-visibility: the gate-block span finder, the field rewriter, the per-verdict message
8
- * builders, the status sets and the loader's per-field readers are all exported so their
9
- * neighbours can reach them without a second copy. Passing that set on wholesale would freeze
10
- * every one of them as something a consumer may depend on, and the first refactor that moved one
11
- * would be a breaking change nobody meant to make. So this file names what a caller may hold and
12
- * the omissions are decisions.
13
- *
14
- * WHAT IS HERE IS THIS LIBRARY'S OWN ENTRY, AND WHAT ITS FIRST CONSUMER NEEDS. The entry is
15
- * `reconcileGate` — hand it the five terms a project owns and it answers with a verdict. Around it
16
- * sit the pieces a consumer that wants to compose its own way needs: the verdict over counts
17
- * already in hand, the two readers that turn a report into counts, the recorder, the loader, the
18
- * three score functions a consumer rendering its own view needs, the kill floor those same figures
19
- * imply in mutants, the default record name, and both error types the functions above raise — the
20
- * record fault and the up-only refusal — because a refusal a caller cannot name in a `catch` is a
21
- * refusal that caller cannot handle.
22
- *
23
- * THE KILL FLOOR CROSSES FOR A SECOND KIND OF CONSUMER, AND THAT IS WHY IT IS NOT A SCORE (3F-2788).
24
- * Everything above answers a reader that wants this library's verdict. `killFloorOf` answers one
25
- * that wants only the BAR — a ledger holding its own measured row to the same figure this library
26
- * reconciles against, so the two cannot disagree by construction. A consumer that derived it
27
- * instead would be the second place knowing how an allowance is spent.
28
- *
29
- * THE TYPES ARE SPELLED FOR A CONSUMER'S NAMESPACE RATHER THAN FOR THIS MODULE'S. `GateRecord` and
30
- * `GateAllowance` are unambiguous inside a directory about nothing else; imported into a repository
31
- * that has gates of several kinds they are not, so they cross this line under the fuller names.
32
- * The aliasing is deliberate and one-directional: the internal spellings stay internal.
33
- *
34
- * AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION NOW RATHER THAN AN OPEN QUESTION. The
35
- * sibling core package's barrel is reflected and compared against a frozen list in both directions,
36
- * so a symbol quietly added or dropped reds. That guard is what a PUBLISHED surface is owed, and
37
- * 3F-2859 stopped publishing this one: no manifest key resolves here, and no caller outside this
38
- * repository can spell the specifier at all. Freezing the list would make every refactor behind
39
- * this barrel a change to a contract nobody holds. What the curation above is still for is the
40
- * reader of this repository's own gate, and @SCN-RAT-014 reads the list back beside it — so a
41
- * symbol added here is a symbol somebody wrote down twice, which is the guard this surface earns.
42
- */
43
- export { RECORD_FILE, reconcileGate, type RatchetRequest } from "./reconcile.js";
44
- export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, recordedScoreOf, scoreOf, type GateAllowance as MutationGateAllowance, type GateRecord as MutationGateRecord, } from "./record.js";
45
- export { FallRefusedError, raisedRecordText } from "./ratchet.js";
46
- export { measurementFromReport, readMutationReport, type MutationReportRead, } from "./report.js";
47
- export { verdictFor, type MutationMeasurement, type MutationVerdict, type MutationVerdictKind, } from "./verdict.js";
48
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,OAAO,EACP,KAAK,aAAa,IAAI,qBAAqB,EAC3C,KAAK,UAAU,IAAI,kBAAkB,GACtC,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC"}
@@ -1,48 +0,0 @@
1
- /**
2
- * THE MODULE'S OWN SURFACE — curated symbol by symbol, never a re-export of the tree behind it
3
- * (@SCN-RAT-014, 3F-2804).
4
- *
5
- * A BARREL THAT RE-EXPORTED EVERY MODULE WOULD BE A CONTRACT NOBODY WROTE. Each module below
6
- * exports what its own siblings need from it, and sibling-visibility is a much wider set than
7
- * consumer-visibility: the gate-block span finder, the field rewriter, the per-verdict message
8
- * builders, the status sets and the loader's per-field readers are all exported so their
9
- * neighbours can reach them without a second copy. Passing that set on wholesale would freeze
10
- * every one of them as something a consumer may depend on, and the first refactor that moved one
11
- * would be a breaking change nobody meant to make. So this file names what a caller may hold and
12
- * the omissions are decisions.
13
- *
14
- * WHAT IS HERE IS THIS LIBRARY'S OWN ENTRY, AND WHAT ITS FIRST CONSUMER NEEDS. The entry is
15
- * `reconcileGate` — hand it the five terms a project owns and it answers with a verdict. Around it
16
- * sit the pieces a consumer that wants to compose its own way needs: the verdict over counts
17
- * already in hand, the two readers that turn a report into counts, the recorder, the loader, the
18
- * three score functions a consumer rendering its own view needs, the kill floor those same figures
19
- * imply in mutants, the default record name, and both error types the functions above raise — the
20
- * record fault and the up-only refusal — because a refusal a caller cannot name in a `catch` is a
21
- * refusal that caller cannot handle.
22
- *
23
- * THE KILL FLOOR CROSSES FOR A SECOND KIND OF CONSUMER, AND THAT IS WHY IT IS NOT A SCORE (3F-2788).
24
- * Everything above answers a reader that wants this library's verdict. `killFloorOf` answers one
25
- * that wants only the BAR — a ledger holding its own measured row to the same figure this library
26
- * reconciles against, so the two cannot disagree by construction. A consumer that derived it
27
- * instead would be the second place knowing how an allowance is spent.
28
- *
29
- * THE TYPES ARE SPELLED FOR A CONSUMER'S NAMESPACE RATHER THAN FOR THIS MODULE'S. `GateRecord` and
30
- * `GateAllowance` are unambiguous inside a directory about nothing else; imported into a repository
31
- * that has gates of several kinds they are not, so they cross this line under the fuller names.
32
- * The aliasing is deliberate and one-directional: the internal spellings stay internal.
33
- *
34
- * AND NO DRIFT GUARD STANDS OVER IT, WHICH IS A DECISION NOW RATHER THAN AN OPEN QUESTION. The
35
- * sibling core package's barrel is reflected and compared against a frozen list in both directions,
36
- * so a symbol quietly added or dropped reds. That guard is what a PUBLISHED surface is owed, and
37
- * 3F-2859 stopped publishing this one: no manifest key resolves here, and no caller outside this
38
- * repository can spell the specifier at all. Freezing the list would make every refactor behind
39
- * this barrel a change to a contract nobody holds. What the curation above is still for is the
40
- * reader of this repository's own gate, and @SCN-RAT-014 reads the list back beside it — so a
41
- * symbol added here is a symbol somebody wrote down twice, which is the guard this surface earns.
42
- */
43
- export { RECORD_FILE, reconcileGate } from "./reconcile.js";
44
- export { floorOf, gateRecordFor, killFloorOf, MalformedRecordError, parseGateRecords, recordedScoreOf, scoreOf, } from "./record.js";
45
- export { FallRefusedError, raisedRecordText } from "./ratchet.js";
46
- export { measurementFromReport, readMutationReport, } from "./report.js";
47
- export { verdictFor, } from "./verdict.js";
48
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mutation-ratchet/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAuB,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,OAAO,GAGR,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,GAIX,MAAM,cAAc,CAAC"}
@@ -1,129 +0,0 @@
1
- /**
2
- * THE RECORDER — a measurement written into the record as a surgical text edit (@SCN-RAT-011,
3
- * 3F-2801), refused outright when it is not a raise (@SCN-RAT-012, 3F-2802), and kept inside the
4
- * block it names when a sibling gate banks the very same counts (@SCN-RAT-013, 3F-2803).
5
- *
6
- * A SURGICAL TEXT EDIT, NEVER A RE-DUMP, AND THAT IS THE WHOLE OF THIS MODULE'S DIFFICULTY.
7
- * Emitting the parsed document back out is the obvious way to write two figures into a record, and
8
- * it throws away every comment on the way through — comments are not part of the document a parser
9
- * hands back. A record file is MOSTLY comment: every allowance's justification lives there, and so
10
- * does the argument for the bar sitting where it sits. So a recorder that re-serialised would
11
- * delete the reasoning for the very bar it was raising, quietly, in the same commit that claims to
12
- * be strengthening it, and with the two figures perfectly correct.
13
- *
14
- * SO THE TEXT ARRIVES AS TEXT AND LEAVES AS TEXT. Nothing below reaches for a document model. The
15
- * record is split on its own line breaks, two lines are rewritten where they lie, and the pieces
16
- * are joined back up — which is why what comes back is the bytes it was handed with two numerals
17
- * different, down to the blank lines, the indent style, the quoting and the trailing newline.
18
- *
19
- * AND THE EDIT IS BOUNDED BY THE NAMED GATE'S OWN BLOCK. A record is a wall of near-identical
20
- * blocks holding identically-named lines, so a rewriter that took the first `detected` line it met
21
- * would raise whichever gate happens to be written first and report success on the one it was
22
- * asked about. The block runs from the gate's key line to the first line after it indented no
23
- * further than that key — the next gate, or the comment introducing it. The search for that key
24
- * starts at the gates section rather than the top of the file, because a record is a project's own
25
- * policy document and may hold anything else it likes above the bars.
26
- *
27
- * THE LINES ARE THEN FOUND BY POSITION INSIDE THAT BLOCK, NEVER BY THE FIGURES THEY CARRY, and the
28
- * difference is invisible over almost every record. A rewriter that struck the OLD numerals out
29
- * wherever they first appeared would be byte-preserving, would move exactly two lines, would keep
30
- * every comment, and would write precisely the right two lines over any record whose gates hold
31
- * distinct figures. It writes the WRONG gate only when two gates bank the same counts — and then
32
- * silently, leaving the two gates stating figures neither of the trees they describe ever measured.
33
- * @SCN-RAT-013's record plants that collision on purpose, and authors it with the named gate above
34
- * its twin and below it, because either rewriter is right by luck when the gate it wants is first.
35
- *
36
- * A LINE THE BLOCK DOES NOT HOLD IS AN ERROR NAMING THE LINE, NEVER A NO-OP. Both of the other
37
- * answers are worse than a refusal: skipping quietly banks half a measurement and reports a raise
38
- * that did not happen, and searching on past the block's end rewrites some other gate's figure with
39
- * this gate's count.
40
- *
41
- * EVERY FAULT IN THE RECORD IS `record.ts`'s ONE REFUSAL TYPE, and its section name and gate
42
- * placeholder are imported rather than respelled. A caller is told to catch `MalformedRecordError`
43
- * for a record it cannot read, so a record fault raised here under a second type is one that caller
44
- * sails past — and a second copy of the section's name is the agreeing-until-somebody-edits-one
45
- * shape this library exists to remove.
46
- *
47
- * AND THE UP-ONLY REFUSAL IS THE ONE THING HERE THAT IS NOT A RECORD FAULT, WHICH IS WHY IT CARRIES
48
- * ITS OWN TYPE. Every fault that other refusal names is a record somebody wrote badly, sitting in
49
- * the file its reader is being sent to open. A run that is not a raise arrives over a record that
50
- * reads perfectly, so borrowing that type would send its reader hunting through a file with nothing
51
- * wrong in it — the exact harm `record.ts` refuses to do to the caller who mistyped a gate name.
52
- *
53
- * THE RATCHET ONLY EVER RAISES, AND AN EQUAL MEASUREMENT IS REFUSED TOO. Writing the same two
54
- * figures back changes nothing, and a no-op that reports success reads, in a shell history or a
55
- * run's own log, as a ratchet that happened; the refusal is what keeps "I banked it" meaning
56
- * something. It is the SCORE that is compared rather than the pair, because a run can move both of
57
- * its counts and hold its ratio exactly — over a record already stating that score, writing it
58
- * raises nothing.
59
- *
60
- * AND THE REFUSAL HAS NO OVERRIDE, DELIBERATELY. A fall that is honest — code deleted, a scope
61
- * narrowed — is a conscious bump: a human edits the two figures and puts the reason in the commit,
62
- * which is the route the refusal names and the same route the shrunk-population red already sends
63
- * its reader down. An escape hatch a tool offers is one nobody has to justify, and it would be
64
- * reached for on the first red night rather than the first honest one. So there is no input here
65
- * that writes a fall — not a flag, not a defaulted parameter, not a setting — and @SCN-RAT-012's
66
- * arm asserts that over this module's own bytes rather than trusting it.
67
- *
68
- * NOTHING HERE NAMES A PROJECT, A CHECK, A RUNNER, A WORKFLOW OR A REPOSITORY. The gate, the
69
- * record's own name and the tree it sits in all arrive from the caller.
70
- */
71
- import { type MutationMeasurement } from "./verdict.js";
72
- /**
73
- * Raised when a run is not a raise — the up-only refusal (@SCN-RAT-012, 3F-2802).
74
- *
75
- * A SECOND TYPE, AND DELIBERATELY NOT `MalformedRecordError`. Every fault that refusal names is a
76
- * record somebody wrote badly, sitting in the file its reader is being sent to open. This one is a
77
- * record that reads perfectly and an ASK that is not a raise, so borrowing the other type would
78
- * send a reader off to hunt for a fault in a file that has none.
79
- */
80
- export declare class FallRefusedError extends Error {
81
- /** The name the record was filed under, as the caller handed it over. */
82
- readonly recordFile: string;
83
- /** The gate that was to have been raised, as the caller names it. */
84
- readonly gate: string;
85
- constructor(
86
- /** The name the record was filed under, as the caller handed it over. */
87
- recordFile: string,
88
- /** The gate that was to have been raised, as the caller names it. */
89
- gate: string, banked: GateFigures, measurement: MutationMeasurement);
90
- }
91
- /** One gate's two figures, as the record currently writes them. */
92
- interface GateFigures {
93
- readonly detected: number;
94
- readonly total: number;
95
- }
96
- /**
97
- * Raise a gate's two recorded figures to a measurement, leaving every other byte alone.
98
- *
99
- * @param text the record file's own bytes, as authored
100
- * @param gate the gate to raise, as the caller names it
101
- * @param measurement the run whose counts are being banked
102
- * @param recordFile the name the record is filed under, so a refusal can say which file it read
103
- * @returns the same bytes with two numerals different
104
- * @throws MalformedRecordError when the record writes no block for the gate, or that block holds no
105
- * line to rewrite — named by the line, never passed over and never sought outside the block.
106
- * @throws FallRefusedError when the measurement does not score above what the gate already banks.
107
- * There is no input that writes it anyway.
108
- */
109
- export declare function raisedRecordText(text: string, gate: string, measurement: MutationMeasurement, recordFile: string): string;
110
- /**
111
- * Write a raised record back over the file it was read from, resolved against the caller's tree.
112
- *
113
- * THE ROOT ARRIVES, AND IS NEVER THIS MODULE'S OWN LOCATION. A recorder that joined the directory it
114
- * was installed into is correct only while it sits inside the tree it is writing to, and stops
115
- * being so the moment it is installed as a dependency of one.
116
- *
117
- * READ AND WRITTEN IN THE SAME ENCODING, so the round trip through the filesystem is a round trip
118
- * rather than a transcoding — the whole promise of this module being that what comes back out is
119
- * what went in.
120
- *
121
- * @param root the CONSUMER'S workspace
122
- * @param recordFile where the record sits, relative to that root
123
- * @param gate the gate to raise, as the caller names it
124
- * @param measurement the run whose counts are being banked
125
- * @returns the path that was written, so a caller can say where the record now stands
126
- */
127
- export declare function bankRaisedRecord(root: string, recordFile: string, gate: string, measurement: MutationMeasurement): string;
128
- export {};
129
- //# sourceMappingURL=ratchet.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ratchet.d.ts","sourceRoot":"","sources":["../../src/mutation-ratchet/ratchet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AAYH,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAEvC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM;;IAHrB,yEAAyE;IAChE,UAAU,EAAE,MAAM;IAC3B,qEAAqE;IAC5D,IAAI,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,mBAAmB;CAcnC;AA6GD,mEAAmE;AACnE,UAAU,WAAW;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,mBAAmB,EAChC,UAAU,EAAE,MAAM,GACjB,MAAM,CAYR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,mBAAmB,GAC/B,MAAM,CAMR"}