@ouro.bot/cli 0.1.0-alpha.744 → 0.1.0-alpha.746
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/changelog.json +13 -0
- package/deploy/unraid/README.txt +2 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +1 -1
- package/deploy/unraid/sanctuary.xml +1 -1
- package/dist/heart/daemon/container-spec-auditor.js +7 -12
- package/dist/senses/telegram-admission.js +13 -2
- package/dist/senses/telegram.js +3 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.746",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Run packaged Sanctuary auditors with constrained root privileges so root-private inspection and staged policy inputs remain readable without widening file permissions.",
|
|
8
|
+
"Audit immutable container image identity from Docker's resolved top-level Image and validate the portable effective root Mounts contract, including private bind propagation, across real Docker inspect output."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"version": "0.1.0-alpha.745",
|
|
13
|
+
"changes": [
|
|
14
|
+
"Tell newly admitted Telegram contacts to resend attachments that stayed safely undownloaded during unknown-sender quarantine."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
4
17
|
{
|
|
5
18
|
"version": "0.1.0-alpha.744",
|
|
6
19
|
"changes": [
|
package/deploy/unraid/README.txt
CHANGED
|
@@ -42,6 +42,7 @@ Effective-spec audit helper:
|
|
|
42
42
|
docker image inspect "$AUDIT_EXPECTED_IMAGE" >"$INSPECT_DIR/image.json" || return $?
|
|
43
43
|
chmod 0600 "$INSPECT_DIR/container.json" "$INSPECT_DIR/image.json" || return $?
|
|
44
44
|
docker run --rm --pull=never --network=none \
|
|
45
|
+
--user 0:0 --read-only --cap-drop=ALL --security-opt=no-new-privileges \
|
|
45
46
|
--entrypoint /opt/ouro/deploy/unraid/audit-container-spec.sh \
|
|
46
47
|
--mount "type=bind,src=$INSPECT_DIR/container.json,dst=/audit/container.json,readonly" \
|
|
47
48
|
--mount "type=bind,src=$INSPECT_DIR/image.json,dst=/audit/image.json,readonly" \
|
|
@@ -1444,6 +1445,7 @@ Update:
|
|
|
1444
1445
|
audit the staged template and runtime policy with the packaged auditor, then
|
|
1445
1446
|
remove the private stage before any Butler mutation:
|
|
1446
1447
|
docker run --rm --pull=never --network=none \
|
|
1448
|
+
--user 0:0 --read-only --cap-drop=ALL --security-opt=no-new-privileges \
|
|
1447
1449
|
--entrypoint /opt/ouro/deploy/unraid/audit-container-spec.sh \
|
|
1448
1450
|
--mount "type=bind,src=$STAGED_TEMPLATE,dst=/audit/sanctuary.xml,readonly" \
|
|
1449
1451
|
--mount "type=bind,src=$STAGED_RUNTIME_POLICY,dst=/audit/container-runtime.json,readonly" \
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0"?>
|
|
2
2
|
<Container version="2">
|
|
3
3
|
<Name>Mendelow Cloud Butler</Name>
|
|
4
|
-
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.
|
|
4
|
+
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.746</Repository>
|
|
5
5
|
<Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
|
|
6
6
|
<Network>host</Network>
|
|
7
7
|
<Shell>sh</Shell>
|
|
@@ -10,13 +10,12 @@ const EXPECTED_BINDS = [
|
|
|
10
10
|
"/mnt/user/appdata/sabnzbd/sabnzbd.ini:/run/sanctuary/sabnzbd.ini:ro",
|
|
11
11
|
];
|
|
12
12
|
const EXPECTED_MOUNTS = [
|
|
13
|
-
["/mnt/user/appdata/ouro-butler/runtime/.ouro-cli", "/home/ouro/.ouro-cli", true],
|
|
14
|
-
["/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro", "/home/ouro/AgentBundles/sanctuary.ouro", true],
|
|
15
|
-
["/boot/config/custom/ouro-events/spool", "/run/ouro-events", false],
|
|
16
|
-
["/mnt/user/appdata/sabnzbd/sabnzbd.ini", "/run/sanctuary/sabnzbd.ini", false],
|
|
13
|
+
["/mnt/user/appdata/ouro-butler/runtime/.ouro-cli", "/home/ouro/.ouro-cli", true, "rprivate"],
|
|
14
|
+
["/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro", "/home/ouro/AgentBundles/sanctuary.ouro", true, "rprivate"],
|
|
15
|
+
["/boot/config/custom/ouro-events/spool", "/run/ouro-events", false, "rprivate"],
|
|
16
|
+
["/mnt/user/appdata/sabnzbd/sabnzbd.ini", "/run/sanctuary/sabnzbd.ini", false, "rprivate"],
|
|
17
17
|
];
|
|
18
18
|
const LEGACY_ALPHA742_IMAGE = "sha256:681449ad47a2621705cd339b481e6339236b31dc65e195b1cf5025d0f2191d7d";
|
|
19
|
-
const LEGACY_ALPHA742_BINDS = EXPECTED_BINDS.slice(0, 2);
|
|
20
19
|
const LEGACY_ALPHA742_MOUNTS = EXPECTED_MOUNTS.slice(0, 2);
|
|
21
20
|
const EXPECTED_EXTRA_PARAMS = "--restart=unless-stopped --user=10001:10001";
|
|
22
21
|
function record(value) {
|
|
@@ -46,9 +45,8 @@ function auditSanctuaryContainerSpec(value, options) {
|
|
|
46
45
|
const mountContract = options.mountContract ?? "canonical";
|
|
47
46
|
if (mountContract === "legacy-alpha742" && options.expectedImage !== LEGACY_ALPHA742_IMAGE)
|
|
48
47
|
violations.push("legacy mount exception requires the pinned alpha.742 image ID");
|
|
49
|
-
const expectedBinds = mountContract === "legacy-alpha742" ? LEGACY_ALPHA742_BINDS : EXPECTED_BINDS;
|
|
50
48
|
const expectedMounts = mountContract === "legacy-alpha742" ? LEGACY_ALPHA742_MOUNTS : EXPECTED_MOUNTS;
|
|
51
|
-
if (
|
|
49
|
+
if (root.Image !== options.expectedImage)
|
|
52
50
|
violations.push("image does not match the reviewed exact local Docker image ID");
|
|
53
51
|
if (root.Path !== "node")
|
|
54
52
|
violations.push("effective container path must be node");
|
|
@@ -92,14 +90,11 @@ function auditSanctuaryContainerSpec(value, options) {
|
|
|
92
90
|
violations.push("container must not publish all exposed ports");
|
|
93
91
|
if (!isEmptyRecord(network?.Ports))
|
|
94
92
|
violations.push("effective network ports must be empty");
|
|
95
|
-
const binds = stringArray(host.Binds);
|
|
96
|
-
if (!binds || JSON.stringify([...binds].sort()) !== JSON.stringify([...expectedBinds].sort()))
|
|
97
|
-
violations.push("bind set does not match the selected Sanctuary mount contract");
|
|
98
93
|
const mounts = Array.isArray(root.Mounts) ? root.Mounts : [];
|
|
99
94
|
const normalizedMounts = mounts.map((mount) => {
|
|
100
95
|
const item = record(mount);
|
|
101
|
-
return item && item.Type === "bind" && typeof item.RW === "boolean" && typeof item.Source === "string" && typeof item.Destination === "string"
|
|
102
|
-
? [item.Source, item.Destination, item.RW]
|
|
96
|
+
return item && item.Type === "bind" && typeof item.RW === "boolean" && typeof item.Source === "string" && typeof item.Destination === "string" && item.Propagation === "rprivate"
|
|
97
|
+
? [item.Source, item.Destination, item.RW, item.Propagation]
|
|
103
98
|
: null;
|
|
104
99
|
});
|
|
105
100
|
if (normalizedMounts.some((mount) => mount === null)
|
|
@@ -46,6 +46,7 @@ const telegram_client_1 = require("./telegram-client");
|
|
|
46
46
|
exports.NEWLY_ADMITTED_ORIENTATION = {
|
|
47
47
|
kind: "newly_admitted",
|
|
48
48
|
instruction: "welcome_and_explain_capabilities",
|
|
49
|
+
attachmentsNeedResend: false,
|
|
49
50
|
};
|
|
50
51
|
const ACTIVE_STATUSES = new Set([
|
|
51
52
|
"pending", "approved", "friend_bound", "ingress_committed", "turn_queued",
|
|
@@ -562,7 +563,10 @@ function createTelegramAdmissionController(options) {
|
|
|
562
563
|
hasAttachments: record.hasAttachments,
|
|
563
564
|
synthetic: false,
|
|
564
565
|
});
|
|
565
|
-
const committed = {
|
|
566
|
+
const committed = {
|
|
567
|
+
...committedBase,
|
|
568
|
+
orientation: { ...exports.NEWLY_ADMITTED_ORIENTATION, attachmentsNeedResend: record.hasAttachments },
|
|
569
|
+
};
|
|
566
570
|
if (committed.admissionId !== record.id || committed.friendId !== record.friendId || committed.reference !== `telegram-admission:${record.id}`) {
|
|
567
571
|
throw new Error("Telegram admission committed ingress changed identity");
|
|
568
572
|
}
|
|
@@ -574,7 +578,14 @@ function createTelegramAdmissionController(options) {
|
|
|
574
578
|
}
|
|
575
579
|
if (!record.friendId || !record.ingressSessionKey || !record.ingressEventId || !record.ingressReference)
|
|
576
580
|
throw new Error("Telegram admission queued work lost its durable reference");
|
|
577
|
-
const settlement = await options.dispatchApprovedWork({
|
|
581
|
+
const settlement = await options.dispatchApprovedWork({
|
|
582
|
+
admissionId: record.id,
|
|
583
|
+
friendId: record.friendId,
|
|
584
|
+
sessionKey: record.ingressSessionKey,
|
|
585
|
+
eventId: record.ingressEventId,
|
|
586
|
+
reference: record.ingressReference,
|
|
587
|
+
orientation: { ...exports.NEWLY_ADMITTED_ORIENTATION, attachmentsNeedResend: record.hasAttachments },
|
|
588
|
+
});
|
|
578
589
|
if (settlement === "indeterminate") {
|
|
579
590
|
await compensateFriend(record);
|
|
580
591
|
return options.store.compareAndSwap({ admissionId: record.id, expectedStatus: "turn_queued", nextStatus: "indeterminate" });
|
package/dist/senses/telegram.js
CHANGED
|
@@ -1094,7 +1094,9 @@ function createTelegramSenseApp(options) {
|
|
|
1094
1094
|
source: {
|
|
1095
1095
|
kind: "telegram_newly_admitted",
|
|
1096
1096
|
authority: "presentation_only",
|
|
1097
|
-
routingHint:
|
|
1097
|
+
routingHint: input.orientation.attachmentsNeedResend
|
|
1098
|
+
? "This is this person’s first admitted turn. Welcome them warmly and briefly explain what the household Butler can help with before answering their request. Their original message included attachments that were not downloaded; ask them to resend those attachments now."
|
|
1099
|
+
: "This is this person’s first admitted turn. Welcome them warmly and briefly explain what the household Butler can help with before answering their request.",
|
|
1098
1100
|
},
|
|
1099
1101
|
}
|
|
1100
1102
|
: undefined;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.746",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.746",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|