@ouro.bot/cli 0.1.0-alpha.934 → 0.1.0-alpha.936

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.
Files changed (40) hide show
  1. package/changelog.json +18 -0
  2. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +1 -1
  3. package/deploy/unraid/sanctuary.xml +1 -1
  4. package/dist/heart/daemon/cli-defaults.js +5 -0
  5. package/dist/heart/daemon/cli-exec.js +9 -0
  6. package/dist/heart/daemon/cli-help.js +2 -2
  7. package/dist/heart/daemon/cli-parse.js +2 -1
  8. package/dist/heart/daemon/daemon.js +14 -0
  9. package/dist/heart/daemon/ouro-entry.js +4 -1
  10. package/dist/heart/daemon/runtime-logging.js +1 -1
  11. package/dist/heart/daemon/sense-manager.js +53 -0
  12. package/dist/heart/mailbox/mailbox-http-hooks.js +1 -0
  13. package/dist/heart/mailbox/mailbox-http-routes.js +8 -0
  14. package/dist/heart/mailbox/mailbox-read.js +3 -1
  15. package/dist/heart/mailbox/mailbox-supervision.js +131 -0
  16. package/dist/heart/shepherd/custody-types.js +2 -0
  17. package/dist/heart/shepherd/mandates.js +352 -0
  18. package/dist/heart/shepherd/operation-commands.js +19 -0
  19. package/dist/heart/shepherd/operations.js +135 -0
  20. package/dist/heart/shepherd/supervision.js +114 -0
  21. package/dist/heart/shepherd/types.js +2 -0
  22. package/dist/mailbox-ui/assets/index-DsiKaPyH.css +1 -0
  23. package/dist/mailbox-ui/assets/index-xU5krmwW.js +1 -0
  24. package/dist/mailbox-ui/index.html +2 -2
  25. package/dist/nerves/coverage/file-completeness.js +4 -0
  26. package/dist/repertoire/tools-shell.js +9 -4
  27. package/dist/senses/shepherd/checkin-store.js +209 -41
  28. package/dist/senses/shepherd/cmux.js +69 -23
  29. package/dist/senses/shepherd/guidance.js +5 -2
  30. package/dist/senses/shepherd/herdr.js +84 -2
  31. package/dist/senses/shepherd/observation-publisher.js +320 -0
  32. package/dist/senses/shepherd/operations-defaults.js +86 -0
  33. package/dist/senses/shepherd/operations.js +159 -0
  34. package/dist/senses/shepherd/recovery.js +543 -0
  35. package/dist/senses/shepherd/sense.js +8 -0
  36. package/dist/senses/teams.js +13 -1
  37. package/npm-shrinkwrap.json +2 -2
  38. package/package.json +1 -1
  39. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +0 -1
  40. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +0 -1
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runShepherdOperation = runShepherdOperation;
37
+ const node_crypto_1 = require("node:crypto");
38
+ const path = __importStar(require("node:path"));
39
+ const mandates_1 = require("../../heart/shepherd/mandates");
40
+ const mailbox_supervision_1 = require("../../heart/mailbox/mailbox-supervision");
41
+ const supervision_1 = require("../../heart/shepherd/supervision");
42
+ const guidance_1 = require("./guidance");
43
+ const checkin_store_1 = require("./checkin-store");
44
+ const recovery_1 = require("./recovery");
45
+ const runtime_1 = require("../../nerves/runtime");
46
+ function fingerprint(command) {
47
+ return (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(command, Object.keys(command).sort())).digest("hex");
48
+ }
49
+ /** Same-UID local administration only. No evidence, actor, or lifecycle claims come from argv. */
50
+ async function runShepherdOperation(command, deps) {
51
+ try {
52
+ const { actorId } = await deps.resolveOwner(command.agent);
53
+ const actor = { kind: "local_owner_administration", actorId };
54
+ const root = deps.agentRoot(command.agent);
55
+ const file = (0, checkin_store_1.checkInStorePath)(root);
56
+ if (command.kind === "shepherd.status")
57
+ return {
58
+ boundary: "same_uid_local_owner_administration_not_human_presence",
59
+ automation: { mode: "legacy_unqualified", mandatesEnforcedForAllTriggers: false, unattendedKeysPossible: true, warning: supervision_1.SHEPHERD_ALPHA_AUTOMATION_WARNING },
60
+ supervision: (0, mailbox_supervision_1.readMailboxSupervision)(command.agent, { agentRoot: root }),
61
+ guidance: (0, guidance_1.readGuidance)(root), mandates: (0, mandates_1.readShepherdMandates)(root),
62
+ custody: (0, recovery_1.readCheckInSnapshot)(file, { limit: 50 }),
63
+ };
64
+ if (command.kind === "shepherd.inspect")
65
+ return (0, recovery_1.readCheckInSnapshot)(file, command);
66
+ if (command.kind === "shepherd.mandate.grant")
67
+ return await (0, mandates_1.updateShepherdMandate)(root, {
68
+ operation: "grant", context: { ...actor, requestId: command.requestId }, expectedRevision: command.expectedRevision,
69
+ target: {
70
+ project: command.project, ...(command.host ? { host: command.host } : {}),
71
+ ...(command.session ? { session: command.session } : {}), ...(command.instance ? { instance: command.instance } : {}),
72
+ },
73
+ task: command.task, expiresAt: command.expiresAt,
74
+ });
75
+ if (command.kind === "shepherd.mandate.revoke")
76
+ return await (0, mandates_1.updateShepherdMandate)(root, {
77
+ operation: "revoke", context: { ...actor, requestId: command.requestId }, expectedRevision: command.expectedRevision,
78
+ mandateId: command.id.startsWith("mandate:") ? command.id : `mandate:${command.id}`,
79
+ });
80
+ if (command.kind === "shepherd.pause" || command.kind === "shepherd.resume") {
81
+ const host = await deps.host(command.agent);
82
+ if (host.name !== command.host)
83
+ throw new Error("requested host does not match the configured host");
84
+ const matches = (await host.list()).filter(session => session.id === command.session);
85
+ if (matches.length !== 1)
86
+ throw new Error("a unique verified live terminal is required");
87
+ const target = { host: host.name, session: matches[0].id, cwd: matches[0].cwd ?? null, task: null };
88
+ return await (0, guidance_1.setShepherdSessionPause)(root, {
89
+ actorId, requestId: command.requestId, expectedRevision: command.expectedRevision,
90
+ requestFingerprint: fingerprint(command), target, paused: command.kind === "shepherd.pause",
91
+ }, [target]);
92
+ }
93
+ if (command.kind === "shepherd.reconcile") {
94
+ if (command.resolution === "delivered")
95
+ throw new Error("confirmed delivery is unsupported: no qualified guarded host receipt lookup is available");
96
+ const snapshot = (0, recovery_1.readCheckInSnapshot)(file, { limit: 1, id: command.id });
97
+ const entry = snapshot.entries[0];
98
+ if (!entry)
99
+ throw new Error("dispatch not found");
100
+ const host = await deps.host(command.agent);
101
+ if (host.name !== entry.host)
102
+ throw new Error("custody host does not match the configured host");
103
+ // Foreground inventories cannot prove that an older process in a surviving terminal exited.
104
+ if (!host.retirementInventory)
105
+ throw new Error("qualified complete retirement inventory is unavailable");
106
+ if ((await host.retirementInventory()).includes(entry.session))
107
+ throw new Error("terminal still exists; foreground inventory cannot prove process retirement");
108
+ const evidence = {
109
+ kind: "host_process_inventory", host: entry.host, session: entry.session, instance: entry.instance,
110
+ checkedAt: new Date().toISOString(), gone: true, wholeSessionRetired: true,
111
+ };
112
+ return await (0, recovery_1.reconcileShepherdDispatch)(root, { id: command.id, expectedRevision: command.expectedRevision, requestId: command.requestId, actor, evidence });
113
+ }
114
+ if (command.kind !== "shepherd.maintenance")
115
+ throw new Error("unsupported Shepherd administration operation");
116
+ const sense = await deps.senseStopped(command.agent);
117
+ const host = await deps.host(command.agent);
118
+ if (!host.retirementInventory)
119
+ throw new Error("qualified complete retirement inventory is unavailable");
120
+ const sessions = await host.retirementInventory();
121
+ const retiredInstances = [];
122
+ const seen = new Set();
123
+ let cursor;
124
+ do {
125
+ const page = (0, recovery_1.readMaintenanceCheckInSnapshot)(file, { limit: 200, ...(cursor ? { cursor } : {}) }, sense);
126
+ if (page.state !== "ready")
127
+ throw new Error("custody store is missing");
128
+ for (const entry of page.entries) {
129
+ if (entry.host !== host.name || sessions.includes(entry.session))
130
+ continue;
131
+ const key = JSON.stringify([entry.host, entry.session, entry.instance]);
132
+ if (seen.has(key))
133
+ continue;
134
+ seen.add(key);
135
+ retiredInstances.push({
136
+ kind: "host_process_inventory", host: entry.host, session: entry.session, instance: entry.instance,
137
+ checkedAt: new Date().toISOString(), gone: true, wholeSessionRetired: true,
138
+ });
139
+ if (retiredInstances.length > 200)
140
+ throw new Error("maintenance exceeds 200 retired instances; narrower native retirement qualification is required");
141
+ }
142
+ cursor = page.nextCursor ?? undefined;
143
+ } while (cursor);
144
+ if (!path.isAbsolute(command.destination))
145
+ throw new Error("maintenance destination must be absolute");
146
+ return await (0, recovery_1.maintainShepherdCustody)(root, {
147
+ expectedRevision: command.expectedRevision, requestId: command.requestId, actor, sense, retiredInstances,
148
+ destination: command.destination, requestFingerprint: fingerprint(command),
149
+ });
150
+ }
151
+ catch (error) {
152
+ (0, runtime_1.emitNervesEvent)({
153
+ component: "senses", level: "warn", event: "senses.shepherd_administration_failed",
154
+ message: "local-owner Shepherd operation failed; no inferred authority or evidence substituted",
155
+ meta: { operation: command.kind },
156
+ });
157
+ throw error;
158
+ }
159
+ }