@jc_stack/ez-agents 0.1.0-beta.13 → 0.1.0-beta.19
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 +3 -0
- package/.env.example +20 -0
- package/AGENTS.md +12 -3
- package/CHANGELOG.md +63 -0
- package/CONTRIBUTING.md +62 -6
- package/Dockerfile +6 -0
- package/README.md +11 -2
- package/bin/ezenciel-agents-watch.mjs +8 -0
- package/compose.workforce-watch.yaml +33 -0
- package/compose.yaml +8 -1
- package/docker/run.ts +1 -1
- package/docs/architecture/ai-selection.md +15 -0
- package/docs/architecture/authority-boundaries.md +24 -1
- package/docs/architecture/telegram-intake.md +1 -1
- package/docs/docker-runtime.md +35 -0
- package/docs/host-service.md +19 -0
- package/docs/pagerduty.md +42 -0
- package/docs/plugin-catalog.md +28 -10
- package/docs/plugin-contributions.md +9 -0
- package/docs/plugins.md +46 -1
- package/docs/releasing.md +20 -9
- package/docs/repair.md +41 -0
- package/docs/responsive-channels.md +57 -0
- package/docs/scheduling.md +32 -4
- package/docs/selective-monitoring.md +12 -4
- package/docs/setup.md +43 -0
- package/docs/trusted-publishing.md +140 -0
- package/docs/upgrades.md +24 -4
- package/docs/workforce-watch.md +101 -0
- package/package.json +9 -4
- package/scripts/generate-publish-caller.mjs +60 -0
- package/scripts/smoke-busy-reply.ts +58 -0
- package/scripts/trusted-beta.mjs +289 -0
- package/src/agent-guidance.ts +9 -0
- package/src/ai-cli.ts +2 -1
- package/src/ai.ts +26 -8
- package/src/client-defaults.ts +29 -13
- package/src/codex-session.ts +4 -2
- package/src/config.ts +29 -1
- package/src/control-state.ts +26 -7
- package/src/desktop-bridge.ts +11 -2
- package/src/event-sources.ts +2 -1
- package/src/execution-authority.ts +2 -1
- package/src/executor.ts +34 -7
- package/src/failure.ts +32 -0
- package/src/host-executor-client.ts +7 -1
- package/src/host-executor.ts +22 -13
- package/src/identity.ts +8 -3
- package/src/inbox.ts +7 -3
- package/src/index.ts +260 -92
- package/src/install-tools.mjs +2 -2
- package/src/menu.ts +8 -6
- package/src/model-policy.ts +18 -0
- package/src/owner.ts +3 -3
- package/src/pagerduty.ts +109 -0
- package/src/plugins/manager.mjs +115 -8
- package/src/plugins/shared.mjs +76 -0
- package/src/repair-policy.ts +13 -0
- package/src/reply-context.ts +71 -0
- package/src/reply-executor.ts +55 -0
- package/src/reply-mcp.ts +23 -0
- package/src/runs.ts +14 -16
- package/src/schedule-cli.ts +36 -7
- package/src/scheduled-tasks.ts +33 -0
- package/src/scheduler.ts +22 -4
- package/src/setup.ts +3 -2
- package/src/software-status.ts +5 -5
- package/src/task-cli.ts +3 -3
- package/src/task-executor.ts +9 -6
- package/src/tasks.ts +35 -17
- package/src/telegram-source.ts +94 -0
- package/src/updates/artifact.mjs +16 -0
- package/src/updates/binding.mjs +3 -1
- package/src/updates/control.mjs +4 -4
- package/src/updates/runtime.mjs +5 -2
- package/src/workforce-watch-cli.ts +14 -0
- package/src/workforce-watch.ts +155 -0
- package/templates/agent/AGENTS.md +10 -2
- package/templates/agent/TOOLS.md +6 -0
- package/templates/agent-guidance.md +24 -0
- package/templates/chat-guidance.md +23 -0
- package/templates/failure-review.md +9 -0
- package/templates/maintainer-purpose.md +15 -0
- package/templates/updates.md +2 -2
- package/test/agent-guidance.test.ts +125 -0
- package/test/ai-cli.test.ts +7 -6
- package/test/ai.test.ts +81 -1
- package/test/busy-reply-relay.test.ts +41 -0
- package/test/client-defaults.test.ts +37 -5
- package/test/codex-context.test.ts +5 -2
- package/test/codex-session.test.ts +4 -2
- package/test/config.test.ts +29 -0
- package/test/event-sources.test.ts +4 -0
- package/test/executor.test.ts +11 -1
- package/test/failure.test.ts +256 -0
- package/test/group-owner.test.ts +36 -0
- package/test/host-executor.test.ts +54 -7
- package/test/intake-relay.test.ts +145 -4
- package/test/model-policy.test.ts +69 -0
- package/test/pagerduty.test.ts +104 -0
- package/test/plugin-manager.test.mjs +52 -2
- package/test/relay.test.ts +2 -2
- package/test/repair-policy.test.ts +23 -0
- package/test/reply.test.ts +153 -0
- package/test/runs.test.ts +7 -0
- package/test/schedule-cli.test.ts +10 -2
- package/test/scheduled-tasks.test.ts +43 -0
- package/test/shared-services.test.mjs +98 -0
- package/test/software-status.test.ts +5 -5
- package/test/task-native.test.ts +2 -2
- package/test/tasks.test.ts +14 -6
- package/test/telegram-source.test.ts +75 -0
- package/test/trusted-beta.test.mjs +224 -0
- package/test/updates.test.mjs +35 -3
- package/test/workforce-watch.test.ts +180 -0
package/docs/plugins.md
CHANGED
|
@@ -191,7 +191,8 @@ and monitoring subscriptions alone never grant task execution. See
|
|
|
191
191
|
|
|
192
192
|
V1 remains supported. V2 adds declared generated `secrets`, service `environment`
|
|
193
193
|
(literal strings or declared secret references with literal prefix/suffix),
|
|
194
|
-
`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).
|
|
195
196
|
Cycles, unknown dependencies and host environment interpolation are rejected.
|
|
196
197
|
Secrets persist privately across reinstall and are never included in registry
|
|
197
198
|
responses. Twenty provides a complete v2 backend example.
|
|
@@ -228,3 +229,47 @@ main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). E
|
|
|
228
229
|
Find released packages and the agent-owned registration path in the
|
|
229
230
|
[plugin catalog](plugin-catalog.md). This listing does not change the empty
|
|
230
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.
|
|
242
|
+
|
|
243
|
+
## Existing local folders
|
|
244
|
+
|
|
245
|
+
Use operator-owned read-only folder bindings when a plugin needs files that
|
|
246
|
+
already exist on the host. Keep indexes and writable metadata in the plugin's
|
|
247
|
+
normal volume. This uses Docker bind mounts; it copies no source bytes and
|
|
248
|
+
starts no provider sync. File edits remain with the host's existing tools.
|
|
249
|
+
|
|
250
|
+
Stop the plugin before changing a binding:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
ez plugins stop library
|
|
254
|
+
ez plugins folder-bind library --service library --source /absolute/existing/notes --target /state/libraries/notes/files
|
|
255
|
+
ez plugins folders library
|
|
256
|
+
ez plugins start library
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The target must be a child of a volume declared by that service, without
|
|
260
|
+
colliding with another mount. Sources must be real existing directories outside
|
|
261
|
+
the private tools directory. Missing sources fail instead of creating empty
|
|
262
|
+
folders. Bindings are operator configuration, separate from package snapshots;
|
|
263
|
+
compatible upgrades retain them and incompatible target changes fail validation.
|
|
264
|
+
Use `folder-unbind ID --service NAME --target PATH` while stopped to detach a
|
|
265
|
+
folder. Uninstall retains bindings and volumes. Unbinding reveals any underlying
|
|
266
|
+
volume contents; inspect those before restarting to avoid using stale files.
|
|
267
|
+
Never enable another sync writer for an already synchronized host folder.
|
|
268
|
+
|
|
269
|
+
For Library, create/select the library name first and retain its QMD state while
|
|
270
|
+
binding the host tree at that library's `files` directory. Keep provider bindings
|
|
271
|
+
disabled for that source. Enable the normal shared embedding worker through
|
|
272
|
+
`plugins shared-enable library embeddings`. Verify `library sources`, real search,
|
|
273
|
+
and original readback from the actual executor. Document any differences between
|
|
274
|
+
indexed snapshots and current originals; do not replace Library with private
|
|
275
|
+
QMD runtimes or edit installed Compose/package files to bypass missing support.
|
package/docs/releasing.md
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Use the same checks for maintainer and external changes. Each repository versions
|
|
4
4
|
independently with SemVer: patch for compatible fixes, minor for new capabilities;
|
|
5
5
|
before 1.0, breaking CLI/state changes require a minor bump and migration notes.
|
|
6
|
-
No automatic dependency updates
|
|
6
|
+
No automatic dependency updates or credentials in pull-request CI. The agent
|
|
7
|
+
operates this process under the authorization rules in CONTRIBUTING.md; a
|
|
8
|
+
separate release bot is not required.
|
|
7
9
|
|
|
8
10
|
1. In an isolated release worktree/PR, finalize package version and CHANGELOG.md;
|
|
9
11
|
update plugin manifest version when present. After lockfile changes, copy
|
|
@@ -32,14 +34,20 @@ No automatic dependency updates, release bot or credentials in pull-request CI.
|
|
|
32
34
|
fill package.json repository, homepage and bugs with the actual public URLs.
|
|
33
35
|
Enable GitHub private vulnerability reporting; verify the route. Protect main
|
|
34
36
|
with CI and independent PR review. Maintainers use the same process.
|
|
35
|
-
7. Record independent review and green CI for the final release PR
|
|
36
|
-
maintainer
|
|
37
|
-
|
|
37
|
+
7. Record independent review and green CI for the final release PR. The
|
|
38
|
+
maintainer's release request supplies authorization: do not ask for a second
|
|
39
|
+
approval. Record the prepared commit, tarball SHA-256, third-party obligations
|
|
40
|
+
and known limits. If release is outside the request, report readiness without
|
|
41
|
+
publishing. For an authorized release, merge the release PR and
|
|
38
42
|
verify its tree matches the reviewed source before tagging `v<version>` and
|
|
39
43
|
publishing that tarball:
|
|
40
|
-
`npm publish /absolute/candidate.tgz --access public --tag
|
|
41
|
-
for
|
|
42
|
-
|
|
44
|
+
`npm publish /absolute/candidate.tgz --access public --tag latest --registry https://registry.npmjs.org/`
|
|
45
|
+
for approved beta releases as well: `latest` is the default distribution tag,
|
|
46
|
+
not a claim that a SemVer prerelease is stable.
|
|
47
|
+
For unattended beta publication use the [shared trusted publisher](trusted-publishing.md)
|
|
48
|
+
and its exact-artifact staging/readback contract. Initial package publication
|
|
49
|
+
requires authenticated npm with 2FA before trust can be enrolled; never paste
|
|
50
|
+
tokens into CI or docs.
|
|
43
51
|
8. Create the GitHub release from CHANGELOG.md, attach artifact/checksum, and
|
|
44
52
|
install the registry version on a clean host. Verify metadata and the same
|
|
45
53
|
onboarding path before posting launch copy. Stop rollout on failure; publish
|
|
@@ -53,13 +61,16 @@ credential revocation; do not delete volumes as a routine rollback.
|
|
|
53
61
|
## Beta channel
|
|
54
62
|
|
|
55
63
|
Use SemVer prereleases (`0.1.0-beta.1`), GitHub's prerelease flag and npm's
|
|
56
|
-
`--tag
|
|
64
|
+
`--tag latest` so default installs and the package page advance automatically.
|
|
65
|
+
The version and GitHub release remain prereleases; stable-only update policies
|
|
66
|
+
still exclude them. The legacy npm beta tag is no longer advanced. For this first beta the maintainer
|
|
57
67
|
explicitly deferred real account/reboot acceptance. Keep that limitation in the
|
|
58
68
|
README and release notes. Source/tarball publication is permitted after the
|
|
59
69
|
automated gates; deferred live checks remain required for stable release.
|
|
60
70
|
GitHub repositories use `jdorado`; npm packages use `jc_stack`. Verify
|
|
61
71
|
`npm whoami --registry https://registry.npmjs.org/` returns `jc_stack` before
|
|
62
|
-
|
|
72
|
+
interactive publication. OIDC publication instead requires package-owner trust
|
|
73
|
+
enrollment for the exact caller workflow; `whoami` is not its publication gate. Never infer npm scope ownership from a GitHub login. After publishing,
|
|
63
74
|
read back `npm view @jc_stack/ez-agents@0.1.0-beta.12 name version dist-tags --json`
|
|
64
75
|
(using the release being published), download it with `npm pack`, and verify its
|
|
65
76
|
contents/checksum against the reviewed artifact. Keep the npm artifact and
|
package/docs/repair.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Native repair ownership
|
|
2
|
+
|
|
3
|
+
Every deployed agent is a repairer by default. When an agent finds a core or
|
|
4
|
+
plugin defect, it keeps the context and pursues a tested contribution PR. The
|
|
5
|
+
core injects the same mandate into CLI/native and desktop execution, including
|
|
6
|
+
existing workspaces; it does not replace the agent's mind or implement a repair
|
|
7
|
+
workflow engine. Use native Git/GitHub CLI or the installed GitHub plugin.
|
|
8
|
+
|
|
9
|
+
The agent searches for the same cause, registers a sanitized issue, requests a
|
|
10
|
+
claim, then works in an isolated contribution checkout after the coordinator's
|
|
11
|
+
grant. It resumes the same issue/branch/PR after interruption. The installed
|
|
12
|
+
runtime is never the repair checkout. Missing credentials or coordination remain
|
|
13
|
+
recorded blockers; the default does not invent repository access. Public reports
|
|
14
|
+
must exclude private runtime data and use the security reporting route when needed.
|
|
15
|
+
|
|
16
|
+
One coordinator grants claims sequentially per repository. Assignment alone is
|
|
17
|
+
not a lock. All participating agents must use that coordinator; this convention
|
|
18
|
+
cannot prevent an unrelated public contributor from opening a competing PR.
|
|
19
|
+
The discovering agent remains the repairer, including when its work moves to a
|
|
20
|
+
background task. The coordinator reconciles duplicates and stalled claims. The
|
|
21
|
+
maintainer independently reviews and tests, then merges/publishes only within
|
|
22
|
+
separate owner-approved policies. Start from templates/maintainer-purpose.md.
|
|
23
|
+
|
|
24
|
+
## Disable
|
|
25
|
+
|
|
26
|
+
Set `EZ_REPAIR_ENABLED=false` in the deployment's Docker environment and recreate
|
|
27
|
+
the relay. The resolved setting crosses the host transport and is included in
|
|
28
|
+
every new execution prompt; the default is true and invalid values fail startup.
|
|
29
|
+
This changes the automatic mandate, not filesystem/GitHub permissions, and does
|
|
30
|
+
not cancel an already running task. Explicitly stop active repair work when needed.
|
|
31
|
+
An owner can also disable repairs globally or for a repository in the agent's
|
|
32
|
+
saved USER.md preferences; carry those restrictions into background task context.
|
|
33
|
+
|
|
34
|
+
## Setup boundary
|
|
35
|
+
|
|
36
|
+
The shipped mandate and maintainer purpose do not provision a GitHub account,
|
|
37
|
+
coordinator service or publishing token. Enroll the allowed repositories and
|
|
38
|
+
configure one maintainer execution lane on the owner's host before unattended
|
|
39
|
+
claims. Reuse authenticated GitHub CLI where authorized. Repository push and PR
|
|
40
|
+
permissions are distinct from package-registry publication and protected-branch
|
|
41
|
+
approval. Never put credentials in prompts, issues or test environments.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Responsive channels
|
|
2
|
+
|
|
3
|
+
Ez treats conversational channels as places to answer, clarify and hand off
|
|
4
|
+
work. A simple question uses the current conversation; a small authorized action
|
|
5
|
+
uses its canonical receipt. Substantial work gets a durable task with enough
|
|
6
|
+
context to finish and verify the job. The agent returns to conversation after
|
|
7
|
+
the handoff is saved, instead of waiting for the worker. This is agent guidance,
|
|
8
|
+
not a keyword classifier, automatic acknowledgement, or latency guarantee.
|
|
9
|
+
|
|
10
|
+
New Codex agents use Sol / medium for chat. Scheduled work defaults independently
|
|
11
|
+
to Terra / high; the agent can choose another model and effort for complex work.
|
|
12
|
+
`ezenciel-agents-schedule create --now --text-file FILE --model MODEL --effort high`
|
|
13
|
+
uses the existing scheduler (include `--name` for a useful task label). Busy owner
|
|
14
|
+
reply sessions expose the same independent model/effort choice through `defer`.
|
|
15
|
+
Its retry returns the first saved schedule; changing arguments does not revise
|
|
16
|
+
an accepted job. `xhigh` is available only for Luna; other models remain capped at high.
|
|
17
|
+
|
|
18
|
+
A handoff includes the objective, relevant context and paths, constraints,
|
|
19
|
+
authorized actions, acceptance checks and delivery destination. Background
|
|
20
|
+
sessions own verification and final delivery, and may use native subagents.
|
|
21
|
+
One writer per workspace still applies. Shared external resources require
|
|
22
|
+
coordination even when task directories differ. Status must distinguish a saved
|
|
23
|
+
schedule from actual execution and a verified result from a process exit.
|
|
24
|
+
|
|
25
|
+
The package loads `templates/chat-guidance.md` at each turn for CLI, desktop,
|
|
26
|
+
busy owner replies and approved plugin messaging tasks. Upgrades refresh this
|
|
27
|
+
behavior without rewriting the agent's personal files. Existing model choices
|
|
28
|
+
remain pinned; an upgrade adds Responsive chat as an available selection.
|
|
29
|
+
|
|
30
|
+
## Channel and authority boundaries
|
|
31
|
+
|
|
32
|
+
Telegram owner conversations can schedule work under the owner's authority.
|
|
33
|
+
The existing restricted busy-reply session keeps Codex chat available while a
|
|
34
|
+
writer is active. Other executors retain their existing concurrency behavior.
|
|
35
|
+
|
|
36
|
+
WhatsApp and other plugin contacts use the approved messaging task's isolated
|
|
37
|
+
context and tools. They receive the conversational guidance and Sol / medium
|
|
38
|
+
selection, but cannot invoke owner schedules, shell tools or native subagents.
|
|
39
|
+
They report work outside their capabilities to the owner; that report is not
|
|
40
|
+
an instruction or permission to execute. Full delegation from a plugin contact
|
|
41
|
+
needs an explicitly scoped worker capability and return route; this update does
|
|
42
|
+
not grant one. The plugin name alone never confers owner authority.
|
|
43
|
+
|
|
44
|
+
An application using `channelBackendUrl` owns its conversation, model and job
|
|
45
|
+
lifecycle. The relay does not inject prompts or override the app's model. Such
|
|
46
|
+
backends (including AI Fit) must adopt the same handoff policy in their own
|
|
47
|
+
runtime to benefit. Reuse their canonical job system; do not create a second
|
|
48
|
+
agent in the transport. Telegram polling and app-side queue waits still count
|
|
49
|
+
toward user-visible latency.
|
|
50
|
+
|
|
51
|
+
## Verification
|
|
52
|
+
|
|
53
|
+
Tests cover independent worker settings, preserved selections across upgrades,
|
|
54
|
+
idempotent handoffs, invalid settings, revocation and restricted tool boundaries.
|
|
55
|
+
Existing scheduler/host tests cover a conversational reply while work remains
|
|
56
|
+
active. Measure time to the first useful reply and verified task completion
|
|
57
|
+
separately on the deployed provider before claiming a performance improvement.
|
package/docs/scheduling.md
CHANGED
|
@@ -32,6 +32,16 @@ the host changes zones. Nonexistent DST wall times are skipped; repeated wall
|
|
|
32
32
|
times fire once, at the earlier instant. Search is bounded to eight years.
|
|
33
33
|
Public-holiday calendars and arbitrary RRULE syntax are not implemented.
|
|
34
34
|
|
|
35
|
+
New tasks, including work deferred by a busy reply session, default to Codex
|
|
36
|
+
`gpt-5.6-terra` with `high` reasoning independently of the creating chat.
|
|
37
|
+
New chats use the separate Sol/medium preset. Busy reply `defer` accepts optional
|
|
38
|
+
`model` and `effort` fields; retries preserve the first saved task choice.
|
|
39
|
+
Use `--cli`, `--model`, and `--effort` to specify another choice. `xhigh` is
|
|
40
|
+
available only with Codex `gpt-5.6-luna`; every other model remains capped at
|
|
41
|
+
`high`. Non-Codex adapters inherit native effort when unset. Editing preserves the existing AI
|
|
42
|
+
choice unless those flags override it. Stored choices are checked again at
|
|
43
|
+
launch, including schedules saved before a policy change.
|
|
44
|
+
|
|
35
45
|
## Execution and authority
|
|
36
46
|
|
|
37
47
|
The relay checks due work once per second. Each occurrence enters the durable
|
|
@@ -41,7 +51,7 @@ Instructions must include any needed context or source paths; full chat history
|
|
|
41
51
|
is not copied. Task folders remain for inspection and artifact delivery.
|
|
42
52
|
|
|
43
53
|
One writer runs per task directory. Up to four background tasks can run alongside
|
|
44
|
-
the
|
|
54
|
+
the main conversation. When a Codex owner message arrives while work is busy, a separate restricted session reads recent messages and run progress and answers through the normal outbox. It can queue requested work through the scheduler, but cannot run shell commands, access plugins, or edit the agent workspace. Only one reply session runs at a time and it releases its slot after a 60-second reply deadline; this deadline does not apply to writer jobs. Its context is a bounded snapshot, not a shared native transcript. Delivered parallel replies are included as historical context in the next normal conversation turn. Codex 0.153.4 and 0.154.0 are supported for this restricted adapter. Other versions fail closed pending tool-surface validation. A recurring schedule has at most one pending
|
|
45
55
|
or active occurrence. Agents should delegate long work with `create --now`, return
|
|
46
56
|
to chat, and inspect `runs` or task progress when asked. Native subagents can be
|
|
47
57
|
used inside the worker. Sharing provider profiles does not make concurrent CRM,
|
|
@@ -70,8 +80,8 @@ The foreground chat still uses `codex exec`. That invocation exits after one
|
|
|
70
80
|
requested turn even if a goal is active, so delegate persistent work to the
|
|
71
81
|
scheduler. Desktop and other executor goal lifecycles need separate validation.
|
|
72
82
|
|
|
73
|
-
The CLI binds jobs to the paired owner and
|
|
74
|
-
work retains that
|
|
83
|
+
The CLI binds jobs to the paired owner and the task AI choice. Queued/scheduled
|
|
84
|
+
work retains that choice after the chat switches AI. Revoking/re-pairing an
|
|
75
85
|
owner invalidates their old schedules, including re-pairing the same Telegram ID.
|
|
76
86
|
External event turns cannot use the scheduling CLI. Credentials still pass only
|
|
77
87
|
through the existing whitelist and installed host binding.
|
|
@@ -88,7 +98,7 @@ queued occurrence; already-running work continues until explicitly cancelled.
|
|
|
88
98
|
`/stop` stops all active work; `cancel RUN_ID` stops one background task. `/cancel`
|
|
89
99
|
clears queued work. Pause/remove a recurring schedule to prevent future runs.
|
|
90
100
|
Stopping the relay also stops its workers. A crashed or interrupted execution is
|
|
91
|
-
not automatically replayed. Runs found active at startup are marked failed with
|
|
101
|
+
not automatically replayed. Status labels failed runs as history and shows recent reasons; new failures retain their exit code or interruption cause. Typing indicators stop after 30 seconds even when work continues. Runs found active at startup are marked failed with
|
|
92
102
|
`interrupted: true`; their schedule revision stays held until the agent inspects
|
|
93
103
|
the evidence and explicitly edits the schedule. Inspect the task's files, native session and delivery
|
|
94
104
|
receipts before deciding whether to resume. A clock cannot reconstruct an
|
|
@@ -125,3 +135,21 @@ minutes. Verify `finished.txt` and exactly one completion in Telegram. Separatel
|
|
|
125
135
|
exercise cancellation, downtime catch-up and an explicitly requested native goal
|
|
126
136
|
that needs more than one turn. Synthetic provider evidence does not prove real
|
|
127
137
|
Telegram delivery, and a sleep test does not prove native goal persistence.
|
|
138
|
+
|
|
139
|
+
Busy-chat regression probe (real Codex, synthetic Telegram):
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
pnpm exec tsx scripts/smoke-busy-reply.ts --transport
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The probe holds a writer on a shared workspace, asks an owner question through
|
|
146
|
+
the relay and host transport, and requires the restricted reply to complete
|
|
147
|
+
while the writer remains active. It sends no real Telegram messages.
|
|
148
|
+
|
|
149
|
+
## Optional failure review
|
|
150
|
+
|
|
151
|
+
Create a normal recurring schedule with `--every-seconds 900 --when unreviewed-failures --text-file templates/failure-review.md`. The condition advances empty occurrences without launching an executor. It considers only failures belonging to the paired owner. No separate monitor or automatic retry is introduced.
|
|
152
|
+
|
|
153
|
+
`failures [--all] [--limit N]` returns failedAt, reason, exit code, native session, captured error and runtime versions. Capture keeps at most 4 KiB of redacted stderr; historical failures are not backfilled. `run RUN_ID` reads an owned run. `review RUN_ID --failed-at ISO --status resolved|attention --diagnosis TEXT --recovery TEXT --outcome TEXT` records the investigation without rewriting execution history. A stale timestamp is rejected; a later failure needs a new review. Restricted reply, external and isolated-task callers cannot review failures. An attention review is handed off, not repeatedly relaunched; another new failure wakes the next review.
|
|
154
|
+
|
|
155
|
+
The prompt controls diagnosis, authorized recovery and quiet notification behavior. Inspect prior effects and receipts before retrying anything. A failed review run itself remains visible as a new failure for the next occurrence.
|
|
@@ -33,7 +33,7 @@ Infer the complete job from ordinary language:
|
|
|
33
33
|
|
|
34
34
|
Apply the required core confirmation to the concrete proposal, not an extra
|
|
35
35
|
questionnaire. Use the owner's existing contact, purpose and disclosure limits.
|
|
36
|
-
|
|
36
|
+
For an ongoing incoming-only conversation, use `--until-revoked`; finite tasks remain bounded. Explain the expiry only
|
|
37
37
|
when it matters to that proposed job; never silently expand or renew permission.
|
|
38
38
|
|
|
39
39
|
## Three capture modes, separate reply authority
|
|
@@ -83,9 +83,17 @@ registered source, canonical contact, purpose, explicitly shareable context file
|
|
|
83
83
|
and expiry. No need to invent a booking objective: “conversational replies to
|
|
84
84
|
this contact, no private disclosures or commitments” is a legitimate purpose.
|
|
85
85
|
If no private facts may be shared, say so in the context file; do not include
|
|
86
|
-
owner memory.
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
owner memory. Finite jobs support at most 72 hours. For an ongoing conversation requested by
|
|
87
|
+
the owner, add `--incoming-only --until-revoked`. This authorizes that exact
|
|
88
|
+
conversation until owner revocation, without a total reply quota. Do not silently
|
|
89
|
+
convert a finite job into an ongoing permission.
|
|
90
|
+
|
|
91
|
+
For Telegram groups, the relay registers source `telegram` automatically when
|
|
92
|
+
paired. Use the exact negative group ID from discovery, never its display name.
|
|
93
|
+
Keep the shared context limited to what every group member may know. All human
|
|
94
|
+
members of that approved group may converse; this does not grant owner tools.
|
|
95
|
+
The group runs with the existing restricted messaging runner, and its notes are
|
|
96
|
+
separate from private PA memory. Group text is supported; media is not yet.
|
|
89
97
|
|
|
90
98
|
The core presents the exact proposal for owner confirmation. Ordinary messages
|
|
91
99
|
inside that grant need no repeated confirmations. Incoming-only grants create
|
package/docs/setup.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Agent-led setup
|
|
2
2
|
|
|
3
|
+
## A group as owner
|
|
4
|
+
|
|
5
|
+
An installer can explicitly approve one Telegram group as the agent's owner.
|
|
6
|
+
Every human member in that group then has owner access, including settings,
|
|
7
|
+
approvals and scheduling. The conversation and replies are shared in that group.
|
|
8
|
+
New members inherit this access. Bots and anonymous sender-chat posts are ignored.
|
|
9
|
+
|
|
10
|
+
Add the bot to the intended group and send it a message addressed to its username.
|
|
11
|
+
`ezenciel-agents-owner status` shows the pending group title and negative chat ID;
|
|
12
|
+
verify the exact group with the installer, then run
|
|
13
|
+
`ezenciel-agents-owner approve-group <negative-chat-id>`. Pairing never happens
|
|
14
|
+
automatically. The existing `approve <user-id>` command approves DMs only.
|
|
15
|
+
An existing owner must be explicitly revoked before replacement; use a fresh
|
|
16
|
+
deployment when its existing workspace contains information unsuitable for the group.
|
|
17
|
+
|
|
18
|
+
Make the bot a group admin so Telegram delivers ordinary member messages and
|
|
19
|
+
allows membership verification for approval and control buttons. Group ownership only authorizes
|
|
20
|
+
the exact approved chat, not other groups or members' private DMs. Telegram group
|
|
21
|
+
migration to a new chat ID requires a new explicit binding. Verify a real group
|
|
22
|
+
reply before considering setup complete. All other groups retain their existing
|
|
23
|
+
restricted conversation-grant behavior.
|
|
24
|
+
|
|
3
25
|
Ez supports two independent, composable uses: an autonomous Telegram agent and
|
|
4
26
|
workspace-scoped plugins called by your existing local CLI/GUI executor.
|
|
5
27
|
For CLI-only requests, follow [standalone setup](standalone-cli.md): no Telegram
|
|
@@ -30,6 +52,27 @@ owner request for standalone plugin development is a separate workflow.
|
|
|
30
52
|
|
|
31
53
|
## Defaults and host prerequisites
|
|
32
54
|
|
|
55
|
+
New agents using `codex` or `codex-gui` start with `gpt-5.6-sol` and `medium`
|
|
56
|
+
reasoning, including when initialized with `ezenciel-agents-setup init`. This
|
|
57
|
+
Ez default takes precedence over discovered host client defaults. Saved agent
|
|
58
|
+
selections permitted by the current policy are preserved; use the AI settings to choose another model or effort.
|
|
59
|
+
Ez accepts `xhigh` only for `gpt-5.6-luna`; every other model rejects explicit
|
|
60
|
+
reasoning above `high` at selection and execution, including old saved or queued choices.
|
|
61
|
+
Unset Codex model/effort resolves to
|
|
62
|
+
Terra/high at launch. This governs Ez-managed launches; it is not an account-wide
|
|
63
|
+
limit on independently launched native clients or executor-created native subagents.
|
|
64
|
+
Other adapters inherit their native effort when none is selected in Ez. That
|
|
65
|
+
inherited configuration is not capped by Ez; explicit above-high Ez selections
|
|
66
|
+
are rejected unless they are Codex Luna/xhigh. Conversation presets pin Sol/medium; the lower-level
|
|
67
|
+
Codex fallback remains Terra/high for work without an explicit choice.
|
|
68
|
+
|
|
69
|
+
New scheduled and one-off background tasks default to Codex Terra/high independently
|
|
70
|
+
of the creating chat. Use scheduler `--cli`, `--model`, and `--effort` flags for
|
|
71
|
+
explicit overrides. Editing a schedule preserves its settings unless overridden.
|
|
72
|
+
Restricted messaging tasks use Sol/medium while retaining their approved tool
|
|
73
|
+
and context boundaries. Upgrades add Responsive chat to saved choices without
|
|
74
|
+
replacing the selected/default preset. See [responsive channels](responsive-channels.md).
|
|
75
|
+
|
|
33
76
|
Use the existing owner's host account. Unless a layout was supplied, use
|
|
34
77
|
`${XDG_DATA_HOME:-$HOME/.local/share}/ez/packages/<version>/` for extracted main
|
|
35
78
|
packages and `${XDG_DATA_HOME:-$HOME/.local/share}/ez/agents/` for private deployments.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Verified beta publication
|
|
2
|
+
|
|
3
|
+
The Mac prepares and independently tests the release. GitHub-hosted Actions
|
|
4
|
+
publishes the exact approved tarball using npm OIDC. The shared implementation
|
|
5
|
+
is `.github/workflows/npm-beta-shared.yml` in this repository; each package has a
|
|
6
|
+
small manually dispatched `publish-beta.yml` caller. This setup does not grant
|
|
7
|
+
release authority or establish npm trust automatically.
|
|
8
|
+
|
|
9
|
+
## Enroll a repository once
|
|
10
|
+
|
|
11
|
+
1. Verify the source is public and explicitly registered in the current
|
|
12
|
+
[public catalog](plugin-catalog.md), or is core itself. Registration does not
|
|
13
|
+
prove a registry release exists. Excluded or private repositories cannot use
|
|
14
|
+
this publisher.
|
|
15
|
+
2. Review and merge the shared publisher first. Generate the caller using its
|
|
16
|
+
full immutable commit SHA and the repository's required CI check names:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
node scripts/generate-publish-caller.mjs jdorado/ez-whatsapp \
|
|
20
|
+
@jc_stack/ez-whatsapp FULL_SHARED_COMMIT_SHA \
|
|
21
|
+
'["test (ubuntu-latest, 22)","test (ubuntu-latest, 24)","test (macos-latest, 22)","test (macos-latest, 24)","docker"]' > publish-beta.yml
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Put that file in the plugin's `.github/workflows/` through its own reviewed
|
|
25
|
+
PR. Inspect the actual CI names; the example does not establish the policy.
|
|
26
|
+
Keep the reusable workflow reference and `publisher-sha` on the same reviewed
|
|
27
|
+
commit. Core uses a local reusable workflow at the dispatch commit. The
|
|
28
|
+
generator writes stdout only; it never grants repository scope or edits npm.
|
|
29
|
+
3. The npm package owner authenticates separately and enrolls the exact caller
|
|
30
|
+
repository and filename `publish-beta.yml` as a trusted publisher. Enable
|
|
31
|
+
**direct publication** explicitly; new trust configurations can default to
|
|
32
|
+
staged publication only. If an environment is configured on npm, add that
|
|
33
|
+
exact environment to the shared publishing job through review before use.
|
|
34
|
+
This workflow currently uses no environment.
|
|
35
|
+
4. Verify enrollment through npm settings or `npm trust list PACKAGE`. npm
|
|
36
|
+
validates the **calling** workflow for reusable workflows. Both caller and
|
|
37
|
+
publishing job need `id-token: write`; test/validation jobs do not receive it. GitHub requires `contents: write`
|
|
38
|
+
to read unpublished draft assets: only the validation job receives that
|
|
39
|
+
capability and makes GET requests only. The separate OIDC job has
|
|
40
|
+
`contents: read`. No package code or lifecycle scripts run in validation.
|
|
41
|
+
Do not add `NODE_AUTH_TOKEN`, npm tokens, or private profiles to these jobs.
|
|
42
|
+
|
|
43
|
+
An npm package must already exist before trust enrollment. If a registered
|
|
44
|
+
plugin has no registry package, the owner must perform a real, approved initial
|
|
45
|
+
beta publication using authenticated npm, with all release checks and exact
|
|
46
|
+
artifact readback. Then enroll trust. Do not create a dummy release to test
|
|
47
|
+
login. A missing GitHub release likewise remains missing until actually created
|
|
48
|
+
and read back; a catalog link or workflow PR is not publication evidence.
|
|
49
|
+
|
|
50
|
+
Current npm requirements and enrollment fields are documented in
|
|
51
|
+
[npm trusted publishers](https://docs.npmjs.com/trusted-publishers/) and
|
|
52
|
+
[npm trust](https://docs.npmjs.com/cli/v11/commands/npm-trust/).
|
|
53
|
+
The workflow uses Node 24 and npm 11.19.1 on GitHub-hosted Ubuntu runners.
|
|
54
|
+
|
|
55
|
+
## Prepare and dispatch one beta
|
|
56
|
+
|
|
57
|
+
Follow [releasing](releasing.md), including isolated Mac tests, packed artifact
|
|
58
|
+
inspection, independent review, required CI and authorized merge. The source
|
|
59
|
+
must be the exact current `main` commit; after a merge, verify that its tree
|
|
60
|
+
matches the tested source and renew invalidated evidence. Wait for that commit's
|
|
61
|
+
CI from `.github/workflows/ci.yml`, triggered by a push on `main`. The caller's reviewed list of required checks is a fail-closed minimum;
|
|
62
|
+
update it when repository policy adds checks. The validator selects the newest
|
|
63
|
+
main-push CI run for that source before checking success, then requires the named
|
|
64
|
+
jobs from its latest attempt. Tag, PR and other workflow runs cannot shadow it;
|
|
65
|
+
failed, pending or incomplete main CI cannot fall back to an older success.
|
|
66
|
+
|
|
67
|
+
Create the `vVERSION` tag at that exact source commit and a **draft prerelease**
|
|
68
|
+
with these assets, using native `gh release create --draft --prerelease` and
|
|
69
|
+
`gh release upload` under existing release authority:
|
|
70
|
+
|
|
71
|
+
- `candidate.tgz`: the exact Mac-tested bytes from `npm pack --ignore-scripts`.
|
|
72
|
+
Do not rebuild it on Actions.
|
|
73
|
+
- `release-receipt.json`: a sanitized record with this shape:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"repository": "jdorado/ez-agents",
|
|
78
|
+
"package": "@jc_stack/ez-agents",
|
|
79
|
+
"version": "0.1.0-beta.14",
|
|
80
|
+
"sourceSha": "FULL_TESTED_MAIN_COMMIT_SHA",
|
|
81
|
+
"sha256": "SHA256_OF_CANDIDATE_TGZ",
|
|
82
|
+
"independentReviewUrl": "https://github.com/jdorado/ez-agents/pull/PR_NUMBER#issuecomment-ID",
|
|
83
|
+
"testEvidenceUrls": ["https://github.com/jdorado/ez-agents/actions/runs/RUN_ID"]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The maintainer verifies those evidence links substantiate independent final-diff
|
|
88
|
+
review, artifact tests and accepted beta limitations before dispatch. The receipt
|
|
89
|
+
binds that attestation to the commit and digest; a syntactically valid URL alone
|
|
90
|
+
cannot prove review quality or release authority.
|
|
91
|
+
|
|
92
|
+
Read the draft's numeric `id` with `gh api repos/OWNER/REPO/releases` (the
|
|
93
|
+
release-by-tag API only returns published releases). Dispatch `publish-beta.yml`
|
|
94
|
+
on `main` with `release-id`, `version`, `source-sha` and
|
|
95
|
+
`artifact-sha256`. Copy the digest from the independently verified Mac receipt,
|
|
96
|
+
not an unreviewed replacement release asset. The validator checks current public
|
|
97
|
+
scope, source/tag identity, required GitHub Actions checks, receipt identity,
|
|
98
|
+
package metadata and tarball hash. It transfers the validated bytes using an
|
|
99
|
+
immutable Actions artifact ID. A fresh job revalidates before publication and
|
|
100
|
+
runs npm from a clean directory without package lifecycle scripts.
|
|
101
|
+
|
|
102
|
+
Only `X.Y.Z-beta.N` versions are supported. Publish to npm `latest` so the
|
|
103
|
+
package page and default installs show the newest approved release. Manifests
|
|
104
|
+
must use `publishConfig.tag: "latest"` (or omit the tag). The version remains a
|
|
105
|
+
SemVer prerelease and the GitHub release remains a prerelease. Private
|
|
106
|
+
packages, wrong package/repository identities and stable versions fail before
|
|
107
|
+
publication. No npm login smoke publication or stable-version release occurs.
|
|
108
|
+
|
|
109
|
+
## Readback, failure and release completion
|
|
110
|
+
|
|
111
|
+
The publisher reads registry metadata, checks that `latest` identifies the released version and downloads the
|
|
112
|
+
published tarball to compare its SHA-256. Preserve the workflow's readback receipt, run URL and source/artifact
|
|
113
|
+
identity on the release PR. A failed command after the publish call may mean npm
|
|
114
|
+
accepted it: inspect registry state first. A rerun may verify an existing exact
|
|
115
|
+
version; if the version is absent it refuses a second write. Reconcile first,
|
|
116
|
+
then create a fresh authorized dispatch if appropriate. Never repeat or overwrite that version or silently repair tags.
|
|
117
|
+
Missing trust or registry access is an external dependency, not a reason to use
|
|
118
|
+
a token workaround.
|
|
119
|
+
|
|
120
|
+
After successful registry readback, finish the GitHub prerelease with the tested
|
|
121
|
+
artifact/checksum and verify its public availability. Perform the clean-host
|
|
122
|
+
installation and runtime/provider checks required by the package's release
|
|
123
|
+
rules. Actions success proves registry delivery only; it does not prove a
|
|
124
|
+
running agent was upgraded. Respect each installation's saved update policy.
|
|
125
|
+
|
|
126
|
+
## Migration from the legacy beta tag
|
|
127
|
+
|
|
128
|
+
Existing plugin callers are SHA-pinned: regenerate each caller against the merged
|
|
129
|
+
shared-publisher revision and update its package publishConfig together through
|
|
130
|
+
review. Old pins retain the old behavior. Do not mutate an already staged or
|
|
131
|
+
published artifact; prepare a new version when package metadata changes.
|
|
132
|
+
|
|
133
|
+
The publisher uses one native npm publish operation with OIDC and `--tag latest`.
|
|
134
|
+
It does not synchronize the legacy `beta` tag: npm trusted publishing does not
|
|
135
|
+
support standalone dist-tag changes. No extra registry token is needed. Ez beta
|
|
136
|
+
update discovery considers both latest and legacy beta during migration; stable-only
|
|
137
|
+
policies select non-deprecated stable versions and cannot automatically install a
|
|
138
|
+
prerelease. Older installed updaters still following only beta require an explicit
|
|
139
|
+
exact-version update to a core release containing this discovery change. Existing
|
|
140
|
+
registry versions/tags are not changed by merging the publisher.
|
package/docs/upgrades.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Available in this beta. Earlier main upgrade/rollback VM QA passed; final-release
|
|
4
4
|
fresh-host/reboot and live plugin upgrade acceptance remain pending. npm
|
|
5
|
-
publication is not required to test this feature.
|
|
6
|
-
automatic channel
|
|
5
|
+
publication is not required to test this feature. The beta channel is the default
|
|
6
|
+
automatic channel for core and plugins without a saved policy. Existing explicit
|
|
7
|
+
stable or manual policies are preserved. The owner may select either per target.
|
|
7
8
|
The main target and installed plugins version independently.
|
|
8
9
|
|
|
9
10
|
The agent owns release review, policy decisions and communication. The host
|
|
@@ -109,8 +110,8 @@ live. A healthy container alone does not prove a Telegram or plugin reply.
|
|
|
109
110
|
|
|
110
111
|
```sh
|
|
111
112
|
ez updates check
|
|
112
|
-
ez updates policy main # defaults: automatic,
|
|
113
|
-
ez updates policy whatsapp
|
|
113
|
+
ez updates policy main # defaults: automatic, beta
|
|
114
|
+
ez updates policy whatsapp stable # opt into stable-only updates
|
|
114
115
|
ez updates policy main manual # disable unattended upgrades
|
|
115
116
|
ez updates prepare main --version 0.1.0-beta.4
|
|
116
117
|
# Or a local candidate, independently of npm:
|
|
@@ -191,3 +192,22 @@ changes also need supervisor restart and requesting-process-exit tests. Run
|
|
|
191
192
|
`node docker/upgrade-smoke.mjs` with a local `EZ_WHATSAPP_SOURCE` containing the
|
|
192
193
|
WhatsApp fixture. The smoke uses synthetic transport only. VM installation,
|
|
193
194
|
agent-led upgrades, restart and real account acceptance remain separate QA gates.
|
|
195
|
+
|
|
196
|
+
Beta policy discovers the newer of npm latest and the legacy beta tag. Stable-only
|
|
197
|
+
policy selects non-deprecated stable versions, even when latest is a prerelease.
|
|
198
|
+
No eligible version is reported as available:null with newer:false. Older installed
|
|
199
|
+
updaters need an exact-version core update to adopt this discovery behavior.
|
|
200
|
+
|
|
201
|
+
## Shared agent guidance
|
|
202
|
+
|
|
203
|
+
Ez includes `templates/agent-guidance.md` from the running package in every
|
|
204
|
+
owner-worker prompt, including resumed CLI and desktop conversations and scheduled
|
|
205
|
+
owner work. After the runtime upgrades, the next turn receives the new guidance.
|
|
206
|
+
An already running turn keeps its original prompt. Restricted contact tasks and
|
|
207
|
+
reply-only workers retain their separate, bounded instructions.
|
|
208
|
+
|
|
209
|
+
Keep general operating defaults in this package-owned file. Keep agent purpose,
|
|
210
|
+
preferences and local conventions in the workspace's `AGENTS.md`, `SOUL.md`,
|
|
211
|
+
`USER.md` and memory files; upgrades preserve them. Shared guidance does not
|
|
212
|
+
grant permissions, and explicit owner instructions take precedence over its
|
|
213
|
+
defaults within existing execution permissions.
|