@codyswann/lisa 2.230.1 → 2.232.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/dist/cli/ui-cmd.d.ts.map +1 -1
- package/dist/cli/ui-cmd.js +8 -2
- package/dist/cli/ui-cmd.js.map +1 -1
- package/dist/cli/ui-config-write.d.ts +13 -0
- package/dist/cli/ui-config-write.d.ts.map +1 -0
- package/dist/cli/ui-config-write.js +283 -0
- package/dist/cli/ui-config-write.js.map +1 -0
- 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/.codex-plugin/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/agents/openai.yaml +4 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-ticket-triage/SKILL.md +20 -0
- package/plugins/lisa/agents/learner.md +8 -1
- package/plugins/lisa/agents/learnings-synthesizer.md +4 -1
- package/plugins/lisa/commands/rework-triage.md +6 -0
- package/plugins/lisa/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/lisa/skills/lisa-rework-triage/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/lisa-ticket-triage/SKILL.md +21 -1
- package/plugins/lisa-agy/agents/learner.md +8 -1
- package/plugins/lisa-agy/agents/learnings-synthesizer.md +4 -1
- package/plugins/lisa-agy/commands/lisa/rework-triage.md +6 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/lisa-agy/skills/lisa-ticket-triage/SKILL.md +21 -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-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/agents/learner.agent.md +8 -1
- package/plugins/lisa-copilot/agents/learnings-synthesizer.agent.md +4 -1
- package/plugins/lisa-copilot/commands/lisa/rework-triage.md +6 -0
- package/plugins/lisa-copilot/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/lisa-copilot/skills/lisa-ticket-triage/SKILL.md +21 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/learner.md +8 -1
- package/plugins/lisa-cursor/agents/learnings-synthesizer.md +4 -1
- package/plugins/lisa-cursor/commands/lisa/rework-triage.md +6 -0
- package/plugins/lisa-cursor/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/lisa-cursor/skills/lisa-ticket-triage/SKILL.md +21 -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-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-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-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-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-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-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-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/src/base/agents/learner.md +8 -1
- package/plugins/src/base/agents/learnings-synthesizer.md +4 -1
- package/plugins/src/base/commands/rework-triage.md +6 -0
- package/plugins/src/base/skills/lisa-debrief-apply/SKILL.md +9 -2
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +155 -0
- package/plugins/src/base/skills/lisa-ticket-triage/SKILL.md +21 -1
package/dist/cli/ui-cmd.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-cmd.d.ts","sourceRoot":"","sources":["../../src/cli/ui-cmd.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ui-cmd.d.ts","sourceRoot":"","sources":["../../src/cli/ui-cmd.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,6CAA6C;AAC7C,eAAO,MAAM,eAAe,OAAO,CAAC;AAKpC,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAYD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUnD;AAmBD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,iBAAiB,GAAE,uBAIlB,GACA,MAAM,CAQR;AAgKD;;;;;;GAMG;AACH,wBAAsB,KAAK,CACzB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,GAAE,YAAiB,EAC1B,YAAY,GAAE,qBAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAkCtB"}
|
package/dist/cli/ui-cmd.js
CHANGED
|
@@ -18,6 +18,7 @@ import { deepMerge, readJsonOrNull } from "../utils/index.js";
|
|
|
18
18
|
import { printSyncReport } from "./sync-cmd.js";
|
|
19
19
|
import { inspectRemoteEnvironment, } from "./remote-environment.js";
|
|
20
20
|
import { createGithubAuthProbe, readStatusSnapshot, validateStatusProbes, } from "./ui-status.js";
|
|
21
|
+
import { serveConfigWrite } from "./ui-config-write.js";
|
|
21
22
|
export { createGithubAuthProbe, runProbe, } from "./ui-status.js";
|
|
22
23
|
export { inspectRemoteEnvironment } from "./remote-environment.js";
|
|
23
24
|
/** Default port for the settings console. */
|
|
@@ -185,9 +186,10 @@ function isLoopbackHost(host) {
|
|
|
185
186
|
* Build the request handler after validating the complete probe registry.
|
|
186
187
|
* @param page - Hydrated settings console HTML
|
|
187
188
|
* @param probes - Live-status probes registered for this server
|
|
189
|
+
* @param destDir - Project root served by this UI process
|
|
188
190
|
* @returns Loopback HTTP request handler
|
|
189
191
|
*/
|
|
190
|
-
function createUiRequestHandler(page, probes) {
|
|
192
|
+
function createUiRequestHandler(page, probes, destDir) {
|
|
191
193
|
const readSnapshot = createStatusSnapshotReader(probes);
|
|
192
194
|
validateStatusProbes(probes);
|
|
193
195
|
return (request, response) => {
|
|
@@ -206,6 +208,10 @@ function createUiRequestHandler(page, probes) {
|
|
|
206
208
|
serveStatus(request, response, readSnapshot);
|
|
207
209
|
return;
|
|
208
210
|
}
|
|
211
|
+
if (pathname === "/api/config") {
|
|
212
|
+
serveConfigWrite(request, response, destDir);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
209
215
|
if (pathname === "/" || pathname === "/index.html") {
|
|
210
216
|
response.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
211
217
|
response.end(page);
|
|
@@ -239,7 +245,7 @@ export async function runUi(targetPath, options = {}, dependencies = {}) {
|
|
|
239
245
|
const remoteEnvironment = await inspectRemoteEnvironment(destDir, config, getProcessEnvironment());
|
|
240
246
|
const page = injectLiveConfig(html, config, remoteEnvironment);
|
|
241
247
|
const probes = dependencies.probes ?? [createGithubAuthProbe(destDir)];
|
|
242
|
-
const server = http.createServer(createUiRequestHandler(page, probes));
|
|
248
|
+
const server = http.createServer(createUiRequestHandler(page, probes, destDir));
|
|
243
249
|
await new Promise(resolve => {
|
|
244
250
|
server.listen(port, "127.0.0.1", resolve);
|
|
245
251
|
});
|
package/dist/cli/ui-cmd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-cmd.js","sourceRoot":"","sources":["../../src/cli/ui-cmd.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ui-cmd.js","sourceRoot":"","sources":["../../src/cli/ui-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Same-origin config write endpoint for `lisa ui`.
|
|
3
|
+
* @module cli/ui-config-write
|
|
4
|
+
*/
|
|
5
|
+
import * as http from "node:http";
|
|
6
|
+
/**
|
|
7
|
+
* Serve the same-origin committed-config write endpoint.
|
|
8
|
+
* @param request - Incoming loopback request
|
|
9
|
+
* @param response - Response associated with the request
|
|
10
|
+
* @param destDir - Project root whose committed config is written
|
|
11
|
+
*/
|
|
12
|
+
export declare function serveConfigWrite(request: http.IncomingMessage, response: http.ServerResponse, destDir: string): void;
|
|
13
|
+
//# sourceMappingURL=ui-config-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-config-write.d.ts","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AA0QlC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,eAAe,EAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc,EAC7B,OAAO,EAAE,MAAM,GACd,IAAI,CAsDN"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { isJsonObject, setAtPath, } from "../sync/json-path.js";
|
|
4
|
+
import { writeJson } from "../utils/index.js";
|
|
5
|
+
const CONFIG_FILE = ".lisa.config.json";
|
|
6
|
+
const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
|
|
7
|
+
const MAX_CONFIG_WRITE_BYTES = 128 * 1024;
|
|
8
|
+
const NO_STORE = "no-store";
|
|
9
|
+
const TEXT_CONTENT_TYPE = "text/plain; charset=utf-8";
|
|
10
|
+
const configWriteQueues = new Map();
|
|
11
|
+
/** Error raised for malformed request bodies that should return 400. */
|
|
12
|
+
class RequestBodyError extends Error {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read the project's committed config file.
|
|
16
|
+
* @param destDir - Project root
|
|
17
|
+
* @returns Committed config object, or an empty config if absent/malformed
|
|
18
|
+
*/
|
|
19
|
+
async function readCommittedConfig(destDir) {
|
|
20
|
+
const configPath = path.join(destDir, CONFIG_FILE);
|
|
21
|
+
try {
|
|
22
|
+
const committed = JSON.parse(await readFile(configPath, "utf8"));
|
|
23
|
+
if (!isJsonObject(committed)) {
|
|
24
|
+
throw new Error(`${CONFIG_FILE} must contain a JSON object`);
|
|
25
|
+
}
|
|
26
|
+
return committed;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (typeof error === "object" &&
|
|
30
|
+
error !== null &&
|
|
31
|
+
"code" in error &&
|
|
32
|
+
error.code === "ENOENT") {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Restrict loopback origins to the authority advertised by `lisa ui`.
|
|
40
|
+
* @param host - Origin URL host
|
|
41
|
+
* @returns Whether the authority is 127.0.0.1 with an optional valid port
|
|
42
|
+
*/
|
|
43
|
+
function isLoopbackHost(host) {
|
|
44
|
+
if (host === "127.0.0.1") {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
const prefix = "127.0.0.1:";
|
|
48
|
+
if (!host.startsWith(prefix)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const portText = host.slice(prefix.length);
|
|
52
|
+
const digitsOnly = Array.from(portText).every(character => character >= "0" && character <= "9");
|
|
53
|
+
const port = Number(portText);
|
|
54
|
+
return (portText.length > 0 &&
|
|
55
|
+
portText.length <= 5 &&
|
|
56
|
+
digitsOnly &&
|
|
57
|
+
port > 0 &&
|
|
58
|
+
port <= 65_535);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Reject request origins that are not the advertised loopback listener.
|
|
62
|
+
* @param origin - Incoming Origin header
|
|
63
|
+
* @param host - Incoming Host header
|
|
64
|
+
* @returns Whether the origin is the exact http://127.0.0.1 listener authority
|
|
65
|
+
*/
|
|
66
|
+
function isExpectedLoopbackOrigin(origin, host) {
|
|
67
|
+
if (origin === undefined || host === undefined) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const parsed = new URL(origin);
|
|
72
|
+
return (origin === parsed.origin &&
|
|
73
|
+
parsed.protocol === "http:" &&
|
|
74
|
+
parsed.host === host &&
|
|
75
|
+
isLoopbackHost(parsed.host));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check whether an unknown value can be serialized as JSON without dropping
|
|
83
|
+
* fields.
|
|
84
|
+
* @param value - Candidate payload value
|
|
85
|
+
* @returns Whether the value is JSON-compatible
|
|
86
|
+
*/
|
|
87
|
+
function isJsonValue(value) {
|
|
88
|
+
if (value === null ||
|
|
89
|
+
typeof value === "string" ||
|
|
90
|
+
typeof value === "number" ||
|
|
91
|
+
typeof value === "boolean") {
|
|
92
|
+
return Number.isFinite(value) || typeof value !== "number";
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
return value.every(isJsonValue);
|
|
96
|
+
}
|
|
97
|
+
if (isJsonObject(value)) {
|
|
98
|
+
return Object.values(value).every(isJsonValue);
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Validate a dot-path config key before it can be written to disk.
|
|
104
|
+
* @param key - Candidate config key
|
|
105
|
+
* @returns Specific validation error, or undefined when valid
|
|
106
|
+
*/
|
|
107
|
+
function validateConfigKey(key) {
|
|
108
|
+
if (key.trim() !== key || key.length === 0) {
|
|
109
|
+
return "Config change keys must be non-empty dot paths";
|
|
110
|
+
}
|
|
111
|
+
const segments = key.split(".");
|
|
112
|
+
if (segments.some(segment => segment.length === 0)) {
|
|
113
|
+
return `Config change key "${key}" contains an empty path segment`;
|
|
114
|
+
}
|
|
115
|
+
const unsafe = new Set(["__proto__", "constructor", "prototype"]);
|
|
116
|
+
if (segments.some(segment => unsafe.has(segment))) {
|
|
117
|
+
return `Config change key "${key}" is not writable`;
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validate one sparse config-write entry.
|
|
123
|
+
* @param key - Dot-path config key
|
|
124
|
+
* @param change - Candidate JSON value
|
|
125
|
+
* @returns Specific validation error, or undefined when valid
|
|
126
|
+
*/
|
|
127
|
+
function validateChangeEntry(key, change) {
|
|
128
|
+
const keyError = validateConfigKey(key);
|
|
129
|
+
if (keyError !== undefined) {
|
|
130
|
+
return keyError;
|
|
131
|
+
}
|
|
132
|
+
if (!isJsonValue(change)) {
|
|
133
|
+
return `Config change "${key}" must be JSON-compatible`;
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Parse and validate the sparse config-write payload.
|
|
139
|
+
* @param value - Parsed JSON request body
|
|
140
|
+
* @returns Dot-path changes, or a specific validation error
|
|
141
|
+
*/
|
|
142
|
+
function parseConfigWritePayload(value) {
|
|
143
|
+
if (!isJsonObject(value)) {
|
|
144
|
+
return { error: "Payload must be a JSON object" };
|
|
145
|
+
}
|
|
146
|
+
const changes = value.changes;
|
|
147
|
+
if (!isJsonObject(changes)) {
|
|
148
|
+
return { error: "Payload must include a changes object" };
|
|
149
|
+
}
|
|
150
|
+
const entries = Object.entries(changes);
|
|
151
|
+
if (entries.length === 0) {
|
|
152
|
+
return { error: "Payload changes must include at least one config key" };
|
|
153
|
+
}
|
|
154
|
+
const error = entries
|
|
155
|
+
.map(([key, change]) => validateChangeEntry(key, change))
|
|
156
|
+
.find(Boolean);
|
|
157
|
+
if (error !== undefined) {
|
|
158
|
+
return { error };
|
|
159
|
+
}
|
|
160
|
+
return { changes: Object.fromEntries(entries) };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Read a bounded JSON body from an incoming request.
|
|
164
|
+
* @param request - Incoming HTTP request
|
|
165
|
+
* @returns Parsed JSON body
|
|
166
|
+
*/
|
|
167
|
+
async function readJsonBody(request) {
|
|
168
|
+
// eslint-disable-next-line functional/no-let -- bounded stream aggregation
|
|
169
|
+
let received = 0;
|
|
170
|
+
// eslint-disable-next-line functional/no-let -- bounded stream aggregation
|
|
171
|
+
let chunks = [];
|
|
172
|
+
for await (const chunk of request) {
|
|
173
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
174
|
+
received += buffer.byteLength;
|
|
175
|
+
if (received > MAX_CONFIG_WRITE_BYTES) {
|
|
176
|
+
throw new RequestBodyError("Payload exceeds 128 KiB limit");
|
|
177
|
+
}
|
|
178
|
+
chunks = [...chunks, buffer];
|
|
179
|
+
}
|
|
180
|
+
if (chunks.length === 0) {
|
|
181
|
+
throw new RequestBodyError("Payload body is required");
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
throw new RequestBodyError("Payload body must be valid JSON");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Serialize committed-config writes per project root.
|
|
192
|
+
* @param destDir - Project root whose committed config is being written
|
|
193
|
+
* @param operation - Read-modify-write operation to run after prior writes
|
|
194
|
+
* @returns Result of the queued operation
|
|
195
|
+
*/
|
|
196
|
+
async function withConfigWriteLock(destDir, operation) {
|
|
197
|
+
const previous = configWriteQueues.get(destDir) ?? Promise.resolve();
|
|
198
|
+
const running = previous.catch(() => undefined).then(operation);
|
|
199
|
+
const marker = running.then(() => undefined, () => undefined);
|
|
200
|
+
// eslint-disable-next-line functional/immutable-data -- per-project async write queue
|
|
201
|
+
configWriteQueues.set(destDir, marker);
|
|
202
|
+
try {
|
|
203
|
+
return await running;
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
if (configWriteQueues.get(destDir) === marker) {
|
|
207
|
+
// eslint-disable-next-line functional/immutable-data -- queue entry is complete
|
|
208
|
+
configWriteQueues.delete(destDir);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Write a sparse config payload after all validation has completed.
|
|
214
|
+
* @param destDir - Project root whose committed config is written
|
|
215
|
+
* @param changes - Validated dot-path changes
|
|
216
|
+
* @returns The updated committed config
|
|
217
|
+
*/
|
|
218
|
+
async function writeConfigChanges(destDir, changes) {
|
|
219
|
+
return await withConfigWriteLock(destDir, async () => {
|
|
220
|
+
const original = await readCommittedConfig(destDir);
|
|
221
|
+
const next = Object.entries(changes).reduce((state, [key, value]) => setAtPath(state, key, value), original);
|
|
222
|
+
await writeJson(path.join(destDir, CONFIG_FILE), next);
|
|
223
|
+
return next;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Serve the same-origin committed-config write endpoint.
|
|
228
|
+
* @param request - Incoming loopback request
|
|
229
|
+
* @param response - Response associated with the request
|
|
230
|
+
* @param destDir - Project root whose committed config is written
|
|
231
|
+
*/
|
|
232
|
+
export function serveConfigWrite(request, response, destDir) {
|
|
233
|
+
if (request.method !== "POST") {
|
|
234
|
+
response.writeHead(405, {
|
|
235
|
+
allow: "POST",
|
|
236
|
+
"cache-control": NO_STORE,
|
|
237
|
+
"content-type": TEXT_CONTENT_TYPE,
|
|
238
|
+
});
|
|
239
|
+
response.end("Method not allowed");
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!isExpectedLoopbackOrigin(request.headers.origin, request.headers.host)) {
|
|
243
|
+
response.writeHead(403, {
|
|
244
|
+
"cache-control": NO_STORE,
|
|
245
|
+
"content-type": JSON_CONTENT_TYPE,
|
|
246
|
+
});
|
|
247
|
+
response.end(JSON.stringify({
|
|
248
|
+
error: "Write requests must come from http://127.0.0.1",
|
|
249
|
+
}));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
void readJsonBody(request)
|
|
253
|
+
.then(parseConfigWritePayload)
|
|
254
|
+
.then(async (parsed) => {
|
|
255
|
+
if ("error" in parsed) {
|
|
256
|
+
response.writeHead(400, {
|
|
257
|
+
"cache-control": NO_STORE,
|
|
258
|
+
"content-type": JSON_CONTENT_TYPE,
|
|
259
|
+
});
|
|
260
|
+
response.end(JSON.stringify({ error: parsed.error }));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const committed = await writeConfigChanges(destDir, parsed.changes);
|
|
264
|
+
response.writeHead(200, {
|
|
265
|
+
"cache-control": NO_STORE,
|
|
266
|
+
"content-type": JSON_CONTENT_TYPE,
|
|
267
|
+
});
|
|
268
|
+
response.end(JSON.stringify({ ok: true, config: committed }));
|
|
269
|
+
})
|
|
270
|
+
.catch(error => {
|
|
271
|
+
const isRequestBodyError = error instanceof RequestBodyError;
|
|
272
|
+
response.writeHead(isRequestBodyError ? 400 : 500, {
|
|
273
|
+
"cache-control": NO_STORE,
|
|
274
|
+
"content-type": JSON_CONTENT_TYPE,
|
|
275
|
+
});
|
|
276
|
+
response.end(JSON.stringify({
|
|
277
|
+
error: isRequestBodyError
|
|
278
|
+
? error.message
|
|
279
|
+
: "Unable to write Lisa config",
|
|
280
|
+
}));
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=ui-config-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-config-write.js","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"form-data": ">=4.0.6"
|
|
103
103
|
},
|
|
104
104
|
"name": "@codyswann/lisa",
|
|
105
|
-
"version": "2.
|
|
105
|
+
"version": "2.232.0",
|
|
106
106
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
107
107
|
"main": "dist/index.js",
|
|
108
108
|
"exports": {
|
|
@@ -29,8 +29,11 @@ For every row marked **Accept**:
|
|
|
29
29
|
| Edge case | Edge Case Brainstorm checklist in `intent-routing.md` | Append the new pattern + question to the matching group (Navigation, Data, Failure, Input, Auth, or a new group if none fit). Use the row's `Summary` and `Evidence` link as a citation comment. |
|
|
30
30
|
| Recurring gotcha | Memory file (`project_*.md`) | Write a new memory entry with `type: project`, structured as: rule, **Why:**, **How to apply:**. Add an index line to `MEMORY.md`. |
|
|
31
31
|
| Process friction | Configured project rules file | Append a one-line guideline to the `.lisa.config.json` `projectRulesFile` destination (default `PROJECT_RULES.md`) under an appropriate heading (or create one). |
|
|
32
|
-
| Tooling gap | Configured tracker |
|
|
32
|
+
| Tooling gap | Configured tracker — or upstream Lisa when harness-level | **Split by level.** Project-level (a missing project script, hook, or automation) → create a ticket via `lisa-tracker-write` with `issue_type: Task`, summary derived from the row's `Summary`, description citing the evidence and the originating debrief doc, labeled `type:tooling` / `lifecycle-improvement`. Harness-level (a Lisa skill/gate/agent that should have caught the issue but didn't) → file an upstream Lisa issue exactly per the "Filing upstream" procedure in `lisa-rework-triage` (dedupe search first, three-audience description, evidence chain, `self-hardening` label; repo from `.lisa.config.json` `hardening.upstreamRepo`, default `CodySwannGT/lisa`). |
|
|
33
33
|
| Convention drift | `CLAUDE.md` for project-wide agent operating instructions; otherwise the configured project rules file for codebase conventions | Append the convention as a one-paragraph note under the relevant section. If no relevant section exists, create one. |
|
|
34
|
+
| Decomposition infidelity | Upstream Lisa repo | File an upstream Lisa issue per the "Filing upstream" procedure in `lisa-rework-triage`, citing the PRD text vs. the distorted ticket AC and naming the gate that passed it. |
|
|
35
|
+
| PRD defect | Source PRD | Comment on the PRD via the `lisa-prd-backlink` lineage quoting the defective requirement and the failure it missed; flag for product review. Never silently edit the spec. |
|
|
36
|
+
| Missing tool access | Configured tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, `type:tooling`) describing the missing tool/credential/environment and which flow needs it. |
|
|
34
37
|
|
|
35
38
|
For every row marked **Reject** or **Defer**: no action. Defer is a no-op for `apply` but worth surfacing in the run summary — the human may want to revisit at the next debrief.
|
|
36
39
|
|
|
@@ -51,8 +54,12 @@ Applied <n> learnings:
|
|
|
51
54
|
<n> edge cases → intent-routing.md
|
|
52
55
|
<n> gotchas → memory
|
|
53
56
|
<n> friction → PROJECT_RULES.md
|
|
54
|
-
<n> tooling gaps → <tracker> (<key1>, <key2>, ...)
|
|
57
|
+
<n> tooling gaps (project) → <tracker> (<key1>, <key2>, ...)
|
|
58
|
+
<n> tooling gaps (harness) → upstream Lisa (<issue-url1>, ...)
|
|
55
59
|
<n> convention drift → CLAUDE.md
|
|
60
|
+
<n> decomposition infidelity → upstream Lisa (<issue-url1>, ...)
|
|
61
|
+
<n> PRD defects → PRD comments (<prd-link1>, ...)
|
|
62
|
+
<n> missing tool access → <tracker> (<key1>, ...)
|
|
56
63
|
Skipped:
|
|
57
64
|
<n> rejected, <n> deferred, <n> already-applied
|
|
58
65
|
Failed:
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa-rework-triage
|
|
3
|
+
description: "Rework detection and…"
|
|
4
|
+
allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rework Triage: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Classify why a previous agent attempt at this ticket failed, and convert that cause into a
|
|
10
|
+
structural improvement. This is the self-hardening arm of the lifecycle: every classified
|
|
11
|
+
failure either hardens the harness (an upstream Lisa issue), the project (a provisioning or
|
|
12
|
+
environment ticket), or the spec (a PRD defect flag). A rework cycle that fixes the bug but
|
|
13
|
+
never asks *why the agent got it wrong* guarantees the mistake recurs.
|
|
14
|
+
|
|
15
|
+
The caller MUST have run `lisa-tracker-read` first and provided the context bundle (all
|
|
16
|
+
comments chronological, linked PRs with review state, issue links, parent epic). Do not
|
|
17
|
+
classify from a bare summary — evidence-free classification is worse than none.
|
|
18
|
+
|
|
19
|
+
## Phase 1 — Rework detection
|
|
20
|
+
|
|
21
|
+
A ticket is **rework** when it was previously implemented by this lifecycle and has returned
|
|
22
|
+
to a build-ready state. Evaluate these signals in order; the first confirmed signal suffices.
|
|
23
|
+
If none confirm, output `## Verdict: NOT_REWORK` and stop — this skill takes no action on
|
|
24
|
+
first-attempt work.
|
|
25
|
+
|
|
26
|
+
1. **Status history shows a post-implementation regression transition.** The ticket's
|
|
27
|
+
changelog contains a transition from a post-build state (the configured `claimed`, any
|
|
28
|
+
`done.*` environment state — e.g. `On Dev`, `On Stg` — or a review state) back to the
|
|
29
|
+
configured `ready` state.
|
|
30
|
+
- JIRA: fetch the changelog via the `lisa-atlassian-access` REST substrate —
|
|
31
|
+
`GET /rest/api/3/issue/<KEY>/changelog` — and scan `items[].field == "status"` entries.
|
|
32
|
+
- GitHub: `gh issue view <n> --json timelineItems` (or the timeline API) — scan for the
|
|
33
|
+
`$DONE`/environment label being removed and `$READY` re-added after a linked PR merged.
|
|
34
|
+
- Linear: the Issue history relation — scan state changes from a completed/started state
|
|
35
|
+
back to the ready-labeled state.
|
|
36
|
+
2. **Merged linked PR + build-ready again.** The bundle shows at least one linked PR that is
|
|
37
|
+
`MERGED`, while the ticket currently carries the build-ready role. First-attempt tickets
|
|
38
|
+
never have merged PRs.
|
|
39
|
+
3. **Prior lifecycle claim marker.** The comments contain a prior implementation-cycle
|
|
40
|
+
marker for THIS ticket: a `[claude-build-intake]` claim comment, or a build-evidence
|
|
41
|
+
comment posted by `lisa-tracker-evidence` (`[lisa-evidence]` / the vendor evidence
|
|
42
|
+
header). Only markers proving a prior *implementation* attempt qualify —
|
|
43
|
+
`[lisa-rework-triage]` comments and other unrelated `[lisa-*]` annotations never do.
|
|
44
|
+
4. **Explicit rework marker.** A `rework`, `qa-fail`, or `regression` label applied by QA or
|
|
45
|
+
the verify lifecycle.
|
|
46
|
+
|
|
47
|
+
Record which signal fired — it is part of the evidence trail.
|
|
48
|
+
|
|
49
|
+
## Phase 2 — Failure-cause classification
|
|
50
|
+
|
|
51
|
+
Classify the failed attempt into **exactly one primary cause**. Every classification must
|
|
52
|
+
cite concrete evidence from the bundle, the codebase, or the PRD lineage — a cause without
|
|
53
|
+
evidence is `UNCLASSIFIED`, which is itself a surfaced outcome, never a silent default.
|
|
54
|
+
|
|
55
|
+
| Cause | Definition | Required evidence |
|
|
56
|
+
|-------|------------|-------------------|
|
|
57
|
+
| `decomposition-infidelity` | The ticket misrepresents the PRD requirement it implements — the agent built what the ticket said, but the ticket distorted the spec. | Resolve the ticket's requirement id(s) from the source PRD's `## Tickets` section (written by `lisa-prd-backlink` — each entry carries `requirements: ["R#"]` and the register maps R# to verbatim PRD text). Quote the PRD text vs. the ticket's AC and name the divergence. |
|
|
58
|
+
| `prd-defect` | The ticket faithfully captured the PRD, but the PRD itself was wrong, ambiguous, or missing the failing case. | Quote the PRD requirement and the QA failure it does not cover or contradicts. |
|
|
59
|
+
| `missing-tool-access` | The agent lacked a tool, credential, environment, or permission the work required, and worked around it blindly. | The prior cycle's comments/PR show the gap (skipped verification step, "could not access", missing env credentials, absent MCP tool) — cite the marker. |
|
|
60
|
+
| `implementation-defect` | Spec and ticket were right; the agent's code was wrong. | The failing behavior contradicts an AC the ticket states correctly; cite the AC and the failure report. |
|
|
61
|
+
| `environment-data` | The failure is caused by environment or data state (drift, missing fixtures, shared-state collision), not by the code under test. | The failure reproduces only in the affected environment, or the report references data absent from the environment's seed/fixtures. |
|
|
62
|
+
| `verification-gap` | The code was wrong AND the verification lifecycle should have caught it — the codified regression test was missing, too weak, or asserted the wrong thing. | Name the verification/codify-verification artifact from the prior cycle that failed to catch this class of failure. Frequently a **secondary** cause alongside `implementation-defect`; record both, primary first. |
|
|
63
|
+
|
|
64
|
+
Classification sources, in priority order: the QA failure report (comments), the prior
|
|
65
|
+
cycle's evidence comment and PR review thread, the PRD requirement register via
|
|
66
|
+
`lisa-prd-backlink` lineage, and the codebase itself (Glob/Grep the failing surface).
|
|
67
|
+
|
|
68
|
+
## Phase 3 — Post the triage comment
|
|
69
|
+
|
|
70
|
+
Post one structured comment on the ticket via the vendor comment surface (`lisa-atlassian-access
|
|
71
|
+
operation: comment`, `gh issue comment`, or the Linear comment mutation):
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
[lisa-rework-triage] Rework detected (signal: <signal>)
|
|
75
|
+
Fingerprint: <ticket-key>|<last merged PR number, or none>|<primary cause>
|
|
76
|
+
Primary cause: <cause>
|
|
77
|
+
Secondary cause: <cause or none>
|
|
78
|
+
Evidence: <2-4 lines citing the specific PRD text / AC / comment / PR review / environment fact>
|
|
79
|
+
Hardening action: <what Phase 4 filed, with link — or "none required (implementation-defect)">
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Idempotency:** the fingerprint is the literal `Fingerprint:` line —
|
|
83
|
+
`<ticket-key>|<last merged PR number>|<primary cause>`, with `none` as the PR component
|
|
84
|
+
when detection fired on a claim marker or label and no merged PR exists. Before posting,
|
|
85
|
+
scan existing comments for a `[lisa-rework-triage]` block whose `Fingerprint:` line
|
|
86
|
+
matches — if present, skip posting and report `already-triaged`. One triage per bounce,
|
|
87
|
+
never one per cycle re-entry.
|
|
88
|
+
|
|
89
|
+
## Phase 4 — Route the cause to its hardening destination
|
|
90
|
+
|
|
91
|
+
Each cause has exactly one destination. File through the proper write path — never raw
|
|
92
|
+
ticket creation — so every hardening artifact passes the same quality gates as any other
|
|
93
|
+
Lisa work item.
|
|
94
|
+
|
|
95
|
+
| Primary cause | Destination | Action |
|
|
96
|
+
|---------------|-------------|--------|
|
|
97
|
+
| `decomposition-infidelity` | **Upstream Lisa issue** | The decomposition pipeline produced an unfaithful ticket and every gate passed it — that is a harness defect. File per "Filing upstream" below, citing the PRD text, the distorted ticket AC, and which gate should have caught it. |
|
|
98
|
+
| `verification-gap` | **Upstream Lisa issue** | The verification lifecycle passed work it should have failed. File per "Filing upstream", citing the missed failure class and the weak/missing codified test. |
|
|
99
|
+
| `missing-tool-access` | Project tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, labeled `type:tooling`) describing the missing tool/credential/environment and which flow needs it. Link it `blocks` the rework ticket. |
|
|
100
|
+
| `environment-data` | Project tracker | Create an environment-hardening ticket via `lisa-tracker-write` citing the drift/fixture/shared-state evidence. Link `relates to` the rework ticket. |
|
|
101
|
+
| `prd-defect` | Source PRD | Comment on the PRD (via the `lisa-prd-backlink` lineage) quoting the defective requirement and the QA failure; flag for product review. Do NOT silently edit the PRD — spec changes are a human gate. |
|
|
102
|
+
| `implementation-defect` (no secondary) | None | Normal fix path; the classification comment is the record. Pass the pattern to the `learner` phase — repeated implementation defects of the same shape escalate to `verification-gap`. |
|
|
103
|
+
|
|
104
|
+
**Secondary causes route too.** A recorded secondary cause triggers its own row's
|
|
105
|
+
destination in addition to the primary's: `implementation-defect` with a
|
|
106
|
+
`verification-gap` secondary files the upstream Lisa issue per the `verification-gap`
|
|
107
|
+
row — the code being wrong does not excuse the verification lifecycle for passing it.
|
|
108
|
+
Deduplicate against the primary's filing (one upstream issue per failure class, not one
|
|
109
|
+
per cause slot).
|
|
110
|
+
| `UNCLASSIFIED` | Surface to human | Include in the triage comment and the caller's summary; a human decides. Never guess a cause to avoid this outcome. |
|
|
111
|
+
|
|
112
|
+
### Filing upstream
|
|
113
|
+
|
|
114
|
+
Upstream issues target the Lisa repository itself so the harness gets fixed for every
|
|
115
|
+
project at once. Resolve the repo from `.lisa.config.json` `hardening.upstreamRepo`;
|
|
116
|
+
default `CodySwannGT/lisa`.
|
|
117
|
+
|
|
118
|
+
1. **Dedupe first.** `gh issue list -R <upstream> --state open --search "<fingerprint terms>"`
|
|
119
|
+
— if an open issue already covers this failure class, comment the new occurrence on it
|
|
120
|
+
(evidence compounds; duplicates dilute) and link it instead of filing.
|
|
121
|
+
2. **File with the same bar as any ticket:** a three-audience description (what failed for
|
|
122
|
+
the operator, what the harness did wrong, what to change), the verbatim evidence chain
|
|
123
|
+
(PRD text → ticket AC → QA failure → gate that passed it), and a `self-hardening` label:
|
|
124
|
+
`gh issue create -R <upstream> --title "<gate/skill>: <failure class>" --label self-hardening`.
|
|
125
|
+
3. **Close the loop.** Reference the upstream issue URL in the triage comment. The upstream
|
|
126
|
+
repo's own build intake implements it; the next kernel release ships the hardening to
|
|
127
|
+
every host project.
|
|
128
|
+
|
|
129
|
+
## Verdict
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
## Verdict: [NOT_REWORK | REWORK_CLASSIFIED | ALREADY_TRIAGED]
|
|
133
|
+
|
|
134
|
+
**Signal:** [status-history | merged-pr | claim-marker | label | n/a]
|
|
135
|
+
**Primary cause:** [cause | n/a]
|
|
136
|
+
**Secondary cause:** [cause | none]
|
|
137
|
+
**Hardening filed:** [upstream <url> | tracker <key> | prd-comment | none | pending-human]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The caller (ticket-triage Phase 2.5, or a standalone invocation) incorporates this into its
|
|
141
|
+
own findings. `REWORK_CLASSIFIED` never blocks the fix — the rework ticket proceeds to
|
|
142
|
+
implementation regardless; hardening runs alongside, not in front of, shipping the fix. The
|
|
143
|
+
one exception: `missing-tool-access` with the gap still present should surface as a Phase 3
|
|
144
|
+
ambiguity in the calling triage ("prior attempt lacked <tool>; it is still unavailable"),
|
|
145
|
+
which blocks per the normal triage rules.
|
|
146
|
+
|
|
147
|
+
## Rules
|
|
148
|
+
|
|
149
|
+
- Never classify without evidence; `UNCLASSIFIED` beats a guess.
|
|
150
|
+
- One primary cause. Record a secondary only when the evidence genuinely supports both.
|
|
151
|
+
- Fire only on confirmed rework — first-attempt tickets exit at Phase 1 with `NOT_REWORK`.
|
|
152
|
+
- All ticket/issue writes go through `lisa-tracker-write` or `gh` as specified — never
|
|
153
|
+
bypass the quality gates this loop exists to strengthen.
|
|
154
|
+
- Noise discipline: one triage comment per bounce (fingerprinted), no upstream issue without
|
|
155
|
+
the dedupe search, and upstream issues describe failure *classes*, not single incidents.
|