create-egregore 0.21.0-runtime-mvp.23 → 0.21.0-runtime-mvp.25
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/assets/egregore-launcher.js +48 -51
- package/lib/setup.js +3 -3
- package/package.json +1 -1
- package/runtime/claude/.claude/skills/save/SKILL.md +4 -11
- package/runtime/claude/bin/agent.sh +8 -0
- package/runtime/claude/bin/runtime-upgrade.sh +3 -1
- package/runtime/claude/egregore_runtime/runtime.py +5 -8
- package/runtime/codex/.codex/skills/save/SKILL.md +4 -7
- package/runtime/codex/bin/agent.sh +8 -0
- package/runtime/codex/bin/runtime-upgrade.sh +3 -1
- package/runtime/codex/egregore_runtime/runtime.py +5 -8
- package/runtime/pi/.codex/skills/save/SKILL.md +4 -7
- package/runtime/pi/bin/agent.sh +8 -0
- package/runtime/pi/bin/runtime-upgrade.sh +3 -1
- package/runtime/pi/egregore_runtime/runtime.py +5 -8
- package/runtime/prime/.codex/skills/save/SKILL.md +4 -7
- package/runtime/prime/bin/agent.sh +8 -0
- package/runtime/prime/bin/runtime-upgrade.sh +3 -1
- package/runtime/prime/egregore_runtime/runtime.py +5 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// egregore-launcher-version: 0.21.0-runtime-mvp.
|
|
2
|
+
// egregore-launcher-version: 0.21.0-runtime-mvp.25
|
|
3
3
|
//
|
|
4
4
|
// egregore — launch and browse Egregore instances from your terminal.
|
|
5
5
|
// Installed by create-egregore. Reads ~/.egregore/instances.json.
|
|
@@ -35,7 +35,7 @@ const crypto = require("node:crypto");
|
|
|
35
35
|
const { spawnSync, spawn } = require("node:child_process");
|
|
36
36
|
const readline = require("node:readline");
|
|
37
37
|
|
|
38
|
-
const VERSION = "0.21.0-runtime-mvp.
|
|
38
|
+
const VERSION = "0.21.0-runtime-mvp.25";
|
|
39
39
|
const REGISTRY = path.join(os.homedir(), ".egregore", "instances.json");
|
|
40
40
|
const DEFAULT_FILE = path.join(os.homedir(), ".egregore", "default");
|
|
41
41
|
const UPDATE_CACHE_FILE = path.join(os.homedir(), ".egregore", "update-check.json");
|
|
@@ -766,9 +766,8 @@ function codexSupportMessage(egregoreDir) {
|
|
|
766
766
|
" .codex/hooks.json",
|
|
767
767
|
" .codex/hooks/",
|
|
768
768
|
"",
|
|
769
|
-
"
|
|
770
|
-
"
|
|
771
|
-
"Then rerun egregore.",
|
|
769
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
770
|
+
"A global CLI refresh does not repair instance files.",
|
|
772
771
|
"Egregore workflows appear as slash commands. In Codex, invoke them with the matching $skill token or ask in natural language.",
|
|
773
772
|
].join("\n");
|
|
774
773
|
}
|
|
@@ -799,7 +798,7 @@ function piSupportMessage(egregoreDir) {
|
|
|
799
798
|
"Pi meta-harness support is missing from this Egregore checkout.",
|
|
800
799
|
` path: ${egregoreDir}`,
|
|
801
800
|
"",
|
|
802
|
-
"
|
|
801
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
803
802
|
].join("\n");
|
|
804
803
|
}
|
|
805
804
|
|
|
@@ -818,31 +817,10 @@ function primeSupportMessage(egregoreDir) {
|
|
|
818
817
|
"Prime Agent runtime support is missing from this Egregore checkout.",
|
|
819
818
|
` path: ${egregoreDir}`,
|
|
820
819
|
"",
|
|
821
|
-
"
|
|
820
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
822
821
|
].join("\n");
|
|
823
822
|
}
|
|
824
823
|
|
|
825
|
-
function repairPortableRuntime(egregoreDir, runtime) {
|
|
826
|
-
const label = runtimeLabel(runtime);
|
|
827
|
-
process.stdout.write(`\n ${CYAN}↻${RESET} ${BOLD}Repairing ${label} support${RESET}${DIM} — updating this checkout${RESET}\n`);
|
|
828
|
-
const result = spawnSync(
|
|
829
|
-
"npx",
|
|
830
|
-
["-y", `${PUBLIC_NPX_PACKAGE}@latest`, "--refresh-launcher"],
|
|
831
|
-
{
|
|
832
|
-
cwd: egregoreDir,
|
|
833
|
-
stdio: "inherit",
|
|
834
|
-
env: { ...process.env, EGREGORE_RUNTIME_REPAIR: runtime },
|
|
835
|
-
timeout: 3 * 60 * 1000,
|
|
836
|
-
},
|
|
837
|
-
);
|
|
838
|
-
if (result.error || result.status !== 0) {
|
|
839
|
-
process.stderr.write(` ${YELLOW}!${RESET} Automatic ${label} repair failed; the checkout was left in place.\n`);
|
|
840
|
-
return false;
|
|
841
|
-
}
|
|
842
|
-
process.stdout.write(` ${GREEN}✓${RESET} ${label} support repaired\n\n`);
|
|
843
|
-
return true;
|
|
844
|
-
}
|
|
845
|
-
|
|
846
824
|
// Minimal y/N line prompt for pre-launch decisions (the TUI select machinery
|
|
847
825
|
// is torn down by the time launch() runs).
|
|
848
826
|
function confirmLine(question) {
|
|
@@ -988,19 +966,15 @@ async function launch(inst, runtimeOverride) {
|
|
|
988
966
|
}
|
|
989
967
|
}
|
|
990
968
|
if (runtime === "codex") {
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
die(codexSupportMessage(inst.path));
|
|
994
|
-
}
|
|
995
|
-
}
|
|
969
|
+
// Launching never changes an instance's runtime or release channel.
|
|
970
|
+
if (!hasCodexCoreSupport(inst.path)) die(codexSupportMessage(inst.path));
|
|
996
971
|
const skillsInstalled = installCodexSkills(inst.path);
|
|
997
972
|
const cardRendered = await renderCodexStartupCard(inst.path);
|
|
998
973
|
if (!skillsInstalled || !cardRendered) {
|
|
999
974
|
die(codexSupportMessage(inst.path));
|
|
1000
975
|
}
|
|
1001
976
|
} else if (runtime === "pi") {
|
|
1002
|
-
if (!hasPiCoreSupport(inst.path)
|
|
1003
|
-
(!repairPortableRuntime(inst.path, runtime) || !hasPiCoreSupport(inst.path))) {
|
|
977
|
+
if (!hasPiCoreSupport(inst.path)) {
|
|
1004
978
|
die(piSupportMessage(inst.path));
|
|
1005
979
|
}
|
|
1006
980
|
}
|
|
@@ -1011,10 +985,7 @@ async function launch(inst, runtimeOverride) {
|
|
|
1011
985
|
// check + the trust-flag probe, which shells out to the binary), then a
|
|
1012
986
|
// single handoff line explains the remaining in-harness startup.
|
|
1013
987
|
const stopLoader = startSpinner("Starting Prime Agent");
|
|
1014
|
-
|
|
1015
|
-
if (!coreOk && repairPortableRuntime(inst.path, runtime)) {
|
|
1016
|
-
coreOk = hasPrimeCoreSupport(inst.path);
|
|
1017
|
-
}
|
|
988
|
+
const coreOk = hasPrimeCoreSupport(inst.path);
|
|
1018
989
|
launchArgs = coreOk ? runtimeLaunchArgs(runtime, inst.path) : null;
|
|
1019
990
|
stopLoader();
|
|
1020
991
|
if (!coreOk) die(primeSupportMessage(inst.path));
|
|
@@ -1317,7 +1288,19 @@ function compareReleaseVersions(a, b) {
|
|
|
1317
1288
|
if (left.prerelease === right.prerelease) return 0;
|
|
1318
1289
|
if (!left.prerelease) return 1;
|
|
1319
1290
|
if (!right.prerelease) return -1;
|
|
1320
|
-
|
|
1291
|
+
const leftIds = left.prerelease.split(".");
|
|
1292
|
+
const rightIds = right.prerelease.split(".");
|
|
1293
|
+
for (let i = 0; i < Math.max(leftIds.length, rightIds.length); i++) {
|
|
1294
|
+
if (leftIds[i] === undefined) return -1;
|
|
1295
|
+
if (rightIds[i] === undefined) return 1;
|
|
1296
|
+
if (leftIds[i] === rightIds[i]) continue;
|
|
1297
|
+
const leftNumeric = /^\d+$/.test(leftIds[i]);
|
|
1298
|
+
const rightNumeric = /^\d+$/.test(rightIds[i]);
|
|
1299
|
+
if (leftNumeric && rightNumeric) return BigInt(leftIds[i]) > BigInt(rightIds[i]) ? 1 : -1;
|
|
1300
|
+
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
1301
|
+
return leftIds[i] > rightIds[i] ? 1 : -1;
|
|
1302
|
+
}
|
|
1303
|
+
return 0;
|
|
1321
1304
|
}
|
|
1322
1305
|
|
|
1323
1306
|
function cliUpdateState(latest) {
|
|
@@ -1883,9 +1866,10 @@ async function cmdConnect(args) {
|
|
|
1883
1866
|
console.log(` ${DIM}${line}${RESET}`);
|
|
1884
1867
|
}
|
|
1885
1868
|
}
|
|
1869
|
+
// Connect is an instance-scoped overlay; never refresh other runtimes here.
|
|
1886
1870
|
const runtimeRefresh = spawnSync(
|
|
1887
1871
|
"npx",
|
|
1888
|
-
["-y", `${PUBLIC_NPX_PACKAGE}
|
|
1872
|
+
["-y", `${PUBLIC_NPX_PACKAGE}@${VERSION}`, "--refresh-connect"],
|
|
1889
1873
|
{
|
|
1890
1874
|
cwd: inst.path,
|
|
1891
1875
|
encoding: "utf-8",
|
|
@@ -1897,7 +1881,7 @@ async function cmdConnect(args) {
|
|
|
1897
1881
|
console.log(` ${GREEN}✓${RESET} Connect features installed`);
|
|
1898
1882
|
} else {
|
|
1899
1883
|
console.log(` ${YELLOW}!${RESET} Connect features will retry on the next update`);
|
|
1900
|
-
console.log(` ${DIM}npx -y ${PUBLIC_NPX_PACKAGE}
|
|
1884
|
+
console.log(` ${DIM}npx -y ${PUBLIC_NPX_PACKAGE}@${VERSION} --refresh-connect${RESET}`);
|
|
1901
1885
|
}
|
|
1902
1886
|
console.log("");
|
|
1903
1887
|
console.log(` ${GREEN}✓${RESET} ${BOLD}${inst.slug}${RESET} is connected. Local files remain the source of truth.`);
|
|
@@ -2381,13 +2365,20 @@ function resolveUpgradeBridge(inst) {
|
|
|
2381
2365
|
return null;
|
|
2382
2366
|
}
|
|
2383
2367
|
|
|
2368
|
+
// Snapshot the bridge before starting Bash: older instances still have a
|
|
2369
|
+
// non-exec bridge that activation overwrites while its shell is running.
|
|
2370
|
+
// Keep $0 and all arguments intact for root resolution and exact forwarding.
|
|
2371
|
+
function upgradeBridgeArgs(bridge, args) {
|
|
2372
|
+
return ["-c", fs.readFileSync(bridge.script, "utf-8"), bridge.script, ...args];
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2384
2375
|
function runUpgrade(inst, args, timeout = 60000) {
|
|
2385
2376
|
const bridge = resolveUpgradeBridge(inst);
|
|
2386
2377
|
if (!bridge) {
|
|
2387
2378
|
return { status: 127, stdout: "", stderr: "Runtime update is unavailable — no upgrade engine in this egregore or the installed launcher package.\n", missing: true };
|
|
2388
2379
|
}
|
|
2389
2380
|
try {
|
|
2390
|
-
return spawnSync("bash",
|
|
2381
|
+
return spawnSync("bash", upgradeBridgeArgs(bridge, args), { cwd: inst.path, stdio: "pipe", encoding: "utf-8", timeout, env: { ...process.env, ...bridge.env } });
|
|
2391
2382
|
} catch (err) {
|
|
2392
2383
|
return { status: 1, stdout: "", stderr: String(err) };
|
|
2393
2384
|
}
|
|
@@ -2530,7 +2521,7 @@ function upgradeStatusAsync(inst, cb) {
|
|
|
2530
2521
|
if (!bridge) return cb({ status: "unavailable", failure: { message: "No Runtime update engine is installed" } });
|
|
2531
2522
|
let buf = ""; let err = "";
|
|
2532
2523
|
try {
|
|
2533
|
-
const child = spawn("bash",
|
|
2524
|
+
const child = spawn("bash", upgradeBridgeArgs(bridge, ["status"]), { cwd: inst.path, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, ...bridge.env } });
|
|
2534
2525
|
child.stdout.on("data", (d) => { buf += d; });
|
|
2535
2526
|
child.stderr.on("data", (d) => { err += d; });
|
|
2536
2527
|
child.on("close", (code) => {
|
|
@@ -2667,12 +2658,18 @@ const UPGRADE_STATUS_LABEL = {
|
|
|
2667
2658
|
// Settings-row truth for the Runtime update line. The row must say outright
|
|
2668
2659
|
// whether this egregore runs the new Runtime — "no update staged" is
|
|
2669
2660
|
// transaction state, not the condition the user needs to see.
|
|
2661
|
+
function runtimeUpdateAvailable(st, candidate) {
|
|
2662
|
+
return st?.status === "active"
|
|
2663
|
+
&& RUNTIME_MVP_VERSION_RE.test(candidate || "")
|
|
2664
|
+
&& compareReleaseVersions(candidate, st.active_version) > 0;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2670
2667
|
function runtimeUpdateRowValue(st, candidate) {
|
|
2671
2668
|
if (st === undefined) return `${DIM}checking…${RESET}`;
|
|
2672
2669
|
if (st === null) return `${DIM}unavailable${RESET}`;
|
|
2673
2670
|
if (st.status === "active") {
|
|
2674
2671
|
const v = st.active_version || "?";
|
|
2675
|
-
if (
|
|
2672
|
+
if (runtimeUpdateAvailable(st, candidate)) return `${v} active ${YELLOW}· update available ${candidate}${RESET}`;
|
|
2676
2673
|
return `${GREEN}${v} active${RESET}${candidate ? `${DIM} · up to date${RESET}` : ""}`;
|
|
2677
2674
|
}
|
|
2678
2675
|
if (st.status === "unavailable") return `${YELLOW}update unavailable${RESET}`;
|
|
@@ -2710,8 +2707,10 @@ function formatUpgradeLines(inst, st, { candidate = "", retrieval = null } = {})
|
|
|
2710
2707
|
lines.push(`Location: ${inst.path}`);
|
|
2711
2708
|
lines.push("");
|
|
2712
2709
|
const activeLabel = d.active_version ? `${d.active_version} active` : "not yet activated here";
|
|
2713
|
-
|
|
2714
|
-
|
|
2710
|
+
const candidateLabel = d.status === "active"
|
|
2711
|
+
? (runtimeUpdateAvailable(d, candidate) ? ` → candidate ${candidate} available` : "")
|
|
2712
|
+
: (d.candidate_version ? ` → candidate ${d.candidate_version}` : candidate ? ` → candidate ${candidate} available` : "");
|
|
2713
|
+
lines.push(`Runtime: ${activeLabel}${candidateLabel}`);
|
|
2715
2714
|
lines.push(`Status: ${UPGRADE_STATUS_LABEL[d.status] || d.status}`);
|
|
2716
2715
|
if (d.candidate_digest) lines.push(`Package digest: sha256 ${String(d.candidate_digest).slice(0, 16)}…`);
|
|
2717
2716
|
// A recorded failure only needs attention while the transaction is stuck
|
|
@@ -3189,7 +3188,7 @@ function renderUpgradePanel({ inst, data, candidate, retrieval, mode, notice, wi
|
|
|
3189
3188
|
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3190
3189
|
const keys = [];
|
|
3191
3190
|
if (!status || status === "none" || ["pending", "failed", "interrupted", "cancelled", "rolled-back"].includes(status)) keys.push(`${BOLD}p${RESET}${DIM} prepare${RESET}`);
|
|
3192
|
-
if (
|
|
3191
|
+
if (runtimeUpdateAvailable(data, candidate)) keys.push(`${BOLD}p${RESET}${DIM} prepare update${RESET}`);
|
|
3193
3192
|
if (status === "ready-to-activate") keys.push(`${BOLD}a${RESET}${DIM} activate${RESET}`);
|
|
3194
3193
|
if (status === "preparing") keys.push(`${BOLD}c${RESET}${DIM} cancel${RESET}`);
|
|
3195
3194
|
if (status === "active") keys.push(`${BOLD}r${RESET}${DIM} roll back${RESET}`);
|
|
@@ -3952,9 +3951,7 @@ async function browser(args = {}) {
|
|
|
3952
3951
|
render(); return;
|
|
3953
3952
|
}
|
|
3954
3953
|
const status = state.upgradeData && state.upgradeData.status;
|
|
3955
|
-
const activeUpdatable =
|
|
3956
|
-
&& state.upgradeCandidate
|
|
3957
|
-
&& state.upgradeCandidate !== (state.upgradeData && state.upgradeData.active_version);
|
|
3954
|
+
const activeUpdatable = runtimeUpdateAvailable(state.upgradeData, state.upgradeCandidate);
|
|
3958
3955
|
if (chunk === "p" && (!status || activeUpdatable || ["none", "pending", "failed", "interrupted", "cancelled", "rolled-back"].includes(status))) {
|
|
3959
3956
|
const staged = state.upgradeData
|
|
3960
3957
|
&& !["none", "cancelled", "rolled-back", "active"].includes(status)
|
package/lib/setup.js
CHANGED
|
@@ -1132,7 +1132,7 @@ function codexSupportMessage(egregoreDir) {
|
|
|
1132
1132
|
" .codex/hooks.json",
|
|
1133
1133
|
" .codex/hooks/",
|
|
1134
1134
|
"",
|
|
1135
|
-
"
|
|
1135
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
1136
1136
|
"Egregore workflows appear as slash commands. In Codex, invoke them with the matching $skill token or ask in natural language.",
|
|
1137
1137
|
].join("\n");
|
|
1138
1138
|
}
|
|
@@ -1146,7 +1146,7 @@ function piSupportMessage(egregoreDir) {
|
|
|
1146
1146
|
"Pi meta-harness support is missing from this Egregore checkout.",
|
|
1147
1147
|
` path: ${egregoreDir}`,
|
|
1148
1148
|
"",
|
|
1149
|
-
"
|
|
1149
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
1150
1150
|
"Pi loads Egregore through project-local .pi resources and the shared portable skill corpus.",
|
|
1151
1151
|
].join("\n");
|
|
1152
1152
|
}
|
|
@@ -1156,7 +1156,7 @@ function primeSupportMessage(egregoreDir) {
|
|
|
1156
1156
|
"Prime Agent runtime support is missing from this Egregore checkout.",
|
|
1157
1157
|
` path: ${egregoreDir}`,
|
|
1158
1158
|
"",
|
|
1159
|
-
"
|
|
1159
|
+
"Restore this instance using its installed runtime version, then rerun egregore.",
|
|
1160
1160
|
"Prime Agent loads Egregore through project-local .prime/agent resources and the shared portable skill corpus.",
|
|
1161
1161
|
].join("\n");
|
|
1162
1162
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-egregore",
|
|
3
|
-
"version": "0.21.0-runtime-mvp.
|
|
3
|
+
"version": "0.21.0-runtime-mvp.25",
|
|
4
4
|
"description": "Set up Egregore for your team in one command — installs the egregore launcher and your choice of Claude Code, Codex, or Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -36,17 +36,10 @@ BASE=$(bash -c 'SCRIPT_DIR="$PWD"; CONFIG="$PWD/egregore.json"; . "$PWD/bin/lib/
|
|
|
36
36
|
|
|
37
37
|
Stop before mutation if it cannot be resolved.
|
|
38
38
|
|
|
39
|
-
3.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
if [ -f bin/capability-distribution.mjs ] && [ -f capability-distribution.json ]; then
|
|
45
|
-
bash bin/node-run.sh bin/capability-distribution.mjs validate --root .
|
|
46
|
-
bash bin/node-run.sh bin/capability-distribution.mjs changes --root . --base "origin/$BASE" --json
|
|
47
|
-
bash bin/node-run.sh bin/capability-distribution.mjs runtime-skill-audit --root . --strict-contract
|
|
48
|
-
fi
|
|
49
|
-
```
|
|
39
|
+
3. The shared `bin/agent.sh save` preflight runs distribution validation,
|
|
40
|
+
the change report, and the strict Runtime-skill audit before any memory or
|
|
41
|
+
project mutation. Both engine and registry must exist; installed public
|
|
42
|
+
instances intentionally omit the development engine.
|
|
50
43
|
|
|
51
44
|
Ask one placement question only for a genuinely new/unclassified component or
|
|
52
45
|
an explicit placement change. Ordinary edits to an existing component do not
|
|
@@ -397,6 +397,14 @@ cmd_save() {
|
|
|
397
397
|
[ -n "$message" ] || message="chore(save): $topic"
|
|
398
398
|
base="$(resolve_base_branch)" || die "save stopped before Git changes"
|
|
399
399
|
|
|
400
|
+
# Shared invariant across harnesses, before memory or project mutations.
|
|
401
|
+
# Installed public instances intentionally omit the development engine.
|
|
402
|
+
if [ -f "$SCRIPT_DIR/bin/capability-distribution.mjs" ] && [ -f "$SCRIPT_DIR/capability-distribution.json" ]; then
|
|
403
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" validate --root "$SCRIPT_DIR" || die "distribution validation failed"
|
|
404
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" changes --root "$SCRIPT_DIR" --base "origin/$base" --json || die "distribution change check failed"
|
|
405
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" runtime-skill-audit --root "$SCRIPT_DIR" --strict-contract || die "runtime skill contract failed"
|
|
406
|
+
fi
|
|
407
|
+
|
|
400
408
|
if [ -d "$MEMORY_DIR" ]; then
|
|
401
409
|
save_memory "$message" "."
|
|
402
410
|
echo "memory: synced"
|
|
@@ -22,10 +22,12 @@ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
|
22
22
|
# tree, while the target instance is set explicitly — never inferred.
|
|
23
23
|
INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
|
|
24
24
|
|
|
25
|
+
# Activation and rollback can replace this script. Hand off the process so
|
|
26
|
+
# Bash never resumes reading changed bytes after the Runtime returns.
|
|
25
27
|
_runtime() {
|
|
26
28
|
EGREGORE_ROOT="$INSTANCE_ROOT" \
|
|
27
29
|
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
28
|
-
python3 -m egregore_runtime.harness_cli "$@"
|
|
30
|
+
exec python3 -m egregore_runtime.harness_cli "$@"
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
_ensure_identity() {
|
|
@@ -230,15 +230,12 @@ class EgregoreRuntime:
|
|
|
230
230
|
"this document is admin-marked; Egregore serves it to organization admins only"
|
|
231
231
|
)
|
|
232
232
|
stable_artifact_id = canonical_artifact_id(content, path)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
stable_decision = self.authorize(actor, Permission.READ, (stable_artifact_id,))
|
|
234
|
+
if not stable_decision.allowed:
|
|
235
|
+
raise AuthorizationDenied(
|
|
236
|
+
"canonical artifact identity is outside the actor read scope"
|
|
236
237
|
)
|
|
237
|
-
|
|
238
|
-
raise AuthorizationDenied(
|
|
239
|
-
"canonical artifact identity is outside the actor read scope"
|
|
240
|
-
)
|
|
241
|
-
artifact_id = stable_artifact_id
|
|
238
|
+
artifact_id = stable_artifact_id
|
|
242
239
|
try:
|
|
243
240
|
self.telemetry.emit(
|
|
244
241
|
TelemetryEvent(
|
|
@@ -42,13 +42,10 @@ esac
|
|
|
42
42
|
- Stop with "everything is already saved" only when there are no repo or
|
|
43
43
|
memory changes and either the branch has no commits to integrate
|
|
44
44
|
(`AHEAD=0`) or an open integration PR already exists.
|
|
45
|
-
4.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bash bin/node-run.sh bin/capability-distribution.mjs validate --root .
|
|
50
|
-
bash bin/node-run.sh bin/capability-distribution.mjs changes --root . --base "origin/$BASE" --json
|
|
51
|
-
```
|
|
45
|
+
4. The shared `bin/agent.sh save` preflight runs distribution validation,
|
|
46
|
+
the change report, and the strict Runtime-skill audit before any memory or
|
|
47
|
+
project mutation. It runs only when both the registry and development
|
|
48
|
+
engine exist; public installed instances intentionally omit that engine.
|
|
52
49
|
|
|
53
50
|
Inspect the diff as well as the receipt. Ask when this work introduces a new
|
|
54
51
|
or unclassified Egregore component, or changes a component's placement
|
|
@@ -397,6 +397,14 @@ cmd_save() {
|
|
|
397
397
|
[ -n "$message" ] || message="chore(save): $topic"
|
|
398
398
|
base="$(resolve_base_branch)" || die "save stopped before Git changes"
|
|
399
399
|
|
|
400
|
+
# Shared invariant across harnesses, before memory or project mutations.
|
|
401
|
+
# Installed public instances intentionally omit the development engine.
|
|
402
|
+
if [ -f "$SCRIPT_DIR/bin/capability-distribution.mjs" ] && [ -f "$SCRIPT_DIR/capability-distribution.json" ]; then
|
|
403
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" validate --root "$SCRIPT_DIR" || die "distribution validation failed"
|
|
404
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" changes --root "$SCRIPT_DIR" --base "origin/$base" --json || die "distribution change check failed"
|
|
405
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" runtime-skill-audit --root "$SCRIPT_DIR" --strict-contract || die "runtime skill contract failed"
|
|
406
|
+
fi
|
|
407
|
+
|
|
400
408
|
if [ -d "$MEMORY_DIR" ]; then
|
|
401
409
|
save_memory "$message" "."
|
|
402
410
|
echo "memory: synced"
|
|
@@ -22,10 +22,12 @@ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
|
22
22
|
# tree, while the target instance is set explicitly — never inferred.
|
|
23
23
|
INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
|
|
24
24
|
|
|
25
|
+
# Activation and rollback can replace this script. Hand off the process so
|
|
26
|
+
# Bash never resumes reading changed bytes after the Runtime returns.
|
|
25
27
|
_runtime() {
|
|
26
28
|
EGREGORE_ROOT="$INSTANCE_ROOT" \
|
|
27
29
|
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
28
|
-
python3 -m egregore_runtime.harness_cli "$@"
|
|
30
|
+
exec python3 -m egregore_runtime.harness_cli "$@"
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
_ensure_identity() {
|
|
@@ -230,15 +230,12 @@ class EgregoreRuntime:
|
|
|
230
230
|
"this document is admin-marked; Egregore serves it to organization admins only"
|
|
231
231
|
)
|
|
232
232
|
stable_artifact_id = canonical_artifact_id(content, path)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
stable_decision = self.authorize(actor, Permission.READ, (stable_artifact_id,))
|
|
234
|
+
if not stable_decision.allowed:
|
|
235
|
+
raise AuthorizationDenied(
|
|
236
|
+
"canonical artifact identity is outside the actor read scope"
|
|
236
237
|
)
|
|
237
|
-
|
|
238
|
-
raise AuthorizationDenied(
|
|
239
|
-
"canonical artifact identity is outside the actor read scope"
|
|
240
|
-
)
|
|
241
|
-
artifact_id = stable_artifact_id
|
|
238
|
+
artifact_id = stable_artifact_id
|
|
242
239
|
try:
|
|
243
240
|
self.telemetry.emit(
|
|
244
241
|
TelemetryEvent(
|
|
@@ -42,13 +42,10 @@ esac
|
|
|
42
42
|
- Stop with "everything is already saved" only when there are no repo or
|
|
43
43
|
memory changes and either the branch has no commits to integrate
|
|
44
44
|
(`AHEAD=0`) or an open integration PR already exists.
|
|
45
|
-
4.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bash bin/node-run.sh bin/capability-distribution.mjs validate --root .
|
|
50
|
-
bash bin/node-run.sh bin/capability-distribution.mjs changes --root . --base "origin/$BASE" --json
|
|
51
|
-
```
|
|
45
|
+
4. The shared `bin/agent.sh save` preflight runs distribution validation,
|
|
46
|
+
the change report, and the strict Runtime-skill audit before any memory or
|
|
47
|
+
project mutation. It runs only when both the registry and development
|
|
48
|
+
engine exist; public installed instances intentionally omit that engine.
|
|
52
49
|
|
|
53
50
|
Inspect the diff as well as the receipt. Ask when this work introduces a new
|
|
54
51
|
or unclassified Egregore component, or changes a component's placement
|
package/runtime/pi/bin/agent.sh
CHANGED
|
@@ -397,6 +397,14 @@ cmd_save() {
|
|
|
397
397
|
[ -n "$message" ] || message="chore(save): $topic"
|
|
398
398
|
base="$(resolve_base_branch)" || die "save stopped before Git changes"
|
|
399
399
|
|
|
400
|
+
# Shared invariant across harnesses, before memory or project mutations.
|
|
401
|
+
# Installed public instances intentionally omit the development engine.
|
|
402
|
+
if [ -f "$SCRIPT_DIR/bin/capability-distribution.mjs" ] && [ -f "$SCRIPT_DIR/capability-distribution.json" ]; then
|
|
403
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" validate --root "$SCRIPT_DIR" || die "distribution validation failed"
|
|
404
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" changes --root "$SCRIPT_DIR" --base "origin/$base" --json || die "distribution change check failed"
|
|
405
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" runtime-skill-audit --root "$SCRIPT_DIR" --strict-contract || die "runtime skill contract failed"
|
|
406
|
+
fi
|
|
407
|
+
|
|
400
408
|
if [ -d "$MEMORY_DIR" ]; then
|
|
401
409
|
save_memory "$message" "."
|
|
402
410
|
echo "memory: synced"
|
|
@@ -22,10 +22,12 @@ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
|
22
22
|
# tree, while the target instance is set explicitly — never inferred.
|
|
23
23
|
INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
|
|
24
24
|
|
|
25
|
+
# Activation and rollback can replace this script. Hand off the process so
|
|
26
|
+
# Bash never resumes reading changed bytes after the Runtime returns.
|
|
25
27
|
_runtime() {
|
|
26
28
|
EGREGORE_ROOT="$INSTANCE_ROOT" \
|
|
27
29
|
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
28
|
-
python3 -m egregore_runtime.harness_cli "$@"
|
|
30
|
+
exec python3 -m egregore_runtime.harness_cli "$@"
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
_ensure_identity() {
|
|
@@ -230,15 +230,12 @@ class EgregoreRuntime:
|
|
|
230
230
|
"this document is admin-marked; Egregore serves it to organization admins only"
|
|
231
231
|
)
|
|
232
232
|
stable_artifact_id = canonical_artifact_id(content, path)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
stable_decision = self.authorize(actor, Permission.READ, (stable_artifact_id,))
|
|
234
|
+
if not stable_decision.allowed:
|
|
235
|
+
raise AuthorizationDenied(
|
|
236
|
+
"canonical artifact identity is outside the actor read scope"
|
|
236
237
|
)
|
|
237
|
-
|
|
238
|
-
raise AuthorizationDenied(
|
|
239
|
-
"canonical artifact identity is outside the actor read scope"
|
|
240
|
-
)
|
|
241
|
-
artifact_id = stable_artifact_id
|
|
238
|
+
artifact_id = stable_artifact_id
|
|
242
239
|
try:
|
|
243
240
|
self.telemetry.emit(
|
|
244
241
|
TelemetryEvent(
|
|
@@ -42,13 +42,10 @@ esac
|
|
|
42
42
|
- Stop with "everything is already saved" only when there are no repo or
|
|
43
43
|
memory changes and either the branch has no commits to integrate
|
|
44
44
|
(`AHEAD=0`) or an open integration PR already exists.
|
|
45
|
-
4.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bash bin/node-run.sh bin/capability-distribution.mjs validate --root .
|
|
50
|
-
bash bin/node-run.sh bin/capability-distribution.mjs changes --root . --base "origin/$BASE" --json
|
|
51
|
-
```
|
|
45
|
+
4. The shared `bin/agent.sh save` preflight runs distribution validation,
|
|
46
|
+
the change report, and the strict Runtime-skill audit before any memory or
|
|
47
|
+
project mutation. It runs only when both the registry and development
|
|
48
|
+
engine exist; public installed instances intentionally omit that engine.
|
|
52
49
|
|
|
53
50
|
Inspect the diff as well as the receipt. Ask when this work introduces a new
|
|
54
51
|
or unclassified Egregore component, or changes a component's placement
|
|
@@ -397,6 +397,14 @@ cmd_save() {
|
|
|
397
397
|
[ -n "$message" ] || message="chore(save): $topic"
|
|
398
398
|
base="$(resolve_base_branch)" || die "save stopped before Git changes"
|
|
399
399
|
|
|
400
|
+
# Shared invariant across harnesses, before memory or project mutations.
|
|
401
|
+
# Installed public instances intentionally omit the development engine.
|
|
402
|
+
if [ -f "$SCRIPT_DIR/bin/capability-distribution.mjs" ] && [ -f "$SCRIPT_DIR/capability-distribution.json" ]; then
|
|
403
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" validate --root "$SCRIPT_DIR" || die "distribution validation failed"
|
|
404
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" changes --root "$SCRIPT_DIR" --base "origin/$base" --json || die "distribution change check failed"
|
|
405
|
+
bash "$SCRIPT_DIR/bin/node-run.sh" "$SCRIPT_DIR/bin/capability-distribution.mjs" runtime-skill-audit --root "$SCRIPT_DIR" --strict-contract || die "runtime skill contract failed"
|
|
406
|
+
fi
|
|
407
|
+
|
|
400
408
|
if [ -d "$MEMORY_DIR" ]; then
|
|
401
409
|
save_memory "$message" "."
|
|
402
410
|
echo "memory: synced"
|
|
@@ -22,10 +22,12 @@ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
|
22
22
|
# tree, while the target instance is set explicitly — never inferred.
|
|
23
23
|
INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
|
|
24
24
|
|
|
25
|
+
# Activation and rollback can replace this script. Hand off the process so
|
|
26
|
+
# Bash never resumes reading changed bytes after the Runtime returns.
|
|
25
27
|
_runtime() {
|
|
26
28
|
EGREGORE_ROOT="$INSTANCE_ROOT" \
|
|
27
29
|
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
28
|
-
python3 -m egregore_runtime.harness_cli "$@"
|
|
30
|
+
exec python3 -m egregore_runtime.harness_cli "$@"
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
_ensure_identity() {
|
|
@@ -230,15 +230,12 @@ class EgregoreRuntime:
|
|
|
230
230
|
"this document is admin-marked; Egregore serves it to organization admins only"
|
|
231
231
|
)
|
|
232
232
|
stable_artifact_id = canonical_artifact_id(content, path)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
stable_decision = self.authorize(actor, Permission.READ, (stable_artifact_id,))
|
|
234
|
+
if not stable_decision.allowed:
|
|
235
|
+
raise AuthorizationDenied(
|
|
236
|
+
"canonical artifact identity is outside the actor read scope"
|
|
236
237
|
)
|
|
237
|
-
|
|
238
|
-
raise AuthorizationDenied(
|
|
239
|
-
"canonical artifact identity is outside the actor read scope"
|
|
240
|
-
)
|
|
241
|
-
artifact_id = stable_artifact_id
|
|
238
|
+
artifact_id = stable_artifact_id
|
|
242
239
|
try:
|
|
243
240
|
self.telemetry.emit(
|
|
244
241
|
TelemetryEvent(
|