@codyswann/lisa 3.52.0 → 3.53.0

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 (116) hide show
  1. package/dist/cli/doctor-declared-contexts.d.ts +32 -0
  2. package/dist/cli/doctor-declared-contexts.d.ts.map +1 -0
  3. package/dist/cli/doctor-declared-contexts.js +144 -0
  4. package/dist/cli/doctor-declared-contexts.js.map +1 -0
  5. package/dist/cli/doctor.d.ts.map +1 -1
  6. package/dist/cli/doctor.js +6 -0
  7. package/dist/cli/doctor.js.map +1 -1
  8. package/dist/cli/gate-report-drift-section.d.ts +8 -0
  9. package/dist/cli/gate-report-drift-section.d.ts.map +1 -0
  10. package/dist/cli/gate-report-drift-section.js +68 -0
  11. package/dist/cli/gate-report-drift-section.js.map +1 -0
  12. package/dist/cli/gate-report-fragment.d.ts.map +1 -1
  13. package/dist/cli/gate-report-fragment.js +4 -0
  14. package/dist/cli/gate-report-fragment.js.map +1 -1
  15. package/dist/cli/gate-report-joins.d.ts +45 -0
  16. package/dist/cli/gate-report-joins.d.ts.map +1 -1
  17. package/dist/cli/gate-report-joins.js +56 -0
  18. package/dist/cli/gate-report-joins.js.map +1 -1
  19. package/dist/cli/gate-report-registry.d.ts +9 -0
  20. package/dist/cli/gate-report-registry.d.ts.map +1 -1
  21. package/dist/cli/gate-report-registry.js +15 -0
  22. package/dist/cli/gate-report-registry.js.map +1 -1
  23. package/dist/cli/gate-report-style.d.ts +1 -1
  24. package/dist/cli/gate-report-style.d.ts.map +1 -1
  25. package/dist/cli/gate-report-style.js +3 -0
  26. package/dist/cli/gate-report-style.js.map +1 -1
  27. package/dist/cli/gate-report-templates.d.ts +22 -0
  28. package/dist/cli/gate-report-templates.d.ts.map +1 -0
  29. package/dist/cli/gate-report-templates.js +110 -0
  30. package/dist/cli/gate-report-templates.js.map +1 -0
  31. package/dist/cli/gate-report-types.d.ts +19 -5
  32. package/dist/cli/gate-report-types.d.ts.map +1 -1
  33. package/dist/cli/gate-report-types.js.map +1 -1
  34. package/dist/cli/gate-report.d.ts +3 -0
  35. package/dist/cli/gate-report.d.ts.map +1 -1
  36. package/dist/cli/gate-report.js +26 -2
  37. package/dist/cli/gate-report.js.map +1 -1
  38. package/dist/core/gate-declaration-drift.d.ts +190 -0
  39. package/dist/core/gate-declaration-drift.d.ts.map +1 -0
  40. package/dist/core/gate-declaration-drift.js +300 -0
  41. package/dist/core/gate-declaration-drift.js.map +1 -0
  42. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  43. package/dist/core/upstream-evidence-manifest.js +12 -1
  44. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  45. package/dist/health/declared-checks-inspection.d.ts +48 -0
  46. package/dist/health/declared-checks-inspection.d.ts.map +1 -0
  47. package/dist/health/declared-checks-inspection.js +154 -0
  48. package/dist/health/declared-checks-inspection.js.map +1 -0
  49. package/dist/health/deterministic-inputs.d.ts +40 -0
  50. package/dist/health/deterministic-inputs.d.ts.map +1 -0
  51. package/dist/health/deterministic-inputs.js +71 -0
  52. package/dist/health/deterministic-inputs.js.map +1 -0
  53. package/dist/health/deterministic.d.ts.map +1 -1
  54. package/dist/health/deterministic.js +10 -45
  55. package/dist/health/deterministic.js.map +1 -1
  56. package/dist/health/ruleset-inspection.d.ts +27 -0
  57. package/dist/health/ruleset-inspection.d.ts.map +1 -1
  58. package/dist/health/ruleset-inspection.js +70 -0
  59. package/dist/health/ruleset-inspection.js.map +1 -1
  60. package/package.json +1 -1
  61. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  63. package/plugins/lisa/.codex-plugin/skills/lisa-doctor/SKILL.md +33 -1
  64. package/plugins/lisa/skills/lisa-doctor/SKILL.md +33 -1
  65. package/plugins/lisa-agy/plugin.json +1 -1
  66. package/plugins/lisa-agy/skills/lisa-doctor/SKILL.md +33 -1
  67. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  69. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  70. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-copilot/skills/lisa-doctor/SKILL.md +33 -1
  74. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-cursor/skills/lisa-doctor/SKILL.md +33 -1
  76. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  78. package/plugins/lisa-expo-agy/plugin.json +1 -1
  79. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  83. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  84. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  88. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  89. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  93. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  94. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  98. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  99. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  100. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  103. package/plugins/lisa-rails-agy/plugin.json +1 -1
  104. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  105. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  108. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  109. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  110. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  113. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  114. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  115. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  116. package/plugins/src/base/skills/lisa-doctor/SKILL.md +33 -1
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Hold the gates declaration against the live ruleset, on a path a machine
3
+ * takes on its own.
4
+ *
5
+ * The comparison itself was not the missing piece. A finished reconciler has
6
+ * existed for some time, unit- and mutation-covered, reporting MISSING, EXTRA,
7
+ * MATCHED and a distinct UNPROVEN — and nothing invoked it. Its only callers
8
+ * were copies of prose in a skill telling a human to type the command, which
9
+ * makes it indistinguishable from a control that was never written. This module
10
+ * is the same comparison sitting on a scheduled, machine-invoked path.
11
+ *
12
+ * Two rules it does not get to bend:
13
+ *
14
+ * - **A source this run could not read is `warn`, never `pass`.** A comparison
15
+ * that silently passes when it could not reach the live ruleset is the exact
16
+ * defect this check exists to catch, sited on the check itself.
17
+ * - **Nothing here proposes removing a live required context.** A context no
18
+ * declaration asks for is reported so it can be told apart from a third-party
19
+ * check, not so it can be pruned. The remedy vocabulary in
20
+ * `core/gate-declaration-drift` structurally contains no removal.
21
+ * @module health/declared-checks-inspection
22
+ */
23
+ import { type DeclarationDriftReport } from "../core/gate-declaration-drift.js";
24
+ import type { HealthFinding } from "./contract.js";
25
+ import { type RulesetReader } from "./ruleset-inspection.js";
26
+ /**
27
+ * The finding one completed comparison produces.
28
+ *
29
+ * A contradiction fails: the two surfaces state opposite things, and one of
30
+ * them is wrong. A gap warns: the declaration is silent, and silence is not
31
+ * permission to stop requiring the context — the registry still carries gates
32
+ * whose jobs run with no declaration anywhere, so reading silence as a defect
33
+ * of the ruleset would point the operator at the wrong file.
34
+ * @param report - The completed comparison
35
+ * @returns The finding
36
+ */
37
+ export declare function declaredChecksFinding(report: DeclarationDriftReport): HealthFinding;
38
+ /**
39
+ * Compare the gates declaration with the live ruleset.
40
+ * @param projectRoot - Canonical host root
41
+ * @param config - Safe project config
42
+ * @param reader - Structured remote ruleset reader
43
+ * @param timeoutMs - Remaining shared deadline
44
+ * @param signal - Shared cancellation signal
45
+ * @returns The finding, never a pass on an unread source
46
+ */
47
+ export declare function declaredChecksDriftFinding(projectRoot: string, config: Readonly<Record<string, unknown>>, reader: RulesetReader, timeoutMs: number, signal: AbortSignal): Promise<HealthFinding>;
48
+ //# sourceMappingURL=declared-checks-inspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declared-checks-inspection.d.ts","sourceRoot":"","sources":["../../src/health/declared-checks-inspection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAiCjC;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,sBAAsB,GAC7B,aAAa,CAmCf;AAED;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAkDxB"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Hold the gates declaration against the live ruleset, on a path a machine
3
+ * takes on its own.
4
+ *
5
+ * The comparison itself was not the missing piece. A finished reconciler has
6
+ * existed for some time, unit- and mutation-covered, reporting MISSING, EXTRA,
7
+ * MATCHED and a distinct UNPROVEN — and nothing invoked it. Its only callers
8
+ * were copies of prose in a skill telling a human to type the command, which
9
+ * makes it indistinguishable from a control that was never written. This module
10
+ * is the same comparison sitting on a scheduled, machine-invoked path.
11
+ *
12
+ * Two rules it does not get to bend:
13
+ *
14
+ * - **A source this run could not read is `warn`, never `pass`.** A comparison
15
+ * that silently passes when it could not reach the live ruleset is the exact
16
+ * defect this check exists to catch, sited on the check itself.
17
+ * - **Nothing here proposes removing a live required context.** A context no
18
+ * declaration asks for is reported so it can be told apart from a third-party
19
+ * check, not so it can be pruned. The remedy vocabulary in
20
+ * `core/gate-declaration-drift` structurally contains no removal.
21
+ * @module health/declared-checks-inspection
22
+ */
23
+ import { classifyDeclarationDrift, contextOwners, } from "../core/gate-declaration-drift.js";
24
+ import { loadGateRegistry } from "../cli/gate-report-registry.js";
25
+ import { deterministicFinding, namedReason } from "./finding-utils.js";
26
+ import { liveRequiredContexts, } from "./ruleset-inspection.js";
27
+ /** This check's stable id. */
28
+ const CHECK = "github.declared-checks";
29
+ /** The workflow whose name prefixes a run gate's status context. */
30
+ const QUALITY_WORKFLOW_NAME = "🔍 Quality Checks";
31
+ /** Repository slug parts this check will address. */
32
+ const REPOSITORY_PART = /^[A-Za-z0-9_.-]{1,100}$/u;
33
+ /**
34
+ * The repository this check would read, when the settings file names one.
35
+ * @param config - Safe project config
36
+ * @returns The owner and repository, or undefined
37
+ */
38
+ function githubTarget(config) {
39
+ const github = config.github;
40
+ if (github === null || typeof github !== "object" || Array.isArray(github)) {
41
+ return undefined;
42
+ }
43
+ const owner = Reflect.get(github, "org");
44
+ const repo = Reflect.get(github, "repo");
45
+ return typeof owner === "string" &&
46
+ typeof repo === "string" &&
47
+ REPOSITORY_PART.test(owner) &&
48
+ REPOSITORY_PART.test(repo)
49
+ ? { owner, repo }
50
+ : undefined;
51
+ }
52
+ /**
53
+ * The finding one completed comparison produces.
54
+ *
55
+ * A contradiction fails: the two surfaces state opposite things, and one of
56
+ * them is wrong. A gap warns: the declaration is silent, and silence is not
57
+ * permission to stop requiring the context — the registry still carries gates
58
+ * whose jobs run with no declaration anywhere, so reading silence as a defect
59
+ * of the ruleset would point the operator at the wrong file.
60
+ * @param report - The completed comparison
61
+ * @returns The finding
62
+ */
63
+ export function declaredChecksFinding(report) {
64
+ const contradictions = report.entries.filter(entry => entry.verdict === "declared-not-enforced" ||
65
+ entry.verdict === "enforced-declared-off");
66
+ if (contradictions.length > 0) {
67
+ return deterministicFinding(CHECK, "fail", namedReason("Gates declarations contradict live branch protection", contradictions.map(entry => `${entry.context} (${entry.verdict})`)));
68
+ }
69
+ const gaps = report.entries.filter(entry => entry.verdict === "enforced-undeclared" ||
70
+ entry.verdict === "enforced-declared-optional");
71
+ return gaps.length === 0
72
+ ? deterministicFinding(CHECK, "pass", "Every context live branch protection requires is governed by a gates declaration.")
73
+ : deterministicFinding(CHECK, "warn", namedReason("Live branch protection requires contexts no declaration governs", gaps.map(entry => `${entry.context} (${entry.verdict})`)));
74
+ }
75
+ /**
76
+ * Compare the gates declaration with the live ruleset.
77
+ * @param projectRoot - Canonical host root
78
+ * @param config - Safe project config
79
+ * @param reader - Structured remote ruleset reader
80
+ * @param timeoutMs - Remaining shared deadline
81
+ * @param signal - Shared cancellation signal
82
+ * @returns The finding, never a pass on an unread source
83
+ */
84
+ export async function declaredChecksDriftFinding(projectRoot, config, reader, timeoutMs, signal) {
85
+ const target = githubTarget(config);
86
+ if (target === undefined) {
87
+ return deterministicFinding(CHECK, "warn", "Unproven: no GitHub repository is configured, so the gates declarations were not held against live branch protection.");
88
+ }
89
+ const registry = await loadGateRegistry();
90
+ if (registry === null) {
91
+ return deterministicFinding(CHECK, "warn", "Unproven: Lisa's shipped gate registry could not be located, so no declaration could be resolved into a status context.");
92
+ }
93
+ const actual = await readLive(reader, {
94
+ owner: target.owner,
95
+ repo: target.repo,
96
+ projectRoot,
97
+ timeoutMs,
98
+ signal,
99
+ });
100
+ if (actual === undefined) {
101
+ return deterministicFinding(CHECK, "warn", "Unproven: live branch protection could not be read within the deterministic deadline, so nothing here claims a declaration does or does not match it.");
102
+ }
103
+ const gates = readGatesSafely(registry, projectRoot);
104
+ if (gates === null) {
105
+ return deterministicFinding(CHECK, "warn", "Unproven: the gates block could not be read, so the contexts it implies could not be compared with live branch protection.");
106
+ }
107
+ return declaredChecksFinding(classifyDeclarationDrift({
108
+ surface: "live-ruleset",
109
+ owners: contextOwners({
110
+ registry,
111
+ gates,
112
+ workflowName: QUALITY_WORKFLOW_NAME,
113
+ }),
114
+ enforced: liveRequiredContexts(actual),
115
+ }));
116
+ }
117
+ /**
118
+ * Call the ruleset reader, surviving a reader that throws synchronously.
119
+ *
120
+ * `.catch()` on the returned promise handles a rejection and nothing else; a
121
+ * reader whose failure happens before it returns one would take the entire
122
+ * health run down, turning "this source was unreadable" into no report at all.
123
+ * @param reader - Structured remote ruleset reader
124
+ * @param options - Reader arguments
125
+ * @param options.owner - Repository owner
126
+ * @param options.repo - Repository name
127
+ * @param options.projectRoot - Canonical host root
128
+ * @param options.timeoutMs - Remaining shared deadline
129
+ * @param options.signal - Shared cancellation signal
130
+ * @returns The rulesets, or undefined when they could not be read
131
+ */
132
+ async function readLive(reader, options) {
133
+ try {
134
+ return await reader(options.owner, options.repo, options.projectRoot, options.timeoutMs, options.signal);
135
+ }
136
+ catch {
137
+ return undefined;
138
+ }
139
+ }
140
+ /**
141
+ * Read the gates block, keeping a refusal distinguishable from an empty one.
142
+ * @param registry - The shipped registry
143
+ * @param projectRoot - Canonical host root
144
+ * @returns The gates block, or null when it could not be read
145
+ */
146
+ function readGatesSafely(registry, projectRoot) {
147
+ try {
148
+ return registry.readGates(projectRoot).gates;
149
+ }
150
+ catch {
151
+ return null;
152
+ }
153
+ }
154
+ //# sourceMappingURL=declared-checks-inspection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declared-checks-inspection.js","sourceRoot":"","sources":["../../src/health/declared-checks-inspection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The two confined project reads every deterministic probe is built on.
3
+ *
4
+ * Both preserve a distinction the checks above them depend on and cannot
5
+ * recover once lost: a settings file that is MISSING is a different finding
6
+ * from one that is present and unreadable, and a JSON file that will not parse
7
+ * is a different finding from one that is not there. Collapsing either into
8
+ * "absent" is how a health run reports a clean project that it simply could
9
+ * not read.
10
+ * @module health/deterministic-inputs
11
+ */
12
+ import type { SyncReadDependencies } from "../sync/config-sync.js";
13
+ import type { HealthConfigState } from "./project-probes.js";
14
+ import type { RulesetReader } from "./ruleset-inspection.js";
15
+ /**
16
+ * Read config while preserving missing vs malformed state.
17
+ * @param projectRoot - Canonical host project root
18
+ * @returns Whether the settings file is present, readable, and its contents
19
+ */
20
+ export declare function loadConfigState(projectRoot: string): Promise<HealthConfigState>;
21
+ /**
22
+ * Confined JSON/path readers for the shared sync planner.
23
+ * @param projectRoot - Canonical host project root
24
+ * @returns Readers that never escape the project root
25
+ */
26
+ export declare function safeSyncReads(projectRoot: string): SyncReadDependencies;
27
+ /**
28
+ * Share one ruleset read between the probes that both need it.
29
+ *
30
+ * Two checks now compare against the same live rulesets — one against Lisa's
31
+ * template, one against the project's declarations — and reading them twice
32
+ * would double a bounded N+1 of GitHub calls inside one shared deadline for an
33
+ * answer that cannot differ between them. A rejection is shared too, on
34
+ * purpose: both probes should report the same source as unread rather than
35
+ * disagree about whether it could be reached.
36
+ * @param reader - The underlying reader
37
+ * @returns A reader that calls through at most once per repository
38
+ */
39
+ export declare function shareRulesetReader(reader: RulesetReader): RulesetReader;
40
+ //# sourceMappingURL=deterministic-inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deterministic-inputs.d.ts","sourceRoot":"","sources":["../../src/health/deterministic-inputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAO7D;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAiB5B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,CAevE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAWvE"}
@@ -0,0 +1,71 @@
1
+ import { projectPathKind, readProjectJsonObject, readProjectText, } from "./read-only-fs.js";
2
+ /**
3
+ * Read config while preserving missing vs malformed state.
4
+ * @param projectRoot - Canonical host project root
5
+ * @returns Whether the settings file is present, readable, and its contents
6
+ */
7
+ export async function loadConfigState(projectRoot) {
8
+ const kind = await projectPathKind(projectRoot, ".lisa.config.json");
9
+ if (kind === "missing") {
10
+ return { config: {}, present: false, readable: false };
11
+ }
12
+ if (kind !== "file") {
13
+ return { config: {}, present: true, readable: false };
14
+ }
15
+ try {
16
+ const config = await readProjectJsonObject(projectRoot, ".lisa.config.json");
17
+ return { config: config ?? {}, present: true, readable: true };
18
+ }
19
+ catch {
20
+ return { config: {}, present: true, readable: false };
21
+ }
22
+ }
23
+ /**
24
+ * Confined JSON/path readers for the shared sync planner.
25
+ * @param projectRoot - Canonical host project root
26
+ * @returns Readers that never escape the project root
27
+ */
28
+ export function safeSyncReads(projectRoot) {
29
+ return {
30
+ readJson: async (relativePath) => {
31
+ const text = await readProjectText(projectRoot, relativePath);
32
+ if (text === undefined)
33
+ return null;
34
+ try {
35
+ return JSON.parse(text);
36
+ }
37
+ catch (error) {
38
+ if (error instanceof SyntaxError)
39
+ return null;
40
+ throw error;
41
+ }
42
+ },
43
+ pathExists: async (relativePath) => (await projectPathKind(projectRoot, relativePath)) !== "missing",
44
+ };
45
+ }
46
+ /**
47
+ * Share one ruleset read between the probes that both need it.
48
+ *
49
+ * Two checks now compare against the same live rulesets — one against Lisa's
50
+ * template, one against the project's declarations — and reading them twice
51
+ * would double a bounded N+1 of GitHub calls inside one shared deadline for an
52
+ * answer that cannot differ between them. A rejection is shared too, on
53
+ * purpose: both probes should report the same source as unread rather than
54
+ * disagree about whether it could be reached.
55
+ * @param reader - The underlying reader
56
+ * @returns A reader that calls through at most once per repository
57
+ */
58
+ export function shareRulesetReader(reader) {
59
+ const inFlight = new Map();
60
+ return (owner, repo, projectRoot, timeoutMs, signal) => {
61
+ const key = `${owner}/${repo}`;
62
+ const existing = inFlight.get(key);
63
+ if (existing !== undefined)
64
+ return existing;
65
+ const started = reader(owner, repo, projectRoot, timeoutMs, signal);
66
+ // eslint-disable-next-line functional/immutable-data -- the cache is the point
67
+ inFlight.set(key, started);
68
+ return started;
69
+ };
70
+ }
71
+ //# sourceMappingURL=deterministic-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deterministic-inputs.js","sourceRoot":"","sources":["../../src/health/deterministic-inputs.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IACrE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CACxC,WAAW,EACX,mBAAmB,CACpB,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACxD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,YAAoB,EAAE,EAAE;YACvC,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAC9D,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACpC,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;YACrC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,WAAW;oBAAE,OAAO,IAAI,CAAC;gBAC9C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,YAAoB,EAAE,EAAE,CACzC,CAAC,MAAM,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,KAAK,SAAS;KACnE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAqB;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqC,CAAC;IAC9D,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QACrD,MAAM,GAAG,GAAG,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACpE,+EAA+E;QAC/E,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"deterministic.d.ts","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAchC,OAAO,EACL,kBAAkB,EAElB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAQjC;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IACtD,uDAAuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;CAC1C;AAqOD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"deterministic.d.ts","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAgBvB,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAShC,OAAO,EACL,kBAAkB,EAElB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAQjC;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IACtD,uDAAuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;CAC1C;AAsMD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -3,15 +3,16 @@
3
3
  import { lstat, realpath } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import { runConfigSync, } from "../sync/config-sync.js";
6
+ import { runConfigSync } from "../sync/config-sync.js";
7
7
  import { summarizeHealthFindings, validateHealthResult, } from "./contract.js";
8
8
  import { HealthDeadline } from "./deadline.js";
9
+ import { declaredChecksDriftFinding } from "./declared-checks-inspection.js";
10
+ import { loadConfigState, safeSyncReads, shareRulesetReader, } from "./deterministic-inputs.js";
9
11
  import { deterministicFinding } from "./finding-utils.js";
10
12
  import { hookFinding, managedTemplateFinding, packageFinding, pluginFinding, workflowFinding, } from "./governance-probes.js";
11
13
  import { readCoreHooksPath } from "./hook-inspection.js";
12
14
  import { readInstalledClaudePlugins, } from "./plugin-inspection.js";
13
15
  import { configFindings, instructionFinding, projectStateFinding, starterFinding, wikiFinding, } from "./project-probes.js";
14
- import { projectPathKind, readProjectJsonObject, readProjectText, } from "./read-only-fs.js";
15
16
  import { readGithubRulesets, rulesetFinding, } from "./ruleset-inspection.js";
16
17
  import { detectHealthProjectShape, } from "./template-inspection.js";
17
18
  const DEFAULT_DEADLINE_MS = 110_000;
@@ -28,6 +29,7 @@ const CHECKS = [
28
29
  { check: "plugins.current", unavailable: "warn" },
29
30
  { check: "ci.workflows", unavailable: "fail" },
30
31
  { check: "github.rulesets", unavailable: "warn" },
32
+ { check: "github.declared-checks", unavailable: "warn" },
31
33
  ];
32
34
  /**
33
35
  * Stable fallback when a check cannot complete inside the shared deadline.
@@ -37,48 +39,6 @@ const CHECKS = [
37
39
  function unavailableFinding(check, status) {
38
40
  return deterministicFinding(check, status, `${check} could not be safely observed within the deterministic deadline.`);
39
41
  }
40
- /**
41
- * Read config while preserving missing vs malformed state.
42
- * @param projectRoot
43
- */
44
- async function loadConfigState(projectRoot) {
45
- const kind = await projectPathKind(projectRoot, ".lisa.config.json");
46
- if (kind === "missing") {
47
- return { config: {}, present: false, readable: false };
48
- }
49
- if (kind !== "file") {
50
- return { config: {}, present: true, readable: false };
51
- }
52
- try {
53
- const config = await readProjectJsonObject(projectRoot, ".lisa.config.json");
54
- return { config: config ?? {}, present: true, readable: true };
55
- }
56
- catch {
57
- return { config: {}, present: true, readable: false };
58
- }
59
- }
60
- /**
61
- * Confined JSON/path readers for the shared sync planner.
62
- * @param projectRoot
63
- */
64
- function safeSyncReads(projectRoot) {
65
- return {
66
- readJson: async (relativePath) => {
67
- const text = await readProjectText(projectRoot, relativePath);
68
- if (text === undefined)
69
- return null;
70
- try {
71
- return JSON.parse(text);
72
- }
73
- catch (error) {
74
- if (error instanceof SyntaxError)
75
- return null;
76
- throw error;
77
- }
78
- },
79
- pathExists: async (relativePath) => (await projectPathKind(projectRoot, relativePath)) !== "missing",
80
- };
81
- }
82
42
  /**
83
43
  * Build a validated immutable HealthResult from ordered findings.
84
44
  * @param started
@@ -132,6 +92,7 @@ function probes(roots, configState, shape, deadline, options) {
132
92
  dryRun: true,
133
93
  reads: safeSyncReads(roots.projectRoot),
134
94
  });
95
+ const rulesets = shareRulesetReader(options.readRulesets ?? readGithubRulesets);
135
96
  return [
136
97
  {
137
98
  ...CHECKS[0],
@@ -164,7 +125,11 @@ function probes(roots, configState, shape, deadline, options) {
164
125
  },
165
126
  {
166
127
  ...CHECKS[11],
167
- run: () => rulesetFinding(roots.lisaRoot, roots.projectRoot, safeShape.types, configState.config, options.readRulesets ?? readGithubRulesets, deadline.remainingMs(), deadline.signal),
128
+ run: () => rulesetFinding(roots.lisaRoot, roots.projectRoot, safeShape.types, configState.config, rulesets, deadline.remainingMs(), deadline.signal),
129
+ },
130
+ {
131
+ ...CHECKS[12],
132
+ run: () => declaredChecksDriftFinding(roots.projectRoot, configState.config, rulesets, deadline.remainingMs(), deadline.signal),
168
133
  },
169
134
  ];
170
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deterministic.js","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deterministic.js","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ProjectType } from "../core/config.js";
2
+ import type { EnforcedContext } from "../core/gate-declaration-drift.js";
2
3
  import type { HealthFinding } from "./contract.js";
3
4
  /** Material ruleset fields health compares. */
4
5
  export interface HealthRuleset {
@@ -36,6 +37,32 @@ export declare const readGithubRulesets: RulesetReader;
36
37
  * @returns Expected rulesets sorted by name
37
38
  */
38
39
  export declare function expectedRulesets(lisaRoot: string, projectRoot: string, types: readonly ProjectType[], config: Readonly<Record<string, unknown>>): Promise<readonly HealthRuleset[]>;
40
+ /**
41
+ * The required status contexts one project's ruleset templates name, with the
42
+ * file each requirement was read from.
43
+ *
44
+ * `expectedRulesets` already normalizes templates the way apply does, but it
45
+ * answers with whole ruleset documents and loses which file said what. The
46
+ * declaration comparison has to name the template file — "this context is
47
+ * required and no declaration asks for it" is not actionable without it — so
48
+ * this walk keeps the attribution instead.
49
+ *
50
+ * Returning an empty list is meaningful and must not be read as "nothing is
51
+ * enforced": callers treat an empty result as a source they could not reach,
52
+ * because a comparison against nothing reports every declaration as unenforced.
53
+ * @param lisaRoot - Lisa package root
54
+ * @param projectRoot - Canonical host root
55
+ * @param types - Canonically ordered project types
56
+ * @param config - Safe project config
57
+ * @returns Required contexts with their ruleset and source file
58
+ */
59
+ export declare function expectedRequiredContexts(lisaRoot: string, projectRoot: string, types: readonly ProjectType[], config: Readonly<Record<string, unknown>>): Promise<readonly EnforcedContext[]>;
60
+ /**
61
+ * The required status contexts a live ruleset payload names.
62
+ * @param actual - Rulesets as the repository actually holds them
63
+ * @returns Required contexts with their ruleset, sorted
64
+ */
65
+ export declare function liveRequiredContexts(actual: readonly HealthRuleset[]): readonly EnforcedContext[];
39
66
  /**
40
67
  * Compare expected and observed material ruleset documents.
41
68
  * @param expected
@@ -1 +1 @@
1
- {"version":3,"file":"ruleset-inspection.d.ts","sourceRoot":"","sources":["../../src/health/ruleset-inspection.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA0BnD,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;AAEvC,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAsED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAsChC,CAAC;AA8LF;;;;;;;GAOG;AAEH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAmCnC;AAwJD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,YAAY,CAiCd;AAuBD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAsDxB"}
1
+ {"version":3,"file":"ruleset-inspection.d.ts","sourceRoot":"","sources":["../../src/health/ruleset-inspection.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA+BnD,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;AAEvC,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAsED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAsChC,CAAC;AA8LF;;;;;;;GAOG;AAEH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAmCnC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CA4CrC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,SAAS,eAAe,EAAE,CAW5B;AAwJD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,YAAY,CAiCd;AAuBD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAsDxB"}
@@ -13,6 +13,10 @@ const ACTIONS_INTEGRATION_ID = 15_368;
13
13
  const REPOSITORY_PART = /^[A-Za-z0-9_.-]{1,100}$/u;
14
14
  const RULESET_CHECK = "github.rulesets";
15
15
  const WARN = "warn";
16
+ /** Where a per-repo required-check opt-in is declared. */
17
+ const CONFIGURED_CHECK_SOURCE = ".lisa.config.json \u2192 github.rulesets.addRequiredChecks";
18
+ /** Where a live requirement was read from. */
19
+ const LIVE_CHECK_SOURCE = "the repository's live rulesets";
16
20
  /**
17
21
  * Return a sorted copy without mutating caller-owned input.
18
22
  * @param items - Caller-owned items
@@ -299,6 +303,72 @@ export async function expectedRulesets(lisaRoot, projectRoot, types, config) {
299
303
  }
300
304
  return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));
301
305
  }
306
+ /**
307
+ * The required status contexts one project's ruleset templates name, with the
308
+ * file each requirement was read from.
309
+ *
310
+ * `expectedRulesets` already normalizes templates the way apply does, but it
311
+ * answers with whole ruleset documents and loses which file said what. The
312
+ * declaration comparison has to name the template file — "this context is
313
+ * required and no declaration asks for it" is not actionable without it — so
314
+ * this walk keeps the attribution instead.
315
+ *
316
+ * Returning an empty list is meaningful and must not be read as "nothing is
317
+ * enforced": callers treat an empty result as a source they could not reach,
318
+ * because a comparison against nothing reports every declaration as unenforced.
319
+ * @param lisaRoot - Lisa package root
320
+ * @param projectRoot - Canonical host root
321
+ * @param types - Canonically ordered project types
322
+ * @param config - Safe project config
323
+ * @returns Required contexts with their ruleset and source file
324
+ */
325
+ export async function expectedRequiredContexts(lisaRoot, projectRoot, types, config) {
326
+ const hasWorkflows = (await projectPathKind(projectRoot, path.join(".github", "workflows"))) ===
327
+ "directory";
328
+ const dropped = droppedChecks(config);
329
+ const byName = new Map();
330
+ for (const type of ["all", ...types]) {
331
+ const directory = path.join(lisaRoot, type, "github-rulesets");
332
+ try {
333
+ for (const file of await listFilesRecursive(directory)) {
334
+ const parsed = JSON.parse(await readFile(file, "utf8"));
335
+ const projected = projectRuleset(parsed);
336
+ const added = addedChecks(config, projected.name);
337
+ const rules = normalizeExpectedRules(withAddedChecks(projected.rules, added), hasWorkflows, dropped);
338
+ const addedContexts = new Set(added.map(check => String(check.context)));
339
+ const template = path
340
+ .relative(lisaRoot, file)
341
+ .split(path.sep)
342
+ .join(path.posix.sep);
343
+ // eslint-disable-next-line functional/immutable-data -- most-specific stack wins, matching expectedRulesets
344
+ byName.set(projected.name, [...requiredStatusChecksByContext(rules).keys()].map(context => ({
345
+ context,
346
+ ruleset: projected.name,
347
+ source: addedContexts.has(context)
348
+ ? CONFIGURED_CHECK_SOURCE
349
+ : template,
350
+ })));
351
+ }
352
+ }
353
+ catch (error) {
354
+ if (error.code !== "ENOENT")
355
+ throw error;
356
+ }
357
+ }
358
+ return sortedCopy([...byName.values()].flat(), (left, right) => left.context.localeCompare(right.context));
359
+ }
360
+ /**
361
+ * The required status contexts a live ruleset payload names.
362
+ * @param actual - Rulesets as the repository actually holds them
363
+ * @returns Required contexts with their ruleset, sorted
364
+ */
365
+ export function liveRequiredContexts(actual) {
366
+ return sortedCopy(actual.flatMap(ruleset => [...requiredStatusChecksByContext(ruleset.rules).keys()].map(context => ({
367
+ context,
368
+ ruleset: ruleset.name,
369
+ source: LIVE_CHECK_SOURCE,
370
+ }))), (left, right) => left.context.localeCompare(right.context));
371
+ }
302
372
  /**
303
373
  * Canonicalize semantically unordered JSON objects and arrays.
304
374
  * @param value