@codyswann/lisa 2.323.0 → 2.324.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 (85) hide show
  1. package/all/copy-overwrite/scripts/lisa-work-item.mjs +154 -15
  2. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  3. package/dist/core/upstream-evidence-manifest.js +13 -7
  4. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  5. package/dist/strategies/package-lisa.d.ts.map +1 -1
  6. package/dist/strategies/package-lisa.js +67 -2
  7. package/dist/strategies/package-lisa.js.map +1 -1
  8. package/package.json +1 -1
  9. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/SKILL.md +24 -0
  12. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  13. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  14. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  15. package/plugins/lisa/skills/lisa-setup-remote-env/SKILL.md +24 -0
  16. package/plugins/lisa/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  17. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  18. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  19. package/plugins/lisa-agy/plugin.json +1 -1
  20. package/plugins/lisa-agy/skills/lisa-setup-remote-env/SKILL.md +24 -0
  21. package/plugins/lisa-agy/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  22. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  23. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  24. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  26. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  27. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/SKILL.md +24 -0
  31. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  32. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  33. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  34. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/SKILL.md +24 -0
  36. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  37. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  38. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  39. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-expo-agy/plugin.json +1 -1
  42. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  47. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  52. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  57. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  62. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-rails-agy/plugin.json +1 -1
  67. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  72. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  77. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/src/base/skills/lisa-setup-remote-env/SKILL.md +24 -0
  80. package/plugins/src/base/skills/lisa-setup-remote-env/assets/session-start.sh +17 -0
  81. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +37 -0
  82. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs +7 -3
  83. package/scripts/lisa-enforcement-fallback.sh +57 -0
  84. package/scripts/lisa-remote-env/session-start.sh +17 -0
  85. package/scripts/lisa-work-item.mjs +8 -1
@@ -15,6 +15,7 @@ import {
15
15
  writeFileSync,
16
16
  } from "node:fs";
17
17
  import { dirname, join, resolve } from "node:path";
18
+ import { pathToFileURL } from "node:url";
18
19
 
19
20
  const RELEASE_SUBJECT =
20
21
  /^chore\(release\): \d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)? \[skip ci\]$/;
@@ -27,6 +28,69 @@ const GUIDANCE = [
27
28
 
28
29
  class TrackingError extends Error {}
29
30
 
31
+ /**
32
+ * Say which of three different failures a `gh` invocation actually hit.
33
+ *
34
+ * The three are indistinguishable from an exit status alone, and they send the
35
+ * reader to three different places: a missing binary is an environment to
36
+ * provision, a refused credential is an access grant to obtain, and only the
37
+ * third is anything to do with the ticket.
38
+ *
39
+ * Collapsing them cost a real round trip. On Claude Code web, where `gh` is not
40
+ * pre-installed, every commit was refused with "issue #2202 does not exist or
41
+ * is inaccessible" — about an issue that was open and correct. The message
42
+ * accused the ticket, so that is where the reader went.
43
+ * @param {{status: number|null, error?: Error, stderr?: string}} result Spawn result.
44
+ * @param {string} ref Work item reference, for the message.
45
+ * @param {string} noun What the reference names.
46
+ * @returns {string} A message naming the actual fault.
47
+ */
48
+ export class TrackerUnreachableError extends TrackingError {}
49
+
50
+ /**
51
+ * Turn a failed `gh` invocation into the right kind of refusal.
52
+ *
53
+ * The distinction is the whole point: a missing binary or a refused credential
54
+ * means the tracker could not be ASKED, while a "no" from the tracker is an
55
+ * answer. Absence of evidence is not evidence of absence, and only the first
56
+ * kind may be degraded — treating them alike would either strand finished work
57
+ * or wave through an item that genuinely is not committable.
58
+ * @param {{status: number|null, error?: Error, stderr?: string}} result Spawn result.
59
+ * @param {string} ref Work item reference.
60
+ * @returns {Error} The error to throw.
61
+ */
62
+ export function githubFailure(result, ref) {
63
+ const reason = githubFailureReason(result, ref, "GitHub issue");
64
+ const unreachable =
65
+ result.error?.code === "ENOENT" || /cannot authenticate/.test(reason);
66
+ return unreachable
67
+ ? new TrackerUnreachableError(reason)
68
+ : new TrackingError(reason);
69
+ }
70
+
71
+ export function githubFailureReason(result, ref, noun) {
72
+ if (result.error?.code === "ENOENT") {
73
+ return (
74
+ `the GitHub CLI (gh) is not installed, so ${noun} ${ref} could not be ` +
75
+ `checked.\nThis is an environment gap, not a problem with the work item. ` +
76
+ `Pin gh in remoteEnv.tools.install for surfaces that lack it.`
77
+ );
78
+ }
79
+ const stderr = String(result.stderr ?? "");
80
+ if (
81
+ /not enabled for this session|gh auth login|HTTP 40[13]|Bad credentials|authentication/i.test(
82
+ stderr
83
+ )
84
+ ) {
85
+ return (
86
+ `the GitHub CLI cannot authenticate, so ${noun} ${ref} could not be ` +
87
+ `checked.\nThis is a credential gap, not a problem with the work item.` +
88
+ `\n${stderr.trim().slice(0, 300)}`
89
+ );
90
+ }
91
+ return `${noun} ${ref} does not exist or is inaccessible`;
92
+ }
93
+
30
94
  function run(command, args, options = {}) {
31
95
  const result = spawnSync(command, args, {
32
96
  cwd: options.cwd ?? process.cwd(),
@@ -536,10 +600,7 @@ function githubIssue(ref, contract) {
536
600
  allowFailure: true,
537
601
  }
538
602
  );
539
- if (result.status !== 0)
540
- throw new TrackingError(
541
- `GitHub issue ${ref} does not exist or is inaccessible`
542
- );
603
+ if (result.status !== 0) throw githubFailure(result, ref);
543
604
  const issue = safeJson(result.stdout, `GitHub issue ${ref}`);
544
605
  if (String(issue.number) !== number)
545
606
  throw new TrackingError(`GitHub returned the wrong issue for ${ref}`);
@@ -775,10 +836,48 @@ function linearIssue(ref, contract) {
775
836
  return issue;
776
837
  }
777
838
 
839
+ /**
840
+ * Ask the tracker whether this work item may be committed against.
841
+ *
842
+ * When the tracker cannot be REACHED, the live checks are reported as skipped
843
+ * rather than enforced or silently dropped. Everything checkable without a
844
+ * network — the trailer is present, well formed, and matches this branch's
845
+ * binding — has already run by the time this is called, and the semantic
846
+ * checks it cannot do here are re-run in CI by a REQUIRED status check
847
+ * ("Work-Item Traceability"), with credentials, before anything can merge.
848
+ *
849
+ * So the guarantee is not lost; it moves to a gate that cannot be bypassed.
850
+ * That is the whole justification, and it holds only while that check stays
851
+ * required — if it is ever made optional, this degradation becomes a hole.
852
+ *
853
+ * The alternative was worse in both directions. Refusing outright strands
854
+ * finished, green work on any surface without a GitHub credential — a cloud
855
+ * container, for one — and the agent's only remaining move is a bypass that
856
+ * skips the offline checks too. Enforcing nothing hides the difference between
857
+ * "could not ask" and "the tracker said no".
858
+ * @param {string} ref Work item reference.
859
+ * @param {object} [contract] Tracker contract.
860
+ * @returns {object|undefined} The live item, or undefined when unreachable.
861
+ */
778
862
  function validateLive(ref, contract = trackerContract()) {
779
- if (contract.provider === "github") return githubIssue(ref, contract);
780
- if (contract.provider === "jira") return jiraIssue(ref, contract);
781
- return linearIssue(ref, contract);
863
+ try {
864
+ if (contract.provider === "github") return githubIssue(ref, contract);
865
+ if (contract.provider === "jira") return jiraIssue(ref, contract);
866
+ return linearIssue(ref, contract);
867
+ } catch (error) {
868
+ if (!(error instanceof TrackerUnreachableError)) throw error;
869
+ // Loud on stderr, never silent: a degradation nobody sees is the failure
870
+ // mode this exists to avoid, not a milder version of it.
871
+ console.error(
872
+ `\n⚠️ Work-item live validation SKIPPED for ${ref}.\n` +
873
+ `${error.message}\n\n` +
874
+ `The offline checks still ran: the trailer is present, well formed and ` +
875
+ `bound to this branch.\nWhat could not be checked here — that the item ` +
876
+ `is open, claimed and a leaf — is re-run\nwith credentials by the ` +
877
+ `required "Work-Item Traceability" check before this can merge.\n`
878
+ );
879
+ return undefined;
880
+ }
782
881
  }
783
882
 
784
883
  function textContainsBacklink(value, prUrl) {
@@ -797,6 +896,18 @@ function assertBacklink(
797
896
  contract,
798
897
  issue = validateLive(ref, contract)
799
898
  ) {
899
+ // The PR check never degrades, because it IS the re-check the local hooks
900
+ // degrade in favour of. A required status check that passes when it could
901
+ // not reach the tracker would make the whole arrangement circular: local
902
+ // defers to CI, CI defers to nothing.
903
+ if (!issue) {
904
+ throw new TrackingError(
905
+ `cannot verify ${ref} against the tracker, and this check is the one ` +
906
+ `that must.\nLocal hooks may skip live validation when the tracker ` +
907
+ `is unreachable; this check may not,\nbecause it is what they defer ` +
908
+ `to. Fix the tracker credential for this run.`
909
+ );
910
+ }
800
911
  if (contract.provider === "github") {
801
912
  const native = (issue.closedByPullRequestsReferences ?? []).some(
802
913
  pr => pr.url === prUrl
@@ -1165,12 +1276,40 @@ function main() {
1165
1276
  );
1166
1277
  }
1167
1278
 
1168
- try {
1169
- main();
1170
- } catch (error) {
1171
- const detail = error instanceof Error ? error.message : String(error);
1172
- console.error(
1173
- `\n❌ Work-item tracking blocked this operation: ${detail}\n\n${GUIDANCE}\n`
1174
- );
1175
- process.exitCode = 1;
1279
+ /**
1280
+ * Run the CLI, reporting any refusal the way the Git hooks expect.
1281
+ *
1282
+ * Exported so the thin entrypoint at `scripts/lisa-work-item.mjs` can invoke it
1283
+ * explicitly. That entrypoint re-exports this module rather than duplicating
1284
+ * it, so inside here `import.meta.url` names THIS file while `argv[1]` names
1285
+ * the entrypoint — the two never match, and a guard comparing them would leave
1286
+ * Lisa's own hooks doing nothing at all, silently and with exit 0. An exported
1287
+ * call is unambiguous where a path comparison is a guess.
1288
+ */
1289
+ export function runCli() {
1290
+ try {
1291
+ main();
1292
+ } catch (error) {
1293
+ const detail = error instanceof Error ? error.message : String(error);
1294
+ console.error(
1295
+ `\n❌ Work-item tracking blocked this operation: ${detail}\n\n${GUIDANCE}\n`
1296
+ );
1297
+ process.exitCode = 1;
1298
+ }
1299
+ }
1300
+
1301
+ // Only when invoked as a program. Running on import made every function here
1302
+ // unreachable from a test: importing the module executed the CLI, so the only
1303
+ // way to exercise any of it was to spawn a process and drive it through the
1304
+ // filesystem and PATH. That is why a bug in the message above shipped — the
1305
+ // branch that produced it had no way to be asserted on.
1306
+ //
1307
+ // This branch covers a host project, where the file is copied to
1308
+ // `scripts/lisa-work-item.mjs` and invoked directly. Lisa's own checkout keeps
1309
+ // a re-exporting entrypoint instead, which calls runCli() itself.
1310
+ if (
1311
+ process.argv[1] &&
1312
+ import.meta.url === pathToFileURL(process.argv[1]).href
1313
+ ) {
1314
+ runCli();
1176
1315
  }
@@ -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,CAgnEpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAujNjE,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,CAknEpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CA4jNjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
@@ -3,7 +3,7 @@
3
3
  export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
4
4
  "all/copy-contents/.gitattributes": "9d3831007e681186a3673e1037ef3fc82980cab2fc04e27c0868e562912c9e9f",
5
5
  "all/copy-contents/gitignore": "2dbf7fd2f2020fc7824c432342002d9ca3ebb57b2872e761b14e942b23479a11",
6
- "all/copy-overwrite/scripts/lisa-work-item.mjs": "5eb31c284e820a51312d4484f0669128007326af55ee515923fec33700d003a1",
6
+ "all/copy-overwrite/scripts/lisa-work-item.mjs": "6a8be8577242588f14ab52b25b2a22b6def53aefa9513b4d3d7c49f4d8027079",
7
7
  "all/create-only/.claude/rules/PROJECT_RULES.md": "6e1c7923ad2a15356babc60c97e7f97be728d790af285b6a7cd7d1b4d39cd97f",
8
8
  "all/create-only/.lisaignore": "3c9827e7e98daa46510b5357cd6dd9406da1821e64cc46d2eea9f311cd6d06b9",
9
9
  "all/create-only/scripts/remote-agent-aws-setup.sh": "7677908a345891810d2104ba8b2fd1a8318bb29c408fb5ce0110d57beef9b556",
@@ -559,11 +559,11 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
559
559
  "plugins/src/base/skills/lisa-setup-linear/SKILL.md": "ec76f832a6df6f58b163f7f5ba6826ed2fcbddc91e44a8372e874858e4d0c518",
560
560
  "plugins/src/base/skills/lisa-setup-notion/SKILL.md": "f5a1e9290789fd1c33675168d30461fb24a11c98a433ef777c1f536bc2f905ef",
561
561
  "plugins/src/base/skills/lisa-setup-remote-aws/SKILL.md": "80fbf157f9c562c033886c25a99b37356602edd9e61cd2d492f339769ddcf97e",
562
- "plugins/src/base/skills/lisa-setup-remote-env/SKILL.md": "5627c45a4ce7d0f0d122791f699b6dd2841602adf873678c693ad08a48eab401",
563
- "plugins/src/base/skills/lisa-setup-remote-env/assets/session-start.sh": "6e3871ec2f8d56b8ebb85376ebdd3956f3ed8fa4f7b278c2ed90ca9b8845897c",
562
+ "plugins/src/base/skills/lisa-setup-remote-env/SKILL.md": "821f9f7db39259c3aef24dc369c7cdcfb55a85d61742b32ac2a961e1b3e263a4",
563
+ "plugins/src/base/skills/lisa-setup-remote-env/assets/session-start.sh": "cb63d08b14ab7aa2d405e6770e0cf7db5d6588ae1dcb924ea6224b026fcff496",
564
564
  "plugins/src/base/skills/lisa-setup-remote-env/assets/setup.sh": "c04afb1cf8e14a2713645228e679fa7772559488330a240ec0297cae6afd03e2",
565
- "plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs": "68339117f7d2fe1fdb9f05c8039ffe719f24da7cf700bc3c940bfccbf82cded2",
566
- "plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs": "ff66d33ba41a068d09be18f81ac68988238c2afa1d4e3733ae906b73eea74324",
565
+ "plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs": "1f451881342364d086640b59914a3b07286a3734caa63f01efe64531d3bde7e4",
566
+ "plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs": "8822af39d0251a2e4fb0eac9157ba9e63ea813d914240ca0cacacd6cb7cbb5bb",
567
567
  "plugins/src/base/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs": "82bc2a27a0a5afb2ff413a88365c619fd7f0eaada5de3ccabf2000938f0607a4",
568
568
  "plugins/src/base/skills/lisa-setup-sonar/SKILL.md": "53fbd8acce4b5e47e88195a7b90d5be424fa6ef7ad872f52c50467c690664c3b",
569
569
  "plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md": "031acb01195ae59010a65335da98d46a1d6080e749823d6f6d157938d9e96648",
@@ -985,14 +985,15 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
985
985
  "scripts/lib/reusable-workflow-contract.d.mts": "791f01b55dd7a6b5d9a5f4cb9c44167caa146c2fc3c31a2ae4c2d8a350adc2f1",
986
986
  "scripts/lib/reusable-workflow-contract.mjs": "134ee2a327290f066f1eb318b5ed53c711557c3e10ed462c00ff5c97cfb20863",
987
987
  "scripts/lisa-commit-and-pr-local.sh": "605409c3ce6ec38ad3275604291a1ceae98f7807a605654263bc14f811c03903",
988
+ "scripts/lisa-enforcement-fallback.sh": "8dc942ac4edc2017d6b8277296c8f80542e7c024eef1bb65de609979d0ca9a0e",
988
989
  "scripts/lisa-github-environments.sh": "0a76e92f108519abaf3e29991299ec3b0db20ea533e69e6d2a53d802dba9c370",
989
990
  "scripts/lisa-github-repo-settings.sh": "4afbccdfb08c62ba13afee42ec8561a28facf87c61f6f4b80000115328364d54",
990
991
  "scripts/lisa-github-repo-setup.sh": "dc2f1c9d718aa34ba57161120d9319b5f78fe6b0b496d8e3c77226a08795aa36",
991
992
  "scripts/lisa-github-rulesets.sh": "920a43ba268421b6fe55096062bd85850468bee9389f6006ad7c671010e7cccb",
992
- "scripts/lisa-remote-env/session-start.sh": "6e3871ec2f8d56b8ebb85376ebdd3956f3ed8fa4f7b278c2ed90ca9b8845897c",
993
+ "scripts/lisa-remote-env/session-start.sh": "cb63d08b14ab7aa2d405e6770e0cf7db5d6588ae1dcb924ea6224b026fcff496",
993
994
  "scripts/lisa-remote-env/setup.sh": "c04afb1cf8e14a2713645228e679fa7772559488330a240ec0297cae6afd03e2",
994
995
  "scripts/lisa-update-local.sh": "c811f9e10dbcb38499a9791c1ae9051460b347051d04a1d2046925bab9a53c96",
995
- "scripts/lisa-work-item.mjs": "acb359ed7a39150fd5e1e68f4c95144045e75d9d53b735da4a7a9271f063044e",
996
+ "scripts/lisa-work-item.mjs": "51081847e980f314a764c2e50a7a121b1ced9ef4b980f33898057de4c7b852e6",
996
997
  "scripts/migrate-deploy-order.sh": "77d909b4cbbfc05169a79168d7868600ea7f56f846feefb7d5121618c54800c3",
997
998
  "scripts/plugin-parity-drift.mjs": "34235c4c75c8735aaca96e3e0a52073ba1dee8bad54c85af01c3cf9912d0ea57",
998
999
  "scripts/plugin-routing-validate.mjs": "eb38cf139eb04a27dd6493ff6f766945060d5bf73a35856bd3da4c8e4110e2ba",
@@ -6543,6 +6544,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
6543
6544
  "scripts/lib/reusable-workflow-contract.d.mts": true,
6544
6545
  "scripts/lib/reusable-workflow-contract.mjs": true,
6545
6546
  "scripts/lisa-commit-and-pr-local.sh": true,
6547
+ "scripts/lisa-enforcement-fallback.sh": true,
6546
6548
  "scripts/lisa-github-environments.sh": true,
6547
6549
  "scripts/lisa-github-repo-settings.sh": true,
6548
6550
  "scripts/lisa-github-repo-setup.sh": true,
@@ -7174,6 +7176,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7174
7176
  "tests/unit/hooks/enforce-verification-gate-preserve.test.ts": true,
7175
7177
  "tests/unit/hooks/enforce-verification-gate-v1.test.ts": true,
7176
7178
  "tests/unit/hooks/enforce-verification-gate-v2.test.ts": true,
7179
+ "tests/unit/hooks/enforcement-fallback.test.ts": true,
7177
7180
  "tests/unit/hooks/enforcement-gates-e2e.test.ts": true,
7178
7181
  "tests/unit/hooks/inject-rules.test.ts": true,
7179
7182
  "tests/unit/hooks/install-pkgs-worktree-node-modules.test.ts": true,
@@ -7252,6 +7255,8 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7252
7255
  "tests/unit/scripts/threshold-ratchet.test.ts": true,
7253
7256
  "tests/unit/scripts/upstream-evidence-manifest.test.ts": true,
7254
7257
  "tests/unit/scripts/verification-coverage.test.ts": true,
7258
+ "tests/unit/scripts/work-item-github-failure-diagnosis.test.ts": true,
7259
+ "tests/unit/scripts/work-item-tracker-unreachable.test.ts": true,
7255
7260
  "tests/unit/secrets/automation-workflow.test.ts": true,
7256
7261
  "tests/unit/secrets/bootstrap-key-naming.test.ts": true,
7257
7262
  "tests/unit/secrets/doctor-secrets.test.ts": true,
@@ -7260,6 +7265,7 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7260
7265
  "tests/unit/secrets/remote-env-bindir-path.test.ts": true,
7261
7266
  "tests/unit/secrets/remote-env-installed-copy.test.ts": true,
7262
7267
  "tests/unit/secrets/remote-env-phases.test.ts": true,
7268
+ "tests/unit/secrets/remote-env-session-start-hook.test.ts": true,
7263
7269
  "tests/unit/secrets/remote-env-setup-field.test.ts": true,
7264
7270
  "tests/unit/secrets/remote-env-skill-resolution.test.ts": true,
7265
7271
  "tests/unit/secrets/remote-env-toolchain.test.ts": true,