@jc_stack/ez-agents 0.1.0-beta.13 → 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.
Files changed (101) hide show
  1. package/.dockerignore +3 -0
  2. package/.env.example +15 -0
  3. package/AGENTS.md +6 -3
  4. package/CHANGELOG.md +49 -0
  5. package/CONTRIBUTING.md +34 -4
  6. package/README.md +3 -0
  7. package/compose.yaml +8 -1
  8. package/docker/run.ts +1 -1
  9. package/docs/architecture/ai-selection.md +8 -0
  10. package/docs/architecture/authority-boundaries.md +24 -1
  11. package/docs/architecture/telegram-intake.md +1 -1
  12. package/docs/docker-runtime.md +35 -0
  13. package/docs/host-service.md +19 -0
  14. package/docs/pagerduty.md +42 -0
  15. package/docs/plugin-catalog.md +27 -10
  16. package/docs/plugin-contributions.md +9 -0
  17. package/docs/plugins.md +12 -1
  18. package/docs/releasing.md +20 -9
  19. package/docs/repair.md +41 -0
  20. package/docs/scheduling.md +30 -4
  21. package/docs/selective-monitoring.md +12 -4
  22. package/docs/setup.md +39 -0
  23. package/docs/trusted-publishing.md +140 -0
  24. package/docs/upgrades.md +24 -4
  25. package/package.json +6 -3
  26. package/scripts/generate-publish-caller.mjs +60 -0
  27. package/scripts/smoke-busy-reply.ts +58 -0
  28. package/scripts/trusted-beta.mjs +289 -0
  29. package/src/agent-guidance.ts +5 -0
  30. package/src/ai-cli.ts +2 -1
  31. package/src/ai.ts +15 -5
  32. package/src/client-defaults.ts +29 -13
  33. package/src/codex-session.ts +4 -2
  34. package/src/config.ts +29 -1
  35. package/src/control-state.ts +24 -7
  36. package/src/desktop-bridge.ts +8 -1
  37. package/src/event-sources.ts +2 -1
  38. package/src/execution-authority.ts +2 -1
  39. package/src/executor.ts +31 -6
  40. package/src/failure.ts +32 -0
  41. package/src/host-executor.ts +22 -13
  42. package/src/identity.ts +8 -3
  43. package/src/inbox.ts +7 -3
  44. package/src/index.ts +207 -79
  45. package/src/install-tools.mjs +2 -2
  46. package/src/menu.ts +6 -4
  47. package/src/model-policy.ts +15 -0
  48. package/src/owner.ts +3 -3
  49. package/src/pagerduty.ts +109 -0
  50. package/src/plugins/manager.mjs +47 -8
  51. package/src/plugins/shared.mjs +76 -0
  52. package/src/repair-policy.ts +13 -0
  53. package/src/reply-context.ts +67 -0
  54. package/src/reply-executor.ts +54 -0
  55. package/src/reply-mcp.ts +23 -0
  56. package/src/runs.ts +15 -4
  57. package/src/schedule-cli.ts +36 -7
  58. package/src/scheduler.ts +12 -3
  59. package/src/setup.ts +2 -1
  60. package/src/software-status.ts +5 -5
  61. package/src/task-cli.ts +3 -3
  62. package/src/task-executor.ts +7 -5
  63. package/src/tasks.ts +35 -17
  64. package/src/telegram-source.ts +94 -0
  65. package/src/updates/artifact.mjs +16 -0
  66. package/src/updates/binding.mjs +3 -1
  67. package/src/updates/control.mjs +4 -4
  68. package/src/updates/runtime.mjs +3 -1
  69. package/templates/agent/AGENTS.md +10 -2
  70. package/templates/agent/TOOLS.md +6 -0
  71. package/templates/agent-guidance.md +13 -0
  72. package/templates/failure-review.md +9 -0
  73. package/templates/maintainer-purpose.md +15 -0
  74. package/templates/updates.md +2 -2
  75. package/test/agent-guidance.test.ts +110 -0
  76. package/test/ai-cli.test.ts +7 -6
  77. package/test/ai.test.ts +41 -0
  78. package/test/busy-reply-relay.test.ts +41 -0
  79. package/test/client-defaults.test.ts +37 -5
  80. package/test/codex-context.test.ts +5 -2
  81. package/test/codex-session.test.ts +4 -2
  82. package/test/config.test.ts +29 -0
  83. package/test/executor.test.ts +11 -1
  84. package/test/failure.test.ts +250 -0
  85. package/test/group-owner.test.ts +36 -0
  86. package/test/host-executor.test.ts +38 -7
  87. package/test/intake-relay.test.ts +141 -4
  88. package/test/model-policy.test.ts +61 -0
  89. package/test/pagerduty.test.ts +104 -0
  90. package/test/plugin-manager.test.mjs +3 -2
  91. package/test/relay.test.ts +2 -2
  92. package/test/repair-policy.test.ts +23 -0
  93. package/test/reply.test.ts +131 -0
  94. package/test/schedule-cli.test.ts +8 -2
  95. package/test/shared-services.test.mjs +98 -0
  96. package/test/software-status.test.ts +5 -5
  97. package/test/task-native.test.ts +2 -2
  98. package/test/tasks.test.ts +14 -6
  99. package/test/telegram-source.test.ts +75 -0
  100. package/test/trusted-beta.test.mjs +224 -0
  101. package/test/updates.test.mjs +35 -3
package/.dockerignore CHANGED
@@ -23,3 +23,6 @@
23
23
  !scripts/release-check.mjs
24
24
  !scripts/stage-qa.mjs
25
25
  !default-plugins.json
26
+ !scripts/trusted-beta.mjs
27
+ !scripts/generate-publish-caller.mjs
28
+ !scripts/smoke-busy-reply.ts
package/.env.example CHANGED
@@ -24,3 +24,18 @@ EZ_EXECUTOR_CLI=agy
24
24
  # Optional: OpenRouter API key for OpenCode CLI (Nemotron 3.5 Lightning)
25
25
  # OPENROUTER_API_KEY=
26
26
  # OPENCODE_MODEL=openrouter/nvidia/nemotron-3.5-lightning
27
+
28
+ # Interactive Codex CLI context limit; native compaction preserves the session.
29
+ EZ_CODEX_AUTO_COMPACT_TOKENS=64000
30
+
31
+ # Automatic core/plugin repair mandate. Set in deployment docker.env for Compose.
32
+ # Does not grant GitHub access, merge or publication permissions.
33
+ EZ_REPAIR_ENABLED=true
34
+
35
+ # Optional PagerDuty incident paging for critical Stocks outages. Put the routing
36
+ # key only in the private relay.env file when running Docker; place the other
37
+ # settings in docker.env so Compose passes them to the relay.
38
+ # PAGERDUTY_ROUTING_KEY=
39
+ # EZ_PAGERDUTY_STOCKS_HEALTH_URL=http://10.97.0.1:3006/health/critical
40
+ # EZ_PAGERDUTY_POLL_SECONDS=30
41
+ # EZ_PAGERDUTY_FAILURE_THRESHOLD=3
package/AGENTS.md CHANGED
@@ -66,14 +66,14 @@ This package will be published as an open-source, lightweight Telegram-to-CLI re
66
66
  - Main-conversation jobs queue sequentially in `RunStore`. Scheduled/background work uses separate task directories and native CLI sessions (up to four alongside chat). Never share a mutable task directory. Delegation decisions and goal persistence belong to the agent/executor; there is no automatic planner or canned chat ACK. Production executor runs have no wall-clock timeout; cancellation is explicit.
67
67
 
68
68
  ## 7. Fail-Closed Authority (Channel Access ≠ Execution)
69
- - Incoming messages from unapproved senders must **never** spawn the executor. First DM registers an unapproved pairing request, then stops.
70
- - Group messages or unknown DMs fail silently.
69
+ - Incoming messages outside the approved owner binding must **never** spawn the executor. A first DM or group message records a pending request only. Explicitly approved owner groups grant owner access to all human members in that exact chat; bots and anonymous posts are ignored.
70
+ - Unapproved group messages from other senders and unknown DMs fail silently. Approved group text uses the existing conversation grant and restricted task runner. Paired-owner group text is discovery routed to the owner's private chat; it grants no group reply authority.
71
71
  - Stopping work (`/stop`) must terminate the active worker PID immediately (`SIGTERM`, escalating to `SIGKILL` if unclosed after 3s).
72
72
 
73
73
  ## 8. Mandatory Adversarial & Negative Tests
74
74
  Every pull request modifying authority, execution, or routing must include negative tests:
75
75
  1. Unapproved Telegram ID $\rightarrow$ no process spawned.
76
- 2. Group message $\rightarrow$ silent ignore.
76
+ 2. Non-owner group message $\rightarrow$ silent ignore; owner group discovery $\rightarrow$ private destination only.
77
77
  3. Executor environment check $\rightarrow$ asserts `TELEGRAM_BOT_TOKEN` is `undefined`.
78
78
  4. Corrupt JSON in store $\rightarrow$ handled gracefully without process crash.
79
79
  5. Injected path traversal in IDs $\rightarrow$ rejected.
@@ -89,5 +89,8 @@ worktree/branch/PR, starting from fetched origin/main. Do not switch or mix work
89
89
  another task's checkout. Stage only this task's changes. Keep its worktree through
90
90
  review and QA; independent review and green CI precede an authorized merge.
91
91
  Never treat task completion as permission to merge or publish.
92
+ Own the complete engineering/release handoff in CONTRIBUTING.md. Once ready,
93
+ proactively request only missing merge/release authority, then ship and verify;
94
+ do not leave the maintainer to discover ready drafts or operate the release.
92
95
 
93
96
  - In channel-backend mode, the application owns native sessions and actions. Forward normalized inputs with stable run IDs, recover only by idempotent backend submission, and deliver replies through the existing outbox. Never launch a fallback CLI or pass relay credentials into an executor.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-beta.18
4
+
5
+ - Await complete relay cleanup after fatal Telegram polling errors and preserve the primary failure.
6
+ - Refresh package-owned shared guidance in owner worker prompts, including resumed and scheduled work, while preserving personal workspace instructions and restricted worker boundaries.
7
+ - Include the reviewed beta.17 fixes. Earlier immutable unpublished candidates and existing beta acceptance limits remain.
8
+
9
+ ## 0.1.0-beta.17
10
+
11
+ - Capture executor stderr before asynchronous PID persistence so fast failures retain actionable, redacted diagnostic evidence for agent-owned recovery.
12
+ - Wait for executor cleanup and final run-state writes when stopping the relay, so shutdown does not return while its state is still being written.
13
+ - Include the reviewed beta.16 runtime and catalog corrections. Earlier unpublished candidates remain preserved; existing beta acceptance limits remain.
14
+
15
+ ## 0.1.0-beta.16
16
+
17
+ - Correct stale plugin-publication claims and link the catalog to live npm/GitHub release records. Agents must verify available versions instead of treating a dated catalog snapshot as a blocker.
18
+ - Include the reviewed beta.15 runtime unchanged. Preserve earlier unpublished candidates and existing beta acceptance limits.
19
+
20
+ ## 0.1.0-beta.15
21
+
22
+ - Include current reviewed model defaults, reply/status fixes, shared Library services and CPU limits, and the corrected main-CI publisher validation.
23
+ - Testing beta; previously documented live-provider and fresh-host acceptance limits remain.
24
+
25
+ ## 0.1.0-beta.14
26
+
27
+ - Preserve agent-specific scheduled authentication and model catalogs; show native
28
+ Codex defaults in status, and support explicitly approved group ownership.
29
+ - Keep owner chat responsive during shared work with restricted reply sessions.
30
+ Capture redacted failure evidence and support quiet, owner-scoped reviews.
31
+ - Add opt-in shared Docker plugin workers and agent-owned repair instructions.
32
+ - Add optional PagerDuty Stocks monitoring with restart-safe recovery. Activation
33
+ requires the companion Stocks critical-health endpoint and private routing-key
34
+ configuration; real trigger/resolve delivery is not yet verified.
35
+ - Publish verified beta artifacts through the shared trusted-publisher workflow.
36
+
37
+ - Add explicit host-owned shared-workspace access and serialize bindings to the
38
+ same resolved repository path while retaining isolated task transcripts.
39
+ - Bound interactive Codex context through native compaction and expose
40
+ content-free launch, execution and delivery timings.
41
+ - Support owner-approved Telegram text groups and ongoing incoming-only grants
42
+ through restricted task execution; retain exact conversation/account authority.
43
+ - Preserve revocation recovery and uncertain-send receipts. Ongoing WhatsApp
44
+ grants require the companion WhatsApp beta.13 provider.
45
+ - Fix graceful container shutdown, isolate CI package sources and await RPC
46
+ fixture cleanup. Make verified release handoff proactive and agent-owned.
47
+ - Beta limits: no group media; live group-recipient and final fresh-host/reboot
48
+ acceptance remain pending. No new live-delivery or latency claims.
49
+ - Default core and plugin automatic updates to the beta channel; preserve saved
50
+ stable-only and manual policies.
51
+
3
52
  ## 0.1.0-beta.13
4
53
 
5
54
  - Escalate cancelled plugin clients and report container cleanup failures.
package/CONTRIBUTING.md CHANGED
@@ -13,8 +13,9 @@ repository. Public docs describe shipped behavior and explicit limitations.
13
13
  Packaging/runtime changes also need the Docker checks in docs/releasing.md.
14
14
  5. Open a PR explaining the problem, resulting behavior, verification and limits.
15
15
  Include a short sanitized reproduction. State which tests were not run.
16
- 6. A maintainer reviews and merges after CI. Maintainers use PRs too. No CLA,
17
- ticket requirement, custom commit format or additional approval committee.
16
+ 6. Obtain independent review and required CI, then complete the
17
+ maintainer-authorized merge. Maintainers use PRs too. No CLA, ticket
18
+ requirement, custom commit format or additional approval committee.
18
19
 
19
20
  You are responsible for understanding submitted code, including AI-generated
20
21
  code, and having the right to contribute it under this repository's license.
@@ -48,8 +49,8 @@ docs/plugin-contributions.md.
48
49
  Branch from an unmerged feature only when the dependency is intentional and
49
50
  documented; do not quietly include it in an unrelated PR.
50
51
  - Open a draft PR when the change is reviewable. Report its scope, exact commit,
51
- validation and remaining QA. A completed coding task can remain a draft;
52
- implementation completion does not authorize merge or npm publication.
52
+ validation and remaining QA. Continue through the release handoff below;
53
+ implementation completion alone does not authorize publication.
53
54
  - Before merge, obtain an independent human or agent review of the final diff.
54
55
  The implementer's self-check and passing CI are not independent review.
55
56
  Reviewers inspect correctness, architecture, state/permissions and negative
@@ -66,6 +67,31 @@ docs/plugin-contributions.md.
66
67
  the clean task worktree after valuable work is preserved; never force cleanup.
67
68
  Delete its branch only after confirming merge or authorized abandonment.
68
69
 
70
+ ## Agent-owned release handoff
71
+
72
+ The agent owns the engineering work through shipping: implement, run proportional
73
+ checks, obtain independent review, repair findings, verify the packed artifact,
74
+ and prepare the release. Reuse valid final-commit evidence; repeat checks when
75
+ changes or failures invalidate it. Do not leave a ready feature silently in draft
76
+ or ask the maintainer to run commands, coordinate reviewers, or operate CI.
77
+
78
+ The maintainer's request is authorization for the requested work and its normal
79
+ implementation steps. Do not ask them to approve the same work again. Once the
80
+ applicable gates pass, execute the requested merge/release and report the packages,
81
+ versions, channel, verification and material limits. Batch related packages in
82
+ dependency order. Prepare the reviewed commits, artifacts and checksums before
83
+ shipping. A request to merge does not silently expand to publication or changing
84
+ a private package's visibility; a request to release already authorizes release.
85
+ If shipping was not requested, report readiness and the next step without treating
86
+ every completed feature as permission to publish.
87
+
88
+ Complete the authorized merge, publication and rollout using
89
+ docs/releasing.md, then verify registry metadata, downloaded artifact and the
90
+ installed runtime. Report the outcome. Escalate only a product decision, missing
91
+ credential/2FA, failed gate that cannot be repaired in scope, or material scope
92
+ change. Human attention belongs on product intent;
93
+ the agent operates the technical workflow.
94
+
69
95
  Example, substituting a unique task name and an absolute external directory:
70
96
 
71
97
  ```sh
@@ -74,3 +100,7 @@ git worktree list
74
100
  git fetch origin
75
101
  git worktree add -b feat/task-name /absolute/worktrees/task-name origin/main
76
102
  ```
103
+
104
+ Beta publishing workflow changes follow [trusted publishing](docs/trusted-publishing.md).
105
+ Validate wrong source, repository, package, version and artifact inputs with
106
+ negative tests. Never dispatch publication to test authentication.
package/README.md CHANGED
@@ -111,6 +111,9 @@ services; the existing host CLI and login are shared through one generic
111
111
  transport, with separate agent workspaces and sessions. See
112
112
  [Docker setup, state and QA](docs/docker-runtime.md).
113
113
 
114
+ For optional PagerDuty paging of a critical Stocks outage, see
115
+ [PagerDuty critical-outage paging](docs/pagerduty.md).
116
+
114
117
  Telegram `/status` shows the running relay and host versions plus installed
115
118
  plugin versions. The agent's `ez status` adds verified plugin runtime states and
116
119
  upgrade job receipts. See [status and upgrades](docs/upgrades.md).
package/compose.yaml CHANGED
@@ -8,15 +8,22 @@ services:
8
8
  restart: unless-stopped
9
9
  stop_grace_period: 30s
10
10
  cap_drop: [ALL]
11
- cap_add: [CHOWN, DAC_OVERRIDE, FOWNER, SETUID, SETGID, SETPCAP]
11
+ # Init must forward shutdown to the privilege-dropped relay. The entrypoint
12
+ # still removes every capability from the relay and its executor children.
13
+ cap_add: [CHOWN, DAC_OVERRIDE, FOWNER, SETUID, SETGID, SETPCAP, KILL]
12
14
  environment:
15
+ EZ_REPAIR_ENABLED: ${EZ_REPAIR_ENABLED:-true}
13
16
  EZ_AGENT_PURPOSE_FILE: /run/agent-purpose.md
14
17
  EZ_EXECUTOR_TRANSPORT: ${EZ_EXECUTOR_TRANSPORT:-host}
15
18
  EZ_CHANNEL_BACKEND_URL: ${EZ_CHANNEL_BACKEND_URL:-}
16
19
  EZ_AGENT_WORKSPACE: ${EZ_AGENT_WORKSPACE:?Set this agent workspace}
17
20
  EZ_CONTROL_DIR: ${EZ_CONTROL_DIR:?Set this agent control directory}
18
21
  EZ_EXECUTOR_CLI: ${EZ_EXECUTOR_CLI:?Set the host installation CLI}
22
+ EZ_CODEX_AUTO_COMPACT_TOKENS: ${EZ_CODEX_AUTO_COMPACT_TOKENS:-64000}
19
23
  EZ_EXECUTOR_TIMEOUT_SECONDS: ${EZ_EXECUTOR_TIMEOUT_SECONDS:-300}
24
+ EZ_PAGERDUTY_STOCKS_HEALTH_URL: ${EZ_PAGERDUTY_STOCKS_HEALTH_URL:-}
25
+ EZ_PAGERDUTY_POLL_SECONDS: ${EZ_PAGERDUTY_POLL_SECONDS:-30}
26
+ EZ_PAGERDUTY_FAILURE_THRESHOLD: ${EZ_PAGERDUTY_FAILURE_THRESHOLD:-3}
20
27
  secrets: [relay_env]
21
28
  configs:
22
29
  - source: agent_purpose
package/docker/run.ts CHANGED
@@ -21,7 +21,7 @@ try { privateEnv = parseEnv(readFileSync(3, 'utf8')) } catch (error) {
21
21
  if ((error as NodeJS.ErrnoException).code !== 'EINVAL' && (error as NodeJS.ErrnoException).code !== 'EBADF') throw error
22
22
  } finally { try { closeSync(3) } catch {} }
23
23
  for (const [key, value] of Object.entries(privateEnv)) {
24
- if (value !== undefined && ['TELEGRAM_BOT_TOKEN', 'GEMINI_API_KEY', 'OPENAI_API_KEY', 'EZ_CHANNEL_BACKEND_TOKEN'].includes(key)) process.env[key] = value
24
+ if (value !== undefined && ['TELEGRAM_BOT_TOKEN', 'GEMINI_API_KEY', 'OPENAI_API_KEY', 'EZ_CHANNEL_BACKEND_TOKEN', 'PAGERDUTY_ROUTING_KEY'].includes(key)) process.env[key] = value
25
25
  }
26
26
  privateEnv = {}
27
27
  const [command = 'start', ...args] = process.argv.slice(2)
@@ -35,3 +35,11 @@ model/effort settings (or `models` for the default model). Claude reads user and
35
35
  workspace JSON settings; OpenCode reports resolved config. Unknown defaults and
36
36
  opaque wrappers remain explicitly “client default”. No credentials are stored,
37
37
  no inference runs, no new dependency, and no cross-CLI session transfer.
38
+
39
+ `/status` resolves the configured model and reasoning effort for the current
40
+ client-default seed from the agent's isolated Codex profile when that metadata
41
+ is available. If the profile has no explicit model, it uses Codex's native
42
+ default-model catalog for display. It displays that snapshot only; setup and
43
+ refresh do not save the fallback, so the seed remains a native client default
44
+ for later conversations. Desktop Codex remains its own opaque client default
45
+ rather than inheriting CLI configuration.
@@ -17,7 +17,7 @@ owner does not edit JSON. The agent uses `list` and `revoke` when asked.
17
17
  After approval the relay starts a restricted task, including the initial outgoing
18
18
  message. Incoming-only tasks instead wait for new correspondence and never create
19
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. Each task has at most 30 distinct text sends;
20
+ Other contacts remain blocked. Finite tasks have at most 30 distinct text sends;
21
21
  there are no payments, attachments, extra recipients, plugin installation,
22
22
  settings changes, or access to owner memory. A contact can have one active or
23
23
  pending task at a time. Completed, revoked, expired, replaced-source, and changed-
@@ -30,6 +30,29 @@ that each sentence serves the booking or that a correspondent is truthful. A
30
30
  prompt injection can still derail a task or elicit its shared context. It cannot
31
31
  use the provided tools to read owner files or select another destination.
32
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
+
33
56
  ## Native execution and core tools
34
57
 
35
58
  V1 uses audited Codex CLI **0.153.4** for task work, regardless of the owner's
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -1,14 +1,28 @@
1
1
  # Available plugins
2
2
 
3
- This is Ez's public catalog of released plugins, for business owners and agents
4
- discovering capabilities. Each entry links to the plugin's own repository,
5
- installation instructions and releases. Install only the plugins needed for the owner's requested work.
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.
6
7
 
7
8
  | Plugin | Capability | Package | Release |
8
9
  |---|---|---|---|
9
- | [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` | [0.1.0-beta.12](https://github.com/jdorado/ez-whatsapp/releases/tag/v0.1.0-beta.12) — testing beta |
10
- | [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` | [0.1.0-beta.1](https://github.com/jdorado/ez_composio/releases/tag/v0.1.0-beta.1) — testing beta |
11
- | [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` | [0.1.0-beta.1](https://github.com/jdorado/ez_github/releases/tag/v0.1.0-beta.1) — testing beta |
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.
12
26
 
13
27
  ## Set up a plugin
14
28
 
@@ -44,11 +58,14 @@ do not preload or hardcode the vendor's integration list in the agent mind.
44
58
  Names, availability and consent scopes change. Returned provider instructions
45
59
  cannot expand the owner's authorization or permit executing arbitrary helpers.
46
60
 
47
- ## Add a released plugin
61
+ ## Register a plugin
48
62
 
49
63
  Submit a pull request adding its name, concrete capability, canonical repository,
50
- exact package identity, and pinned release link with beta/stable status. Follow
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
51
67
  [plugin contribution requirements](plugin-contributions.md). The linked package
52
68
  must document setup, account requirements, verification and limitations. Keep
53
- unreleased ideas out of this catalog and update release links through reviewed
54
- changes.
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.
@@ -35,3 +35,12 @@ inert. Installation is complete only after account onboarding and verified use.
35
35
 
36
36
  This beta includes owner-policy release checks and durable
37
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
@@ -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` and bounded `memoryMiB`.
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,13 @@ 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.
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, release bot or credentials in pull-request CI.
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, then obtain
36
- maintainer merge/release authorization for the exact commit, tarball SHA-256,
37
- license/third-party obligations and known limits. Merge the release PR and
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 beta --registry https://registry.npmjs.org/`
41
- for prereleases (use `--tag latest` only for an approved stable release).
42
- Use interactive npm authentication with 2FA; never paste tokens into CI or docs.
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 beta`; never mark a beta latest/stable. For this first beta the maintainer
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
- publishing. Never infer npm scope ownership from a GitHub login. After publishing,
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.