@codyswann/lisa 2.100.1 → 2.101.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.
- package/README.md +1 -0
- package/dist/utils/decimal-sum.d.ts +8 -0
- package/dist/utils/decimal-sum.d.ts.map +1 -0
- package/dist/utils/decimal-sum.js +68 -0
- package/dist/utils/decimal-sum.js.map +1 -0
- package/dist/utils/usage-accounting.d.ts.map +1 -1
- package/dist/utils/usage-accounting.js +60 -17
- package/dist/utils/usage-accounting.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/commands/intake-explain.md +18 -1
- package/plugins/lisa/rules/usage-accounting.md +2 -2
- package/plugins/lisa/scripts/automation-status-claude-adapter.mjs +1 -1
- package/plugins/lisa/scripts/automation-status-codex-adapter.mjs +1 -1
- package/plugins/lisa/scripts/doctor-report.mjs +14 -3
- package/plugins/lisa/skills/intake-explain/SKILL.md +52 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-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-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-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-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-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-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-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/src/base/commands/intake-explain.md +18 -1
- package/plugins/src/base/rules/usage-accounting.md +2 -2
- package/plugins/src/base/scripts/automation-status-claude-adapter.mjs +1 -1
- package/plugins/src/base/scripts/automation-status-codex-adapter.mjs +1 -1
- package/plugins/src/base/scripts/doctor-report.mjs +14 -3
- package/plugins/src/base/skills/intake-explain/SKILL.md +52 -0
package/README.md
CHANGED
|
@@ -79,6 +79,7 @@ Most users only ever call `/lisa:research`, `/lisa:plan`, and `/lisa:implement`.
|
|
|
79
79
|
| Command | What it does |
|
|
80
80
|
| --- | --- |
|
|
81
81
|
| `/lisa:intake <queue-url>` | Scans a Ready queue (Notion PRD database, JIRA project, GitHub repo, Linear team, Confluence space) and dispatches each item through the right lifecycle command. Designed as the cron target for unattended runs. |
|
|
82
|
+
| `/lisa:intake-explain <item-ref>` | Read-only per-item diagnosis for PRD or build work. Reports the lifecycle role, verdict, decisive intake or repair gate, and smallest next action before an operator chooses `/lisa:intake`, `/lisa:repair-intake`, blocker cleanup, decomposition, or product follow-up. |
|
|
82
83
|
| `/lisa:queue-status [queue=prd|queue=build]` | Read-only queue inspection for the current repo. Distinguishes idle vs misconfigured queues, highlights the most actionable item, and points operators to `/lisa:intake`, `/lisa:repair-intake`, `/lisa:automation-status`, or `/lisa:verify-prd`. |
|
|
83
84
|
| `/lisa:repair-intake <queue-url>` | Read/write recovery scan for blocked, stale, or inconsistent queue state when normal intake is not the right next move. |
|
|
84
85
|
| `/lisa:automation-status` | Read-only inspection of the repo's expected Lisa automation fleet so operators can distinguish empty queues from stale, drifted, or failing scheduler jobs. |
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sum nullable decimal amounts using scaled integer math.
|
|
3
|
+
*
|
|
4
|
+
* @param values Decimal values to aggregate.
|
|
5
|
+
* @returns The decimal sum of present values, or null when all are missing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sumNullableDecimals(values: readonly (number | null)[]): number | null;
|
|
8
|
+
//# sourceMappingURL=decimal-sum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decimal-sum.d.ts","sourceRoot":"","sources":["../../src/utils/decimal-sum.ts"],"names":[],"mappings":"AA6CA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GACjC,MAAM,GAAG,IAAI,CA6Bf"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a finite number in plain decimal notation for BigInt scaling.
|
|
3
|
+
*
|
|
4
|
+
* @param value Finite number to normalize.
|
|
5
|
+
* @returns A plain decimal string without exponent notation.
|
|
6
|
+
*/
|
|
7
|
+
function renderPlainDecimal(value) {
|
|
8
|
+
const rendered = String(value);
|
|
9
|
+
if (!rendered.includes("e") && !rendered.includes("E")) {
|
|
10
|
+
return rendered;
|
|
11
|
+
}
|
|
12
|
+
const [mantissa = "0", exponentPart = "0"] = rendered
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.split("e");
|
|
15
|
+
const exponent = Number(exponentPart);
|
|
16
|
+
const negative = mantissa.startsWith("-");
|
|
17
|
+
const unsigned = negative ? mantissa.slice(1) : mantissa;
|
|
18
|
+
const [whole = "0", fractional = ""] = unsigned.split(".");
|
|
19
|
+
const digits = `${whole}${fractional}`;
|
|
20
|
+
const decimalIndex = whole.length + exponent;
|
|
21
|
+
const plain = decimalIndex <= 0
|
|
22
|
+
? `0.${"0".repeat(Math.abs(decimalIndex))}${digits}`
|
|
23
|
+
: decimalIndex >= digits.length
|
|
24
|
+
? `${digits}${"0".repeat(decimalIndex - digits.length)}`
|
|
25
|
+
: `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
|
26
|
+
return negative ? `-${plain}` : plain;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Remove insignificant trailing zeros from a fractional decimal string.
|
|
30
|
+
*
|
|
31
|
+
* @param value Fractional decimal digits.
|
|
32
|
+
* @returns Fractional digits with redundant right-side zeros removed.
|
|
33
|
+
*/
|
|
34
|
+
function trimTrailingZeros(value) {
|
|
35
|
+
const end = [...value].reduce((lastNonZero, digit, index) => (digit === "0" ? lastNonZero : index + 1), 0);
|
|
36
|
+
return value.slice(0, end);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sum nullable decimal amounts using scaled integer math.
|
|
40
|
+
*
|
|
41
|
+
* @param values Decimal values to aggregate.
|
|
42
|
+
* @returns The decimal sum of present values, or null when all are missing.
|
|
43
|
+
*/
|
|
44
|
+
export function sumNullableDecimals(values) {
|
|
45
|
+
const present = values.filter((value) => value !== null);
|
|
46
|
+
if (present.length === 0) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const decimals = present.map(value => renderPlainDecimal(value));
|
|
50
|
+
const scale = Math.max(...decimals.map(decimal => decimal.split(".")[1]?.length ?? 0));
|
|
51
|
+
const factor = 10n ** BigInt(scale);
|
|
52
|
+
const total = decimals.reduce((sum, decimal) => {
|
|
53
|
+
const negative = decimal.startsWith("-");
|
|
54
|
+
const unsigned = negative ? decimal.slice(1) : decimal;
|
|
55
|
+
const [whole = "0", fractional = ""] = unsigned.split(".");
|
|
56
|
+
const units = BigInt(`${whole}${fractional.padEnd(scale, "0")}` || "0");
|
|
57
|
+
return negative ? sum - units : sum + units;
|
|
58
|
+
}, 0n);
|
|
59
|
+
const negative = total < 0n;
|
|
60
|
+
const absolute = negative ? -total : total;
|
|
61
|
+
const whole = absolute / factor;
|
|
62
|
+
const fractional = scale === 0 ? "" : String(absolute % factor).padStart(scale, "0");
|
|
63
|
+
const rendered = scale === 0
|
|
64
|
+
? String(whole)
|
|
65
|
+
: `${whole}.${trimTrailingZeros(fractional) || "0"}`;
|
|
66
|
+
return Number(negative ? `-${rendered}` : rendered);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=decimal-sum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decimal-sum.js","sourceRoot":"","sources":["../../src/utils/decimal-sum.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-accounting.d.ts","sourceRoot":"","sources":["../../src/utils/usage-accounting.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usage-accounting.d.ts","sourceRoot":"","sources":["../../src/utils/usage-accounting.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7C,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CAChC;AAqMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,WAAW,EAAE,SAAS,cAAc,EAAE,GACrC,SAAS,cAAc,EAAE,CAa3B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,GACtC,eAAe,CAiCjB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,MAAM,EAAE,eAAe,CAAC;CACzB,GAAG,MAAM,CAsBT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GACf,sBAAsB,CAwCxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IACL,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACjC,GACA,MAAM,CAsBR"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sumNullableDecimals } from "./decimal-sum.js";
|
|
1
2
|
export const LISA_USAGE_HEADING = "## Lisa Usage";
|
|
2
3
|
const ENTRY_PATTERN = /<!-- lisa:usage-entry entry_id=(\S+) flow=(\S+) run_id=(\S+) provider=(\S+) model=(\S+) source=(\S+) input_tokens=(\S+) cached_input_tokens=(\S+) output_tokens=(\S+) reasoning_tokens=(\S+) total_tokens=(\S+) cost=(\S+) currency=(\S+) pricing_status=(\S+) pricing_source=(\S+) artifact_ref=(\S+) parent_artifact_ref=(\S*) -->/g;
|
|
3
4
|
const ROLLUP_PATTERN = /<!-- lisa:usage-rollup direct_entry_ids=(\S*) child_entry_ids=(\S*) child_refs=(\S*) direct_tokens=(\S+) child_tokens=(\S+) total_tokens=(\S+) direct_cost=(\S+) child_cost=(\S+) total_cost=(\S+) currency=(\S+) -->/;
|
|
@@ -12,7 +13,10 @@ function parseNullableNumber(value) {
|
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
15
|
const parsed = Number(value);
|
|
15
|
-
|
|
16
|
+
if (!Number.isFinite(parsed)) {
|
|
17
|
+
throw new Error(`Invalid Lisa usage numeric token: ${value}`);
|
|
18
|
+
}
|
|
19
|
+
return parsed;
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
22
|
* Parse a nullable string token field.
|
|
@@ -24,7 +28,31 @@ function parseNullableString(value) {
|
|
|
24
28
|
if (value === "null" || value.length === 0) {
|
|
25
29
|
return null;
|
|
26
30
|
}
|
|
27
|
-
return value;
|
|
31
|
+
return decodeTokenValue(value);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decode a percent-encoded token field.
|
|
35
|
+
*
|
|
36
|
+
* @param value Serialized token field.
|
|
37
|
+
* @returns The decoded token value, or the original value for legacy tokens.
|
|
38
|
+
*/
|
|
39
|
+
function decodeTokenValue(value) {
|
|
40
|
+
try {
|
|
41
|
+
return decodeURIComponent(value);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Serialize a token field so whitespace, delimiters, and HTML comment endings
|
|
49
|
+
* cannot corrupt the machine-readable comment on the next parse.
|
|
50
|
+
*
|
|
51
|
+
* @param value String token value to render.
|
|
52
|
+
* @returns The percent-encoded token value.
|
|
53
|
+
*/
|
|
54
|
+
function encodeTokenValue(value) {
|
|
55
|
+
return encodeURIComponent(value);
|
|
28
56
|
}
|
|
29
57
|
/**
|
|
30
58
|
* Serialize a nullable token field.
|
|
@@ -33,7 +61,10 @@ function parseNullableString(value) {
|
|
|
33
61
|
* @returns The canonical string form used inside usage tokens.
|
|
34
62
|
*/
|
|
35
63
|
function renderNullable(value) {
|
|
36
|
-
|
|
64
|
+
if (value === null) {
|
|
65
|
+
return "null";
|
|
66
|
+
}
|
|
67
|
+
return typeof value === "number" ? String(value) : encodeTokenValue(value);
|
|
37
68
|
}
|
|
38
69
|
/**
|
|
39
70
|
* Parse a comma-separated token field into stable document order.
|
|
@@ -45,7 +76,17 @@ function parseCsv(value) {
|
|
|
45
76
|
if (value.length === 0) {
|
|
46
77
|
return [];
|
|
47
78
|
}
|
|
48
|
-
return value.split(",");
|
|
79
|
+
return value.split(",").map(decodeTokenValue);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Serialize a list as a comma-delimited token field with each item encoded
|
|
83
|
+
* independently, so commas inside item values are preserved.
|
|
84
|
+
*
|
|
85
|
+
* @param values String values to serialize.
|
|
86
|
+
* @returns Encoded comma-delimited list.
|
|
87
|
+
*/
|
|
88
|
+
function renderCsv(values) {
|
|
89
|
+
return values.map(encodeTokenValue).join(",");
|
|
49
90
|
}
|
|
50
91
|
/**
|
|
51
92
|
* Sum nullable numeric values while preserving null when nothing was recorded.
|
|
@@ -148,7 +189,7 @@ export function mergeLisaUsageEntries(existingEntries, nextEntries) {
|
|
|
148
189
|
export function createLisaUsageRollup(entries, previousRollup) {
|
|
149
190
|
const directEntryIds = entries.map(entry => entry.entryId);
|
|
150
191
|
const directTokens = sumNullable(entries.map(entry => entry.totalTokens));
|
|
151
|
-
const directCost =
|
|
192
|
+
const directCost = sumNullableDecimals(entries.map(entry => entry.cost));
|
|
152
193
|
const childEntryIds = previousRollup?.childEntryIds ?? [];
|
|
153
194
|
const childRefs = previousRollup?.childRefs ?? [];
|
|
154
195
|
const childTokens = previousRollup ? previousRollup.childTokens : null;
|
|
@@ -158,7 +199,7 @@ export function createLisaUsageRollup(entries, previousRollup) {
|
|
|
158
199
|
: (directTokens ?? 0) + (childTokens ?? 0);
|
|
159
200
|
const totalCost = directCost === null && childCost === null
|
|
160
201
|
? null
|
|
161
|
-
: (directCost
|
|
202
|
+
: sumNullableDecimals([directCost, childCost]);
|
|
162
203
|
const currency = entries.find(entry => entry.currency !== null)?.currency ??
|
|
163
204
|
previousRollup?.currency ??
|
|
164
205
|
null;
|
|
@@ -182,7 +223,7 @@ export function createLisaUsageRollup(entries, previousRollup) {
|
|
|
182
223
|
* @returns The canonical `lisa:usage-entry` token line.
|
|
183
224
|
*/
|
|
184
225
|
export function renderLisaUsageEntryToken(entry) {
|
|
185
|
-
return `<!-- lisa:usage-entry entry_id=${entry.entryId} flow=${entry.flow} run_id=${entry.runId} provider=${entry.provider} model=${entry.model} source=${entry.source} input_tokens=${renderNullable(entry.inputTokens)} cached_input_tokens=${renderNullable(entry.cachedInputTokens)} output_tokens=${renderNullable(entry.outputTokens)} reasoning_tokens=${renderNullable(entry.reasoningTokens)} total_tokens=${renderNullable(entry.totalTokens)} cost=${renderNullable(entry.cost)} currency=${renderNullable(entry.currency)} pricing_status=${entry.pricingStatus} pricing_source=${renderNullable(entry.pricingSource)} artifact_ref=${entry.artifactRef} parent_artifact_ref=${entry.parentArtifactRef
|
|
226
|
+
return `<!-- lisa:usage-entry entry_id=${encodeTokenValue(entry.entryId)} flow=${encodeTokenValue(entry.flow)} run_id=${encodeTokenValue(entry.runId)} provider=${encodeTokenValue(entry.provider)} model=${encodeTokenValue(entry.model)} source=${encodeTokenValue(entry.source)} input_tokens=${renderNullable(entry.inputTokens)} cached_input_tokens=${renderNullable(entry.cachedInputTokens)} output_tokens=${renderNullable(entry.outputTokens)} reasoning_tokens=${renderNullable(entry.reasoningTokens)} total_tokens=${renderNullable(entry.totalTokens)} cost=${renderNullable(entry.cost)} currency=${renderNullable(entry.currency)} pricing_status=${encodeTokenValue(entry.pricingStatus)} pricing_source=${renderNullable(entry.pricingSource)} artifact_ref=${encodeTokenValue(entry.artifactRef)} parent_artifact_ref=${entry.parentArtifactRef === null ? "" : encodeTokenValue(entry.parentArtifactRef)} -->`;
|
|
186
227
|
}
|
|
187
228
|
/**
|
|
188
229
|
* Render the machine-readable rollup token for a managed usage section.
|
|
@@ -191,7 +232,7 @@ export function renderLisaUsageEntryToken(entry) {
|
|
|
191
232
|
* @returns The canonical `lisa:usage-rollup` token line.
|
|
192
233
|
*/
|
|
193
234
|
export function renderLisaUsageRollupToken(rollup) {
|
|
194
|
-
return `<!-- lisa:usage-rollup direct_entry_ids=${rollup.directEntryIds
|
|
235
|
+
return `<!-- lisa:usage-rollup direct_entry_ids=${renderCsv(rollup.directEntryIds)} child_entry_ids=${renderCsv(rollup.childEntryIds)} child_refs=${renderCsv(rollup.childRefs)} direct_tokens=${renderNullable(rollup.directTokens)} child_tokens=${renderNullable(rollup.childTokens)} total_tokens=${renderNullable(rollup.totalTokens)} direct_cost=${renderNullable(rollup.directCost)} child_cost=${renderNullable(rollup.childCost)} total_cost=${renderNullable(rollup.totalCost)} currency=${renderNullable(rollup.currency)} -->`;
|
|
195
236
|
}
|
|
196
237
|
/**
|
|
197
238
|
* Render the canonical `## Lisa Usage` section body from direct entries and a
|
|
@@ -230,12 +271,12 @@ export function parseLisaUsageSection(document) {
|
|
|
230
271
|
const range = findUsageSectionRange(document);
|
|
231
272
|
const section = range ? document.slice(range.start, range.end) : "";
|
|
232
273
|
const entries = Array.from(section.matchAll(ENTRY_PATTERN), match => ({
|
|
233
|
-
entryId: match[1] ?? "",
|
|
234
|
-
flow: match[2] ?? "",
|
|
235
|
-
runId: match[3] ?? "",
|
|
236
|
-
provider: match[4] ?? "",
|
|
237
|
-
model: match[5] ?? "",
|
|
238
|
-
source: match[6] ?? "",
|
|
274
|
+
entryId: decodeTokenValue(match[1] ?? ""),
|
|
275
|
+
flow: decodeTokenValue(match[2] ?? ""),
|
|
276
|
+
runId: decodeTokenValue(match[3] ?? ""),
|
|
277
|
+
provider: decodeTokenValue(match[4] ?? ""),
|
|
278
|
+
model: decodeTokenValue(match[5] ?? ""),
|
|
279
|
+
source: decodeTokenValue(match[6] ?? ""),
|
|
239
280
|
inputTokens: parseNullableNumber(match[7] ?? ""),
|
|
240
281
|
cachedInputTokens: parseNullableNumber(match[8] ?? ""),
|
|
241
282
|
outputTokens: parseNullableNumber(match[9] ?? ""),
|
|
@@ -243,9 +284,9 @@ export function parseLisaUsageSection(document) {
|
|
|
243
284
|
totalTokens: parseNullableNumber(match[11] ?? ""),
|
|
244
285
|
cost: parseNullableNumber(match[12] ?? ""),
|
|
245
286
|
currency: parseNullableString(match[13] ?? ""),
|
|
246
|
-
pricingStatus: match[14] ?? "",
|
|
287
|
+
pricingStatus: decodeTokenValue(match[14] ?? ""),
|
|
247
288
|
pricingSource: parseNullableString(match[15] ?? ""),
|
|
248
|
-
artifactRef: match[16] ?? "",
|
|
289
|
+
artifactRef: decodeTokenValue(match[16] ?? ""),
|
|
249
290
|
parentArtifactRef: parseNullableString(match[17] ?? ""),
|
|
250
291
|
}));
|
|
251
292
|
const rollupMatch = ROLLUP_PATTERN.exec(section);
|
|
@@ -278,7 +319,9 @@ export function parseLisaUsageSection(document) {
|
|
|
278
319
|
export function upsertLisaUsageSection(document, input) {
|
|
279
320
|
const parsed = parseLisaUsageSection(document);
|
|
280
321
|
const mergedEntries = mergeLisaUsageEntries(parsed.entries, input.entries);
|
|
281
|
-
const rollup =
|
|
322
|
+
const rollup = mergedEntries.length === 0 && input.rollup
|
|
323
|
+
? input.rollup
|
|
324
|
+
: createLisaUsageRollup(mergedEntries, input.rollup ?? parsed.rollup);
|
|
282
325
|
const usageSection = renderLisaUsageSection({
|
|
283
326
|
entries: mergedEntries,
|
|
284
327
|
rollup,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-accounting.js","sourceRoot":"","sources":["../../src/utils/usage-accounting.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usage-accounting.js","sourceRoot":"","sources":["../../src/utils/usage-accounting.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"lodash": ">=4.18.1"
|
|
83
83
|
},
|
|
84
84
|
"name": "@codyswann/lisa",
|
|
85
|
-
"version": "2.
|
|
85
|
+
"version": "2.101.0",
|
|
86
86
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
87
87
|
"main": "dist/index.js",
|
|
88
88
|
"exports": {
|
|
@@ -11,4 +11,21 @@ Common operator usage:
|
|
|
11
11
|
- `/lisa:intake-explain PRD-456`
|
|
12
12
|
- `/lisa:intake-explain https://linear.app/acme/issue/ENG-123/example`
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
The diagnosis uses stable verdicts:
|
|
15
|
+
|
|
16
|
+
- `ELIGIBLE_FOR_INTAKE`: run `/lisa:intake <queue>` when normal pickup is the next move.
|
|
17
|
+
- `ELIGIBLE_FOR_REPAIR`: run `/lisa:repair-intake <queue>` when Lisa-owned stuck work is actionable.
|
|
18
|
+
- `WAITING_ON_STALENESS`: wait and re-check after the configured freshness window.
|
|
19
|
+
- `HELD_BY_BLOCKERS`: clear the listed dependency or blocker before rerunning intake.
|
|
20
|
+
- `NON_LEAF_CONTAINER`: decompose the item or move build-ready status to leaf work.
|
|
21
|
+
- `PRODUCT_OWNED_STATE`: finish product clarification, promotion, or verification first.
|
|
22
|
+
- `MISCONFIGURED`: fix lifecycle labels, repo scope, or queue configuration before relying on automation.
|
|
23
|
+
|
|
24
|
+
Use it for these operator workflows:
|
|
25
|
+
|
|
26
|
+
- Intake triage: confirm whether one item would be picked up by `/lisa:intake` right now.
|
|
27
|
+
- Repair triage: decide whether a blocked or in-progress item is stale enough for `/lisa:repair-intake`.
|
|
28
|
+
- Product follow-up: distinguish product-owned draft/shipped/verified states from Lisa-owned work.
|
|
29
|
+
- Queue cleanup: identify leaf-only, repo-scope, dependency, or lifecycle-adoption fixes without mutating the item.
|
|
30
|
+
|
|
31
|
+
This surface is read-only in v1. It never claims, relabels, comments on, repairs, or decomposes the item; it only reports the item facts, verdict, decisive gate, and smallest useful next action before an operator chooses `/lisa:intake`, `/lisa:repair-intake`, `/lisa:queue-status`, or a tracker-native fix.
|
|
@@ -73,7 +73,7 @@ Every visible direct entry row ends with exactly one machine-readable token:
|
|
|
73
73
|
<!-- lisa:usage-entry entry_id=<id> flow=<flow> run_id=<run-id> provider=<provider> model=<model> source=<source> input_tokens=<n|null> cached_input_tokens=<n|null> output_tokens=<n|null> reasoning_tokens=<n|null> total_tokens=<n|null> cost=<decimal|null> currency=<code|null> pricing_status=<status> pricing_source=<ref|null> artifact_ref=<ref> parent_artifact_ref=<ref-or-empty> -->
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
Field order is fixed. A reader parses the usage ledger by matching `<!-- lisa:usage-entry ` lines only; it never needs to scrape prose or table cell positions.
|
|
76
|
+
Field order is fixed. A reader parses the usage ledger by matching `<!-- lisa:usage-entry ` lines only; it never needs to scrape prose or table cell positions. String fields are percent-encoded before rendering and decoded after parsing, so whitespace, commas, and HTML comment terminators inside source values cannot split or truncate the token.
|
|
77
77
|
|
|
78
78
|
Every managed section also ends with exactly one rollup token:
|
|
79
79
|
|
|
@@ -86,7 +86,7 @@ Every managed section also ends with exactly one rollup token:
|
|
|
86
86
|
- `child_refs` enumerates the child artifacts consulted for the rollup.
|
|
87
87
|
- `total_*` fields equal direct plus child totals over the deduped entry set.
|
|
88
88
|
|
|
89
|
-
The rollup token is the machine-readable summary. The visible rollup table mirrors it for humans.
|
|
89
|
+
The rollup token is the machine-readable summary. The visible rollup table mirrors it for humans. List fields are comma-delimited after encoding each item independently; commas inside an item are encoded as data, not treated as separators.
|
|
90
90
|
|
|
91
91
|
## Visible rendering contract
|
|
92
92
|
|
|
@@ -21,7 +21,7 @@ const CLAUDE_ACTIVE_STATUSES = new Set([
|
|
|
21
21
|
const RUN_FAILURE_PATTERN =
|
|
22
22
|
/\b(failed|failure|errored|error|exception|crash(?:ed)?)\b/i;
|
|
23
23
|
const NEGATED_FAILURE_PATTERN =
|
|
24
|
-
/\b(no|without)\s+(?:recent\s+)?fail(?:ure|ed)\b/i;
|
|
24
|
+
/\b(no|without)\s+(?:recent\s+)?(?:fail(?:ure|ed)|errors?|exceptions?)\b/i;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @typedef {import("./automation-status-expected-fleet.mjs").resolveExpectedAutomationFleet extends (...args: any[]) => infer T ? T : never} ExpectedFleet
|
|
@@ -20,7 +20,7 @@ const CODEx_RUNTIME_LABEL = "Codex automations";
|
|
|
20
20
|
const RUN_FAILURE_PATTERN =
|
|
21
21
|
/\b(failed|failure|errored|error|exception|crash(?:ed)?)\b/i;
|
|
22
22
|
const NEGATED_FAILURE_PATTERN =
|
|
23
|
-
/\b(no|without)\s+(?:recent\s+)?fail(?:ure|ed)\b/i;
|
|
23
|
+
/\b(no|without)\s+(?:recent\s+)?(?:fail(?:ure|ed)|errors?|exceptions?)\b/i;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* @typedef {import("./automation-status-expected-fleet.mjs").resolveExpectedAutomationFleet extends (...args: any[]) => infer T ? T : never} ExpectedFleet
|
|
@@ -39,7 +39,7 @@ export const DOCTOR_VERDICTS = ["READY", "READY_WITH_WARNINGS", "NOT_READY"];
|
|
|
39
39
|
* @returns {DoctorVerdict}
|
|
40
40
|
*/
|
|
41
41
|
export function computeDoctorVerdict(groups) {
|
|
42
|
-
const checks = groups.flatMap(group => group.checks);
|
|
42
|
+
const checks = groups.flatMap(group => group.checks.map(normalizeCheck));
|
|
43
43
|
if (checks.some(check => check.status === "FAIL")) {
|
|
44
44
|
return "NOT_READY";
|
|
45
45
|
}
|
|
@@ -55,7 +55,7 @@ export function computeDoctorVerdict(groups) {
|
|
|
55
55
|
*/
|
|
56
56
|
export function countDoctorStatuses(groups) {
|
|
57
57
|
return groups
|
|
58
|
-
.flatMap(group => group.checks)
|
|
58
|
+
.flatMap(group => group.checks.map(normalizeCheck))
|
|
59
59
|
.reduce(
|
|
60
60
|
(counts, check) => ({
|
|
61
61
|
...counts,
|
|
@@ -111,9 +111,20 @@ export function renderDoctorReport(input) {
|
|
|
111
111
|
* @returns {DoctorGroup}
|
|
112
112
|
*/
|
|
113
113
|
function normalizeGroup(group) {
|
|
114
|
+
const checks =
|
|
115
|
+
group.checks.length === 0
|
|
116
|
+
? [
|
|
117
|
+
{
|
|
118
|
+
id: "empty-group",
|
|
119
|
+
status: "SKIP",
|
|
120
|
+
summary: "no checks registered yet",
|
|
121
|
+
},
|
|
122
|
+
]
|
|
123
|
+
: group.checks.map(normalizeCheck);
|
|
124
|
+
|
|
114
125
|
return {
|
|
115
126
|
...group,
|
|
116
|
-
checks
|
|
127
|
+
checks,
|
|
117
128
|
};
|
|
118
129
|
}
|
|
119
130
|
|
|
@@ -143,6 +143,58 @@ The explanation must stay aligned with existing Lisa rules:
|
|
|
143
143
|
- If a claimed, in-review, or blocked item is not yet repairable, explain the relevant staleness or backoff condition at a human-readable level.
|
|
144
144
|
- If the source lane, tracker lane, repo/project scope, or lifecycle namespace is unresolved, report `MISCONFIGURED` instead of pretending the item is idle or actionable.
|
|
145
145
|
|
|
146
|
+
## PRD item role and repair diagnosis
|
|
147
|
+
|
|
148
|
+
For PRD lifecycle items, run the same read-side checks that PRD intake and repair-intake use before they would claim, validate, roll up, or retry a PRD. This is still a read-only explanation: if execution intake would transition `ready -> in_review`, route a `ticketed` PRD through rollup, move a `blocked` PRD after new answers, or suppress repair because a `[lisa-repair-intake]` marker is still inside its backoff window, intake-explain reports that decision and does not mutate the PRD, comments, labels, parent page, project labels, or generated work.
|
|
149
|
+
|
|
150
|
+
Resolve the source lane from `.lisa.config.json` `source` and the PRD lifecycle roles from the same vendor-specific config keys PRD intake and repair-intake use (`github.labels.prd.*`, `linear.labels.prd.*`, `notion.values.*`, or `confluence.parents.*`) with the usual defaults (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`, and `verified` equivalents). If the current item carries conflicting PRD lifecycle roles, lacks an adopted PRD namespace, or cannot be tied to the configured source lane, return `MISCONFIGURED` rather than guessing.
|
|
151
|
+
|
|
152
|
+
For GitHub-backed PRDs, collect these reader signals before choosing a verdict:
|
|
153
|
+
|
|
154
|
+
- current PRD lifecycle role label and any conflicting `prd-*` labels
|
|
155
|
+
- source-lane role ownership: `draft`, `shipped`, and `verified` are product-owned or verification-owned; `ready`, `in_review`, `blocked`, and `ticketed` are Lisa-owned for intake, repair, or rollup purposes
|
|
156
|
+
- provider-native timestamps (`updatedAt`) plus latest PRD comments, with special attention to comments after the most recent blocked or in-review marker
|
|
157
|
+
- `[lisa-repair-intake]` marker comments, including state fingerprint, repair verdict, retry count, and backoff window when present
|
|
158
|
+
- generated top-level work from native sub-issues first, then the `## Tickets` / `## Generated Work` section used by `prd-lifecycle-rollup`
|
|
159
|
+
- generated child terminal status so `ticketed` PRDs can explain whether rollup is waiting on downstream work or ready for `/lisa:repair-intake`
|
|
160
|
+
- clarifying-answer signals on `blocked` PRDs: new product comments, changed body text, changed blocker refs, or cleared dependencies compared with the last blocked/repair fingerprint
|
|
161
|
+
|
|
162
|
+
Apply PRD verdicts in the same order as PRD intake and repair-intake:
|
|
163
|
+
|
|
164
|
+
1. **Product-owned or verification-owned roles.** A PRD in `draft` returns `PRODUCT_OWNED_STATE`; the next action is manual product clarification or promotion to the configured `ready` role. A PRD in `shipped` returns `PRODUCT_OWNED_STATE` with `/lisa:verify-prd <item-ref>` as the next Lisa workflow because shipped-to-verified acceptance is outside PRD intake. A PRD in `verified` returns `PRODUCT_OWNED_STATE` or a terminal no-op explanation; normal intake and repair must not mutate it.
|
|
165
|
+
2. **Ready PRD.** A PRD in the configured `ready` role returns `ELIGIBLE_FOR_INTAKE` when the source lane and lifecycle namespace resolve cleanly. The `Why:` line should say PRD intake would claim it into the configured `in_review` role and run the source-to-tracker dry-run validate-to-route pipeline.
|
|
166
|
+
3. **In-review PRD.** A PRD in `in_review` is already Lisa-owned. Compare the newest activity signal against the resolved repair `stale_after` threshold (`$ARGUMENTS` override if present, `.lisa.config.json` `intake.repair.staleAfterHours`, then the 24h default). If provider activity, a progress comment, or a source edit is newer than `now - stale_after`, return `WAITING_ON_STALENESS` and name the activity timestamp. If no reliable timestamp exists, return `WAITING_ON_STALENESS` unless the caller explicitly uses the repair flow with `stale_after=0`; intake-explain should not imply automatic recovery from unknown freshness. If the item is stale and no repair-backoff marker suppresses retry, return `ELIGIBLE_FOR_REPAIR`.
|
|
167
|
+
4. **Blocked PRD.** A PRD in `blocked` is Lisa-owned but repairable only when the next validate-to-route pass can materially differ. Treat new human answers after the blocking comment, body edits after the blocking marker, cleared blockers, changed blocker refs, or changed validator fingerprint as repair-enabling signals. If none are present, return `HELD_BY_BLOCKERS` or `WAITING_ON_STALENESS` depending on whether the decisive fact is an active blocker/unchanged clarification need or a still-fresh blocked marker. If the blocker/answer state changed and repair backoff is clear, return `ELIGIBLE_FOR_REPAIR`.
|
|
168
|
+
5. **Ticketed PRD.** A PRD in `ticketed` is not ready for first intake. Read generated top-level work using the same `prd-lifecycle-rollup` boundary as PRD intake: top-level Epics and top-level Stories count; nested Stories and Sub-tasks do not. If any generated top-level child is non-terminal, return `PRODUCT_OWNED_STATE` or a waiting explanation that downstream build work is still in progress. If all generated top-level work is terminal but the PRD has not rolled up to `shipped`, return `ELIGIBLE_FOR_REPAIR` and recommend `/lisa:repair-intake <queue>` to reconcile rollup drift.
|
|
169
|
+
6. **Repair backoff suppression.** Before returning `ELIGIBLE_FOR_REPAIR` for `in_review`, `blocked`, or `ticketed` PRDs, inspect `[lisa-repair-intake]` markers. If the latest marker's state fingerprint matches the current reader signals and its backoff window has not expired, return `WAITING_ON_STALENESS` with a `Why:` line that says repair-intake would suppress an unchanged retry to avoid a loop. If the fingerprint changed, the backoff expired, or a human uses repair-intake `force=true`, the item may be repair-eligible.
|
|
170
|
+
|
|
171
|
+
Relevant `Signals:` should include the decisive context, not every field: for example `prd-blocked; new product comment after blocker`, `prd-in-review; last activity 2h ago; stale_after=24h`, `prd-ticketed; generated top-level work #12/#13 terminal`, or `[lisa-repair-intake] fingerprint unchanged; backoff until 2026-05-27T12:00:00Z`.
|
|
172
|
+
|
|
173
|
+
## Build item gate diagnosis
|
|
174
|
+
|
|
175
|
+
For build lifecycle items, run the same read-side checks that build intake runs before it would claim an issue. This is still a read-only explanation: if execution intake would stamp repo labels, split a cross-repo leaf, move a stale container from `ready` to `claimed`, or post a dependency-hold comment, intake-explain reports what intake would do but does not stamp, does not split, does not move labels, and does not comment.
|
|
176
|
+
|
|
177
|
+
Resolve the current repo using the same repo-scope contract as build intake: local config `repo`, then `.lisa.config.json` `github.repo`, then the git remote basename. Resolve the build lifecycle roles from `.lisa.config.json` `github.labels.build.*` with the usual defaults (`status:ready`, `status:in-progress`, `status:blocked`, `status:done`, plus any configured env-specific done labels). If those signals cannot be resolved, return `MISCONFIGURED`.
|
|
178
|
+
|
|
179
|
+
For GitHub build items, collect these reader signals before choosing a verdict:
|
|
180
|
+
|
|
181
|
+
- current build lifecycle role label and any conflicting `status:*` labels
|
|
182
|
+
- `repo:<current>` / `repo:<other>` labels, including whether the item is unlabeled for repo scope
|
|
183
|
+
- type labels such as `type:Epic`, `type:Story`, `type:Spike`, `type:Bug`, `type:Task`, `type:Sub-task`, and `type:Improvement`
|
|
184
|
+
- native GitHub sub-issues and their open/closed state
|
|
185
|
+
- body parentage used by `github-read-issue`, including task-list child references and `Parent: #123` style references
|
|
186
|
+
- explicit dependency holds from `Blocked by: #123`, comma-separated refs, `owner/repo#123`, and GitHub issue URLs
|
|
187
|
+
- blocker issue state and blocker status labels
|
|
188
|
+
|
|
189
|
+
Apply gate verdicts in the same order as build intake:
|
|
190
|
+
|
|
191
|
+
1. **Repo-scope gate.** A build item carrying `repo:<other>` and not `repo:<current>` is outside this repo's pickup lane. Return `MISCONFIGURED` when repo scope is absent or contradictory enough that the current repo cannot be determined confidently; otherwise explain the repo-scope mismatch and recommend running intake in the target repo or fixing the `repo:<name>` label. For an unlabeled item whose target repo is obvious from the item body, report the inferred repo signal but stay read-only: execution intake would stamp `repo:<name>`, while intake-explain only says it would do so. A multi-repo leaf is not directly buildable; explain that execution intake would split it per `repo-scope-split`, but this read-only diagnosis does not split.
|
|
192
|
+
2. **Leaf-only gate.** If the item has open child work from native GitHub sub-issues or body parentage, return `NON_LEAF_CONTAINER` and explain that direct build pickup is leaf-only per `leaf-only-lifecycle`. If it has no open children but carries a container type (`type:Epic`, `type:Story`, or `type:Spike`), also return `NON_LEAF_CONTAINER` because a childless container type still needs decomposition or reclassification. The next action is decomposition, moving `status:ready` to leaf children, or correcting the issue type. Execution build intake would move such a stale ready container out of the pickup queue; this read-only diagnosis must not perform that repair.
|
|
193
|
+
3. **Dependency hold gate.** If a single-repo leaf for the current repo has explicit blockers, read each blocker. Closed blockers are clear. Open blockers are clear only when they carry a cleared build status such as `status:code-review`, `status:on-dev`, `status:on-stg`, `status:done`, or the configured done-equivalent labels. Open blockers with `status:ready`, `status:in-progress`, no cleared status label, or inaccessible state are active. Return `HELD_BY_BLOCKERS`, list the active blocker refs, and make the next action blocker resolution rather than `/lisa:intake`.
|
|
194
|
+
4. **Ready leaf.** A build item in the configured ready role, scoped to the current repo, with no open child work and no active blockers returns `ELIGIBLE_FOR_INTAKE`. The `Why:` line should say it is a single-repo leaf for the current repo and that leaf-only, repo-scope, and dependency gates all pass.
|
|
195
|
+
|
|
196
|
+
Relevant `Signals:` should include the decisive context, not every field: for example `repo:lisa; type:Sub-task; no open children`, `open children #12/#13`, `repo:api but current repo is web`, or `active blockers CodySwannGT/lisa#123`.
|
|
197
|
+
|
|
146
198
|
## Rule explanation expectations
|
|
147
199
|
|
|
148
200
|
The `Why:` line should name the decisive Lisa contract in plain English rather than only echoing a raw status label. Good explanations usually mention one of:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.101.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.101.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -11,4 +11,21 @@ Common operator usage:
|
|
|
11
11
|
- `/lisa:intake-explain PRD-456`
|
|
12
12
|
- `/lisa:intake-explain https://linear.app/acme/issue/ENG-123/example`
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
The diagnosis uses stable verdicts:
|
|
15
|
+
|
|
16
|
+
- `ELIGIBLE_FOR_INTAKE`: run `/lisa:intake <queue>` when normal pickup is the next move.
|
|
17
|
+
- `ELIGIBLE_FOR_REPAIR`: run `/lisa:repair-intake <queue>` when Lisa-owned stuck work is actionable.
|
|
18
|
+
- `WAITING_ON_STALENESS`: wait and re-check after the configured freshness window.
|
|
19
|
+
- `HELD_BY_BLOCKERS`: clear the listed dependency or blocker before rerunning intake.
|
|
20
|
+
- `NON_LEAF_CONTAINER`: decompose the item or move build-ready status to leaf work.
|
|
21
|
+
- `PRODUCT_OWNED_STATE`: finish product clarification, promotion, or verification first.
|
|
22
|
+
- `MISCONFIGURED`: fix lifecycle labels, repo scope, or queue configuration before relying on automation.
|
|
23
|
+
|
|
24
|
+
Use it for these operator workflows:
|
|
25
|
+
|
|
26
|
+
- Intake triage: confirm whether one item would be picked up by `/lisa:intake` right now.
|
|
27
|
+
- Repair triage: decide whether a blocked or in-progress item is stale enough for `/lisa:repair-intake`.
|
|
28
|
+
- Product follow-up: distinguish product-owned draft/shipped/verified states from Lisa-owned work.
|
|
29
|
+
- Queue cleanup: identify leaf-only, repo-scope, dependency, or lifecycle-adoption fixes without mutating the item.
|
|
30
|
+
|
|
31
|
+
This surface is read-only in v1. It never claims, relabels, comments on, repairs, or decomposes the item; it only reports the item facts, verdict, decisive gate, and smallest useful next action before an operator chooses `/lisa:intake`, `/lisa:repair-intake`, `/lisa:queue-status`, or a tracker-native fix.
|
|
@@ -73,7 +73,7 @@ Every visible direct entry row ends with exactly one machine-readable token:
|
|
|
73
73
|
<!-- lisa:usage-entry entry_id=<id> flow=<flow> run_id=<run-id> provider=<provider> model=<model> source=<source> input_tokens=<n|null> cached_input_tokens=<n|null> output_tokens=<n|null> reasoning_tokens=<n|null> total_tokens=<n|null> cost=<decimal|null> currency=<code|null> pricing_status=<status> pricing_source=<ref|null> artifact_ref=<ref> parent_artifact_ref=<ref-or-empty> -->
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
Field order is fixed. A reader parses the usage ledger by matching `<!-- lisa:usage-entry ` lines only; it never needs to scrape prose or table cell positions.
|
|
76
|
+
Field order is fixed. A reader parses the usage ledger by matching `<!-- lisa:usage-entry ` lines only; it never needs to scrape prose or table cell positions. String fields are percent-encoded before rendering and decoded after parsing, so whitespace, commas, and HTML comment terminators inside source values cannot split or truncate the token.
|
|
77
77
|
|
|
78
78
|
Every managed section also ends with exactly one rollup token:
|
|
79
79
|
|
|
@@ -86,7 +86,7 @@ Every managed section also ends with exactly one rollup token:
|
|
|
86
86
|
- `child_refs` enumerates the child artifacts consulted for the rollup.
|
|
87
87
|
- `total_*` fields equal direct plus child totals over the deduped entry set.
|
|
88
88
|
|
|
89
|
-
The rollup token is the machine-readable summary. The visible rollup table mirrors it for humans.
|
|
89
|
+
The rollup token is the machine-readable summary. The visible rollup table mirrors it for humans. List fields are comma-delimited after encoding each item independently; commas inside an item are encoded as data, not treated as separators.
|
|
90
90
|
|
|
91
91
|
## Visible rendering contract
|
|
92
92
|
|
|
@@ -21,7 +21,7 @@ const CLAUDE_ACTIVE_STATUSES = new Set([
|
|
|
21
21
|
const RUN_FAILURE_PATTERN =
|
|
22
22
|
/\b(failed|failure|errored|error|exception|crash(?:ed)?)\b/i;
|
|
23
23
|
const NEGATED_FAILURE_PATTERN =
|
|
24
|
-
/\b(no|without)\s+(?:recent\s+)?fail(?:ure|ed)\b/i;
|
|
24
|
+
/\b(no|without)\s+(?:recent\s+)?(?:fail(?:ure|ed)|errors?|exceptions?)\b/i;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @typedef {import("./automation-status-expected-fleet.mjs").resolveExpectedAutomationFleet extends (...args: any[]) => infer T ? T : never} ExpectedFleet
|
|
@@ -20,7 +20,7 @@ const CODEx_RUNTIME_LABEL = "Codex automations";
|
|
|
20
20
|
const RUN_FAILURE_PATTERN =
|
|
21
21
|
/\b(failed|failure|errored|error|exception|crash(?:ed)?)\b/i;
|
|
22
22
|
const NEGATED_FAILURE_PATTERN =
|
|
23
|
-
/\b(no|without)\s+(?:recent\s+)?fail(?:ure|ed)\b/i;
|
|
23
|
+
/\b(no|without)\s+(?:recent\s+)?(?:fail(?:ure|ed)|errors?|exceptions?)\b/i;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* @typedef {import("./automation-status-expected-fleet.mjs").resolveExpectedAutomationFleet extends (...args: any[]) => infer T ? T : never} ExpectedFleet
|
|
@@ -39,7 +39,7 @@ export const DOCTOR_VERDICTS = ["READY", "READY_WITH_WARNINGS", "NOT_READY"];
|
|
|
39
39
|
* @returns {DoctorVerdict}
|
|
40
40
|
*/
|
|
41
41
|
export function computeDoctorVerdict(groups) {
|
|
42
|
-
const checks = groups.flatMap(group => group.checks);
|
|
42
|
+
const checks = groups.flatMap(group => group.checks.map(normalizeCheck));
|
|
43
43
|
if (checks.some(check => check.status === "FAIL")) {
|
|
44
44
|
return "NOT_READY";
|
|
45
45
|
}
|
|
@@ -55,7 +55,7 @@ export function computeDoctorVerdict(groups) {
|
|
|
55
55
|
*/
|
|
56
56
|
export function countDoctorStatuses(groups) {
|
|
57
57
|
return groups
|
|
58
|
-
.flatMap(group => group.checks)
|
|
58
|
+
.flatMap(group => group.checks.map(normalizeCheck))
|
|
59
59
|
.reduce(
|
|
60
60
|
(counts, check) => ({
|
|
61
61
|
...counts,
|
|
@@ -111,9 +111,20 @@ export function renderDoctorReport(input) {
|
|
|
111
111
|
* @returns {DoctorGroup}
|
|
112
112
|
*/
|
|
113
113
|
function normalizeGroup(group) {
|
|
114
|
+
const checks =
|
|
115
|
+
group.checks.length === 0
|
|
116
|
+
? [
|
|
117
|
+
{
|
|
118
|
+
id: "empty-group",
|
|
119
|
+
status: "SKIP",
|
|
120
|
+
summary: "no checks registered yet",
|
|
121
|
+
},
|
|
122
|
+
]
|
|
123
|
+
: group.checks.map(normalizeCheck);
|
|
124
|
+
|
|
114
125
|
return {
|
|
115
126
|
...group,
|
|
116
|
-
checks
|
|
127
|
+
checks,
|
|
117
128
|
};
|
|
118
129
|
}
|
|
119
130
|
|
|
@@ -143,6 +143,58 @@ The explanation must stay aligned with existing Lisa rules:
|
|
|
143
143
|
- If a claimed, in-review, or blocked item is not yet repairable, explain the relevant staleness or backoff condition at a human-readable level.
|
|
144
144
|
- If the source lane, tracker lane, repo/project scope, or lifecycle namespace is unresolved, report `MISCONFIGURED` instead of pretending the item is idle or actionable.
|
|
145
145
|
|
|
146
|
+
## PRD item role and repair diagnosis
|
|
147
|
+
|
|
148
|
+
For PRD lifecycle items, run the same read-side checks that PRD intake and repair-intake use before they would claim, validate, roll up, or retry a PRD. This is still a read-only explanation: if execution intake would transition `ready -> in_review`, route a `ticketed` PRD through rollup, move a `blocked` PRD after new answers, or suppress repair because a `[lisa-repair-intake]` marker is still inside its backoff window, intake-explain reports that decision and does not mutate the PRD, comments, labels, parent page, project labels, or generated work.
|
|
149
|
+
|
|
150
|
+
Resolve the source lane from `.lisa.config.json` `source` and the PRD lifecycle roles from the same vendor-specific config keys PRD intake and repair-intake use (`github.labels.prd.*`, `linear.labels.prd.*`, `notion.values.*`, or `confluence.parents.*`) with the usual defaults (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`, and `verified` equivalents). If the current item carries conflicting PRD lifecycle roles, lacks an adopted PRD namespace, or cannot be tied to the configured source lane, return `MISCONFIGURED` rather than guessing.
|
|
151
|
+
|
|
152
|
+
For GitHub-backed PRDs, collect these reader signals before choosing a verdict:
|
|
153
|
+
|
|
154
|
+
- current PRD lifecycle role label and any conflicting `prd-*` labels
|
|
155
|
+
- source-lane role ownership: `draft`, `shipped`, and `verified` are product-owned or verification-owned; `ready`, `in_review`, `blocked`, and `ticketed` are Lisa-owned for intake, repair, or rollup purposes
|
|
156
|
+
- provider-native timestamps (`updatedAt`) plus latest PRD comments, with special attention to comments after the most recent blocked or in-review marker
|
|
157
|
+
- `[lisa-repair-intake]` marker comments, including state fingerprint, repair verdict, retry count, and backoff window when present
|
|
158
|
+
- generated top-level work from native sub-issues first, then the `## Tickets` / `## Generated Work` section used by `prd-lifecycle-rollup`
|
|
159
|
+
- generated child terminal status so `ticketed` PRDs can explain whether rollup is waiting on downstream work or ready for `/lisa:repair-intake`
|
|
160
|
+
- clarifying-answer signals on `blocked` PRDs: new product comments, changed body text, changed blocker refs, or cleared dependencies compared with the last blocked/repair fingerprint
|
|
161
|
+
|
|
162
|
+
Apply PRD verdicts in the same order as PRD intake and repair-intake:
|
|
163
|
+
|
|
164
|
+
1. **Product-owned or verification-owned roles.** A PRD in `draft` returns `PRODUCT_OWNED_STATE`; the next action is manual product clarification or promotion to the configured `ready` role. A PRD in `shipped` returns `PRODUCT_OWNED_STATE` with `/lisa:verify-prd <item-ref>` as the next Lisa workflow because shipped-to-verified acceptance is outside PRD intake. A PRD in `verified` returns `PRODUCT_OWNED_STATE` or a terminal no-op explanation; normal intake and repair must not mutate it.
|
|
165
|
+
2. **Ready PRD.** A PRD in the configured `ready` role returns `ELIGIBLE_FOR_INTAKE` when the source lane and lifecycle namespace resolve cleanly. The `Why:` line should say PRD intake would claim it into the configured `in_review` role and run the source-to-tracker dry-run validate-to-route pipeline.
|
|
166
|
+
3. **In-review PRD.** A PRD in `in_review` is already Lisa-owned. Compare the newest activity signal against the resolved repair `stale_after` threshold (`$ARGUMENTS` override if present, `.lisa.config.json` `intake.repair.staleAfterHours`, then the 24h default). If provider activity, a progress comment, or a source edit is newer than `now - stale_after`, return `WAITING_ON_STALENESS` and name the activity timestamp. If no reliable timestamp exists, return `WAITING_ON_STALENESS` unless the caller explicitly uses the repair flow with `stale_after=0`; intake-explain should not imply automatic recovery from unknown freshness. If the item is stale and no repair-backoff marker suppresses retry, return `ELIGIBLE_FOR_REPAIR`.
|
|
167
|
+
4. **Blocked PRD.** A PRD in `blocked` is Lisa-owned but repairable only when the next validate-to-route pass can materially differ. Treat new human answers after the blocking comment, body edits after the blocking marker, cleared blockers, changed blocker refs, or changed validator fingerprint as repair-enabling signals. If none are present, return `HELD_BY_BLOCKERS` or `WAITING_ON_STALENESS` depending on whether the decisive fact is an active blocker/unchanged clarification need or a still-fresh blocked marker. If the blocker/answer state changed and repair backoff is clear, return `ELIGIBLE_FOR_REPAIR`.
|
|
168
|
+
5. **Ticketed PRD.** A PRD in `ticketed` is not ready for first intake. Read generated top-level work using the same `prd-lifecycle-rollup` boundary as PRD intake: top-level Epics and top-level Stories count; nested Stories and Sub-tasks do not. If any generated top-level child is non-terminal, return `PRODUCT_OWNED_STATE` or a waiting explanation that downstream build work is still in progress. If all generated top-level work is terminal but the PRD has not rolled up to `shipped`, return `ELIGIBLE_FOR_REPAIR` and recommend `/lisa:repair-intake <queue>` to reconcile rollup drift.
|
|
169
|
+
6. **Repair backoff suppression.** Before returning `ELIGIBLE_FOR_REPAIR` for `in_review`, `blocked`, or `ticketed` PRDs, inspect `[lisa-repair-intake]` markers. If the latest marker's state fingerprint matches the current reader signals and its backoff window has not expired, return `WAITING_ON_STALENESS` with a `Why:` line that says repair-intake would suppress an unchanged retry to avoid a loop. If the fingerprint changed, the backoff expired, or a human uses repair-intake `force=true`, the item may be repair-eligible.
|
|
170
|
+
|
|
171
|
+
Relevant `Signals:` should include the decisive context, not every field: for example `prd-blocked; new product comment after blocker`, `prd-in-review; last activity 2h ago; stale_after=24h`, `prd-ticketed; generated top-level work #12/#13 terminal`, or `[lisa-repair-intake] fingerprint unchanged; backoff until 2026-05-27T12:00:00Z`.
|
|
172
|
+
|
|
173
|
+
## Build item gate diagnosis
|
|
174
|
+
|
|
175
|
+
For build lifecycle items, run the same read-side checks that build intake runs before it would claim an issue. This is still a read-only explanation: if execution intake would stamp repo labels, split a cross-repo leaf, move a stale container from `ready` to `claimed`, or post a dependency-hold comment, intake-explain reports what intake would do but does not stamp, does not split, does not move labels, and does not comment.
|
|
176
|
+
|
|
177
|
+
Resolve the current repo using the same repo-scope contract as build intake: local config `repo`, then `.lisa.config.json` `github.repo`, then the git remote basename. Resolve the build lifecycle roles from `.lisa.config.json` `github.labels.build.*` with the usual defaults (`status:ready`, `status:in-progress`, `status:blocked`, `status:done`, plus any configured env-specific done labels). If those signals cannot be resolved, return `MISCONFIGURED`.
|
|
178
|
+
|
|
179
|
+
For GitHub build items, collect these reader signals before choosing a verdict:
|
|
180
|
+
|
|
181
|
+
- current build lifecycle role label and any conflicting `status:*` labels
|
|
182
|
+
- `repo:<current>` / `repo:<other>` labels, including whether the item is unlabeled for repo scope
|
|
183
|
+
- type labels such as `type:Epic`, `type:Story`, `type:Spike`, `type:Bug`, `type:Task`, `type:Sub-task`, and `type:Improvement`
|
|
184
|
+
- native GitHub sub-issues and their open/closed state
|
|
185
|
+
- body parentage used by `github-read-issue`, including task-list child references and `Parent: #123` style references
|
|
186
|
+
- explicit dependency holds from `Blocked by: #123`, comma-separated refs, `owner/repo#123`, and GitHub issue URLs
|
|
187
|
+
- blocker issue state and blocker status labels
|
|
188
|
+
|
|
189
|
+
Apply gate verdicts in the same order as build intake:
|
|
190
|
+
|
|
191
|
+
1. **Repo-scope gate.** A build item carrying `repo:<other>` and not `repo:<current>` is outside this repo's pickup lane. Return `MISCONFIGURED` when repo scope is absent or contradictory enough that the current repo cannot be determined confidently; otherwise explain the repo-scope mismatch and recommend running intake in the target repo or fixing the `repo:<name>` label. For an unlabeled item whose target repo is obvious from the item body, report the inferred repo signal but stay read-only: execution intake would stamp `repo:<name>`, while intake-explain only says it would do so. A multi-repo leaf is not directly buildable; explain that execution intake would split it per `repo-scope-split`, but this read-only diagnosis does not split.
|
|
192
|
+
2. **Leaf-only gate.** If the item has open child work from native GitHub sub-issues or body parentage, return `NON_LEAF_CONTAINER` and explain that direct build pickup is leaf-only per `leaf-only-lifecycle`. If it has no open children but carries a container type (`type:Epic`, `type:Story`, or `type:Spike`), also return `NON_LEAF_CONTAINER` because a childless container type still needs decomposition or reclassification. The next action is decomposition, moving `status:ready` to leaf children, or correcting the issue type. Execution build intake would move such a stale ready container out of the pickup queue; this read-only diagnosis must not perform that repair.
|
|
193
|
+
3. **Dependency hold gate.** If a single-repo leaf for the current repo has explicit blockers, read each blocker. Closed blockers are clear. Open blockers are clear only when they carry a cleared build status such as `status:code-review`, `status:on-dev`, `status:on-stg`, `status:done`, or the configured done-equivalent labels. Open blockers with `status:ready`, `status:in-progress`, no cleared status label, or inaccessible state are active. Return `HELD_BY_BLOCKERS`, list the active blocker refs, and make the next action blocker resolution rather than `/lisa:intake`.
|
|
194
|
+
4. **Ready leaf.** A build item in the configured ready role, scoped to the current repo, with no open child work and no active blockers returns `ELIGIBLE_FOR_INTAKE`. The `Why:` line should say it is a single-repo leaf for the current repo and that leaf-only, repo-scope, and dependency gates all pass.
|
|
195
|
+
|
|
196
|
+
Relevant `Signals:` should include the decisive context, not every field: for example `repo:lisa; type:Sub-task; no open children`, `open children #12/#13`, `repo:api but current repo is web`, or `active blockers CodySwannGT/lisa#123`.
|
|
197
|
+
|
|
146
198
|
## Rule explanation expectations
|
|
147
199
|
|
|
148
200
|
The `Why:` line should name the decisive Lisa contract in plain English rather than only echoing a raw status label. Good explanations usually mention one of:
|