@sjawhar/pi-legion 9.8.0 → 9.8.2
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/legion.js
CHANGED
|
@@ -15729,7 +15729,7 @@ function onEnvoyRoleRegained(listener) {
|
|
|
15729
15729
|
// package.json
|
|
15730
15730
|
var package_default = {
|
|
15731
15731
|
name: "@sjawhar/pi-legion",
|
|
15732
|
-
version: "9.8.
|
|
15732
|
+
version: "9.8.2",
|
|
15733
15733
|
license: "Apache-2.0",
|
|
15734
15734
|
type: "module",
|
|
15735
15735
|
omp: {
|
|
@@ -16515,6 +16515,45 @@ function createControllerSession(deps) {
|
|
|
16515
16515
|
// src/handoff-commit.ts
|
|
16516
16516
|
import { execFile as execFile2 } from "child_process";
|
|
16517
16517
|
import { promisify as promisify2 } from "util";
|
|
16518
|
+
|
|
16519
|
+
// src/git-lock.ts
|
|
16520
|
+
import { lstat } from "fs/promises";
|
|
16521
|
+
var GIT_LOCK_REPORTS = [
|
|
16522
|
+
/The lockfile at '([^']+)' might need manual deletion/g,
|
|
16523
|
+
/Unable to create '([^']+)': File exists/g
|
|
16524
|
+
];
|
|
16525
|
+
function age(ms) {
|
|
16526
|
+
const total = Math.round(Math.abs(ms) / 1000);
|
|
16527
|
+
const sign = ms < 0 && total > 0 ? "-" : "";
|
|
16528
|
+
const hours = Math.floor(total / 3600);
|
|
16529
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
16530
|
+
const seconds = total % 60;
|
|
16531
|
+
if (hours > 0)
|
|
16532
|
+
return `${sign}${hours}h${minutes}m${seconds}s`;
|
|
16533
|
+
if (minutes > 0)
|
|
16534
|
+
return `${sign}${minutes}m${seconds}s`;
|
|
16535
|
+
return `${sign}${seconds}s`;
|
|
16536
|
+
}
|
|
16537
|
+
async function staleGitLockNote(output, now = Date.now()) {
|
|
16538
|
+
const locks = new Set;
|
|
16539
|
+
for (const report of GIT_LOCK_REPORTS) {
|
|
16540
|
+
for (const match of output.matchAll(report))
|
|
16541
|
+
locks.add(match[1]);
|
|
16542
|
+
}
|
|
16543
|
+
const notes = [];
|
|
16544
|
+
for (const lock of locks) {
|
|
16545
|
+
const written = await lstat(lock).then((info) => info.mtimeMs, () => {
|
|
16546
|
+
return;
|
|
16547
|
+
});
|
|
16548
|
+
if (written === undefined)
|
|
16549
|
+
continue;
|
|
16550
|
+
notes.push(`git lock ${lock} was last written ${age(now - written)} ago and blocks this command. Do not remove it while the issue's pod runs: another role's git, which this container cannot see, may hold it. Replacing the issue's pod removes it. Under the tmux runtime nothing removes it: remove it by hand only once no git or jj process on the host is using the repository.`);
|
|
16551
|
+
}
|
|
16552
|
+
return notes.join(`
|
|
16553
|
+
`);
|
|
16554
|
+
}
|
|
16555
|
+
|
|
16556
|
+
// src/handoff-commit.ts
|
|
16518
16557
|
var FILE_BACKED = {
|
|
16519
16558
|
planning: { word: "plan", role: "planner" },
|
|
16520
16559
|
implementing: { word: "implement", role: "implementer" },
|
|
@@ -16531,7 +16570,9 @@ var pathJj = async (args, cwd) => {
|
|
|
16531
16570
|
return stdout.trim();
|
|
16532
16571
|
} catch (error48) {
|
|
16533
16572
|
const detail = error48 !== null && typeof error48 === "object" && "stderr" in error48 ? String(error48.stderr).trim() : error48 instanceof Error ? error48.message : String(error48);
|
|
16534
|
-
|
|
16573
|
+
const note = await staleGitLockNote(detail);
|
|
16574
|
+
throw new Error(`jj ${args.join(" ")} failed: ${detail}${note === "" ? "" : `
|
|
16575
|
+
${note}`}`);
|
|
16535
16576
|
}
|
|
16536
16577
|
};
|
|
16537
16578
|
function requiredVariable(env, name) {
|
|
@@ -197,7 +197,8 @@ credential can exist without any skill having told you so). When the evidence ge
|
|
|
197
197
|
reachable, do not have a different running session perform the read on this tree's behalf and
|
|
198
198
|
fold the result into the spec as if it were routine: write the missing capability as its own
|
|
199
199
|
decision block — which external system, which read or write, why the spec needs it — addressed
|
|
200
|
-
to the human, in the same spirit as the implementer
|
|
200
|
+
to the human, in the same spirit as the implementer's ask to a person when the deployment
|
|
201
|
+
instructions name nobody for a deploy (section 6), and leave it
|
|
201
202
|
open until the human resolves it. A workaround substituted for that record only hides the gap
|
|
202
203
|
from the next tree that hits it.
|
|
203
204
|
|
|
@@ -314,9 +315,12 @@ The daemon keeps this order from its fixed table; you start none of its steps:
|
|
|
314
315
|
It drives the changed path in production through the user's own access path and records
|
|
315
316
|
what it saw on the pull request and on this issue. Sign off only after the implementer's production
|
|
316
317
|
report exists. A defect it finds is a corrective child issue of this tree, not a note on a
|
|
317
|
-
closed one
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
closed one. If the implementer cannot perform the deploy itself, it asks the agent or role the
|
|
319
|
+
deployment instructions name for that deploy (an Envoy role), gives it the merge commit, and
|
|
320
|
+
waits on the production signal the instructions name; the issue waits with it. It opens a
|
|
321
|
+
`dispatch ask` to a person only when the instructions name nobody for that deploy, starting
|
|
322
|
+
with the production gap and why it matters, then naming the required step, its risk, and
|
|
323
|
+
outcome-named options. No one is ever asked for approval to deploy.
|
|
320
324
|
|
|
321
325
|
What returns the tree to review: a changed diff — a commit above the approved head that
|
|
322
326
|
touches anything outside `docs/solutions/` and the issue's `.legion/<issue>/`, or a
|
|
@@ -180,7 +180,7 @@ dispatch message --issue <KEY> --body-file - <<'EOF'
|
|
|
180
180
|
|
|
181
181
|
**Proofs read:** implementer <surface/command>, tester <surface/command>.
|
|
182
182
|
|
|
183
|
-
**Production check:** <what the implementer will drive after the merge,
|
|
183
|
+
**Production check:** <what the implementer will drive after the merge, and any deploy or restart it waits on first, with the agent or role the deployment instructions name to perform it, or the person it asks when they name none>
|
|
184
184
|
|
|
185
185
|
<!-- legion: {"session":"<session-id>","phase":"retro"} -->
|
|
186
186
|
EOF
|
|
@@ -151,8 +151,12 @@ review posted without a completion leaves the issue in reviewing until you finis
|
|
|
151
151
|
carrying the Legion footer, and a `dispatch message` on the issue — the reviewer and merger
|
|
152
152
|
read GitHub, the architect reads the issue. When the deploy that carries the merge has not
|
|
153
153
|
happened (a shared profile still holding the previous plugin release, a daemon still running
|
|
154
|
-
the previous commit, a slot nobody has run)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
the previous commit, a slot nobody has run) and you cannot perform it yourself, ask the agent or
|
|
155
|
+
role the deployment instructions name for that deploy: `envoy_publish` to its role topic with the
|
|
156
|
+
merge commit and `expects_reply: required`, then wait on the production signal the instructions
|
|
157
|
+
name. Open a `dispatch ask` to a person only when the instructions name nobody for that deploy;
|
|
158
|
+
it starts with the production gap and why it matters, then names the required install or restart
|
|
159
|
+
step, its risk, and outcome-named options. Never ask anyone for approval to deploy. Keep the
|
|
160
|
+
`Production:` line at `pending <what is missing>`, and complete the check once that signal shows
|
|
161
|
+
the deploy carries the merge (or the person answers, when an ask was the route). Never record a
|
|
162
|
+
staging pass as the production check, and never let the architect sign off on a `pending` line.
|