@codyswann/lisa 3.48.7 → 3.49.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 (65) hide show
  1. package/dist/cli/doctor-hook-copy-parity.d.ts +8 -0
  2. package/dist/cli/doctor-hook-copy-parity.d.ts.map +1 -0
  3. package/dist/cli/doctor-hook-copy-parity.js +121 -0
  4. package/dist/cli/doctor-hook-copy-parity.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/core/hook-copy-parity.d.ts +81 -0
  9. package/dist/core/hook-copy-parity.d.ts.map +1 -0
  10. package/dist/core/hook-copy-parity.js +111 -0
  11. package/dist/core/hook-copy-parity.js.map +1 -0
  12. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  13. package/dist/core/upstream-evidence-manifest.js +8 -0
  14. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  15. package/package.json +1 -1
  16. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  18. package/plugins/lisa-agy/plugin.json +1 -1
  19. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  22. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa-expo-agy/plugin.json +1 -1
  29. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  48. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  49. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  53. package/plugins/lisa-rails-agy/plugin.json +1 -1
  54. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  59. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  63. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  64. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
@@ -0,0 +1,8 @@
1
+ import type { DoctorCheck } from "./doctor.js";
2
+ /**
3
+ * Report hooks whose tracked copies declare different features.
4
+ * @param targetPath - Project path to inspect
5
+ * @returns Doctor check result
6
+ */
7
+ export declare function checkHookCopyParity(targetPath: string): Promise<DoctorCheck>;
8
+ //# sourceMappingURL=doctor-hook-copy-parity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-hook-copy-parity.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-hook-copy-parity.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA2E/C;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CAgDtB"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Report sibling copies of one git hook that disagree about a declared feature.
3
+ *
4
+ * Answers a question no other check asks. The Lisa-owned artifact check
5
+ * (`doctor-lisa-owned-artifacts`) compares one destination path in a project
6
+ * against the copies the package ships for it — "is this host running a stale
7
+ * copy of what we shipped?". This asks the orthogonal question: "do the copies
8
+ * inside ONE tree agree with each other?" A second copy at a different path,
9
+ * in a directory the package does not ship, is invisible to the first check by
10
+ * construction and was invisible for four weeks (CodySwannGT/lisa#2847).
11
+ *
12
+ * Naturally quiet in a host project, where each hook has exactly one tracked
13
+ * copy and there is nothing to disagree.
14
+ * @module cli/doctor-hook-copy-parity
15
+ */
16
+ import { execFile } from "node:child_process";
17
+ import { readFile } from "node:fs/promises";
18
+ import * as path from "node:path";
19
+ import { promisify } from "node:util";
20
+ import { declaredHookFeatures, deriveHookCopyGroups, describeHookCopyFinding, findHookCopyDrift, } from "../core/hook-copy-parity.js";
21
+ const CHECK_NAME = "Hook copies agree?";
22
+ const GIT_TIMEOUT_MS = 10_000;
23
+ const GIT_MAX_BUFFER_BYTES = 8 * 1024 * 1024;
24
+ const MAX_REPORTED_FINDINGS = 5;
25
+ const run = promisify(execFile);
26
+ /**
27
+ * Every path git tracks in a checkout.
28
+ * @param targetPath - Project path to inspect
29
+ * @returns Repo-relative tracked paths, or undefined when git cannot answer
30
+ */
31
+ async function trackedPaths(targetPath) {
32
+ try {
33
+ const { stdout } = await run("git", ["ls-files", "-z"], {
34
+ cwd: targetPath,
35
+ maxBuffer: GIT_MAX_BUFFER_BYTES,
36
+ timeout: GIT_TIMEOUT_MS,
37
+ });
38
+ return stdout.split("\0").filter(entry => entry.length > 0);
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ }
44
+ /**
45
+ * Read one hook copy and extract what it declares.
46
+ *
47
+ * A copy that cannot be read is reported as declaring nothing rather than
48
+ * dropped: dropping it would let an unreadable copy silently leave the roster,
49
+ * which is the failure this check exists to prevent.
50
+ * @param targetPath - Project root
51
+ * @param relative - Repo-relative path of the copy
52
+ * @returns The copy and its declared features
53
+ */
54
+ async function readHookCopy(targetPath, relative) {
55
+ try {
56
+ const source = await readFile(path.join(targetPath, relative), "utf8");
57
+ return { path: relative, features: declaredHookFeatures(source) };
58
+ }
59
+ catch {
60
+ return { path: relative, features: [] };
61
+ }
62
+ }
63
+ /**
64
+ * Collect every disagreement between sibling copies of a hook in one checkout.
65
+ * @param targetPath - Project path to inspect
66
+ * @param paths - Repo-relative tracked paths
67
+ * @returns Findings across every hook with more than one copy
68
+ */
69
+ async function collectFindings(targetPath, paths) {
70
+ const groups = deriveHookCopyGroups(paths).filter(group => group.paths.length > 1);
71
+ const perGroup = await Promise.all(groups.map(async (group) => {
72
+ const copies = await Promise.all(group.paths.map(relative => readHookCopy(targetPath, relative)));
73
+ return findHookCopyDrift(group.hook, copies);
74
+ }));
75
+ return perGroup.flat();
76
+ }
77
+ /**
78
+ * Report hooks whose tracked copies declare different features.
79
+ * @param targetPath - Project path to inspect
80
+ * @returns Doctor check result
81
+ */
82
+ export async function checkHookCopyParity(targetPath) {
83
+ const paths = await trackedPaths(targetPath);
84
+ if (paths === undefined) {
85
+ return {
86
+ name: CHECK_NAME,
87
+ status: "warn",
88
+ detail: "Could not list tracked files, so sibling hook copies were not compared. " +
89
+ "This is not a pass — run `lisa doctor` from inside a git checkout",
90
+ };
91
+ }
92
+ const multiCopy = deriveHookCopyGroups(paths).filter(group => group.paths.length > 1);
93
+ if (multiCopy.length === 0) {
94
+ return {
95
+ name: CHECK_NAME,
96
+ status: "ok",
97
+ detail: "No hook has more than one tracked copy",
98
+ };
99
+ }
100
+ const findings = await collectFindings(targetPath, paths);
101
+ if (findings.length === 0) {
102
+ const copies = multiCopy.reduce((total, group) => total + group.paths.length, 0);
103
+ return {
104
+ name: CHECK_NAME,
105
+ status: "ok",
106
+ detail: `${copies} tracked copies across ${multiCopy.length} hook(s) declare the same features`,
107
+ };
108
+ }
109
+ const shown = findings
110
+ .slice(0, MAX_REPORTED_FINDINGS)
111
+ .map(describeHookCopyFinding);
112
+ const more = findings.length > MAX_REPORTED_FINDINGS
113
+ ? ` (+${findings.length - MAX_REPORTED_FINDINGS} more)`
114
+ : "";
115
+ return {
116
+ name: CHECK_NAME,
117
+ status: "fail",
118
+ detail: `${findings.length} feature(s) differ between copies of the same hook: ${shown.join("; ")}${more}`,
119
+ };
120
+ }
121
+ //# sourceMappingURL=doctor-hook-copy-parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-hook-copy-parity.js","sourceRoot":"","sources":["../../src/cli/doctor-hook-copy-parity.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAmBnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAMzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,mDAAmD;AACnD,KAAK,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAO3C,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sCAAsC;AACtC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,KAAK,CAAC;IACxB,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;CACjD;AAaD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAChD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,WAAW,CAAC,CAyBtB;AA4MD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,aAAa,EACtB,YAAY,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAC7C,OAAO,CAAC,YAAY,CAAC,CA2EvB"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAmBnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,mDAAmD;AACnD,KAAK,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAO3C,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sCAAsC;AACtC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,KAAK,CAAC;IACxB,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;CACjD;AAaD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAChD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,WAAW,CAAC,CAyBtB;AA4MD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,aAAa,EACtB,YAAY,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAC7C,OAAO,CAAC,YAAY,CAAC,CAgFvB"}
@@ -23,6 +23,7 @@ import { checkApplyFailure } from "./doctor-apply-failure.js";
23
23
  import { renderDoctorResult } from "./doctor-render.js";
24
24
  import { checkSkipJobsMigration } from "./doctor-skip-jobs-migration.js";
25
25
  import { checkTraceabilityGate } from "./doctor-traceability-gate.js";
26
+ import { checkHookCopyParity } from "./doctor-hook-copy-parity.js";
26
27
  import { checkWorktreeHygiene } from "./doctor-worktree-hygiene.js";
27
28
  import { checkWorktreeWorkAtRisk } from "./doctor-worktree-work-at-risk.js";
28
29
  import { STARTERS } from "./starters.js";
@@ -306,6 +307,11 @@ export async function runDoctor(targetPath, options, dependencies = {}) {
306
307
  // Static answer to a runtime failure that is deliberately silent: an
307
308
  // incomplete serialize opt-in warns at 2am on a green job and nowhere else.
308
309
  await checkSerializeLegsContract(resolvedTarget),
310
+ // Sibling copies of one hook inside THIS tree, which the Lisa-owned
311
+ // artifact check cannot see: its axis is host copy vs shipped package copy
312
+ // for one destination, so a second copy at another path is outside it by
313
+ // construction (CodySwannGT/lisa#2847).
314
+ await checkHookCopyParity(resolvedTarget),
309
315
  await checkWorktreeHygiene(resolvedTarget),
310
316
  // Immediately after the count check, and deliberately separate from it.
311
317
  // Hygiene answers "how many checkouts is every crawler walking past"; this
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Sibling copies of one git hook, derived from the tree rather than written down.
3
+ *
4
+ * Three tracked copies of the pre-push hook existed in this repository; every
5
+ * test that could have caught the third drifting six commits behind was named a
6
+ * parity test and hardcoded a two-entry roster that omitted it. Each such test
7
+ * proves parity across the copies it happens to list, so "the copies agree"
8
+ * silently meant "the copies someone remembered agree" the moment a third copy
9
+ * appeared (CodySwannGT/lisa#2847).
10
+ *
11
+ * The roster here is derived from the set of tracked paths, so a copy added
12
+ * tomorrow joins every check that consumes it without anyone editing a list.
13
+ *
14
+ * The feature axis is the gate ids a hook declares through `lisa_gate_covers`.
15
+ * That marker is the one machine-readable link between a built-in hook step and
16
+ * the gate registry entry that can stand it down, so a copy missing an id is a
17
+ * copy in which that property is either unprovable or ungovernable — the exact
18
+ * shape the drift took. Comparing whole bytes instead would be useless: sibling
19
+ * copies legitimately differ (Lisa's own hook is not its shipped template), so a
20
+ * byte check would be permanently red and would prove nothing about behaviour.
21
+ * @module core/hook-copy-parity
22
+ */
23
+ /** One tracked copy of a hook, with the features it declares. */
24
+ export interface HookCopy {
25
+ /** Repo-relative path of this copy. */
26
+ readonly path: string;
27
+ /** Features this copy declares, sorted. */
28
+ readonly features: readonly string[];
29
+ }
30
+ /** Every tracked copy of one hook name. */
31
+ export interface HookCopyGroup {
32
+ /** The hook's file name, e.g. `pre-push`. */
33
+ readonly hook: string;
34
+ /** Repo-relative paths of every tracked copy, sorted. */
35
+ readonly paths: readonly string[];
36
+ }
37
+ /** A feature some copies of a hook declare and others do not. */
38
+ export interface HookCopyFinding {
39
+ /** The hook name the disagreeing copies share. */
40
+ readonly hook: string;
41
+ /** The feature that is present in one copy and absent from another. */
42
+ readonly feature: string;
43
+ /** Copies that declare the feature, sorted. */
44
+ readonly present: readonly string[];
45
+ /** Copies that do not, sorted. */
46
+ readonly absent: readonly string[];
47
+ }
48
+ /**
49
+ * Group tracked paths into the hooks they are copies of.
50
+ *
51
+ * Identity is the file name under `.husky/`: `.husky/pre-push` and
52
+ * `any/prefix/.husky/pre-push` are two copies of one logical hook. Paths that
53
+ * are not hooks are ignored, and a hook with a single copy still gets a group —
54
+ * callers decide what a one-copy group means.
55
+ * @param trackedPaths - Repo-relative paths of every tracked file
56
+ * @returns One group per hook name, sorted by hook name
57
+ */
58
+ export declare function deriveHookCopyGroups(trackedPaths: readonly string[]): readonly HookCopyGroup[];
59
+ /**
60
+ * The features one hook's source declares.
61
+ * @param source - Full text of the hook
62
+ * @returns Declared feature ids, sorted and de-duplicated
63
+ */
64
+ export declare function declaredHookFeatures(source: string): readonly string[];
65
+ /**
66
+ * Report every feature that sibling copies of one hook disagree about.
67
+ *
68
+ * A hook with fewer than two copies can never disagree, and a feature no copy
69
+ * declares is not a feature, so both cases produce nothing.
70
+ * @param hook - The hook name these copies share
71
+ * @param copies - Every tracked copy of that hook
72
+ * @returns One finding per disputed feature, sorted by feature
73
+ */
74
+ export declare function findHookCopyDrift(hook: string, copies: readonly HookCopy[]): readonly HookCopyFinding[];
75
+ /**
76
+ * One operator-readable line per finding.
77
+ * @param finding - A disputed feature
78
+ * @returns A sentence naming the feature and both sides
79
+ */
80
+ export declare function describeHookCopyFinding(finding: HookCopyFinding): string;
81
+ //# sourceMappingURL=hook-copy-parity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-copy-parity.d.ts","sourceRoot":"","sources":["../../src/core/hook-copy-parity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,iEAAiE;AACjE,MAAM,WAAW,QAAQ;IACvB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAuBD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,SAAS,aAAa,EAAE,CAc1B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAQtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,QAAQ,EAAE,GAC1B,SAAS,eAAe,EAAE,CAgB5B;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAKxE"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Sibling copies of one git hook, derived from the tree rather than written down.
3
+ *
4
+ * Three tracked copies of the pre-push hook existed in this repository; every
5
+ * test that could have caught the third drifting six commits behind was named a
6
+ * parity test and hardcoded a two-entry roster that omitted it. Each such test
7
+ * proves parity across the copies it happens to list, so "the copies agree"
8
+ * silently meant "the copies someone remembered agree" the moment a third copy
9
+ * appeared (CodySwannGT/lisa#2847).
10
+ *
11
+ * The roster here is derived from the set of tracked paths, so a copy added
12
+ * tomorrow joins every check that consumes it without anyone editing a list.
13
+ *
14
+ * The feature axis is the gate ids a hook declares through `lisa_gate_covers`.
15
+ * That marker is the one machine-readable link between a built-in hook step and
16
+ * the gate registry entry that can stand it down, so a copy missing an id is a
17
+ * copy in which that property is either unprovable or ungovernable — the exact
18
+ * shape the drift took. Comparing whole bytes instead would be useless: sibling
19
+ * copies legitimately differ (Lisa's own hook is not its shipped template), so a
20
+ * byte check would be permanently red and would prove nothing about behaviour.
21
+ * @module core/hook-copy-parity
22
+ */
23
+ /** Matches any tracked path that is a file directly inside a `.husky` directory. */
24
+ const HUSKY_HOOK = /(?:^|\/)\.husky\/([^/]+)$/u;
25
+ /**
26
+ * Matches a `lisa_gate_covers` call and captures its arguments.
27
+ *
28
+ * Anchored at the start of a shell word so the helper's own definition
29
+ * (`lisa_gate_covers() {`) and its body never register as declarations — only a
30
+ * call site passing at least one gate id does.
31
+ */
32
+ const GATE_COVERS = /(?:^|\s)lisa_gate_covers((?:[ \t]+[A-Za-z0-9][\w-]*)+)/gmu;
33
+ /**
34
+ * Alphabetical order that does not depend on the ambient locale's default.
35
+ * @param left - First name
36
+ * @param right - Second name
37
+ * @returns Negative, zero, or positive per `String.localeCompare`
38
+ */
39
+ const byName = (left, right) => left.localeCompare(right);
40
+ /**
41
+ * Group tracked paths into the hooks they are copies of.
42
+ *
43
+ * Identity is the file name under `.husky/`: `.husky/pre-push` and
44
+ * `any/prefix/.husky/pre-push` are two copies of one logical hook. Paths that
45
+ * are not hooks are ignored, and a hook with a single copy still gets a group —
46
+ * callers decide what a one-copy group means.
47
+ * @param trackedPaths - Repo-relative paths of every tracked file
48
+ * @returns One group per hook name, sorted by hook name
49
+ */
50
+ export function deriveHookCopyGroups(trackedPaths) {
51
+ const located = trackedPaths.flatMap(trackedPath => {
52
+ const hook = HUSKY_HOOK.exec(trackedPath)?.[1];
53
+ return hook === undefined ? [] : [{ hook, path: trackedPath }];
54
+ });
55
+ return [...new Set(located.map(entry => entry.hook))]
56
+ .sort(byName)
57
+ .map(hook => ({
58
+ hook,
59
+ paths: located
60
+ .filter(entry => entry.hook === hook)
61
+ .map(entry => entry.path)
62
+ .sort(byName),
63
+ }));
64
+ }
65
+ /**
66
+ * The features one hook's source declares.
67
+ * @param source - Full text of the hook
68
+ * @returns Declared feature ids, sorted and de-duplicated
69
+ */
70
+ export function declaredHookFeatures(source) {
71
+ const declared = [...source.matchAll(GATE_COVERS)].flatMap(match => (match[1] ?? "")
72
+ .trim()
73
+ .split(/[ \t]+/u)
74
+ .map(id => `gate:${id}`));
75
+ return [...new Set(declared)].sort(byName);
76
+ }
77
+ /**
78
+ * Report every feature that sibling copies of one hook disagree about.
79
+ *
80
+ * A hook with fewer than two copies can never disagree, and a feature no copy
81
+ * declares is not a feature, so both cases produce nothing.
82
+ * @param hook - The hook name these copies share
83
+ * @param copies - Every tracked copy of that hook
84
+ * @returns One finding per disputed feature, sorted by feature
85
+ */
86
+ export function findHookCopyDrift(hook, copies) {
87
+ if (copies.length < 2)
88
+ return [];
89
+ const union = [...new Set(copies.flatMap(copy => [...copy.features]))].sort(byName);
90
+ return union.flatMap(feature => {
91
+ const present = copies
92
+ .filter(copy => copy.features.includes(feature))
93
+ .map(copy => copy.path)
94
+ .sort(byName);
95
+ const absent = copies
96
+ .filter(copy => !copy.features.includes(feature))
97
+ .map(copy => copy.path)
98
+ .sort(byName);
99
+ return absent.length === 0 ? [] : [{ hook, feature, present, absent }];
100
+ });
101
+ }
102
+ /**
103
+ * One operator-readable line per finding.
104
+ * @param finding - A disputed feature
105
+ * @returns A sentence naming the feature and both sides
106
+ */
107
+ export function describeHookCopyFinding(finding) {
108
+ return (`${finding.hook}: ${finding.feature} is declared by ` +
109
+ `${finding.present.join(", ")} but absent from ${finding.absent.join(", ")}`);
110
+ }
111
+ //# sourceMappingURL=hook-copy-parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-copy-parity.js","sourceRoot":"","sources":["../../src/core/hook-copy-parity.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAg3EpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CA+2OjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
1
+ {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAg3EpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAu3OjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
@@ -7111,6 +7111,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7111
7111
  "src/cli/doctor-apply-failure.ts": true,
7112
7112
  "src/cli/doctor-apply-freshness.ts": true,
7113
7113
  "src/cli/doctor-gate-recommendation.ts": true,
7114
+ "src/cli/doctor-hook-copy-parity.ts": true,
7114
7115
  "src/cli/doctor-kane.ts": true,
7115
7116
  "src/cli/doctor-learnings-ledger.ts": true,
7116
7117
  "src/cli/doctor-learnings-merge-driver.ts": true,
@@ -7288,6 +7289,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7288
7289
  "src/core/downstream-references.ts": true,
7289
7290
  "src/core/git-service.ts": true,
7290
7291
  "src/core/guard-capabilities.ts": true,
7292
+ "src/core/hook-copy-parity.ts": true,
7291
7293
  "src/core/host-rules-pointer.ts": true,
7292
7294
  "src/core/index.ts": true,
7293
7295
  "src/core/instruction-files-migration.ts": true,
@@ -7547,8 +7549,10 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7547
7549
  "tests/fixtures/verification/v2_structurally_invalid_claims.json": true,
7548
7550
  "tests/fixtures/wiki-safety/allowed-contacts.md": true,
7549
7551
  "tests/fixtures/wiki-safety/redaction-source.md": true,
7552
+ "tests/helpers/__fixtures__/margin-guard-case.ts": true,
7550
7553
  "tests/helpers/__fixtures__/wiki-status-fixture.ts": true,
7551
7554
  "tests/helpers/cpu-budget.ts": true,
7555
+ "tests/helpers/hook-roster.ts": true,
7552
7556
  "tests/helpers/io-latency-budget.ts": true,
7553
7557
  "tests/helpers/nightly-e2e-gate-harness.ts": true,
7554
7558
  "tests/helpers/nightly-e2e-reporting-harness.ts": true,
@@ -7628,6 +7632,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7628
7632
  "tests/integration/support/reusable-workflow-scopes.ts": true,
7629
7633
  "tests/integration/threshold-ratchet-gate-fail-closed.test.ts": true,
7630
7634
  "tests/integration/tracked-source-nul-bytes.test.ts": true,
7635
+ "tests/support/git-executable.ts": true,
7631
7636
  "tests/support/work-item-cli.ts": true,
7632
7637
  "tests/unit/agy/block-no-verify-agy.test.ts": true,
7633
7638
  "tests/unit/agy/mcp-collect.test.ts": true,
@@ -7639,6 +7644,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7639
7644
  "tests/unit/cli/doctor-apply-failure.test.ts": true,
7640
7645
  "tests/unit/cli/doctor-apply-freshness.test.ts": true,
7641
7646
  "tests/unit/cli/doctor-gate-recommendation.test.ts": true,
7647
+ "tests/unit/cli/doctor-hook-copy-parity.test.ts": true,
7642
7648
  "tests/unit/cli/doctor-kane.test.ts": true,
7643
7649
  "tests/unit/cli/doctor-learnings-ledger.test.ts": true,
7644
7650
  "tests/unit/cli/doctor-learnings-merge-driver.test.ts": true,
@@ -7828,6 +7834,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7828
7834
  "tests/unit/core/bootstrap-environment.test.ts": true,
7829
7835
  "tests/unit/core/fs-extra-namespace-callsites.test.ts": true,
7830
7836
  "tests/unit/core/fs-extra-namespace-members.test.ts": true,
7837
+ "tests/unit/core/hook-copy-parity.test.ts": true,
7831
7838
  "tests/unit/core/host-rules-parity.test.ts": true,
7832
7839
  "tests/unit/core/host-rules-pointer.test.ts": true,
7833
7840
  "tests/unit/core/instruction-files-migration.test.ts": true,
@@ -7890,6 +7897,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7890
7897
  "tests/unit/health/gitignore.test.ts": true,
7891
7898
  "tests/unit/health/package-surfaces.test.ts": true,
7892
7899
  "tests/unit/health/storage.test.ts": true,
7900
+ "tests/unit/helpers/io-latency-budget.test.ts": true,
7893
7901
  "tests/unit/hooks/block-direct-issue-create-bypasses.test.ts": true,
7894
7902
  "tests/unit/hooks/block-direct-issue-create-declarations.test.ts": true,
7895
7903
  "tests/unit/hooks/block-direct-issue-create-missing-interpreter.test.ts": true,