@jc_stack/ez-agents 0.1.0-beta.12 → 0.1.0-beta.18
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/.dockerignore +4 -0
- package/.env.example +16 -1
- package/AGENTS.md +16 -4
- package/CHANGELOG.md +71 -0
- package/CONTRIBUTING.md +37 -4
- package/README.md +114 -9
- package/SECURITY.md +7 -1
- package/bin/ezenciel-agents-schedule +2 -0
- package/bin/ezenciel-agents-schedule.mjs +16 -0
- package/bin/ezenciel-agents-task +2 -0
- package/bin/ezenciel-agents-task.mjs +16 -0
- package/compose.yaml +10 -2
- package/docker/recovery.ts +2 -2
- package/docker/run.ts +2 -2
- package/docs/architecture/ai-selection.md +8 -0
- package/docs/architecture/authority-boundaries.md +137 -12
- package/docs/architecture/event-sources.md +12 -7
- package/docs/architecture/telegram-intake.md +1 -1
- package/docs/channel-backend.md +36 -0
- package/docs/docker-runtime.md +35 -0
- package/docs/host-service.md +19 -0
- package/docs/local-qa.md +45 -0
- package/docs/pagerduty.md +42 -0
- package/docs/plugin-catalog.md +71 -0
- package/docs/plugin-contributions.md +12 -0
- package/docs/plugins.md +61 -1
- package/docs/releasing.md +20 -9
- package/docs/repair.md +41 -0
- package/docs/scheduling.md +153 -0
- package/docs/selective-monitoring.md +114 -0
- package/docs/setup.md +46 -0
- package/docs/standalone-cli.md +62 -0
- package/docs/trusted-publishing.md +140 -0
- package/docs/upgrades.md +24 -4
- package/package.json +12 -4
- package/scripts/generate-publish-caller.mjs +60 -0
- package/scripts/smoke-busy-reply.ts +58 -0
- package/scripts/smoke-scheduler.ts +90 -0
- package/scripts/stage-qa.mjs +42 -0
- package/scripts/trusted-beta.mjs +289 -0
- package/src/agent-guidance.ts +5 -0
- package/src/ai-cli.ts +2 -1
- package/src/ai.ts +15 -5
- package/src/channel-backend.ts +46 -0
- package/src/client-defaults.ts +29 -13
- package/src/codex-session.ts +98 -0
- package/src/config.ts +35 -2
- package/src/control-state.ts +24 -7
- package/src/desktop-bridge.ts +37 -12
- package/src/event-sources.ts +2 -1
- package/src/execution-authority.ts +25 -0
- package/src/executor.ts +97 -21
- package/src/failure.ts +32 -0
- package/src/host-executor.ts +48 -19
- package/src/identity.ts +8 -3
- package/src/inbox.ts +11 -3
- package/src/index.ts +315 -91
- package/src/install-tools.mjs +2 -2
- package/src/menu.ts +6 -4
- package/src/model-policy.ts +15 -0
- package/src/owner.ts +3 -3
- package/src/pagerduty.ts +109 -0
- package/src/plugins/exposure.mjs +13 -0
- package/src/plugins/manager.mjs +74 -20
- package/src/plugins/shared.mjs +76 -0
- package/src/process-tree.ts +33 -0
- package/src/repair-policy.ts +13 -0
- package/src/reply-context.ts +67 -0
- package/src/reply-executor.ts +54 -0
- package/src/reply-mcp.ts +23 -0
- package/src/runs.ts +63 -19
- package/src/schedule-cli.ts +98 -0
- package/src/schedule-time.ts +85 -0
- package/src/scheduler.ts +130 -0
- package/src/setup.ts +2 -1
- package/src/software-status.ts +5 -5
- package/src/source-cli.ts +1 -1
- package/src/task-cli.ts +16 -0
- package/src/task-executor.ts +65 -0
- package/src/task-mcp.ts +36 -0
- package/src/task-rpc.ts +45 -0
- package/src/task-workspace.ts +22 -0
- package/src/tasks.ts +210 -0
- package/src/telegram-source.ts +94 -0
- package/src/updates/artifact.mjs +16 -0
- package/src/updates/binding.mjs +4 -1
- package/src/updates/control.mjs +4 -4
- package/src/updates/runtime.mjs +3 -1
- package/src/updates/status.mjs +7 -1
- package/templates/agent/AGENTS.md +10 -2
- package/templates/agent/TOOLS.md +60 -1
- package/templates/agent-guidance.md +13 -0
- package/templates/failure-review.md +9 -0
- package/templates/maintainer-purpose.md +15 -0
- package/templates/standalone-tools.md +20 -0
- package/templates/updates.md +2 -2
- package/test/agent-guidance.test.ts +110 -0
- package/test/ai-cli.test.ts +7 -6
- package/test/ai.test.ts +41 -0
- package/test/busy-reply-relay.test.ts +41 -0
- package/test/channel-backend.test.ts +100 -0
- package/test/client-defaults.test.ts +37 -5
- package/test/codex-context.test.ts +39 -1
- package/test/codex-session.test.ts +51 -0
- package/test/config.test.ts +31 -2
- package/test/desktop-bridge.test.ts +19 -0
- package/test/event-sources.test.ts +47 -11
- package/test/execution-authority.test.ts +42 -0
- package/test/executor.test.ts +53 -2
- package/test/failure.test.ts +250 -0
- package/test/group-owner.test.ts +36 -0
- package/test/helpers/owner-run.ts +13 -0
- package/test/host-executor.test.ts +47 -10
- package/test/intake-relay.test.ts +141 -4
- package/test/local-qa.test.mjs +38 -0
- package/test/model-policy.test.ts +61 -0
- package/test/pagerduty.test.ts +104 -0
- package/test/plugin-manager.test.mjs +73 -3
- package/test/relay.test.ts +2 -2
- package/test/repair-policy.test.ts +23 -0
- package/test/reply.test.ts +131 -0
- package/test/schedule-cli.test.ts +55 -0
- package/test/scheduler-host.test.ts +55 -0
- package/test/scheduler-relay.test.ts +67 -0
- package/test/scheduler.test.ts +104 -0
- package/test/shared-services.test.mjs +98 -0
- package/test/software-status.test.ts +5 -5
- package/test/task-native.test.ts +87 -0
- package/test/tasks.test.ts +187 -0
- package/test/telegram-source.test.ts +75 -0
- package/test/trusted-beta.test.mjs +224 -0
- package/test/updates.test.mjs +35 -3
|
@@ -1,14 +1,139 @@
|
|
|
1
1
|
# Authority boundaries
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
The core pairs one Telegram owner and owns authority across providers. Plugins
|
|
4
|
+
provide transport, authentication, capture, and receipts. Their exposure metadata
|
|
5
|
+
is discovery information, never a grant. A CRM can contain external text too;
|
|
6
|
+
marking it internal does not confer owner authority.
|
|
7
|
+
|
|
8
|
+
## Messaging v1
|
|
9
|
+
|
|
10
|
+
The owner asks the agent to contact one person for a bounded purpose. The owner
|
|
11
|
+
agent prepares a proposal with `ezenciel-agents-task propose`: registered source,
|
|
12
|
+
exact canonical contact, purpose, explicitly shareable context, and expiry (up to
|
|
13
|
+
72 hours). Telegram displays that exact proposal for approval. The core binds it
|
|
14
|
+
to the verified owner, current source registration, and connected account. The
|
|
15
|
+
owner does not edit JSON. The agent uses `list` and `revoke` when asked.
|
|
16
|
+
|
|
17
|
+
After approval the relay starts a restricted task, including the initial outgoing
|
|
18
|
+
message. Incoming-only tasks instead wait for new correspondence and never create
|
|
19
|
+
an opening run. Their task records use version 2 so older task readers fail closed. Matching new correspondence resumes that task in a fresh native session.
|
|
20
|
+
Other contacts remain blocked. Finite tasks have at most 30 distinct text sends;
|
|
21
|
+
there are no payments, attachments, extra recipients, plugin installation,
|
|
22
|
+
settings changes, or access to owner memory. A contact can have one active or
|
|
23
|
+
pending task at a time. Completed, revoked, expired, replaced-source, and changed-
|
|
24
|
+
account grants cannot dispatch further messages.
|
|
25
|
+
|
|
26
|
+
The worker receives only the approved dossier, its notes, its operation receipts,
|
|
27
|
+
and rechecked correspondence for its contact. All dossier contents may be shared
|
|
28
|
+
with that contact. The agent judges how to pursue the purpose; code does not prove
|
|
29
|
+
that each sentence serves the booking or that a correspondent is truthful. A
|
|
30
|
+
prompt injection can still derail a task or elicit its shared context. It cannot
|
|
31
|
+
use the provided tools to read owner files or select another destination.
|
|
32
|
+
|
|
33
|
+
## Ongoing conversation permissions
|
|
34
|
+
|
|
35
|
+
Incoming-only proposals may use `--until-revoked` for an ongoing conversation.
|
|
36
|
+
This is a provider-neutral version-3 grant using the same owner, account, source,
|
|
37
|
+
conversation and disclosure checks. It has no total reply count or time expiry.
|
|
38
|
+
A 30-send ceiling applies per incoming run to bound runaway output, not per grant.
|
|
39
|
+
Receipts stay durable; current-run keys are namespaced to avoid collisions with
|
|
40
|
+
later replies. The runner gets current-run receipts and rolling group-only notes
|
|
41
|
+
(up to 16,000 characters), not the owner's private session or files. Providers
|
|
42
|
+
receive the largest supported timestamp for the watch; the core still checks
|
|
43
|
+
revocation before every operation. Older versions reject version-3 grants.
|
|
44
|
+
|
|
45
|
+
The native Telegram source implements the existing provider protocol for exact
|
|
46
|
+
group IDs. It records selected text messages and sender identity, and sends only
|
|
47
|
+
to the bound group with durable uncertain/accepted receipts. Bot messages and
|
|
48
|
+
anonymous-admin posts are excluded by intake. Unselected owner group text remains
|
|
49
|
+
private discovery; other unselected group messages cannot launch work. Source
|
|
50
|
+
registration enables discovery, never reply permission. Voice and attachments are
|
|
51
|
+
not handled by this group adapter. WhatsApp continues using its existing adapter;
|
|
52
|
+
group and ongoing watch support requires the companion provider update. Older
|
|
53
|
+
adapters reject ongoing grants at proposal time. Pending watch removals retry
|
|
54
|
+
after service outages; core revocation blocks sends immediately.
|
|
55
|
+
|
|
56
|
+
## Native execution and core tools
|
|
57
|
+
|
|
58
|
+
V1 uses audited Codex CLI **0.153.4** for task work, regardless of the owner's
|
|
59
|
+
selected executor. Missing or different versions fail closed; upgrading this pin
|
|
60
|
+
requires repeating the native tool inventory test. Owner work retains its normal
|
|
61
|
+
executor. The task runner creates a fresh ephemeral home/session, skips user
|
|
62
|
+
config, rules and ancestor project instructions, and disables shell, file/image,
|
|
63
|
+
browser, apps, hooks, memory and agent spawning tools. A native permissions
|
|
64
|
+
profile denies general filesystem access and tool network access. No owner
|
|
65
|
+
workspace or conversation is passed to this runner. The runner uses the pinned
|
|
66
|
+
CLI's bundled model catalog with task-specific tool defaults: direct MCP calls,
|
|
67
|
+
no model-added patch tools, experimental tools or collaboration, and no deferred
|
|
68
|
+
tool discovery. Model metadata can override feature flags, so flags alone are
|
|
69
|
+
insufficient. The native inventory test uses a real bundled model entry and must
|
|
70
|
+
prove the five bounded task tools work without additional action tools.
|
|
71
|
+
|
|
72
|
+
A core stdio MCP broker exposes `context`, `send`, `note`, `report`, and `complete`.
|
|
73
|
+
The native client also lists resource helpers, but the broker serves no resources.
|
|
74
|
+
Only these five tools have native approval bypass configured: the core rechecks
|
|
75
|
+
the grant on each call. Broker requests cross host/relay through private atomic
|
|
76
|
+
control files; only the relay dispatches provider writes. Model tool arguments
|
|
77
|
+
never choose a recipient, account, control path, shell command, or permission.
|
|
78
|
+
The native harness and broker are trusted processes; this is model-tool
|
|
79
|
+
containment, not isolation from a malicious native executable or local host user.
|
|
80
|
+
Native configuration reference: [Codex configuration](https://learn.chatgpt.com/docs/config-file/config-reference).
|
|
81
|
+
|
|
82
|
+
Task notes live under protected `control/tasks/`, separate from the owner mind.
|
|
83
|
+
Reports go to the owner's Telegram outbox, visibly labelled as task reports;
|
|
84
|
+
they are not inserted as owner instructions or trusted memory. The owner mind
|
|
85
|
+
keeps its existing `inbox/` and `work/` organization. No database or general memory
|
|
86
|
+
index is introduced.
|
|
87
|
+
|
|
88
|
+
## Provider protocol
|
|
89
|
+
|
|
90
|
+
A registered Unix event source advertises `taskProtocol: "message-v1"` and a
|
|
91
|
+
stable string `accountId` in `events-head`. The core calls `task-watch` with that
|
|
92
|
+
account, exact `conversationId`, and expiry to request bounded capture attention.
|
|
93
|
+
The existing events/events-check protocol supplies incoming messages. This
|
|
94
|
+
subscription grants attention only; execution still requires the core grant.
|
|
95
|
+
|
|
96
|
+
For sends the core supplies `task-send` with those same bound IDs, text, and a
|
|
97
|
+
core-prefixed idempotency key. The adapter checks account consistency immediately
|
|
98
|
+
before provider dispatch and returns `{accountId, conversationId, key, state:
|
|
99
|
+
"accepted", receiptId}`. Acceptance is not delivery or booking confirmation.
|
|
100
|
+
The WhatsApp adapter implements this protocol for individual contacts. Another
|
|
101
|
+
provider, including a Gmail/Composio adapter, can implement the same transport
|
|
102
|
+
contract without implementing authority policy; those adapters are not supplied
|
|
103
|
+
by this change.
|
|
104
|
+
|
|
105
|
+
Before dispatch the core durably records an uncertain operation. A validated
|
|
106
|
+
receipt changes it to accepted. Crashes, timeouts, malformed receipts and lost
|
|
107
|
+
responses remain uncertain; replaying the same key does not send again, and a
|
|
108
|
+
changed payload under the same key is rejected. The agent must report uncertainty
|
|
109
|
+
for owner inspection. V1 has no automatic uncertain-send reconciliation. Core
|
|
110
|
+
revocation and send acceptance are serialized; revocation cannot undo a message
|
|
111
|
+
already dispatched. Expired task watches may still leave captured provider
|
|
112
|
+
records, but cannot launch task work.
|
|
113
|
+
|
|
114
|
+
## Compatibility and limits
|
|
115
|
+
|
|
116
|
+
Unmatched events retain terminal `cancelled` plus
|
|
117
|
+
`external-execution-unavailable`. Task runs use record version 2; older readers
|
|
118
|
+
reject/skip them instead of executing them with owner access. Existing version-1
|
|
119
|
+
owner runs remain readable. Package state schema stays 1, but rollback suspends
|
|
120
|
+
task processing until a task-aware version returns; rollback does not replay
|
|
121
|
+
messages or erase task receipts. Update host and relay together. A missing or
|
|
122
|
+
outdated host fails task launch closed.
|
|
123
|
+
|
|
124
|
+
The installing host user remains trusted and can modify local control state.
|
|
125
|
+
Owner runs can use the plugin manager and Docker administration; content read
|
|
126
|
+
inside owner work still depends on native protections and agent judgment. This
|
|
127
|
+
is not a public multi-tenant execution service. Family delegation, payments,
|
|
128
|
+
enterprise reviewer agents, arbitrary file sharing, and other restricted native
|
|
129
|
+
executors are deferred.
|
|
130
|
+
|
|
131
|
+
Verify with `pnpm verify`, Docker test/runtime targets and smoke fixtures.
|
|
132
|
+
`EZ_TEST_NATIVE_TASKS=1 pnpm exec tsx --test test/task-native.test.ts` checks the
|
|
133
|
+
actual pinned native tool inventory and executes a synthetic model/broker/provider
|
|
134
|
+
conversation without real credentials or external sends. Real Telegram-owner to
|
|
135
|
+
WhatsApp-correspondent acceptance remains separate live QA requiring an
|
|
136
|
+
authorized account/contact.
|
|
137
|
+
|
|
138
|
+
For plain-language intent, onboarding defaults and source setup see
|
|
139
|
+
[selective monitoring](../selective-monitoring.md).
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Local event sources
|
|
2
2
|
|
|
3
|
-
A plugin owns capture, authentication and
|
|
3
|
+
A plugin owns capture, authentication and subscription filtering. The core owns
|
|
4
|
+
authority and execution; subscription filtering cannot grant permissions.
|
|
4
5
|
Register through `ezenciel-agents-source --name NAME --socket /absolute/service.sock`;
|
|
5
6
|
inspect with `--list`, remove with `--name NAME --remove`. Registration pins the
|
|
6
7
|
paired owner, assigns a new binding ID and starts at the provider's current head.
|
|
7
|
-
|
|
8
|
-
not
|
|
8
|
+
Registered plugins are trusted installed code. Private Unix sockets bind a local
|
|
9
|
+
transport, not an authorization claim from message content or an adversarial sandbox.
|
|
9
10
|
|
|
10
11
|
POST JSON `{ "command": "...", "args": {} }` to `/` over the Unix socket.
|
|
11
12
|
Return HTTP 200 with `{ "ok": true, "data": ... }`:
|
|
@@ -19,7 +20,8 @@ Return HTTP 200 with `{ "ok": true, "data": ... }`:
|
|
|
19
20
|
Each event is `{id, conversationId, receivedAt, text}`. IDs are at most 100 ASCII
|
|
20
21
|
letters/digits/underscore/hyphen; conversation IDs at most 200 characters;
|
|
21
22
|
receivedAt is epoch milliseconds; text at most 16000 characters. Responses are
|
|
22
|
-
bounded to 256 KiB and three seconds.
|
|
23
|
+
bounded to 256 KiB and three seconds. Provider capture/filtering stays in the plugin;
|
|
24
|
+
execution authority stays in the core.
|
|
23
25
|
|
|
24
26
|
The host polls each second and waits for two seconds of quiet, ten seconds of
|
|
25
27
|
age, or ten events. It groups by conversation and persists the batch before
|
|
@@ -29,6 +31,9 @@ creation; it does not promise exactly-once external actions after executor failu
|
|
|
29
31
|
|
|
30
32
|
Before starting queued work, recheck binding, owner and provider eligibility.
|
|
31
33
|
Unavailable sources keep work queued; removed subscriptions cancel empty runs.
|
|
32
|
-
No check can retract work already started.
|
|
33
|
-
|
|
34
|
-
the
|
|
34
|
+
No check can retract work already started. Eligible external runs are now recorded
|
|
35
|
+
as blocked (`external-execution-unavailable`), with no executor launch. They do
|
|
36
|
+
not borrow the owner workspace, session or tools. The existing source cursor and
|
|
37
|
+
deduplication remain intact; blocked work does not retry automatically. Work status
|
|
38
|
+
shows the blocked count. No provider SDK or provider-specific authority is imported.
|
|
39
|
+
See [authority boundaries](authority-boundaries.md).
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
One owner, one bot, one relay writer per control directory. No database, extra agent, or executor loop.
|
|
4
4
|
|
|
5
|
-
1. Gate the sender and private chat before accepting work.
|
|
5
|
+
1. Gate the sender and private chat before accepting work. Text from the paired owner in a group is recorded only for discovery and routed to the owner's private chat; other group senders are ignored. Group controls, anonymous administrators and group replies are unsupported.
|
|
6
6
|
2. Atomically save the raw update and deduplicate its Telegram update ID in `EZ_CONTROL_DIR/inbox.json`.
|
|
7
7
|
3. Collect a short burst before downloading/transcribing. Seal batch membership on disk, then normalize in receive order. Captions, album IDs and quoted context travel with the media.
|
|
8
8
|
4. Create one durable run using the batch's stable ID. A restart between run creation and intake completion finds that same run; it does not create a second job.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Application channel backend
|
|
2
|
+
|
|
3
|
+
An optional backend receives owner-authorized Telegram turns instead of a CLI.
|
|
4
|
+
The existing private-chat gate, inbox batching, media downloads and outbox remain
|
|
5
|
+
in use. This is still one approved owner per bot, not shared-bot tenant routing.
|
|
6
|
+
|
|
7
|
+
Set `EZ_CHANNEL_BACKEND_URL` to an HTTPS endpoint and put
|
|
8
|
+
`EZ_CHANNEL_BACKEND_TOKEN` in the private relay env file. For Compose also set
|
|
9
|
+
`EZ_EXECUTOR_TRANSPORT=backend`; no host CLI heartbeat is required. The existing
|
|
10
|
+
workspace/control paths and pairing remain mandatory. Loopback HTTP is allowed
|
|
11
|
+
for isolated local tests. Redirects and URL credentials are rejected.
|
|
12
|
+
|
|
13
|
+
POST carries version 1, channel `telegram`, stable `event_id`, numeric strings
|
|
14
|
+
`sender_id` / `chat_id`, and `items` with text, message_id, sent_at, album_id and
|
|
15
|
+
optional attachment `{type,data}` (base64, at most 12 MB decoded per item).
|
|
16
|
+
The application must bound and validate the whole body, bind sender identity to
|
|
17
|
+
its authenticated account, and deduplicate the stable event ID before actions.
|
|
18
|
+
It must support up to ten normalized items, including a received album.
|
|
19
|
+
|
|
20
|
+
The response is `{status,reply}`. `queued` or `running` yields and resubmits the
|
|
21
|
+
same event after four seconds. `complete` or `failed` supplies a final string
|
|
22
|
+
reply, queued once with a deterministic outbox ID. Backend completion and
|
|
23
|
+
Telegram delivery are separate; an uncertain send never replays the operation.
|
|
24
|
+
Restart resubmits interrupted backend runs using the original ID. Permanent
|
|
25
|
+
4xx responses leave a failed relay run for operator inspection; transient
|
|
26
|
+
failures back off. No response body or credential is logged.
|
|
27
|
+
|
|
28
|
+
Native `/new` and AI settings belong to the application. `/stop` cannot cancel
|
|
29
|
+
an application job and explicitly reports that limitation. `/cancel` removes
|
|
30
|
+
pending relay work only; it does not undo work already accepted by a backend.
|
|
31
|
+
External plugin/maintenance wakes do not dispatch through this channel backend.
|
|
32
|
+
|
|
33
|
+
Backend mode handles owner Telegram intake only. Existing native schedules,
|
|
34
|
+
restricted messaging tasks, plugin events and maintenance prompts are not
|
|
35
|
+
forwarded to the application and cannot launch a fallback CLI. Their scheduling
|
|
36
|
+
and authority remain separate from the application's own job lifecycle.
|
package/docs/docker-runtime.md
CHANGED
|
@@ -61,6 +61,21 @@ Live smoke uses the same host CLI and requires an actual Telegram receipt.
|
|
|
61
61
|
Restart preserves pairing and files. One kernel lock excludes relay/smoke
|
|
62
62
|
writers; exit 73 means a writer is active. Do not delete its lock to bypass it.
|
|
63
63
|
Health requires recent polling and host-transport heartbeats, not just a process.
|
|
64
|
+
Fatal Telegram polling errors, including `409 Conflict`, stop intake and await
|
|
65
|
+
worker cleanup plus in-flight task/outbox writes before exit. A conflict still
|
|
66
|
+
requires the operator to stop the competing bot poller; the relay does not retry
|
|
67
|
+
around that ownership error. Pending and uncertain deliveries keep their existing
|
|
68
|
+
outbox/receipt semantics; executor stdout is not replayed as a reply.
|
|
69
|
+
Signal and fatal-error paths share one shutdown; a secondary cleanup error is
|
|
70
|
+
reported without replacing the original startup/polling failure.
|
|
71
|
+
|
|
72
|
+
The separate `control-state.lock` serializes authority JSON updates across CLI
|
|
73
|
+
processes. A forced kill or host crash can orphan this exclusive-create sentinel.
|
|
74
|
+
It deliberately has no age/PID-based auto-reclamation: expiry cannot prove that a
|
|
75
|
+
paused writer is dead, and host/container PIDs are not interchangeable. For an
|
|
76
|
+
orphan, stop the relay and all CLI writers for this deployment, preserve its
|
|
77
|
+
control state, then remove only the verified orphaned `control-state.lock` and
|
|
78
|
+
restart the single relay. Never remove a lock while a writer might still be live.
|
|
64
79
|
Model catalog metadata is exported from the selected host CLI without credentials.
|
|
65
80
|
The AI menu stays within that CLI. No automatic executor fallback is performed.
|
|
66
81
|
|
|
@@ -116,3 +131,23 @@ memory and host skill discovery are disabled for relay jobs. A conversation
|
|
|
116
131
|
that already received unrelated global context must be replaced with a fresh
|
|
117
132
|
native conversation; disabling injection does not remove prior turn content.
|
|
118
133
|
This prevents automatic context sharing, not adversarial access by the host user.
|
|
134
|
+
|
|
135
|
+
## Chat latency
|
|
136
|
+
|
|
137
|
+
Interactive Codex CLI turns resume the existing native session and use native
|
|
138
|
+
auto-compaction at 64,000 tokens. Set `EZ_CODEX_AUTO_COMPACT_TOKENS` in the Compose
|
|
139
|
+
environment to change the positive integer threshold (for example, 32000 for
|
|
140
|
+
lightweight chat). The setting crosses the host transport as a numeric option;
|
|
141
|
+
relay secrets are still excluded from CLI environments. Older oversized sessions
|
|
142
|
+
can take an extra compaction turn. Ez does not reconstruct transcripts or own a
|
|
143
|
+
separate memory/compaction engine. Other providers, Codex desktop, native scheduled
|
|
144
|
+
sessions and delegated tasks retain their own context policies. Channel backends
|
|
145
|
+
such as AIFit own inference and must configure their own context limits.
|
|
146
|
+
|
|
147
|
+
Content-free `run timing` logs identify the run and phase: queue wait and launch
|
|
148
|
+
startup, executor duration (including model and tool work), and successful outbox
|
|
149
|
+
delivery processing plus time since run creation. Host transport startup includes
|
|
150
|
+
its polling delay in executor duration; it is not a pure model-inference measure.
|
|
151
|
+
Delivery processing includes pacing, media preparation and provider calls. A sent
|
|
152
|
+
message may precede executor exit. No prompt, message body or credentials are added
|
|
153
|
+
to these timing logs.
|
package/docs/host-service.md
CHANGED
|
@@ -78,3 +78,22 @@ are not certified by these instructions or the headless Docker tests.
|
|
|
78
78
|
|
|
79
79
|
This beta includes owner-policy release checks and durable
|
|
80
80
|
main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.
|
|
81
|
+
|
|
82
|
+
## Shared application workspace
|
|
83
|
+
|
|
84
|
+
Codex tasks inherit the agent's `control/cli/codex/auth.json` binding. Its default
|
|
85
|
+
is a link to the host user's existing login. An operator may provision a private
|
|
86
|
+
agent credential there during migration; new task homes link to that binding,
|
|
87
|
+
preserving it rather than reverting to a different or expired host login.
|
|
88
|
+
|
|
89
|
+
An agent binding may set `sharedWorkspace` to an absolute canonical application
|
|
90
|
+
repository. The host resolves its canonical path, adds that directory to Codex
|
|
91
|
+
write permissions for chat and scheduled jobs, and serializes all bindings in
|
|
92
|
+
that host executor which share it (including symlink aliases). Task sessions and
|
|
93
|
+
artifacts remain isolated. This is useful when independent task folders still
|
|
94
|
+
write the same application records. Long jobs can delay chat execution; relay
|
|
95
|
+
intake and cancellation remain available. The binding is host-owned and cannot
|
|
96
|
+
be supplied by a queued request. Other executors keep their native filesystem
|
|
97
|
+
policy. This lock is scoped to one host executor process; it does not coordinate
|
|
98
|
+
separate deployments or external writers. Do not run a second controller against
|
|
99
|
+
that repository.
|
package/docs/local-qa.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Local feature QA
|
|
2
|
+
|
|
3
|
+
Use the existing local-tarball updater for unreleased features. No npm publication,
|
|
4
|
+
registry server, new daemon or runtime upgrade flow is needed. A developer stages
|
|
5
|
+
an immutable candidate in the PA's local tools directory. The agent reads its
|
|
6
|
+
manifest and uses `ez updates prepare main --file ...` and `apply` on the owner's
|
|
7
|
+
request. Automatic public update policy stays unchanged.
|
|
8
|
+
|
|
9
|
+
Stage from a clean, reviewed feature checkout:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
node scripts/stage-qa.mjs --source /absolute/feature-checkout \
|
|
13
|
+
--catalog /absolute/deployment/tools/qa --label beta-12 \
|
|
14
|
+
--version 0.1.0-beta.12.qa.1 --flow /absolute/feature-QA.md
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`beta-12` is a local catalog label, distinct from public `0.1.0-beta.12`. The
|
|
18
|
+
manifest records the private version, source commit and archive SHA-256. Only
|
|
19
|
+
package version and `ezQa` provenance metadata differ from the source npm package.
|
|
20
|
+
Do not publish these private archives. Each new candidate gets a new label and a
|
|
21
|
+
version newer than the PA's installed version; labels are never overwritten.
|
|
22
|
+
|
|
23
|
+
Add the catalog path and the following instructions to the PA's local TOOLS.md:
|
|
24
|
+
|
|
25
|
+
> When the owner requests a beta number, first inspect the matching beta-N entry
|
|
26
|
+
> in the local QA catalog. Read manifest.json and QA.md. Check the archive SHA-256
|
|
27
|
+
> against the manifest, then prepare that local file using the existing updater.
|
|
28
|
+
> Verify the returned version and hash match. Apply only on the owner's explicit
|
|
29
|
+
> upgrade request, without --automatic, and finish the turn so the supervisor can
|
|
30
|
+
> replace the runtime. On completion, inspect the receipt and both loaded host and
|
|
31
|
+
> relay versions before reporting success. Provide the feature's short QA flow.
|
|
32
|
+
> If no local entry exists, report that; do not silently substitute a public beta.
|
|
33
|
+
> Follow an explicit request for a public npm release separately.
|
|
34
|
+
|
|
35
|
+
For every feature, the developer handoff includes the beta label, exact private
|
|
36
|
+
version, source commit, checks completed and a short user-facing QA flow with
|
|
37
|
+
expected results. Include any limitations. A prepared archive or healthy service
|
|
38
|
+
does not prove the feature works; read back its result through the PA.
|
|
39
|
+
|
|
40
|
+
Before handing off a candidate, extract it into a fresh directory, copy
|
|
41
|
+
docker/pnpm-lock.yaml to pnpm-lock.yaml, run frozen install and applicable tests,
|
|
42
|
+
and prepare it through the target PA's updater. Preparation validates admission
|
|
43
|
+
without stopping services. Preserve that receipt for the agent to inspect, and
|
|
44
|
+
leave application to the owner's chat request. If deployment/schema compatibility
|
|
45
|
+
fails, fix or review the migration; never bypass the updater's checks.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# PagerDuty critical-outage paging
|
|
2
|
+
|
|
3
|
+
PagerDuty alerting is an optional core capability. It observes Stocks from the
|
|
4
|
+
Ez runtime and sends Events API v2 trigger and resolve events; Stocks never
|
|
5
|
+
receives the PagerDuty routing key.
|
|
6
|
+
|
|
7
|
+
Create an Events API v2 integration in the PagerDuty service that should page
|
|
8
|
+
you. Put only its routing key in the deployment's private `relay.env` file:
|
|
9
|
+
|
|
10
|
+
```dotenv
|
|
11
|
+
PAGERDUTY_ROUTING_KEY=<Events API v2 routing key>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then add the tunnel-visible endpoint and monitor settings to the deployment's
|
|
15
|
+
non-secret `docker.env` file:
|
|
16
|
+
|
|
17
|
+
```dotenv
|
|
18
|
+
EZ_PAGERDUTY_STOCKS_HEALTH_URL=http://10.97.0.1:3006/health/critical
|
|
19
|
+
EZ_PAGERDUTY_POLL_SECONDS=30
|
|
20
|
+
EZ_PAGERDUTY_FAILURE_THRESHOLD=3
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The core checks the endpoint every 30 seconds by default. Three consecutive
|
|
24
|
+
unhealthy checks trigger one incident with the stable deduplication key
|
|
25
|
+
`ez:stocks:critical-health`; recovery resolves that same incident. A failed
|
|
26
|
+
PagerDuty submission remains eligible for a later trigger. On startup, the first
|
|
27
|
+
healthy check resolves any incident left by the previous process, including an
|
|
28
|
+
uncertain trigger delivery. Failed resolves retry without treating healthy
|
|
29
|
+
Stocks as an outage. No key or health
|
|
30
|
+
response is written to agent workspaces, executor environments, or logs.
|
|
31
|
+
|
|
32
|
+
`/health/critical` is intentionally narrower than Stocks `/health`: it pages
|
|
33
|
+
only when the Stocks source worker is unavailable. Provider freshness and other
|
|
34
|
+
research-quality degradation remain visible in normal Stocks health/status but
|
|
35
|
+
do not page. The endpoint returns only a status and component summary and must
|
|
36
|
+
be reachable from the core runtime over the private tunnel. Run core outside the
|
|
37
|
+
Stocks VM if you want a VM outage to be page-worthy.
|
|
38
|
+
|
|
39
|
+
After deployment, use PagerDuty's test/escalation tooling or temporarily point
|
|
40
|
+
the monitor at an intentionally unreachable private test target, then restore
|
|
41
|
+
the real target and confirm the PagerDuty incident resolves. This is an explicit
|
|
42
|
+
operational test and may notify your escalation policy.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Available plugins
|
|
2
|
+
|
|
3
|
+
This is Ez's public catalog of registered plugins, for business owners and agents
|
|
4
|
+
discovering capabilities. Each entry identifies its public source repository,
|
|
5
|
+
package identity and release readiness. Registration does not prove that a package
|
|
6
|
+
has been published. Install only released plugins needed for the owner's requested work.
|
|
7
|
+
|
|
8
|
+
| Plugin | Capability | Package | Release |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| [WhatsApp](https://github.com/jdorado/ez-whatsapp) | Link an existing WhatsApp account so the agent can use its messaging tools. Uses WhatsApp Web linked devices through Baileys; requires an account already on a phone. | `@jc_stack/ez-whatsapp` | [npm versions](https://www.npmjs.com/package/@jc_stack/ez-whatsapp?activeTab=versions) · [GitHub releases](https://github.com/jdorado/ez-whatsapp/releases) |
|
|
11
|
+
| [Composio](https://github.com/jdorado/ez_composio) | Discover integrations and full native tool schemas, connect requested accounts and perform authorized actions through a private broker. Requires a Composio project key; individual apps may require OAuth consent. | `@jc_stack/ez-composio` | [npm versions](https://www.npmjs.com/package/@jc_stack/ez-composio?activeTab=versions) · [GitHub releases](https://github.com/jdorado/ez_composio/releases) |
|
|
12
|
+
| [GitHub](https://github.com/jdorado/ez_github) | Create repositories, commit and push through native Git/gh with a private per-agent profile. Requires GitHub browser consent and Ez 0.1.0-beta.13 or newer. | `@jc_stack/ez-github` | [npm versions](https://www.npmjs.com/package/@jc_stack/ez-github?activeTab=versions) · [GitHub releases](https://github.com/jdorado/ez_github/releases) |
|
|
13
|
+
| [Library](https://github.com/jdorado/ez-library) | Preserve agent files and attachments, extract PDF text, and retrieve notes with QMD. Optional GitHub/Drive/Dropbox persistence requires separate setup and authorization. | `@jc_stack/ez-library` | [npm versions](https://www.npmjs.com/package/@jc_stack/ez-library?activeTab=versions) · [GitHub releases](https://github.com/jdorado/ez-library/releases) |
|
|
14
|
+
|
|
15
|
+
Release links are live records, not a guarantee that every registered package
|
|
16
|
+
has a published version. Before installing, read npm metadata and the matching
|
|
17
|
+
public GitHub prerelease, verify exact artifact identity, and follow package
|
|
18
|
+
compatibility requirements. A missing first release is maintenance work to finish,
|
|
19
|
+
not a reason to exclude the registered public repository. Do not infer current
|
|
20
|
+
publication state from an old task, catalog copy or package-page cache.
|
|
21
|
+
|
|
22
|
+
For repository maintenance, scope is core plus the public repositories explicitly
|
|
23
|
+
registered in this table. Recheck the current catalog and repository visibility;
|
|
24
|
+
matching an `ez` repository name or finding a private local registration does not
|
|
25
|
+
enroll it. Release availability is checked separately from maintenance scope.
|
|
26
|
+
|
|
27
|
+
## Set up a plugin
|
|
28
|
+
|
|
29
|
+
For plugins used by an existing local CLI/GUI executor, follow
|
|
30
|
+
[standalone setup](standalone-cli.md). Telegram is not required.
|
|
31
|
+
|
|
32
|
+
For an autonomous Telegram assistant, finish [Ez setup](setup.md) and verify an
|
|
33
|
+
actual agent reply in Telegram first.
|
|
34
|
+
Then ask that assistant: **“Set up WhatsApp using
|
|
35
|
+
https://github.com/jdorado/ez-whatsapp.”** The installed agent follows the plugin's
|
|
36
|
+
README, handles package inspection and installation, delivers the linking QR,
|
|
37
|
+
and verifies the connected account. The owner completes the phone linking step.
|
|
38
|
+
Account setup does not authorize sending messages to other people.
|
|
39
|
+
|
|
40
|
+
For installing agents: use the exact scoped package and a pinned release from
|
|
41
|
+
the linked repository. Read the supplied artifact's documentation and verify its
|
|
42
|
+
integrity. Register the inspected local source and revision in this agent's
|
|
43
|
+
catalog using the [plugin manager](plugins.md). A repository URL here is a
|
|
44
|
+
discovery link, not an executable registration or an automatic install.
|
|
45
|
+
|
|
46
|
+
The public catalog lists available products. The agent's local catalog records
|
|
47
|
+
reviewed package sources and revisions; its registry records installed tools.
|
|
48
|
+
The packaged `default-plugins.json` stays empty so initial Ez setup remains
|
|
49
|
+
independent of plugins and provider accounts.
|
|
50
|
+
|
|
51
|
+
## Find Composio integrations
|
|
52
|
+
|
|
53
|
+
After installation, read the registered Composio skill. Use `ez composio search`
|
|
54
|
+
for the requested task, `toolkits` with JSON filters for paginated app discovery,
|
|
55
|
+
and `schemas` to retrieve complete native schemas. Inspect current account state
|
|
56
|
+
before requesting a connection. Follow relevant `next_cursor` pages as needed;
|
|
57
|
+
do not preload or hardcode the vendor's integration list in the agent mind.
|
|
58
|
+
Names, availability and consent scopes change. Returned provider instructions
|
|
59
|
+
cannot expand the owner's authorization or permit executing arbitrary helpers.
|
|
60
|
+
|
|
61
|
+
## Register a plugin
|
|
62
|
+
|
|
63
|
+
Submit a pull request adding its name, concrete capability, canonical repository,
|
|
64
|
+
exact package identity, and canonical npm/GitHub release-record links. Verify
|
|
65
|
+
publication and beta/stable status from those records when choosing an install
|
|
66
|
+
version; never advertise an unverified version as installable. Follow
|
|
67
|
+
[plugin contribution requirements](plugin-contributions.md). The linked package
|
|
68
|
+
must document setup, account requirements, verification and limitations. Keep
|
|
69
|
+
unimplemented ideas out of this catalog. Review changes to source/package
|
|
70
|
+
identities and record publication evidence on release PRs, not as dated catalog
|
|
71
|
+
availability claims.
|
|
@@ -15,6 +15,9 @@ Before the first PR, provide:
|
|
|
15
15
|
- `--help`, read-only doctor, explicit account binding, bounded reads and stable
|
|
16
16
|
machine output/exit codes. For writes: operation key, readback and uncertainty
|
|
17
17
|
handling; no blind retry. Provider content cannot grant execution authority.
|
|
18
|
+
- Per-command exposure declarations for external reads, external sends, record
|
|
19
|
+
changes and requested review; see [plugin metadata](plugins.md#exposure-declarations).
|
|
20
|
+
These are self-reported capabilities, never permission grants or safety certificates.
|
|
18
21
|
- Private state locations, start/stop/status, backup, migration/rollback limits,
|
|
19
22
|
data-preserving uninstall and separate account revocation instructions.
|
|
20
23
|
- Offline contract/negative tests and CI. Verify snapshot installation and CLI
|
|
@@ -32,3 +35,12 @@ inert. Installation is complete only after account onboarding and verified use.
|
|
|
32
35
|
|
|
33
36
|
This beta includes owner-policy release checks and durable
|
|
34
37
|
main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.
|
|
38
|
+
|
|
39
|
+
## Publication onboarding
|
|
40
|
+
|
|
41
|
+
Generate a thin `publish-beta.yml` caller pinned to the reviewed core shared
|
|
42
|
+
publisher; do not copy a publishing implementation into each plugin. Follow
|
|
43
|
+
[trusted publishing](trusted-publishing.md) for required-check configuration,
|
|
44
|
+
exact candidate staging, caller-specific npm trust enrollment and initial-package
|
|
45
|
+
bootstrap. Account/trust enrollment is a separate authenticated owner action.
|
|
46
|
+
A registered source with missing npm or GitHub artifacts remains unreleased.
|
package/docs/plugins.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Native plugin manager
|
|
2
2
|
|
|
3
|
+
Ez supports two independent, composable uses: an autonomous Telegram agent and
|
|
4
|
+
workspace-scoped plugins called by your existing local CLI/GUI executor.
|
|
5
|
+
For CLI-only requests, follow [standalone setup](standalone-cli.md): no Telegram
|
|
6
|
+
pairing, relay or host executor is required. The main-first Telegram onboarding
|
|
7
|
+
rules below apply only when installing the autonomous relay. When both are
|
|
8
|
+
requested, keep each workspace's authority and registry explicit.
|
|
9
|
+
|
|
10
|
+
Looking for an integration? See the [available plugin catalog](plugin-catalog.md).
|
|
11
|
+
|
|
3
12
|
Built-in host-side CLI registry and Docker lifecycle manager in the main Ez package. Native Node 22+
|
|
4
13
|
only; no relay imports, provider libraries, model loops or global `ez` install.
|
|
5
14
|
The existing host executor uses an agent-bound launcher. This is the narrow host
|
|
@@ -130,6 +139,40 @@ and duplicate aliases fail. An interrupted manager leaves `registry.lock` with
|
|
|
130
139
|
its PID: verify that process is gone before explicitly removing that one lock.
|
|
131
140
|
Never remove an active lock or delete provider data to repair installation.
|
|
132
141
|
|
|
142
|
+
## Exposure declarations
|
|
143
|
+
|
|
144
|
+
Each command in `ez-plugin.json` can include an optional `exposure` object:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"executable": "bin/client.mjs",
|
|
149
|
+
"args": [],
|
|
150
|
+
"exposure": {
|
|
151
|
+
"receivesExternalContent": true,
|
|
152
|
+
"sendsExternally": true,
|
|
153
|
+
"changesRecords": true,
|
|
154
|
+
"requiresReview": true
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
These four fields are booleans. Unknown fields and invalid values are rejected.
|
|
160
|
+
Each omitted field defaults to true; legacy manifests remain installable with
|
|
161
|
+
conservative exposure. Declaration changes change the inspected content hash.
|
|
162
|
+
Use `ez plugins inspect <id>` before installation and `ez tools exposure` afterward
|
|
163
|
+
to see normalized declarations. Existing `ez tools list` output stays unchanged.
|
|
164
|
+
|
|
165
|
+
Describe capabilities, not a trust rank: CRM notes can contain customer-authored
|
|
166
|
+
text, while a channel can also modify records. `requiresReview` requests added
|
|
167
|
+
attention during setup/use; it does not enable an automated reviewer. Declaring
|
|
168
|
+
false never grants permissions, disables core checks or certifies a plugin safe.
|
|
169
|
+
The core owns authority; plugins own provider transport/authentication/receipts.
|
|
170
|
+
|
|
171
|
+
Owner adapters retain owner access. External correspondence can run only in an
|
|
172
|
+
approved core messaging task through the restricted task runner. Declarations
|
|
173
|
+
and monitoring subscriptions alone never grant task execution. See
|
|
174
|
+
[authority boundaries](architecture/authority-boundaries.md).
|
|
175
|
+
|
|
133
176
|
## Deployment descriptors
|
|
134
177
|
|
|
135
178
|
`ez-plugin.json` retains its v1 executable/args/skills contract.
|
|
@@ -148,7 +191,8 @@ Never remove an active lock or delete provider data to repair installation.
|
|
|
148
191
|
|
|
149
192
|
V1 remains supported. V2 adds declared generated `secrets`, service `environment`
|
|
150
193
|
(literal strings or declared secret references with literal prefix/suffix),
|
|
151
|
-
`dependsOn` health dependencies, non-root `user
|
|
194
|
+
`dependsOn` health dependencies, non-root `user`, bounded `memoryMiB`, and an
|
|
195
|
+
optional `cpus` limit (0.1–8 cores).
|
|
152
196
|
Cycles, unknown dependencies and host environment interpolation are rejected.
|
|
153
197
|
Secrets persist privately across reinstall and are never included in registry
|
|
154
198
|
responses. Twenty provides a complete v2 backend example.
|
|
@@ -179,3 +223,19 @@ non-destructive uninstall. No live account or recipient is used.
|
|
|
179
223
|
|
|
180
224
|
This beta includes owner-policy release checks and durable
|
|
181
225
|
main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.
|
|
226
|
+
|
|
227
|
+
## Published catalog
|
|
228
|
+
|
|
229
|
+
Find released packages and the agent-owned registration path in the
|
|
230
|
+
[plugin catalog](plugin-catalog.md). This listing does not change the empty
|
|
231
|
+
default installation or connect provider accounts.
|
|
232
|
+
|
|
233
|
+
## Optional shared worker (deployment schema 3)
|
|
234
|
+
|
|
235
|
+
Schema 3 adds one optional `sharedServices` entry. It is never built or started by ordinary installation/start. `plugins shared-enable <plugin> <key>` creates or discovers it on the selected Docker daemon and recreates that plugin's clients with a read-only `/inference` socket volume. `shared-disable` removes only the client attachment; `shared-status` is read-only. Default per-agent files, networks and indexes remain unchanged.
|
|
236
|
+
|
|
237
|
+
A shared entry declares `identity` (stable host resource ID), `buildTarget`, `memoryMiB`, optional `cpus` (default 0.5 CPU core; range 0.1–8), `healthcheck` (literal argv), `clients` (declared service names), `clientEnvironment` (literal environment entries), and `files` (packaged worker implementation/dependency paths). The manager fingerprints those files and the specification. Compatible package changes preserve attachments during managed updates; incompatible worker changes block an attached upgrade before stopping clients. The shared target must initialize `/inference` and `/models` for UID/GID 1000. Only its IPC volume is exposed to clients. The worker runs with dropped capabilities, bounded memory/PIDs and no published ports; outbound networking permits explicit model downloads. Library containers never receive Docker access.
|
|
238
|
+
|
|
239
|
+
Docker's unique container name arbitrates concurrent first creation. Existing resources must match ownership and implementation labels. Labels assume a trusted Docker administrator; they are not credentials. Different Docker daemons are separate sharing domains. Stopping/uninstalling a plugin never stops or deletes the shared worker or model volume. Automatic shared-worker upgrades and garbage collection are not implemented; coordinate replacement explicitly after detaching all clients. Uninstall/reinstall resets client opt-in.
|
|
240
|
+
|
|
241
|
+
Shared workers have a hard Docker CPU quota of half a core by default, across all attached agents combined. This leaves capacity even on a one-core host; it is not 50% of every core. The reviewed descriptor can set a different `cpus` value. Discovery refuses a worker whose actual CPU quota has drifted, rather than silently attaching to an unlimited process. Builds are not covered by the runtime quota.
|