@codyswann/lisa 3.33.6 → 3.33.7
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/all/copy-overwrite/scripts/lisa-work-item.mjs +284 -2
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +1 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +7 -7
- 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-git-submit-pr/SKILL.md +11 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-sync/SKILL.md +7 -2
- package/plugins/lisa/skills/lisa-git-submit-pr/SKILL.md +11 -4
- package/plugins/lisa/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/lisa/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/lisa/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/lisa/skills/lisa-tracker-sync/SKILL.md +7 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-git-submit-pr/SKILL.md +11 -4
- package/plugins/lisa-agy/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/lisa-agy/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/lisa-agy/skills/lisa-tracker-sync/SKILL.md +7 -2
- 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/skills/lisa-git-submit-pr/SKILL.md +11 -4
- package/plugins/lisa-copilot/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/lisa-copilot/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/lisa-copilot/skills/lisa-tracker-sync/SKILL.md +7 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-git-submit-pr/SKILL.md +11 -4
- package/plugins/lisa-cursor/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/lisa-cursor/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/lisa-cursor/skills/lisa-tracker-sync/SKILL.md +7 -2
- 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/skills/lisa-git-submit-pr/SKILL.md +11 -4
- package/plugins/src/base/skills/lisa-github-sync/SKILL.md +7 -2
- package/plugins/src/base/skills/lisa-implement/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-sync/SKILL.md +7 -2
- package/plugins/src/base/skills/lisa-linear-sync/SKILL.md +7 -2
- package/plugins/src/base/skills/lisa-tracker-sync/SKILL.md +7 -2
|
@@ -25,6 +25,14 @@ const RELEASE_SUBJECT =
|
|
|
25
25
|
/^chore\(release\): \d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)? \[skip ci\]$/;
|
|
26
26
|
const ZERO_OID = /^0+$/;
|
|
27
27
|
const MARKER = "[lisa-pr-link]";
|
|
28
|
+
/**
|
|
29
|
+
* The command that establishes the ticket-side backlink.
|
|
30
|
+
*
|
|
31
|
+
* Named in every refusal that the backlink is missing. A validator that
|
|
32
|
+
* reports "no verified backlink" without the remedy sends the reader looking
|
|
33
|
+
* for a producer that, until this command existed, was prose in a SKILL.md.
|
|
34
|
+
*/
|
|
35
|
+
const BACKLINK_COMMAND = "node scripts/lisa-work-item.mjs backlink";
|
|
28
36
|
/**
|
|
29
37
|
* The prefix only — an anchored, fixed-length literal with no quantifier, so
|
|
30
38
|
* it cannot backtrack. The ReDoS was never here; it was in the `\s*(.+?)\s*$`
|
|
@@ -1217,6 +1225,247 @@ export function textContainsBacklink(value, prUrl) {
|
|
|
1217
1225
|
return false;
|
|
1218
1226
|
}
|
|
1219
1227
|
|
|
1228
|
+
/**
|
|
1229
|
+
* The managed backlink comment's body.
|
|
1230
|
+
*
|
|
1231
|
+
* One line, and the whole body — so establishing the backlink is a whole-body
|
|
1232
|
+
* replace rather than an append, which is what makes a rerun converge instead
|
|
1233
|
+
* of accumulating. Nothing else is carried here on purpose: the milestone and
|
|
1234
|
+
* the merge SHA belong to the vendor sync skills' progress notes, and putting
|
|
1235
|
+
* them in this body would make every rerun a content change.
|
|
1236
|
+
* @param {string} prUrl Pull request URL.
|
|
1237
|
+
* @returns {string} The comment body.
|
|
1238
|
+
*/
|
|
1239
|
+
function backlinkBody(prUrl) {
|
|
1240
|
+
return `${MARKER} ${prUrl}`;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Whether a comment payload is Lisa's managed backlink comment.
|
|
1245
|
+
*
|
|
1246
|
+
* Shape-agnostic deliberately: GitHub and Linear return a plain string body,
|
|
1247
|
+
* Jira returns an Atlassian Document Format tree. Serialising covers all three
|
|
1248
|
+
* without a per-provider walker, and the marker is distinctive enough that a
|
|
1249
|
+
* false positive would have to be a comment quoting it verbatim — which is
|
|
1250
|
+
* still Lisa's comment to reuse rather than a second one to add.
|
|
1251
|
+
* @param {unknown} body Comment body in whatever shape the provider returned.
|
|
1252
|
+
* @returns {boolean} True when this is the managed comment.
|
|
1253
|
+
*/
|
|
1254
|
+
function carriesMarker(body) {
|
|
1255
|
+
return JSON.stringify(body ?? "").includes(MARKER);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Establish the backlink on a GitHub issue.
|
|
1260
|
+
* @param {string} ref Canonical `owner/repo#number` reference.
|
|
1261
|
+
* @param {string} prUrl Pull request URL.
|
|
1262
|
+
* @returns {string} What changed: created, updated, or unchanged.
|
|
1263
|
+
*/
|
|
1264
|
+
function githubBacklink(ref, prUrl) {
|
|
1265
|
+
const [repository, number] = ref.split("#");
|
|
1266
|
+
const listing = run(
|
|
1267
|
+
"gh",
|
|
1268
|
+
[
|
|
1269
|
+
"api",
|
|
1270
|
+
"--paginate",
|
|
1271
|
+
`repos/${repository}/issues/${number}/comments?per_page=100`,
|
|
1272
|
+
],
|
|
1273
|
+
{ allowFailure: true }
|
|
1274
|
+
);
|
|
1275
|
+
if (listing.status !== 0) throw githubFailure(listing, ref);
|
|
1276
|
+
const comments = safeJson(listing.stdout, `GitHub comments on ${ref}`);
|
|
1277
|
+
const managed = (Array.isArray(comments) ? comments : []).find(comment =>
|
|
1278
|
+
carriesMarker(comment?.body)
|
|
1279
|
+
);
|
|
1280
|
+
const body = backlinkBody(prUrl);
|
|
1281
|
+
if (managed && managed.body === body) return "unchanged";
|
|
1282
|
+
const [method, endpoint] = managed
|
|
1283
|
+
? ["PATCH", `repos/${repository}/issues/comments/${managed.id}`]
|
|
1284
|
+
: ["POST", `repos/${repository}/issues/${number}/comments`];
|
|
1285
|
+
run("gh", ["api", "--method", method, endpoint, "--field", `body=${body}`], {
|
|
1286
|
+
error: `could not write the backlink comment on ${ref}`,
|
|
1287
|
+
});
|
|
1288
|
+
return managed ? "updated" : "created";
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* Send one Linear GraphQL document, refusing on either failure surface.
|
|
1293
|
+
*
|
|
1294
|
+
* GraphQL answers an invalid mutation with HTTP 200 and an `errors` array, so
|
|
1295
|
+
* a status-only check reports success for a comment that was never written.
|
|
1296
|
+
* @param {string} token Linear API key.
|
|
1297
|
+
* @param {string} query The document.
|
|
1298
|
+
* @param {object} variables Its variables.
|
|
1299
|
+
* @param {string} context What the call was for, for the message.
|
|
1300
|
+
* @returns {object} The `data` payload.
|
|
1301
|
+
*/
|
|
1302
|
+
function linearGraphql(token, query, variables, context) {
|
|
1303
|
+
const result = secureCurl(
|
|
1304
|
+
["https://api.linear.app/graphql"],
|
|
1305
|
+
[
|
|
1306
|
+
["request", "POST"],
|
|
1307
|
+
["header", "Content-Type: application/json"],
|
|
1308
|
+
["header", `Authorization: ${token}`],
|
|
1309
|
+
["data-binary", JSON.stringify({ query, variables })],
|
|
1310
|
+
],
|
|
1311
|
+
{ allowFailure: true }
|
|
1312
|
+
);
|
|
1313
|
+
if (result.status !== 0) throw new TrackingError(`${context} failed`);
|
|
1314
|
+
const response = safeJson(result.stdout, context);
|
|
1315
|
+
if (Array.isArray(response.errors) && response.errors.length > 0)
|
|
1316
|
+
throw new TrackingError(
|
|
1317
|
+
`${context} failed: ${response.errors[0]?.message}`
|
|
1318
|
+
);
|
|
1319
|
+
return response.data ?? {};
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* Establish the backlink on a Linear issue.
|
|
1324
|
+
* @param {string} ref Canonical `KEY-123` identifier.
|
|
1325
|
+
* @param {string} prUrl Pull request URL.
|
|
1326
|
+
* @param {object} contract Resolved tracker contract.
|
|
1327
|
+
* @returns {string} What changed: created, updated, or unchanged.
|
|
1328
|
+
*/
|
|
1329
|
+
function linearBacklink(ref, prUrl, contract) {
|
|
1330
|
+
const token = readLinearKey(contract.workspace);
|
|
1331
|
+
if (!token)
|
|
1332
|
+
throw new TrackingError(
|
|
1333
|
+
"writing a Linear backlink requires LINEAR_API_KEY or a lisa-linear keychain entry"
|
|
1334
|
+
);
|
|
1335
|
+
const issue = linearGraphql(
|
|
1336
|
+
token,
|
|
1337
|
+
"query($id:String!){issue(id:$id){id comments{nodes{id body}}}}",
|
|
1338
|
+
{ id: ref },
|
|
1339
|
+
`Linear issue ${ref} lookup`
|
|
1340
|
+
).issue;
|
|
1341
|
+
if (!issue?.id)
|
|
1342
|
+
throw new TrackingError(
|
|
1343
|
+
`Linear issue ${ref} does not exist or is inaccessible`
|
|
1344
|
+
);
|
|
1345
|
+
const managed = (issue.comments?.nodes ?? []).find(comment =>
|
|
1346
|
+
carriesMarker(comment?.body)
|
|
1347
|
+
);
|
|
1348
|
+
const body = backlinkBody(prUrl);
|
|
1349
|
+
if (managed && managed.body === body) return "unchanged";
|
|
1350
|
+
if (managed) {
|
|
1351
|
+
linearGraphql(
|
|
1352
|
+
token,
|
|
1353
|
+
"mutation($id:String!,$body:String!){commentUpdate(id:$id,input:{body:$body}){success}}",
|
|
1354
|
+
{ body, id: managed.id },
|
|
1355
|
+
`Linear backlink update on ${ref}`
|
|
1356
|
+
);
|
|
1357
|
+
return "updated";
|
|
1358
|
+
}
|
|
1359
|
+
linearGraphql(
|
|
1360
|
+
token,
|
|
1361
|
+
"mutation($id:String!,$body:String!){commentCreate(input:{issueId:$id,body:$body}){success}}",
|
|
1362
|
+
{ body, id: issue.id },
|
|
1363
|
+
`Linear backlink comment on ${ref}`
|
|
1364
|
+
);
|
|
1365
|
+
return "created";
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* The managed comment as an Atlassian Document Format tree.
|
|
1370
|
+
*
|
|
1371
|
+
* A single text node, so the marker and the URL land in one string — which is
|
|
1372
|
+
* what `textContainsBacklink` walks the tree looking for. Splitting them across
|
|
1373
|
+
* nodes would write a comment the reader accepts visually and the check
|
|
1374
|
+
* rejects.
|
|
1375
|
+
* @param {string} prUrl Pull request URL.
|
|
1376
|
+
* @returns {object} The ADF document.
|
|
1377
|
+
*/
|
|
1378
|
+
function jiraCommentDocument(prUrl) {
|
|
1379
|
+
return {
|
|
1380
|
+
content: [
|
|
1381
|
+
{
|
|
1382
|
+
content: [{ text: backlinkBody(prUrl), type: "text" }],
|
|
1383
|
+
type: "paragraph",
|
|
1384
|
+
},
|
|
1385
|
+
],
|
|
1386
|
+
type: "doc",
|
|
1387
|
+
version: 1,
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* Establish the backlink on a Jira ticket.
|
|
1393
|
+
*
|
|
1394
|
+
* Requires API credentials rather than falling back to `acli`: the read path
|
|
1395
|
+
* may degrade to whatever can answer, but a write that silently does not
|
|
1396
|
+
* happen is exactly the failure this command exists to remove.
|
|
1397
|
+
* @param {string} ref Canonical `KEY-123` reference.
|
|
1398
|
+
* @param {string} prUrl Pull request URL.
|
|
1399
|
+
* @param {object} contract Resolved tracker contract.
|
|
1400
|
+
* @returns {string} What changed: created, updated, or unchanged.
|
|
1401
|
+
*/
|
|
1402
|
+
function jiraBacklink(ref, prUrl, contract) {
|
|
1403
|
+
const credentials = jiraCredentials(contract);
|
|
1404
|
+
if (!credentials)
|
|
1405
|
+
throw new TrackingError(
|
|
1406
|
+
"writing a Jira backlink requires ATLASSIAN_API_TOKEN/JIRA_API_TOKEN with JIRA_LOGIN and atlassian.cloudId/site"
|
|
1407
|
+
);
|
|
1408
|
+
const issueUrl = `${credentials.baseUrl}/rest/api/3/issue/${encodeURIComponent(ref)}/comment`;
|
|
1409
|
+
const auth = [
|
|
1410
|
+
["user", `${credentials.login}:${credentials.token}`],
|
|
1411
|
+
["header", "Accept: application/json"],
|
|
1412
|
+
];
|
|
1413
|
+
const listing = secureCurl([`${issueUrl}?maxResults=100`], auth, {
|
|
1414
|
+
allowFailure: true,
|
|
1415
|
+
});
|
|
1416
|
+
if (listing.status !== 0)
|
|
1417
|
+
throw new TrackingError(`Jira ticket ${ref} comments are inaccessible`);
|
|
1418
|
+
const existing = safeJson(listing.stdout, `Jira comments on ${ref}`);
|
|
1419
|
+
const managed = (existing.comments ?? []).find(comment =>
|
|
1420
|
+
carriesMarker(comment?.body)
|
|
1421
|
+
);
|
|
1422
|
+
const document = jiraCommentDocument(prUrl);
|
|
1423
|
+
const payload = JSON.stringify({ body: document });
|
|
1424
|
+
if (managed && JSON.stringify(managed.body) === JSON.stringify(document))
|
|
1425
|
+
return "unchanged";
|
|
1426
|
+
secureCurl(
|
|
1427
|
+
[managed ? `${issueUrl}/${encodeURIComponent(managed.id)}` : issueUrl],
|
|
1428
|
+
[
|
|
1429
|
+
...auth,
|
|
1430
|
+
["request", managed ? "PUT" : "POST"],
|
|
1431
|
+
["header", "Content-Type: application/json"],
|
|
1432
|
+
["data-binary", payload],
|
|
1433
|
+
],
|
|
1434
|
+
{ error: `could not write the backlink comment on ${ref}` }
|
|
1435
|
+
);
|
|
1436
|
+
return managed ? "updated" : "created";
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
/**
|
|
1440
|
+
* Establish the ticket-side backlink, whatever the tracker.
|
|
1441
|
+
*
|
|
1442
|
+
* This is the producer for the comment `assertBacklink` consumes, and it lives
|
|
1443
|
+
* in this file for that reason: the requirement was documented in a SKILL.md
|
|
1444
|
+
* and enforced here, so nothing executable ever wrote it and a required check
|
|
1445
|
+
* failed on a step no command performed.
|
|
1446
|
+
*
|
|
1447
|
+
* Every provider `assertBacklink` reads is written here. A provider that is
|
|
1448
|
+
* not refuses loudly rather than returning quietly, because a silent no-op
|
|
1449
|
+
* here reproduces the original defect one layer down: the command reports
|
|
1450
|
+
* success and the check still fails.
|
|
1451
|
+
* @param {string} ref Canonical work-item reference.
|
|
1452
|
+
* @param {string} prUrl Pull request URL.
|
|
1453
|
+
* @param {object} contract Resolved tracker contract.
|
|
1454
|
+
* @returns {string} What changed: created, updated, or unchanged.
|
|
1455
|
+
*/
|
|
1456
|
+
function postBacklink(ref, prUrl, contract) {
|
|
1457
|
+
if (contract.provider === "github") return githubBacklink(ref, prUrl);
|
|
1458
|
+
if (contract.provider === "linear")
|
|
1459
|
+
return linearBacklink(ref, prUrl, contract);
|
|
1460
|
+
if (contract.provider === "jira") return jiraBacklink(ref, prUrl, contract);
|
|
1461
|
+
throw new TrackingError(
|
|
1462
|
+
`no backlink writer for tracker '${contract.provider}'; ` +
|
|
1463
|
+
`github, jira and linear are supported.\nThe Work-Item Traceability check ` +
|
|
1464
|
+
`reads a managed ${MARKER} comment for this provider, so it cannot pass ` +
|
|
1465
|
+
`until a writer exists here — add one rather than posting by hand.`
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1220
1469
|
function assertBacklink(
|
|
1221
1470
|
ref,
|
|
1222
1471
|
prUrl,
|
|
@@ -1502,7 +1751,12 @@ function backlinkAdvice(ref, prUrl, contract) {
|
|
|
1502
1751
|
contract.provider === "linear"
|
|
1503
1752
|
? `The tracker builds that link from the BRANCH NAME, so a branch carrying no ticket id can never acquire one: no edit to this pull request, its body, or its commits will do it. Fixing it that way needs a NEW branch named for ${ref} and a new pull request from it. `
|
|
1504
1753
|
: "";
|
|
1505
|
-
return
|
|
1754
|
+
return (
|
|
1755
|
+
`${branchDerived}The one remedy that needs no new branch is the managed comment ` +
|
|
1756
|
+
`\`${MARKER} ${prUrl}\` on ${ref}. Do not post it by hand — run:\n\n` +
|
|
1757
|
+
` ${BACKLINK_COMMAND} --ref ${ref} --pr-url ${prUrl}\n\n` +
|
|
1758
|
+
`which creates that comment or updates the existing one, so running it twice is safe`
|
|
1759
|
+
);
|
|
1506
1760
|
}
|
|
1507
1761
|
|
|
1508
1762
|
/**
|
|
@@ -1620,6 +1874,33 @@ function bind(args) {
|
|
|
1620
1874
|
console.log(`work-item bound: ${ref} (${file})`);
|
|
1621
1875
|
}
|
|
1622
1876
|
|
|
1877
|
+
/**
|
|
1878
|
+
* Establish the ticket-side backlink for one work item and pull request.
|
|
1879
|
+
*
|
|
1880
|
+
* Idempotent by construction — the writer updates the managed comment it finds
|
|
1881
|
+
* rather than adding a second — so this is safe to run on every push, and safe
|
|
1882
|
+
* to rerun after a failure without inspecting what the last run managed to do.
|
|
1883
|
+
* @param {string[]} args CLI arguments.
|
|
1884
|
+
*/
|
|
1885
|
+
function backlink(args) {
|
|
1886
|
+
const contract = trackerContract();
|
|
1887
|
+
const supplied = option(args, "--ref", "LISA_WORK_ITEM_REF");
|
|
1888
|
+
const bound = readState(true)?.ref;
|
|
1889
|
+
if (!supplied && !bound) {
|
|
1890
|
+
throw new TrackingError(
|
|
1891
|
+
`${BACKLINK_COMMAND} requires --ref <work-item>, or a worktree binding from \`lisa-work-item.mjs link\``
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
const ref = canonicalizeRef(supplied ?? bound, contract);
|
|
1895
|
+
const prUrl =
|
|
1896
|
+
option(args, "--pr-url", "LISA_PR_URL") ??
|
|
1897
|
+
option(args, "--url", "LISA_PR_URL");
|
|
1898
|
+
if (!prUrl)
|
|
1899
|
+
throw new TrackingError(`${BACKLINK_COMMAND} requires --pr-url <url>`);
|
|
1900
|
+
const outcome = postBacklink(ref, prUrl, contract);
|
|
1901
|
+
console.log(`work-item backlink ${outcome} on ${ref}: ${MARKER} ${prUrl}`);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1623
1904
|
function prepareCommitMessage(args) {
|
|
1624
1905
|
const [file, source = ""] = args;
|
|
1625
1906
|
if (!file)
|
|
@@ -1755,12 +2036,13 @@ function main() {
|
|
|
1755
2036
|
rmSync(statePath(), { force: true });
|
|
1756
2037
|
return console.log("work-item binding cleared");
|
|
1757
2038
|
}
|
|
2039
|
+
if (command === "backlink") return backlink(args);
|
|
1758
2040
|
if (command === "prepare-commit-msg") return prepareCommitMessage(args);
|
|
1759
2041
|
if (command === "validate-commit") return validateCommit(args);
|
|
1760
2042
|
if (command === "validate-push") return validatePush(args);
|
|
1761
2043
|
if (command === "validate-pr") return validatePr(args);
|
|
1762
2044
|
throw new TrackingError(
|
|
1763
|
-
"Usage: lisa-work-item.mjs link|current|attach-branch|clear|prepare-commit-msg|validate-commit|validate-push|validate-pr" +
|
|
2045
|
+
"Usage: lisa-work-item.mjs link|current|attach-branch|clear|backlink|prepare-commit-msg|validate-commit|validate-push|validate-pr" +
|
|
1764
2046
|
"\n(`bind` is accepted as an alias for `link`, but some agent harnesses refuse the token `bind` in a command line.)"
|
|
1765
2047
|
);
|
|
1766
2048
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAgXjC,CAAC"}
|
|
@@ -340,6 +340,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
340
340
|
"ab0dede91c5c8a07984ae13aa48ec70cdcd2fa691b59617bc4b57998dc79a51c",
|
|
341
341
|
"b4e8aea72219f2c568429686a2ff1acd0da75ca26f244a66f3c4334297c8cd8e",
|
|
342
342
|
"c78df9d5f0f3fc388ff60a7db5898478a2a4d6d7325833f10384b5a8c62bb34a",
|
|
343
|
+
"d22e31021947e5090c58ee5cfc9c4ee206bf2cf30d25f46b097bafcec59f55f3",
|
|
343
344
|
"d63f21c64271875a9c796312d3af21ee5c0c855fbafa5af8a887e5df57ec1f25",
|
|
344
345
|
"d89d1d6c365dac268cada974179c4152833fd6894287856a9e95adc03fabeff8",
|
|
345
346
|
"e30016a49deff1c3cd3ae7951262aeb2ef3d472bce76bbbe2a177db6017c7cad",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
21
21
|
"all/copy-overwrite/scripts/lisa-run-gates.mjs": "0978ac24f28bf9f11230781d271997384009b1528ed61de523333e52a5a4cf57",
|
|
22
22
|
"all/copy-overwrite/scripts/lisa-schema-validate.mjs": "2ace82daacdebbbb00a7eceb09fbe82cabec04330a083ca10417b2ee4e0a63eb",
|
|
23
23
|
"all/copy-overwrite/scripts/lisa-test-node.mjs": "31b338144af00e20e3de02202982846d7333433a9bbda76a8c77d50e6fdbc47b",
|
|
24
|
-
"all/copy-overwrite/scripts/lisa-work-item.mjs": "
|
|
24
|
+
"all/copy-overwrite/scripts/lisa-work-item.mjs": "d22e31021947e5090c58ee5cfc9c4ee206bf2cf30d25f46b097bafcec59f55f3",
|
|
25
25
|
"all/copy-overwrite/scripts/schemas/lisa-command-envelope.v1.schema.json": "d153b7c2953a30f180e38f09e98240c63327f5196eeba9bdf545e5a1f125a879",
|
|
26
26
|
"all/copy-overwrite/scripts/schemas/lisa-state-contract.v1.schema.json": "6b7afe4ffeba8aaa53871d8855172f7eacde05953b1321145218ec638ff5c1c4",
|
|
27
27
|
"all/create-only/.agents/rules/README.md": "fd260fd9b2934d0d698a8098dfff07fedc071849d588e602d773666678c3d540",
|
|
@@ -515,7 +515,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
515
515
|
"plugins/src/base/skills/lisa-generate-claude-remote-build-script/SKILL.md": "9ae66050b046b3d5bcf4acb582928cb56f295d4d869b712e85b6e0717b67dc7b",
|
|
516
516
|
"plugins/src/base/skills/lisa-git-commit/SKILL.md": "56320566e9278fb43b4d51c00854f3714dc61edc960292d51962a6f49116ac0f",
|
|
517
517
|
"plugins/src/base/skills/lisa-git-prune/SKILL.md": "11fad06d109538f1a8ee4ef8043bb0e083672e3c9a7cb7ae8a7233c5411d6dd2",
|
|
518
|
-
"plugins/src/base/skills/lisa-git-submit-pr/SKILL.md": "
|
|
518
|
+
"plugins/src/base/skills/lisa-git-submit-pr/SKILL.md": "5d8d123ad4986210308af7777d5488536e0b9ac0166cf10fa5900623c959aa4b",
|
|
519
519
|
"plugins/src/base/skills/lisa-github-add-journey/SKILL.md": "6b3bbe8ff85c7cb20412dcfcab3d7506a3efc67907cb749622c329fb4130baf4",
|
|
520
520
|
"plugins/src/base/skills/lisa-github-build-intake/SKILL.md": "ad703d7e7a9f13de6e708fc31fa321b329295b0cc8b31de8804c2fdc3b2fa7fa",
|
|
521
521
|
"plugins/src/base/skills/lisa-github-claim/SKILL.md": "71301c6d45d7eb5523e74aa7f070bb2becf57ca68fb8bde9e02ee937b78815f7",
|
|
@@ -525,7 +525,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
525
525
|
"plugins/src/base/skills/lisa-github-prd-intake/SKILL.md": "80898cc844785596b22c2c24c5abb92fefbe4b15ecfbf6deb59425e6f86e834b",
|
|
526
526
|
"plugins/src/base/skills/lisa-github-project-v2/SKILL.md": "80fac6d91ae36c6e130c220d9d35c5a20e6610d790fbb91343503f49cdb9ec3a",
|
|
527
527
|
"plugins/src/base/skills/lisa-github-read-issue/SKILL.md": "b0db6c44d3f3659905313b1a96c6536e2b3856c082bfbc3b2d6f92f349d7f90a",
|
|
528
|
-
"plugins/src/base/skills/lisa-github-sync/SKILL.md": "
|
|
528
|
+
"plugins/src/base/skills/lisa-github-sync/SKILL.md": "277662186863550daa8675a548ac0949ed3424f8515752f85ce6ccaab98b4688",
|
|
529
529
|
"plugins/src/base/skills/lisa-github-to-tracker/SKILL.md": "b5015eb515f1ad9a442af7e23eaa6f1b204f106a8729bf7ec2b991b9ff509aa9",
|
|
530
530
|
"plugins/src/base/skills/lisa-github-validate-issue/SKILL.md": "d58e970f4a76d3fa3984c5b3054c2710dc0b5c9bb7f3c1890ae89844e53ff395",
|
|
531
531
|
"plugins/src/base/skills/lisa-github-verify/SKILL.md": "0d8dce0fff60591d1efff30e340c2cbbef2e8a849ed650389f2391518580ca53",
|
|
@@ -533,7 +533,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
533
533
|
"plugins/src/base/skills/lisa-github-write-prd/SKILL.md": "262f8a1bcfad4c5dd4456cfaaf1b71abf9697a0da588966e58ff491acd3c17e8",
|
|
534
534
|
"plugins/src/base/skills/lisa-health-drift-cron/SKILL.md": "852eb7410ce26badc7e441d32d43dc15004431abf413fd702f80b4dc5fff4a89",
|
|
535
535
|
"plugins/src/base/skills/lisa-health/SKILL.md": "dfdb08a863e78bff42671793dcec29cfae0654db18ebf66a4aa77aeb56ddb775",
|
|
536
|
-
"plugins/src/base/skills/lisa-implement/SKILL.md": "
|
|
536
|
+
"plugins/src/base/skills/lisa-implement/SKILL.md": "a50f6c92eed59262036c908453a70e3587b79da95264fb99343897e3d75b9167",
|
|
537
537
|
"plugins/src/base/skills/lisa-improve-code-complexity/SKILL.md": "24ab5b193b409db6ee6bee981a1c0a48d08991782d7846116ad01658c8bc1ae8",
|
|
538
538
|
"plugins/src/base/skills/lisa-improve-harness/SKILL.md": "98ad4b896785ac51826969a0ff077ef11c51353f2a2e03444c8b38e6c0363d05",
|
|
539
539
|
"plugins/src/base/skills/lisa-improve-max-lines-per-function/SKILL.md": "95c875950c9848fdaf520a18b9bbb264e33d7347be10170add768e01d9cd8e52",
|
|
@@ -554,7 +554,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
554
554
|
"plugins/src/base/skills/lisa-jira-journey/scripts/parse-plan.py": "0c1921c0996e5d82c2c833e23afdab82a0b2e506f1b8783f87bd7ac0edd789e6",
|
|
555
555
|
"plugins/src/base/skills/lisa-jira-read-ticket/SKILL.md": "1b7cd9a56bae1108c9814b8f8365411dad1e7f3cd294a28baeab6321d0b636b4",
|
|
556
556
|
"plugins/src/base/skills/lisa-jira-read-ticket/scripts/download-attachment.sh": "f0a9b3c5bd82f0f86edb0ad86db5a9501cced9ec4a2a3bfa644bdff01c8eb460",
|
|
557
|
-
"plugins/src/base/skills/lisa-jira-sync/SKILL.md": "
|
|
557
|
+
"plugins/src/base/skills/lisa-jira-sync/SKILL.md": "4ea3cd7efc23eafc9f7bd88a3fb922c4786ff382f91162e666efff199609c1df",
|
|
558
558
|
"plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md": "5eae1b662ada55c4a0737904351ad101fba2b622571562c93f29cf120cca1318",
|
|
559
559
|
"plugins/src/base/skills/lisa-jira-verify/SKILL.md": "4e48dcd9e1144837890359e75cc405280bf5f52cf497e44f294b608ad681580c",
|
|
560
560
|
"plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md": "5352b209c42c8263b0ecdd1826116a244d3eba70c861592b8d4df6bf13a0b5bf",
|
|
@@ -570,7 +570,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
570
570
|
"plugins/src/base/skills/lisa-linear-journey/SKILL.md": "6f189eba5d96f8537883277de1d2d6c87d08226e90df5dd73f16852b0a46224e",
|
|
571
571
|
"plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md": "8a2d577e16b3762093fd2a217a544896676ef00b4fc9d72903ae03853134eb3b",
|
|
572
572
|
"plugins/src/base/skills/lisa-linear-read-issue/SKILL.md": "a6b8241648ba4b7b9f1196a37e9924ffaccc5461f3ac2ee8ae283c58559e9717",
|
|
573
|
-
"plugins/src/base/skills/lisa-linear-sync/SKILL.md": "
|
|
573
|
+
"plugins/src/base/skills/lisa-linear-sync/SKILL.md": "03db1f1237b2b810af832042d4b89a5bf4a7aa36efb45dd41e6f75c6fe342fdf",
|
|
574
574
|
"plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md": "3190bbf85223c7a0508f8bc894fd2c21fc9dce4c977a5af2252191d09c0c6f97",
|
|
575
575
|
"plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md": "db1c68a80c29e0d7b1f8431eaa02f43c0e7c65ff4f0af0f3d54ca772f22c0d4c",
|
|
576
576
|
"plugins/src/base/skills/lisa-linear-verify/SKILL.md": "d11a58bd7c2b773a973fe8f8ad19a2621f038327ee2d8afa3039bd72885f5e97",
|
|
@@ -690,7 +690,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
|
|
|
690
690
|
"plugins/src/base/skills/lisa-tracker-journey/SKILL.md": "65fe727adfdbcc22141ad009e89cd7d91195600377c5357d552d50ed98ecf66b",
|
|
691
691
|
"plugins/src/base/skills/lisa-tracker-read/SKILL.md": "2a1047a723193ce999c0d4dc4d205a49f231c724fd812581c78fdef9e8f58b30",
|
|
692
692
|
"plugins/src/base/skills/lisa-tracker-source-artifacts/SKILL.md": "32d411ae12378c3446d798f60d006b9f9ec0bdf82b86a5f60287766a96541fb3",
|
|
693
|
-
"plugins/src/base/skills/lisa-tracker-sync/SKILL.md": "
|
|
693
|
+
"plugins/src/base/skills/lisa-tracker-sync/SKILL.md": "fc1e3944ef1aa43374fbe3ed64a49065063122fe1281b99d843b98d6389351e0",
|
|
694
694
|
"plugins/src/base/skills/lisa-tracker-validate/SKILL.md": "1527ee91ae0db42c2551ce579ab25e4daf9e7290df5ad3e77c618c4fd1ed8b16",
|
|
695
695
|
"plugins/src/base/skills/lisa-tracker-verify/SKILL.md": "552685eb08a76100df64c33f84d2c5f78867f4074e9fa1aa34fa9f905e06da1a",
|
|
696
696
|
"plugins/src/base/skills/lisa-tracker-write/SKILL.md": "3c2e12ef37a8e20abe4d7ce4d01799dc2bc7b5304f6a18108da8f2318be31da1",
|
package/package.json
CHANGED
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"ws": ">=8.21.0"
|
|
132
132
|
},
|
|
133
133
|
"name": "@codyswann/lisa",
|
|
134
|
-
"version": "3.33.
|
|
134
|
+
"version": "3.33.7",
|
|
135
135
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
136
136
|
"main": "dist/index.js",
|
|
137
137
|
"exports": {
|
|
@@ -66,10 +66,17 @@ When updating an existing PR, preserve any existing linkage line unless the new
|
|
|
66
66
|
After creating or updating the PR, always make the reverse link durable on the source work item when `work_item_ref` is available:
|
|
67
67
|
|
|
68
68
|
1. Resolve the live PR URL with `gh pr view <pr-number> --json url --jq .url`.
|
|
69
|
-
2.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
2. Run the backlink command. It is the executable form of this requirement — it writes the managed `[lisa-pr-link]` comment on the work item, or updates the one already there, for every tracker Lisa supports:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node scripts/lisa-work-item.mjs backlink --ref <work_item_ref> --pr-url <url>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It is idempotent, so run it on every push rather than deciding whether it is needed. It refuses loudly for a tracker it cannot write, and never silently no-ops. Do not hand-post the comment, and do not describe the posting procedure anywhere: the same file that writes it is the file that checks it, which is what keeps producer and consumer from drifting.
|
|
76
|
+
3. Invoke `lisa-tracker-sync` with the original work item ref, milestone `pr-ready`, `pr_url=<url>`, and `tracker_provider=<provider>` when known. That is the progress-note and status side; it is not what satisfies the traceability check.
|
|
77
|
+
4. When the PR later merges, invoke `lisa-tracker-sync` again with milestone `pr-merged`, the same `pr_url`, and the merge SHA when available.
|
|
78
|
+
|
|
79
|
+
**Why step 2 exists — do not "simplify" it away as redundant with the `Refs` line.** Under the non-closing rule above, GitHub never creates a native development link at all: that surface *is* the closing-reference mechanism, so no non-closing form can populate it. A PR carrying a perfectly correct `Refs` line still fails the required Work-Item Traceability check without the comment. The managed comment is the ticket-side half of the link, not a fallback for when native linkage happens to be absent.
|
|
73
80
|
|
|
74
81
|
Do not report PR submission as fully synced while the PR body references the ticket but the ticket has neither a verified native PR link nor the managed backlink comment.
|
|
75
82
|
|
|
@@ -57,8 +57,13 @@ Optional arguments include `pr_url=<url>` for the live pull request and `merge_s
|
|
|
57
57
|
When `$ARGUMENTS` includes `pr_url=<url>` for `PR ready` or `PR merged`, ensure the GitHub Issue has a durable ticket -> PR link:
|
|
58
58
|
|
|
59
59
|
1. Make sure the PR body contains `Refs #<n>` (or the fully qualified cross-repo form) — never a closing keyword, per the GitHub rule in `lisa-git-submit-pr`. Read the issue side with `gh api graphql` against `issue.timelineItems`, or `gh issue view <number> --json closedByPullRequestsReferences`. **Not** `gh issue view --json timelineItems`: `timelineItems` is not a supported field for that command, so the check silently returns nothing useful rather than failing loudly.
|
|
60
|
-
2.
|
|
61
|
-
|
|
60
|
+
2. Establish the managed backlink comment by running the command that owns it — never by hand, and never by describing the procedure here:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
node scripts/lisa-work-item.mjs backlink --ref <work-item> --pr-url <url>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
It creates the `[lisa-pr-link]` comment or updates the one already present, instead of appending duplicates, so it is safe to run on every milestone. This is **unconditional**, not contingent on step 1 failing: under the non-closing rule GitHub never creates a native development link (that surface is the closing-reference mechanism), so this comment is the only ticket-side backlink there will be — run it whether or not native linkage exists or cannot be verified, because the required Work-Item Traceability check reads this comment and nothing else guarantees one. The comment carries the marker and the PR URL only; the milestone (`pr-ready` / `pr-merged`) and merge SHA belong in the milestone progress note, so that a rerun at a new milestone still converges on one backlink comment.
|
|
62
67
|
|
|
63
68
|
Native GitHub linkage cannot be verified under the non-closing rule because it is never created in the first place, so the managed comment is not a contingency here — it is the mechanism. The issue must show the PR from at least one ticket-side surface, and this is the only one available.
|
|
64
69
|
|
|
@@ -341,7 +341,7 @@ Before shutting down the team, execute the Verify flow:
|
|
|
341
341
|
5. Commit ALL outstanding changes in logical batches on the branch (minus sensitive data/information) — not just changes made by the agent team. This includes pre-existing uncommitted changes that were on the branch before the plan started. Do NOT filter commits to only "task-related" files. If it shows up in git status, it gets committed (unless it contains secrets).
|
|
342
342
|
6. Push the changes - if any pre-push hook blocks you, create a task for the agent team to fix the error/problem whether it was pre-existing or not
|
|
343
343
|
7. Open a pull request with auto-merge on via `lisa-git-submit-pr`, targeting the **base branch resolved from the ticket's environment** (`target_branch=<base>`, per the branch step above), and including the mandatory work-item ref so the PR can be linked natively to the source issue.
|
|
344
|
-
7a. Confirm two-way linkage before treating PR submission as complete: the PR body/title/branch must reference the work item, and the work item must have either a verified native PR link or
|
|
344
|
+
7a. Confirm two-way linkage before treating PR submission as complete: the PR body/title/branch must reference the work item, and the work item must have either a verified native PR link or the single managed `[lisa-pr-link]` comment. Establish that comment with `node scripts/lisa-work-item.mjs backlink --ref <work_item_ref> --pr-url <url>` rather than posting it by hand — it is idempotent, and it is the same file that enforces the check, so producer and consumer cannot drift.
|
|
345
345
|
8. PR Watch Loop: Drive the PR to merge via the `drive-pr-to-merge` skill — the single source of truth for clearing every blocker (auto-merge with direct-merge fallback, `BEHIND` re-sync, conflict resolution, failing-check fixes, human + bot review-comment handling with thread resolution, stale `CHANGES_REQUESTED` dismissal, and post-merge ancestry verification). `git-submit-pr` already invokes it; if you reach this step with a PR already open, invoke `drive-pr-to-merge` directly with the PR number. For a large review backlog you may fan the code-fix work out to the agent team, but `drive-pr-to-merge` owns the loop and the terminal conditions — do not re-implement them.
|
|
346
346
|
9. Merge the PR, then refresh the ticket-side backlink with `lisa-tracker-sync <work_item_ref> pr-merged pr_url=<url> merge_sha=<sha> tracker_provider=<provider>`.
|
|
347
347
|
10. Monitor the deploy action that triggers automatically from the successful merge
|
|
@@ -55,8 +55,13 @@ Before adding a comment, check for an existing milestone comment to avoid duplic
|
|
|
55
55
|
When `$ARGUMENTS` includes `pr_url=<url>` for `PR ready` or `PR merged`, ensure the JIRA ticket has a durable ticket -> PR link:
|
|
56
56
|
|
|
57
57
|
1. Prefer the JIRA development-link surface when the site's GitHub/JIRA integration or remote-link API is available through `lisa-atlassian-access`; verify by re-reading the ticket's remote links / development metadata.
|
|
58
|
-
2.
|
|
59
|
-
|
|
58
|
+
2. Establish the managed backlink comment by running the command that owns it — never by hand, and never by describing the procedure here:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
node scripts/lisa-work-item.mjs backlink --ref <work-item> --pr-url <url>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
It creates the `[lisa-pr-link]` comment or updates the one already present, instead of appending duplicates, so it is safe to run on every milestone. This is **unconditional** — run it whether or not native linkage exists or cannot be verified, because the required Work-Item Traceability check reads this comment and nothing else guarantees one. The comment carries the marker and the PR URL only; the milestone (`pr-ready` / `pr-merged`) and merge SHA belong in the milestone progress note, so that a rerun at a new milestone still converges on one backlink comment.
|
|
60
65
|
|
|
61
66
|
The PR body/branch issue key is the PR -> ticket side. This step is the required ticket -> PR side.
|
|
62
67
|
|
|
@@ -72,8 +72,13 @@ Call `lisa-linear-access operation: save-comment({issueId: <id>, body: <comment>
|
|
|
72
72
|
When `$ARGUMENTS` includes `pr_url=<url>` for `pr-ready` or `pr-merged`, ensure the Linear Issue has a durable ticket -> PR link:
|
|
73
73
|
|
|
74
74
|
1. Prefer Linear's native GitHub attachment / pull request link when the integration has attached the PR through the branch name, PR title, or PR body issue identifier. Verify by re-reading the Issue and its attachments / relations where the Linear access layer exposes them.
|
|
75
|
-
2.
|
|
76
|
-
|
|
75
|
+
2. Establish the managed backlink comment by running the command that owns it — never by hand, and never by describing the procedure here:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
node scripts/lisa-work-item.mjs backlink --ref <work-item> --pr-url <url>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
It creates the `[lisa-pr-link]` comment or updates the one already present, instead of appending duplicates, so it is safe to run on every milestone. This is **unconditional** — run it whether or not native linkage exists or cannot be verified, because the required Work-Item Traceability check reads this comment and nothing else guarantees one. The comment carries the marker and the PR URL only; the milestone (`pr-ready` / `pr-merged`) and merge SHA belong in the milestone progress note, so that a rerun at a new milestone still converges on one backlink comment.
|
|
77
82
|
|
|
78
83
|
The PR branch/title/body identifier is the PR -> Linear side. This phase is the required Linear -> PR side.
|
|
79
84
|
|
|
@@ -52,8 +52,13 @@ When `$ARGUMENTS` includes `pr_url=<url>` with milestone `pr-ready` or `pr-merge
|
|
|
52
52
|
|
|
53
53
|
1. Prefer the provider's native development-link primitive when Lisa can write and verify it for that provider.
|
|
54
54
|
2. Verify the native link using the provider read surface when available.
|
|
55
|
-
3.
|
|
56
|
-
|
|
55
|
+
3. Whether or not the native link exists or cannot be verified, establish the managed backlink comment with the one command that owns it:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
node scripts/lisa-work-item.mjs backlink --ref <work-item> --pr-url <url>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
4. That command is idempotent by construction — it updates the existing `[lisa-pr-link]` comment rather than appending duplicates — and it refuses loudly for a tracker it cannot write. Do not restate its procedure in a vendor skill; the file that writes the comment is the file that checks it, and that is what stops the two from drifting.
|
|
57
62
|
|
|
58
63
|
This is the reverse half of `lisa-git-submit-pr`'s PR body linkage. A PR that mentions a ticket is not considered fully synced until the ticket also has either a verified native PR link or the managed fallback comment.
|
|
59
64
|
|
|
@@ -66,10 +66,17 @@ When updating an existing PR, preserve any existing linkage line unless the new
|
|
|
66
66
|
After creating or updating the PR, always make the reverse link durable on the source work item when `work_item_ref` is available:
|
|
67
67
|
|
|
68
68
|
1. Resolve the live PR URL with `gh pr view <pr-number> --json url --jq .url`.
|
|
69
|
-
2.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
2. Run the backlink command. It is the executable form of this requirement — it writes the managed `[lisa-pr-link]` comment on the work item, or updates the one already there, for every tracker Lisa supports:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node scripts/lisa-work-item.mjs backlink --ref <work_item_ref> --pr-url <url>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It is idempotent, so run it on every push rather than deciding whether it is needed. It refuses loudly for a tracker it cannot write, and never silently no-ops. Do not hand-post the comment, and do not describe the posting procedure anywhere: the same file that writes it is the file that checks it, which is what keeps producer and consumer from drifting.
|
|
76
|
+
3. Invoke `lisa-tracker-sync` with the original work item ref, milestone `pr-ready`, `pr_url=<url>`, and `tracker_provider=<provider>` when known. That is the progress-note and status side; it is not what satisfies the traceability check.
|
|
77
|
+
4. When the PR later merges, invoke `lisa-tracker-sync` again with milestone `pr-merged`, the same `pr_url`, and the merge SHA when available.
|
|
78
|
+
|
|
79
|
+
**Why step 2 exists — do not "simplify" it away as redundant with the `Refs` line.** Under the non-closing rule above, GitHub never creates a native development link at all: that surface *is* the closing-reference mechanism, so no non-closing form can populate it. A PR carrying a perfectly correct `Refs` line still fails the required Work-Item Traceability check without the comment. The managed comment is the ticket-side half of the link, not a fallback for when native linkage happens to be absent.
|
|
73
80
|
|
|
74
81
|
Do not report PR submission as fully synced while the PR body references the ticket but the ticket has neither a verified native PR link nor the managed backlink comment.
|
|
75
82
|
|
|
@@ -57,8 +57,13 @@ Optional arguments include `pr_url=<url>` for the live pull request and `merge_s
|
|
|
57
57
|
When `$ARGUMENTS` includes `pr_url=<url>` for `PR ready` or `PR merged`, ensure the GitHub Issue has a durable ticket -> PR link:
|
|
58
58
|
|
|
59
59
|
1. Make sure the PR body contains `Refs #<n>` (or the fully qualified cross-repo form) — never a closing keyword, per the GitHub rule in `lisa-git-submit-pr`. Read the issue side with `gh api graphql` against `issue.timelineItems`, or `gh issue view <number> --json closedByPullRequestsReferences`. **Not** `gh issue view --json timelineItems`: `timelineItems` is not a supported field for that command, so the check silently returns nothing useful rather than failing loudly.
|
|
60
|
-
2.
|
|
61
|
-
|
|
60
|
+
2. Establish the managed backlink comment by running the command that owns it — never by hand, and never by describing the procedure here:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
node scripts/lisa-work-item.mjs backlink --ref <work-item> --pr-url <url>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
It creates the `[lisa-pr-link]` comment or updates the one already present, instead of appending duplicates, so it is safe to run on every milestone. This is **unconditional**, not contingent on step 1 failing: under the non-closing rule GitHub never creates a native development link (that surface is the closing-reference mechanism), so this comment is the only ticket-side backlink there will be — run it whether or not native linkage exists or cannot be verified, because the required Work-Item Traceability check reads this comment and nothing else guarantees one. The comment carries the marker and the PR URL only; the milestone (`pr-ready` / `pr-merged`) and merge SHA belong in the milestone progress note, so that a rerun at a new milestone still converges on one backlink comment.
|
|
62
67
|
|
|
63
68
|
Native GitHub linkage cannot be verified under the non-closing rule because it is never created in the first place, so the managed comment is not a contingency here — it is the mechanism. The issue must show the PR from at least one ticket-side surface, and this is the only one available.
|
|
64
69
|
|