@codyswann/lisa 4.84.8 → 4.84.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +14 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +8 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +116 -17
|
@@ -2366,8 +2366,9 @@ export function reviewGateState(reading, vocabulary = {}) {
|
|
|
2366
2366
|
if (state === "FAILURE" || state === "ERROR") {
|
|
2367
2367
|
return objectedReviewGateState(state, text, reading.description);
|
|
2368
2368
|
}
|
|
2369
|
-
if (state === "SKIPPED") {
|
|
2370
|
-
return
|
|
2369
|
+
if (state === "SKIPPED" || state === "NEUTRAL") {
|
|
2370
|
+
return terminalReviewGateState(
|
|
2371
|
+
state,
|
|
2371
2372
|
text,
|
|
2372
2373
|
reading.description,
|
|
2373
2374
|
vocabulary,
|
|
@@ -2386,16 +2387,23 @@ export function reviewGateState(reading, vocabulary = {}) {
|
|
|
2386
2387
|
}
|
|
2387
2388
|
|
|
2388
2389
|
/**
|
|
2389
|
-
* A terminal
|
|
2390
|
-
* Existing exact waivers retain their policy;
|
|
2390
|
+
* A terminal result alone never proves review, even with a positive title.
|
|
2391
|
+
* Existing exact waivers retain their policy; other terminal results need a trusted
|
|
2391
2392
|
* head-bound substitute and a clean, readable review surface to permit merging.
|
|
2393
|
+
* @param {string} state - Observed terminal check state
|
|
2392
2394
|
* @param {string} text - Normalized description
|
|
2393
2395
|
* @param {string|undefined} description - Original description
|
|
2394
2396
|
* @param {{waive?: readonly string[]}} vocabulary - Per-check waiver extensions
|
|
2395
2397
|
* @param {{read: boolean, present: boolean, objected: boolean}|undefined} activity - Independent review surface
|
|
2396
2398
|
* @returns {{state: string, condition: string, why: string}} Terminal no-review verdict
|
|
2397
2399
|
*/
|
|
2398
|
-
function
|
|
2400
|
+
function terminalReviewGateState(
|
|
2401
|
+
state,
|
|
2402
|
+
text,
|
|
2403
|
+
description,
|
|
2404
|
+
vocabulary,
|
|
2405
|
+
activity
|
|
2406
|
+
) {
|
|
2399
2407
|
const waivers = [...ENTITLEMENT_WAIVERS, ...(vocabulary.waive ?? [])];
|
|
2400
2408
|
if (waivers.some(phrase => text === normalizeDescription(phrase))) {
|
|
2401
2409
|
return waivedReviewGateState(description, activity);
|
|
@@ -2403,7 +2411,7 @@ function skippedReviewGateState(text, description, vocabulary, activity) {
|
|
|
2403
2411
|
return {
|
|
2404
2412
|
state: REVIEW_GATE_STATES.unsatisfied,
|
|
2405
2413
|
condition: REVIEW_GATE_CONDITIONS.notReviewed,
|
|
2406
|
-
why: `reported terminal
|
|
2414
|
+
why: `reported terminal ${state} with the description ${JSON.stringify(description ?? "")}. This result does not establish qualifying completed-review proof; its title cannot supply that proof. An existing exact waiver or a trusted substitute for this head is required, and no substitute covers an objection.`,
|
|
2407
2415
|
};
|
|
2408
2416
|
}
|
|
2409
2417
|
|
|
@@ -2527,6 +2535,22 @@ function waivedReviewGateState(description, activity) {
|
|
|
2527
2535
|
};
|
|
2528
2536
|
}
|
|
2529
2537
|
|
|
2538
|
+
/**
|
|
2539
|
+
* Match explicit waivers exactly, independently of loose no-work detection.
|
|
2540
|
+
*
|
|
2541
|
+
* Shared by raw result decoding and the gate so normalization cannot discard
|
|
2542
|
+
* a supported waiver merely because it is absent from the no-work list.
|
|
2543
|
+
*
|
|
2544
|
+
* @param {string|undefined} description - Original description.
|
|
2545
|
+
* @param {{waive?: readonly string[]}} vocabulary - Per-check extensions.
|
|
2546
|
+
* @returns {boolean} Whether the whole normalized phrase is an explicit waiver.
|
|
2547
|
+
*/
|
|
2548
|
+
function matchesReviewWaiver(description, vocabulary) {
|
|
2549
|
+
const text = normalizeDescription(description);
|
|
2550
|
+
const waivers = [...ENTITLEMENT_WAIVERS, ...(vocabulary.waive ?? [])];
|
|
2551
|
+
return waivers.some(phrase => text === normalizeDescription(phrase));
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2530
2554
|
/**
|
|
2531
2555
|
* Classifies a successful check from its exact description vocabulary.
|
|
2532
2556
|
*
|
|
@@ -2545,8 +2569,7 @@ function successfulReviewGateState(text, description, vocabulary, activity) {
|
|
|
2545
2569
|
why: `reported ${JSON.stringify(description ?? "")}, which is a review that ran.`,
|
|
2546
2570
|
};
|
|
2547
2571
|
}
|
|
2548
|
-
|
|
2549
|
-
if (waivers.some(phrase => text === normalizeDescription(phrase))) {
|
|
2572
|
+
if (matchesReviewWaiver(description, vocabulary)) {
|
|
2550
2573
|
return waivedReviewGateState(description, activity);
|
|
2551
2574
|
}
|
|
2552
2575
|
return {
|
|
@@ -3796,7 +3819,15 @@ export function readCarriedReview(declaration, pr, repo, options = {}) {
|
|
|
3796
3819
|
declaration,
|
|
3797
3820
|
listed.map(entry => {
|
|
3798
3821
|
try {
|
|
3799
|
-
return {
|
|
3822
|
+
return {
|
|
3823
|
+
...entry,
|
|
3824
|
+
checks: readChecks(
|
|
3825
|
+
entry.headSha,
|
|
3826
|
+
repo,
|
|
3827
|
+
/** @type {{evidence_bearing_checks?: ReviewEvidenceChecks|null}} */
|
|
3828
|
+
(declaration).evidence_bearing_checks ?? {}
|
|
3829
|
+
),
|
|
3830
|
+
};
|
|
3800
3831
|
} catch (error) {
|
|
3801
3832
|
return {
|
|
3802
3833
|
...entry,
|
|
@@ -3852,10 +3883,11 @@ export function writeVerdictOutputs(verdict, env = process.env) {
|
|
|
3852
3883
|
*
|
|
3853
3884
|
* @param {string|number} pr - Pull request number or URL
|
|
3854
3885
|
* @param {string} [repo] - `OWNER/NAME`; defaults to the current repository
|
|
3886
|
+
* @param {Record<string, {proof?: readonly string[], no_work?: readonly string[], satisfy?: readonly string[], waive?: readonly string[]}>} [evidenceChecks] - Per-context vocabulary from the declaration
|
|
3855
3887
|
* @returns {Array<{name: string, state: string, bucket?: string, description?: string}>} The checks
|
|
3856
3888
|
* @throws {Error} When `gh` is unavailable or its output cannot be parsed
|
|
3857
3889
|
*/
|
|
3858
|
-
export function fetchPullRequestChecks(pr, repo) {
|
|
3890
|
+
export function fetchPullRequestChecks(pr, repo, evidenceChecks = {}) {
|
|
3859
3891
|
const args = [
|
|
3860
3892
|
"pr",
|
|
3861
3893
|
"checks",
|
|
@@ -3876,7 +3908,7 @@ export function fetchPullRequestChecks(pr, repo) {
|
|
|
3876
3908
|
// shaped exactly like unreadable content, which never says the word
|
|
3877
3909
|
// "permission". The commit-status route below needs no `actions` scope
|
|
3878
3910
|
// and carries the description this arm reads, so try it before refusing.
|
|
3879
|
-
return fetchChecksViaApi(pr, repo, error);
|
|
3911
|
+
return fetchChecksViaApi(pr, repo, error, evidenceChecks);
|
|
3880
3912
|
}
|
|
3881
3913
|
}
|
|
3882
3914
|
try {
|
|
@@ -4018,10 +4050,11 @@ function ghApiPaginatedArray(endpoint, query) {
|
|
|
4018
4050
|
* @param {string|number} pr - Pull request number
|
|
4019
4051
|
* @param {string|undefined} repo - `OWNER/NAME`, or undefined to resolve it
|
|
4020
4052
|
* @param {unknown} cause - The `gh pr checks` failure this is falling back from
|
|
4053
|
+
* @param {Record<string, {proof?: readonly string[], no_work?: readonly string[], satisfy?: readonly string[], waive?: readonly string[]}>} [evidenceChecks] - Per-context vocabulary from the declaration
|
|
4021
4054
|
* @returns {Array<{name: string, state: string, bucket?: string, description?: string}>} The checks
|
|
4022
4055
|
* @throws {Error} When the fallback cannot answer either
|
|
4023
4056
|
*/
|
|
4024
|
-
export function fetchChecksViaApi(pr, repo, cause) {
|
|
4057
|
+
export function fetchChecksViaApi(pr, repo, cause, evidenceChecks = {}) {
|
|
4025
4058
|
const slug = resolveRepoSlug(repo);
|
|
4026
4059
|
const why = cause instanceof Error ? cause.message : String(cause ?? "");
|
|
4027
4060
|
if (slug === undefined) {
|
|
@@ -4045,7 +4078,7 @@ export function fetchChecksViaApi(pr, repo, cause) {
|
|
|
4045
4078
|
],
|
|
4046
4079
|
{ encoding: "utf8" }
|
|
4047
4080
|
).trim();
|
|
4048
|
-
return fetchChecksForCommit(sha, slug);
|
|
4081
|
+
return fetchChecksForCommit(sha, slug, evidenceChecks);
|
|
4049
4082
|
} catch (error) {
|
|
4050
4083
|
throw new Error(
|
|
4051
4084
|
`check-skipped-required-checks: could not read checks for PR ${pr} in ${slug}. \`gh pr checks\` failed (${why}) — which is what a missing \`actions: read\` looks like, because it resolves the rollup through \`checkSuite.workflowRun\` and exits non-zero with empty output — and the commit-status fallback also failed (${error instanceof Error ? error.message : String(error)}). NOBODY LOOKED at this pull request; that is not the same as nothing being wrong with it.`
|
|
@@ -4053,6 +4086,8 @@ export function fetchChecksViaApi(pr, repo, cause) {
|
|
|
4053
4086
|
}
|
|
4054
4087
|
}
|
|
4055
4088
|
|
|
4089
|
+
/** @typedef {Record<string, {proof?: readonly string[], no_work?: readonly string[], satisfy?: readonly string[], waive?: readonly string[]}>} ReviewEvidenceChecks */
|
|
4090
|
+
|
|
4056
4091
|
/**
|
|
4057
4092
|
* Reads the evidence-bearing rows for one exact commit.
|
|
4058
4093
|
*
|
|
@@ -4062,9 +4097,10 @@ export function fetchChecksViaApi(pr, repo, cause) {
|
|
|
4062
4097
|
*
|
|
4063
4098
|
* @param {string} sha - Exact commit whose statuses and check runs to read
|
|
4064
4099
|
* @param {string|undefined} repo - `OWNER/NAME`, or undefined to resolve it
|
|
4100
|
+
* @param {ReviewEvidenceChecks} [evidenceChecks] - Per-context vocabulary from the declaration
|
|
4065
4101
|
* @returns {Array<{name: string, state: string, bucket?: string, description?: string}>} The checks
|
|
4066
4102
|
*/
|
|
4067
|
-
export function fetchChecksForCommit(sha, repo) {
|
|
4103
|
+
export function fetchChecksForCommit(sha, repo, evidenceChecks = {}) {
|
|
4068
4104
|
const slug = resolveRepoSlug(repo);
|
|
4069
4105
|
if (slug === undefined) {
|
|
4070
4106
|
throw new Error(
|
|
@@ -4077,18 +4113,76 @@ export function fetchChecksForCommit(sha, repo) {
|
|
|
4077
4113
|
);
|
|
4078
4114
|
const runs = ghApiPaginatedArray(
|
|
4079
4115
|
`repos/${slug}/commits/${sha}/check-runs?per_page=100`,
|
|
4080
|
-
'[.check_runs[] | {id: .id, name: .name, conclusion: .conclusion, description: (.output.title // ""), completed_at: .completed_at, created_at: .created_at, started_at: .started_at}]'
|
|
4116
|
+
'[.check_runs[] | {id: .id, name: .name, status: .status, conclusion: .conclusion, description: (.output.title // ""), summary: .output.summary, completed_at: .completed_at, created_at: .created_at, started_at: .started_at}]'
|
|
4081
4117
|
);
|
|
4082
4118
|
return mergeCheckRows(
|
|
4083
4119
|
statuses.map(row =>
|
|
4084
4120
|
normalizeCheckRow(row.name, row.state, row.description)
|
|
4085
4121
|
),
|
|
4086
4122
|
newestCheckRuns(runs).map(row =>
|
|
4087
|
-
normalizeCheckRow(
|
|
4123
|
+
normalizeCheckRow(
|
|
4124
|
+
row.name,
|
|
4125
|
+
/** @type {{status?: string|null}} */ (row).status === "completed"
|
|
4126
|
+
? row.conclusion
|
|
4127
|
+
: null,
|
|
4128
|
+
checkRunReviewDescription(
|
|
4129
|
+
row,
|
|
4130
|
+
evidenceChecks[/** @type {{name: string}} */ (row).name] ?? {}
|
|
4131
|
+
)
|
|
4132
|
+
)
|
|
4088
4133
|
)
|
|
4089
4134
|
);
|
|
4090
4135
|
}
|
|
4091
4136
|
|
|
4137
|
+
/**
|
|
4138
|
+
* Decode a selected check run without changing legacy commit-status policy.
|
|
4139
|
+
*
|
|
4140
|
+
* The first physical line owns structured results. Only the supported positive
|
|
4141
|
+
* result from a successful completed run becomes existing semantic proof;
|
|
4142
|
+
* malformed/negative result data cannot inherit a positive title. Absent/plain
|
|
4143
|
+
* summaries keep the existing title contract. Later prose supplies no new proof
|
|
4144
|
+
* or denial. Configured exact waivers and loose no-work notices both retain
|
|
4145
|
+
* their independent policies before any positive result is canonicalized.
|
|
4146
|
+
*
|
|
4147
|
+
* @param {{description?: unknown, summary?: unknown, status?: string|null, conclusion?: string|null}} row - Structured fields on the newest raw check run.
|
|
4148
|
+
* @param {object} vocabulary - This context's configured description vocabulary.
|
|
4149
|
+
* @returns {string} Canonical proof, authoritative result, or legacy title.
|
|
4150
|
+
*/
|
|
4151
|
+
function checkRunReviewDescription(row, vocabulary) {
|
|
4152
|
+
const title = typeof row.description === "string" ? row.description : "";
|
|
4153
|
+
if (
|
|
4154
|
+
classifyCheckDescription(title, vocabulary) ===
|
|
4155
|
+
DESCRIPTION_VERDICTS.noWork ||
|
|
4156
|
+
matchesReviewWaiver(title, vocabulary)
|
|
4157
|
+
) {
|
|
4158
|
+
return title;
|
|
4159
|
+
}
|
|
4160
|
+
if (row.summary === null || row.summary === undefined) return title;
|
|
4161
|
+
if (typeof row.summary !== "string") return "Malformed check-run summary";
|
|
4162
|
+
const firstLine = /** @type {string} */ (row.summary.split(/\r?\n/u, 1)[0]);
|
|
4163
|
+
if (
|
|
4164
|
+
classifyCheckDescription(firstLine, vocabulary) ===
|
|
4165
|
+
DESCRIPTION_VERDICTS.noWork ||
|
|
4166
|
+
matchesReviewWaiver(firstLine, vocabulary)
|
|
4167
|
+
) {
|
|
4168
|
+
return firstLine;
|
|
4169
|
+
}
|
|
4170
|
+
if (
|
|
4171
|
+
row.status === "completed" &&
|
|
4172
|
+
row.conclusion === "success" &&
|
|
4173
|
+
firstLine === "Result: Success - Review completed"
|
|
4174
|
+
) {
|
|
4175
|
+
return "Review completed";
|
|
4176
|
+
}
|
|
4177
|
+
const resultLooking =
|
|
4178
|
+
/^[\s>#|]*Result\b/iu.test(firstLine) ||
|
|
4179
|
+
/\bResult\s*[:=-]/iu.test(firstLine);
|
|
4180
|
+
if (resultLooking) {
|
|
4181
|
+
return firstLine;
|
|
4182
|
+
}
|
|
4183
|
+
return title;
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4092
4186
|
/**
|
|
4093
4187
|
* Keep the newest check run for each name across every check suite on a SHA.
|
|
4094
4188
|
* @param {ReadonlyArray<object>} runs Raw check-run rows with timestamps and ids.
|
|
@@ -4251,7 +4345,12 @@ export function fetchSettledChecks(declaration, pr, repo, options = {}) {
|
|
|
4251
4345
|
"check-skipped-required-checks: cannot read review evidence without a concrete head commit."
|
|
4252
4346
|
);
|
|
4253
4347
|
}
|
|
4254
|
-
return fetchChecksForCommit(
|
|
4348
|
+
return fetchChecksForCommit(
|
|
4349
|
+
headSha,
|
|
4350
|
+
slug,
|
|
4351
|
+
/** @type {{evidence_bearing_checks?: ReviewEvidenceChecks|null}} */
|
|
4352
|
+
(declaration).evidence_bearing_checks ?? {}
|
|
4353
|
+
);
|
|
4255
4354
|
});
|
|
4256
4355
|
const resolveHead = options.headSha ?? resolveHeadSha;
|
|
4257
4356
|
const clock = options.now ?? Date.now;
|