@codyswann/lisa 3.48.0 → 3.48.2
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/all/copy-overwrite/scripts/lisa-work-item.mjs +19 -6
- package/dist/cli/doctor-gate-recommendation.d.ts +100 -0
- package/dist/cli/doctor-gate-recommendation.d.ts.map +1 -0
- package/dist/cli/doctor-gate-recommendation.js +220 -0
- package/dist/cli/doctor-gate-recommendation.js.map +1 -0
- package/dist/cli/doctor-skip-jobs-migration.d.ts.map +1 -1
- package/dist/cli/doctor-skip-jobs-migration.js +6 -38
- package/dist/cli/doctor-skip-jobs-migration.js.map +1 -1
- package/dist/cli/doctor-traceability-gate.d.ts +1 -5
- package/dist/cli/doctor-traceability-gate.d.ts.map +1 -1
- package/dist/cli/doctor-traceability-gate.js +24 -12
- package/dist/cli/doctor-traceability-gate.js.map +1 -1
- package/dist/cli/gate-registry-source.d.ts +11 -0
- package/dist/cli/gate-registry-source.d.ts.map +1 -0
- package/dist/cli/gate-registry-source.js +55 -0
- package/dist/cli/gate-registry-source.js.map +1 -0
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +1 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +6 -2
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/typescript/package-lisa/package.lisa.json +3 -1
|
@@ -1955,11 +1955,22 @@ function backlinkAdvice(ref, prUrl, contract) {
|
|
|
1955
1955
|
/**
|
|
1956
1956
|
* The FIVE gates a work item passes on its way to merged, and when each bites.
|
|
1957
1957
|
*
|
|
1958
|
-
* They are five separate
|
|
1959
|
-
*
|
|
1960
|
-
*
|
|
1961
|
-
*
|
|
1962
|
-
*
|
|
1958
|
+
* They are five separate requirements, met at five different moments — so
|
|
1959
|
+
* clearing four says nothing about the fifth, and the reader has no way to
|
|
1960
|
+
* learn the fifth exists until it goes red. Measured: two agents in one day
|
|
1961
|
+
* each satisfied three of them and were surprised by another, on a pull request
|
|
1962
|
+
* that was otherwise finished.
|
|
1963
|
+
*
|
|
1964
|
+
* FOUR of the five are ENFORCED; gate 2 is not, and the list says so on its own
|
|
1965
|
+
* line. Claim state stopped being a precondition for committing — see the note
|
|
1966
|
+
* where `assertClaimedLifecycle` used to be — and nothing in this file refuses
|
|
1967
|
+
* anything for it now; the remaining readers of `lifecycle.claimed` are the
|
|
1968
|
+
* completion writer and the sweep. It stays on the checklist because the
|
|
1969
|
+
* claimed role is still real and still what intake dispatches on, and an
|
|
1970
|
+
* operator who never sees it here meets it later with no idea it existed. A
|
|
1971
|
+
* checklist that names an unenforced requirement AND says it is unenforced is
|
|
1972
|
+
* still a checklist; one that silently drops it teaches a wrong model of the
|
|
1973
|
+
* lifecycle, and one that leaves it looking enforced is a threat nothing backs.
|
|
1963
1974
|
*
|
|
1964
1975
|
* This said FOUR until #2681 counted them properly. Gates 3 and 4 shared a
|
|
1965
1976
|
* line — "every commit AND the pull-request body carry ONE matching trailer" —
|
|
@@ -1969,7 +1980,9 @@ function backlinkAdvice(ref, prUrl, contract) {
|
|
|
1969
1980
|
* BLOCKED on "No Work-Item trailer anywhere in the pull request body" holding a
|
|
1970
1981
|
* commit that carried the trailer, an item in the claimed role, and a backlink
|
|
1971
1982
|
* already posted — four of the five satisfied, and the fifth invisible until CI
|
|
1972
|
-
* said so, one cycle later.
|
|
1983
|
+
* said so, one cycle later. (That measurement predates the claim gate's removal
|
|
1984
|
+
* and is left as it was recorded; the counting defect it describes is about
|
|
1985
|
+
* gates 3 and 4, which are both still enforced.)
|
|
1973
1986
|
*
|
|
1974
1987
|
* `Closes owner/repo#N` is called out by name because it is the substitution a
|
|
1975
1988
|
* reader reaches for: it closes the item on merge and satisfies nothing here.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** The subset of `.lisa.config.json` a gate declaration touches. */
|
|
2
|
+
export interface GateConfig {
|
|
3
|
+
readonly gates?: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
/** One registry entry, reduced to what deciding a recommendation needs. */
|
|
6
|
+
interface RegistryGate {
|
|
7
|
+
readonly task?: string | null;
|
|
8
|
+
readonly taskAt?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
/** The slice of the shipped registry this module reads. */
|
|
11
|
+
export interface GateTaskRegistry {
|
|
12
|
+
readonly REGISTRY: Record<string, RegistryGate | undefined>;
|
|
13
|
+
}
|
|
14
|
+
/** Whether a gate may be recommended, and why not when it may not. */
|
|
15
|
+
export type GateRecommendation = {
|
|
16
|
+
readonly recommend: true;
|
|
17
|
+
readonly task: string | null;
|
|
18
|
+
} | {
|
|
19
|
+
readonly recommend: false;
|
|
20
|
+
readonly task: string | null;
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
};
|
|
23
|
+
/** The result of asking for a gate to be declared. */
|
|
24
|
+
export type GateDeclaration = {
|
|
25
|
+
readonly outcome: "declared";
|
|
26
|
+
readonly task: string | null;
|
|
27
|
+
} | {
|
|
28
|
+
readonly outcome: "declined";
|
|
29
|
+
readonly task: string | null;
|
|
30
|
+
readonly reason: string;
|
|
31
|
+
};
|
|
32
|
+
/** What a caller must say to have a gate declared. */
|
|
33
|
+
export interface GateDeclarationRequest {
|
|
34
|
+
/** Project root holding `.lisa.config.json` and `package.json`. */
|
|
35
|
+
readonly targetPath: string;
|
|
36
|
+
/** The already-parsed `.lisa.config.json`. */
|
|
37
|
+
readonly config: GateConfig;
|
|
38
|
+
/** Gate id as the shipped registry spells it. */
|
|
39
|
+
readonly gateId: string;
|
|
40
|
+
/** The moment the gate would be declared at. */
|
|
41
|
+
readonly moment: string;
|
|
42
|
+
/** The level it would be declared at. */
|
|
43
|
+
readonly level: string;
|
|
44
|
+
/** Registry loader; injected by tests, never in production. */
|
|
45
|
+
readonly loadRegistry?: () => Promise<GateTaskRegistry | null>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Add one gate to a config without touching anything else.
|
|
49
|
+
*
|
|
50
|
+
* A gate is declared per MOMENT, and doctor declares one moment per call — so
|
|
51
|
+
* the per-gate object is merged into, never replaced. Replacing it drops a
|
|
52
|
+
* moment the project already declared while leaving the gate id in place, so
|
|
53
|
+
* the config still reads as configured and the moment that stopped running is
|
|
54
|
+
* invisible until something ships past it. The same goes for the gate-level
|
|
55
|
+
* `run` override, a sibling of the moment keys rather than a moment: losing it
|
|
56
|
+
* silently reverts the gate to its registry default task, which is a different
|
|
57
|
+
* check than the project asked for.
|
|
58
|
+
*
|
|
59
|
+
* Returns a new object rather than mutating, so a caller that decides not to
|
|
60
|
+
* write still holds the original.
|
|
61
|
+
* @param config - Parsed `.lisa.config.json`
|
|
62
|
+
* @param gateId - Gate id to declare
|
|
63
|
+
* @param moment - Moment to declare it at
|
|
64
|
+
* @param level - Level to declare it at
|
|
65
|
+
* @returns A copy declaring the gate
|
|
66
|
+
*/
|
|
67
|
+
export declare function withGate<T extends GateConfig>(config: T, gateId: string, moment: string, level: string): T;
|
|
68
|
+
/**
|
|
69
|
+
* The task a gate resolves to at one moment, per the shipped registry.
|
|
70
|
+
*
|
|
71
|
+
* A gate may name a different prover per moment — traceability proves the
|
|
72
|
+
* pull-request moment with `validate-pr` and the push moment with
|
|
73
|
+
* `validate-push` — so the moment is part of the question, not a detail.
|
|
74
|
+
* @param gate - The registry entry
|
|
75
|
+
* @param moment - The moment being declared
|
|
76
|
+
* @returns The task name, or null when the registry names none
|
|
77
|
+
*/
|
|
78
|
+
export declare function taskForMoment(gate: RegistryGate, moment: string): string | null;
|
|
79
|
+
/**
|
|
80
|
+
* Decide whether doctor may recommend a gate.
|
|
81
|
+
*
|
|
82
|
+
* Every decline is a decline: when Lisa cannot READ the registry it does not
|
|
83
|
+
* assume the gate is fine. An unverifiable recommendation and a
|
|
84
|
+
* known-bad recommendation cost a consumer the same red build.
|
|
85
|
+
* @param request - The gate, moment, level, and project being considered
|
|
86
|
+
* @returns Whether the gate may be recommended, and why not when it may not
|
|
87
|
+
*/
|
|
88
|
+
export declare function canRecommendGate(request: GateDeclarationRequest): Promise<GateRecommendation>;
|
|
89
|
+
/**
|
|
90
|
+
* Declare a gate in `.lisa.config.json` — but only when its task resolves.
|
|
91
|
+
*
|
|
92
|
+
* The verification and the write are one call on purpose. See the module note:
|
|
93
|
+
* a guard that a caller must remember to invoke is a guard that a future caller
|
|
94
|
+
* forgets.
|
|
95
|
+
* @param request - The gate, moment, level, and project being declared
|
|
96
|
+
* @returns Whether the declaration was written, and why not when it was not
|
|
97
|
+
*/
|
|
98
|
+
export declare function declareGate(request: GateDeclarationRequest): Promise<GateDeclaration>;
|
|
99
|
+
export {};
|
|
100
|
+
//# sourceMappingURL=doctor-gate-recommendation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-gate-recommendation.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-gate-recommendation.ts"],"names":[],"mappings":"AAiDA,oEAAoE;AACpE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,2EAA2E;AAC3E,UAAU,YAAY;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC;CAC7D;AAED,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1D;IACE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,sDAAsD;AACtD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9D;IACE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,sDAAsD;AACtD,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CAChE;AAoBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,UAAU,EAC3C,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,CAAC,CAWH;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAEf;AAsDD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CAuC7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CA0B1B"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one door through which `lisa doctor` may declare a gate on a project's
|
|
3
|
+
* behalf.
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* Measured 2026-08-20 on a repository upgrading to 3.46.3. `lisa doctor`
|
|
8
|
+
* declared `gates.traceability: {"pull-request": "required"}`, that gate
|
|
9
|
+
* resolves to the package script `check:work-item`, and Lisa shipped that
|
|
10
|
+
* script to no template. The next CI run failed with `Missing script`. A
|
|
11
|
+
* pipeline that was green before the operator ran doctor was red after — caused
|
|
12
|
+
* by the tool they ran to avoid exactly that.
|
|
13
|
+
*
|
|
14
|
+
* The failure mode is asymmetric, which is why it survived a long time. A
|
|
15
|
+
* project that already defines the script sees nothing wrong and never reports
|
|
16
|
+
* it. Only a project lacking it discovers the defect, and it discovers it as a
|
|
17
|
+
* red build mid-upgrade — the worst possible moment to be handed a broken
|
|
18
|
+
* recommendation.
|
|
19
|
+
*
|
|
20
|
+
* ## What the guard is
|
|
21
|
+
*
|
|
22
|
+
* Doctor may not recommend a gate whose task it cannot verify resolves. Not
|
|
23
|
+
* "the traceability gate": ANY gate. Shipping the missing script line fixes one
|
|
24
|
+
* gate once; this fixes the class, so the next gate added to doctor's
|
|
25
|
+
* recommendations cannot reintroduce it.
|
|
26
|
+
*
|
|
27
|
+
* ## Why the guard lives in the write path, not beside it
|
|
28
|
+
*
|
|
29
|
+
* A helper a caller is supposed to consult is a convention, and conventions
|
|
30
|
+
* drift. {@link declareGate} performs the verification AND the write, so a
|
|
31
|
+
* future doctor check that declares a gate gets the guard whether or not its
|
|
32
|
+
* author knew the guard existed. A check that wants to bypass it has to
|
|
33
|
+
* hand-roll a `writeFile`, which is visible in review.
|
|
34
|
+
*
|
|
35
|
+
* ## Turning a gate OFF is exempt
|
|
36
|
+
*
|
|
37
|
+
* A gate declared `off` runs nothing, so there is no task to resolve and no
|
|
38
|
+
* pipeline to redden. The `skip_jobs` migration check emits exactly these, and
|
|
39
|
+
* blocking them would stop a safe migration for no benefit.
|
|
40
|
+
* @module cli/doctor-gate-recommendation
|
|
41
|
+
*/
|
|
42
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
43
|
+
import * as path from "node:path";
|
|
44
|
+
import { importGateRegistry } from "./gate-registry-source.js";
|
|
45
|
+
/** The level at which a gate runs nothing, and so needs no task. */
|
|
46
|
+
const OFF = "off";
|
|
47
|
+
/**
|
|
48
|
+
* The declaration a gate id already carries, when it carries a usable one.
|
|
49
|
+
*
|
|
50
|
+
* A per-gate value must be an object — `lisa-gates.mjs` rejects anything else
|
|
51
|
+
* as `gates."<id>" must be an object`. Spreading a malformed one would be
|
|
52
|
+
* worse than replacing it: a string spreads into character-indexed keys, and
|
|
53
|
+
* an array into numeric ones, neither of which any moment reads.
|
|
54
|
+
* @param declaration - Whatever the config holds under that gate id
|
|
55
|
+
* @returns The existing keys to preserve, or nothing when there are none
|
|
56
|
+
*/
|
|
57
|
+
function existingMoments(declaration) {
|
|
58
|
+
return typeof declaration === "object" &&
|
|
59
|
+
declaration !== null &&
|
|
60
|
+
!Array.isArray(declaration)
|
|
61
|
+
? declaration
|
|
62
|
+
: {};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Add one gate to a config without touching anything else.
|
|
66
|
+
*
|
|
67
|
+
* A gate is declared per MOMENT, and doctor declares one moment per call — so
|
|
68
|
+
* the per-gate object is merged into, never replaced. Replacing it drops a
|
|
69
|
+
* moment the project already declared while leaving the gate id in place, so
|
|
70
|
+
* the config still reads as configured and the moment that stopped running is
|
|
71
|
+
* invisible until something ships past it. The same goes for the gate-level
|
|
72
|
+
* `run` override, a sibling of the moment keys rather than a moment: losing it
|
|
73
|
+
* silently reverts the gate to its registry default task, which is a different
|
|
74
|
+
* check than the project asked for.
|
|
75
|
+
*
|
|
76
|
+
* Returns a new object rather than mutating, so a caller that decides not to
|
|
77
|
+
* write still holds the original.
|
|
78
|
+
* @param config - Parsed `.lisa.config.json`
|
|
79
|
+
* @param gateId - Gate id to declare
|
|
80
|
+
* @param moment - Moment to declare it at
|
|
81
|
+
* @param level - Level to declare it at
|
|
82
|
+
* @returns A copy declaring the gate
|
|
83
|
+
*/
|
|
84
|
+
export function withGate(config, gateId, moment, level) {
|
|
85
|
+
return {
|
|
86
|
+
...config,
|
|
87
|
+
gates: {
|
|
88
|
+
...config.gates,
|
|
89
|
+
[gateId]: {
|
|
90
|
+
...existingMoments(config.gates?.[gateId]),
|
|
91
|
+
[moment]: level,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The task a gate resolves to at one moment, per the shipped registry.
|
|
98
|
+
*
|
|
99
|
+
* A gate may name a different prover per moment — traceability proves the
|
|
100
|
+
* pull-request moment with `validate-pr` and the push moment with
|
|
101
|
+
* `validate-push` — so the moment is part of the question, not a detail.
|
|
102
|
+
* @param gate - The registry entry
|
|
103
|
+
* @param moment - The moment being declared
|
|
104
|
+
* @returns The task name, or null when the registry names none
|
|
105
|
+
*/
|
|
106
|
+
export function taskForMoment(gate, moment) {
|
|
107
|
+
return gate.taskAt?.[moment] ?? gate.task ?? null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Read a project's package scripts.
|
|
111
|
+
* @param targetPath - Project root
|
|
112
|
+
* @returns The scripts block, or null when there is no readable manifest
|
|
113
|
+
*/
|
|
114
|
+
async function readScripts(targetPath) {
|
|
115
|
+
try {
|
|
116
|
+
const raw = await readFile(path.join(targetPath, "package.json"), "utf-8");
|
|
117
|
+
const parsed = JSON.parse(raw);
|
|
118
|
+
return parsed.scripts ?? {};
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Whether the gate's task exists in the project as something runnable.
|
|
126
|
+
* @param targetPath - Project root
|
|
127
|
+
* @param task - Task name the gate resolves to
|
|
128
|
+
* @returns A recommendation, declining with an operator-readable reason
|
|
129
|
+
*/
|
|
130
|
+
async function taskResolves(targetPath, task) {
|
|
131
|
+
const scripts = await readScripts(targetPath);
|
|
132
|
+
if (scripts === null) {
|
|
133
|
+
return {
|
|
134
|
+
recommend: false,
|
|
135
|
+
task,
|
|
136
|
+
reason: `this project has no readable package.json, so Lisa cannot see ` +
|
|
137
|
+
`whether the \`${task}\` task it needs would run.`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const command = scripts[task];
|
|
141
|
+
if (typeof command !== "string" || command.trim() === "") {
|
|
142
|
+
return {
|
|
143
|
+
recommend: false,
|
|
144
|
+
task,
|
|
145
|
+
reason: `this project defines no \`${task}\` script, so the gate's check ` +
|
|
146
|
+
`would fail with "Missing script" on the next build. Run ` +
|
|
147
|
+
`\`npx lisa apply .\` to install it (or add the script yourself), ` +
|
|
148
|
+
`then run \`lisa doctor\` again.`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return { recommend: true, task };
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decide whether doctor may recommend a gate.
|
|
155
|
+
*
|
|
156
|
+
* Every decline is a decline: when Lisa cannot READ the registry it does not
|
|
157
|
+
* assume the gate is fine. An unverifiable recommendation and a
|
|
158
|
+
* known-bad recommendation cost a consumer the same red build.
|
|
159
|
+
* @param request - The gate, moment, level, and project being considered
|
|
160
|
+
* @returns Whether the gate may be recommended, and why not when it may not
|
|
161
|
+
*/
|
|
162
|
+
export async function canRecommendGate(request) {
|
|
163
|
+
const registry = await (request.loadRegistry ?? (() => importGateRegistry()))();
|
|
164
|
+
if (registry === null) {
|
|
165
|
+
return {
|
|
166
|
+
recommend: false,
|
|
167
|
+
task: null,
|
|
168
|
+
reason: `Lisa could not read its own gate registry, so it cannot tell what ` +
|
|
169
|
+
`the \`${request.gateId}\` gate would run.`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const gate = registry.REGISTRY[request.gateId];
|
|
173
|
+
if (gate === undefined) {
|
|
174
|
+
return {
|
|
175
|
+
recommend: false,
|
|
176
|
+
task: null,
|
|
177
|
+
reason: `\`${request.gateId}\` is not a gate this version of Lisa knows.`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const task = taskForMoment(gate, request.moment);
|
|
181
|
+
if (request.level === OFF) {
|
|
182
|
+
// Off runs nothing. There is no command to be missing.
|
|
183
|
+
return { recommend: true, task };
|
|
184
|
+
}
|
|
185
|
+
if (task === null) {
|
|
186
|
+
return {
|
|
187
|
+
recommend: false,
|
|
188
|
+
task: null,
|
|
189
|
+
reason: `the \`${request.gateId}\` gate names no task at the ` +
|
|
190
|
+
`\`${request.moment}\` moment, so Lisa cannot prove it would run.`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return taskResolves(request.targetPath, task);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Declare a gate in `.lisa.config.json` — but only when its task resolves.
|
|
197
|
+
*
|
|
198
|
+
* The verification and the write are one call on purpose. See the module note:
|
|
199
|
+
* a guard that a caller must remember to invoke is a guard that a future caller
|
|
200
|
+
* forgets.
|
|
201
|
+
* @param request - The gate, moment, level, and project being declared
|
|
202
|
+
* @returns Whether the declaration was written, and why not when it was not
|
|
203
|
+
*/
|
|
204
|
+
export async function declareGate(request) {
|
|
205
|
+
const verdict = await canRecommendGate(request);
|
|
206
|
+
if (!verdict.recommend) {
|
|
207
|
+
return {
|
|
208
|
+
outcome: "declined",
|
|
209
|
+
task: verdict.task,
|
|
210
|
+
reason: verdict.reason,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Two-space indent and a trailing newline: the convention every Lisa-written
|
|
214
|
+
// JSON in a host project uses, so the repair does not show up as a whole-file
|
|
215
|
+
// reformat in the diff that carries it.
|
|
216
|
+
const next = withGate(request.config, request.gateId, request.moment, request.level);
|
|
217
|
+
await writeFile(path.join(request.targetPath, ".lisa.config.json"), `${JSON.stringify(next, null, 2)}\n`, "utf-8");
|
|
218
|
+
return { outcome: "declared", task: verdict.task };
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=doctor-gate-recommendation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-gate-recommendation.js","sourceRoot":"","sources":["../../src/cli/doctor-gate-recommendation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-skip-jobs-migration.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-skip-jobs-migration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor-skip-jobs-migration.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-skip-jobs-migration.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAe/C,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAsID;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,EAAE,CAAC,CAQ1B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA4BzD;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CAoCtB"}
|
|
@@ -37,59 +37,27 @@
|
|
|
37
37
|
* has not yet done a migration Lisa only just made possible.
|
|
38
38
|
* @module cli/doctor-skip-jobs-migration
|
|
39
39
|
*/
|
|
40
|
-
import { existsSync } from "node:fs";
|
|
41
40
|
import { readdir, readFile } from "node:fs/promises";
|
|
42
41
|
import * as path from "node:path";
|
|
43
|
-
import {
|
|
42
|
+
import { importGateRegistry } from "./gate-registry-source.js";
|
|
44
43
|
/** Name rendered in the doctor report. */
|
|
45
44
|
const CHECK_NAME = "skip_jobs migrated to gates?";
|
|
46
45
|
/** The moment `quality.yml` resolves gates at when a caller declares none. */
|
|
47
46
|
const DEFAULT_MOMENT = "pull-request";
|
|
48
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
49
47
|
/** A caller's `skip_jobs` input, whatever quoting style it uses. */
|
|
50
48
|
const SKIP_JOBS_INPUT = /^([ \t]{0,64})skip_jobs:[ \t]{0,64}(.{0,4096})$/;
|
|
51
49
|
/** A caller's `moment` input, whatever quoting style it uses. */
|
|
52
50
|
const MOMENT_INPUT = /^([ \t]{0,64})moment:[ \t]{0,64}(.{0,4096})$/;
|
|
53
|
-
/**
|
|
54
|
-
* Walk parents until a package-root-relative file exists.
|
|
55
|
-
* @param startDir - Directory to start searching from
|
|
56
|
-
* @param relativePath - Path under the package root
|
|
57
|
-
* @returns Absolute path, or null when no ancestor holds it
|
|
58
|
-
*/
|
|
59
|
-
function findPackageFileWalk(startDir, relativePath) {
|
|
60
|
-
const candidate = path.join(startDir, relativePath);
|
|
61
|
-
if (existsSync(candidate))
|
|
62
|
-
return candidate;
|
|
63
|
-
const parent = path.dirname(startDir);
|
|
64
|
-
return parent === startDir ? null : findPackageFileWalk(parent, relativePath);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Locate the shipped gate registry inside the running Lisa package.
|
|
68
|
-
*
|
|
69
|
-
* Deliberately Lisa's own copy rather than the project's `scripts/lisa-gates.mjs`.
|
|
70
|
-
* Both are the same file in a healthy repository — it installs by
|
|
71
|
-
* copy-overwrite — but a stale project copy would answer with a table that
|
|
72
|
-
* describes a workflow that is no longer there, which is the failure this whole
|
|
73
|
-
* check exists to stop. The authority is the version of Lisa doing the
|
|
74
|
-
* reporting.
|
|
75
|
-
* @returns Absolute path to the registry, or null when it cannot be found
|
|
76
|
-
*/
|
|
77
|
-
function resolveGateRegistry() {
|
|
78
|
-
const relative = path.join("all", "copy-overwrite", "scripts", "lisa-gates.mjs");
|
|
79
|
-
const fromPackageRoot = path.join(__dirname, "..", "..", relative);
|
|
80
|
-
if (existsSync(fromPackageRoot))
|
|
81
|
-
return fromPackageRoot;
|
|
82
|
-
return findPackageFileWalk(__dirname, relative);
|
|
83
|
-
}
|
|
84
51
|
/**
|
|
85
52
|
* Import the shipped registry.
|
|
53
|
+
*
|
|
54
|
+
* Resolution lives in `gate-registry-source` so every doctor check that reads
|
|
55
|
+
* the registry reads the same copy — the one inside the running Lisa package,
|
|
56
|
+
* never a project's possibly-stale `scripts/lisa-gates.mjs`.
|
|
86
57
|
* @returns The registry module, or null when it is not installed
|
|
87
58
|
*/
|
|
88
59
|
async function loadRegistry() {
|
|
89
|
-
|
|
90
|
-
if (script === null)
|
|
91
|
-
return null;
|
|
92
|
-
return (await import(pathToFileURL(script).href));
|
|
60
|
+
return importGateRegistry();
|
|
93
61
|
}
|
|
94
62
|
/**
|
|
95
63
|
* Strip YAML quoting and a trailing comment from an inline scalar.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-skip-jobs-migration.js","sourceRoot":"","sources":["../../src/cli/doctor-skip-jobs-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"doctor-skip-jobs-migration.js","sourceRoot":"","sources":["../../src/cli/doctor-skip-jobs-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GateConfig } from "./doctor-gate-recommendation.js";
|
|
1
2
|
import type { DoctorCheck } from "./doctor.js";
|
|
2
3
|
/** The gate id as the registry declares it. */
|
|
3
4
|
export declare const GATE_ID = "traceability";
|
|
@@ -5,10 +6,6 @@ export declare const GATE_ID = "traceability";
|
|
|
5
6
|
export declare const GATE_MOMENT = "pull-request";
|
|
6
7
|
/** What an undeclared project is repaired to. */
|
|
7
8
|
export declare const GATE_LEVEL = "required";
|
|
8
|
-
/** The subset of `.lisa.config.json` this check reads. */
|
|
9
|
-
interface GateConfig {
|
|
10
|
-
readonly gates?: Record<string, unknown>;
|
|
11
|
-
}
|
|
12
9
|
/**
|
|
13
10
|
* Whether a config declares the traceability gate at all.
|
|
14
11
|
*
|
|
@@ -35,5 +32,4 @@ export declare function withTraceabilityGate<T extends GateConfig>(config: T): T
|
|
|
35
32
|
* @returns The doctor check result
|
|
36
33
|
*/
|
|
37
34
|
export declare function checkTraceabilityGate(targetPath: string): Promise<DoctorCheck>;
|
|
38
|
-
export {};
|
|
39
35
|
//# sourceMappingURL=doctor-traceability-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-traceability-gate.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-traceability-gate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor-traceability-gate.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-traceability-gate.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsB/C,+CAA+C;AAC/C,eAAO,MAAM,OAAO,iBAAiB,CAAC;AAEtC,qDAAqD;AACrD,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAE1C,iDAAiD;AACjD,eAAO,MAAM,UAAU,aAAa,CAAC;AAErC;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEvE;AA8BD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CAmEtB"}
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
* belongs to `scripts/lisa-github-rulesets.sh`.
|
|
33
33
|
* @module cli/doctor-traceability-gate
|
|
34
34
|
*/
|
|
35
|
-
import { readFile
|
|
35
|
+
import { readFile } from "node:fs/promises";
|
|
36
36
|
import * as path from "node:path";
|
|
37
|
+
import { declareGate, withGate } from "./doctor-gate-recommendation.js";
|
|
37
38
|
const CHECK_NAME = "Work-Item Traceability declared?";
|
|
38
39
|
/**
|
|
39
40
|
* What this check can and cannot see about layer 2.
|
|
@@ -79,13 +80,7 @@ export function declaresTraceability(config) {
|
|
|
79
80
|
* @returns A copy declaring the gate
|
|
80
81
|
*/
|
|
81
82
|
export function withTraceabilityGate(config) {
|
|
82
|
-
return
|
|
83
|
-
...config,
|
|
84
|
-
gates: {
|
|
85
|
-
...config.gates,
|
|
86
|
-
[GATE_ID]: { [GATE_MOMENT]: GATE_LEVEL },
|
|
87
|
-
},
|
|
88
|
-
};
|
|
83
|
+
return withGate(config, GATE_ID, GATE_MOMENT, GATE_LEVEL);
|
|
89
84
|
}
|
|
90
85
|
/**
|
|
91
86
|
* Read the config file, or `null` when there is none.
|
|
@@ -147,10 +142,27 @@ export async function checkTraceabilityGate(targetPath) {
|
|
|
147
142
|
detail: `gates.${GATE_ID} is declared — left as the project set it. ${LAYER_TWO_NOTE}`,
|
|
148
143
|
};
|
|
149
144
|
}
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
await
|
|
145
|
+
// Every write goes through `declareGate`, which refuses to declare a gate
|
|
146
|
+
// whose task it cannot see resolve. Declaring one anyway is what turned a
|
|
147
|
+
// green pipeline red in #2810.
|
|
148
|
+
const declaration = await declareGate({
|
|
149
|
+
targetPath,
|
|
150
|
+
config,
|
|
151
|
+
gateId: GATE_ID,
|
|
152
|
+
moment: GATE_MOMENT,
|
|
153
|
+
level: GATE_LEVEL,
|
|
154
|
+
});
|
|
155
|
+
if (declaration.outcome === "declined") {
|
|
156
|
+
return {
|
|
157
|
+
name: CHECK_NAME,
|
|
158
|
+
status: "warn",
|
|
159
|
+
detail: `gates.${GATE_ID} is undeclared, so a missing Work-Item trailer reds ` +
|
|
160
|
+
`the check and merges anyway. Lisa did NOT declare it for you, ` +
|
|
161
|
+
`because ${declaration.reason} Declaring it now would turn a passing ` +
|
|
162
|
+
`build red, which is a worse place to be than where you are. ` +
|
|
163
|
+
`${LAYER_TWO_NOTE}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
154
166
|
return {
|
|
155
167
|
name: CHECK_NAME,
|
|
156
168
|
status: "warn",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-traceability-gate.js","sourceRoot":"","sources":["../../src/cli/doctor-traceability-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"doctor-traceability-gate.js","sourceRoot":"","sources":["../../src/cli/doctor-traceability-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locate the shipped gate registry inside the running Lisa package.
|
|
3
|
+
* @returns Absolute path to the registry, or null when it cannot be found
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolveGateRegistryPath(): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Import the shipped registry.
|
|
8
|
+
* @returns The registry module, or null when it is not installed
|
|
9
|
+
*/
|
|
10
|
+
export declare function importGateRegistry<T>(): Promise<T | null>;
|
|
11
|
+
//# sourceMappingURL=gate-registry-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-registry-source.d.ts","sourceRoot":"","sources":["../../src/cli/gate-registry-source.ts"],"names":[],"mappings":"AA6CA;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CASvD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAI/D"}
|