@jc_stack/ez-agents 0.1.0-beta.29 → 0.1.0-beta.32

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 (55) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +41 -1
  3. package/README.md +36 -25
  4. package/docs/application-channel.md +29 -2
  5. package/docs/architecture/ai-selection.md +10 -1
  6. package/docs/architecture/authority-boundaries.md +64 -14
  7. package/docs/architecture/event-sources.md +12 -5
  8. package/docs/architecture/telegram-intake.md +1 -1
  9. package/docs/host-service.md +3 -0
  10. package/docs/plugin-contributions.md +2 -0
  11. package/docs/plugins.md +23 -0
  12. package/docs/responsive-channels.md +3 -0
  13. package/docs/selective-monitoring.md +55 -3
  14. package/docs/setup.md +2 -1
  15. package/package.json +1 -1
  16. package/src/application-channel.ts +40 -9
  17. package/src/application-origin.ts +4 -0
  18. package/src/approval.ts +19 -3
  19. package/src/codex-session.ts +2 -2
  20. package/src/desktop-bridge.ts +70 -5
  21. package/src/event-sources.ts +13 -6
  22. package/src/executor.ts +4 -2
  23. package/src/files.ts +12 -0
  24. package/src/host-executor-protocol.ts +2 -2
  25. package/src/host-executor.ts +20 -4
  26. package/src/index.ts +81 -34
  27. package/src/plugins/manager.mjs +52 -20
  28. package/src/runs.ts +19 -2
  29. package/src/task-attachments.ts +56 -0
  30. package/src/task-capability.ts +45 -0
  31. package/src/task-cli.ts +7 -4
  32. package/src/task-executor.ts +8 -4
  33. package/src/task-mcp.ts +25 -8
  34. package/src/tasks.ts +132 -26
  35. package/src/telegram-source.ts +34 -13
  36. package/src/updates/artifact.mjs +2 -2
  37. package/src/updates/binding.mjs +1 -1
  38. package/templates/agent-guidance.md +24 -0
  39. package/test/agent-guidance.test.ts +8 -0
  40. package/test/application-channel.test.ts +52 -1
  41. package/test/codex-session.test.ts +2 -1
  42. package/test/desktop-bridge.test.ts +98 -1
  43. package/test/event-sources.test.ts +68 -8
  44. package/test/executor.test.ts +2 -2
  45. package/test/host-executor.test.ts +32 -3
  46. package/test/intake-relay.test.ts +79 -2
  47. package/test/local-qa.test.mjs +7 -3
  48. package/test/plugin-manager.test.mjs +31 -0
  49. package/test/runs.test.ts +19 -0
  50. package/test/task-attachments.test.ts +77 -0
  51. package/test/task-capability.test.ts +48 -0
  52. package/test/task-native.test.ts +4 -1
  53. package/test/tasks.test.ts +53 -1
  54. package/test/telegram-source.test.ts +28 -1
  55. package/test/updates.test.mjs +3 -2
package/AGENTS.md CHANGED
@@ -94,7 +94,7 @@ Measure progress by usable outcomes and feedback, not code or test volume.
94
94
 
95
95
  ## 7. Fail-Closed Authority (Channel Access ≠ Execution)
96
96
  - 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.
97
- - 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.
97
+ - Unapproved group messages from other senders and unknown DMs fail silently unless an exact-contact or any-conversation owner-approved channel grant admits them. Both grant types use the restricted task runner. Paired-owner group text is discovery routed to the owner's private chat; it grants no group reply authority.
98
98
  - Stopping work (`/stop`) must terminate the active worker PID immediately (`SIGTERM`, escalating to `SIGKILL` if unclosed after 3s).
99
99
 
100
100
  ## 8. Mandatory Adversarial & Negative Tests
package/CHANGELOG.md CHANGED
@@ -1,6 +1,46 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.1.0-beta.32
4
+
5
+ - Add shared authenticated inbound attachment staging for application and
6
+ Telegram channels, preserving literal comments and immutable retries.
7
+ - Support separately scoped host-owned writable workspaces.
8
+ - Reconcile reused host-lock PIDs using process birth identity while failing
9
+ closed on unknown or matching live-process identity.
10
+ - Accept bounded scheduler recovery identifiers and preserve reviewed package
11
+ modes when extracting under a restrictive umask.
12
+ - Allow concurrent plugin commands, scoped approved outgoing files, and the
13
+ host CLI configuration needed for restricted read-only plugin commands.
14
+ - Clarify domain-agent positioning while preserving native engine ownership.
15
+
16
+ - Answer native app-server requests with their current protocol shapes. Scheduled
17
+ `codex-gui` browser work now surfaces approval requests and grants only its
18
+ active turn session-scoped HTTPS browser-origin and Chrome app elicitations,
19
+ while audio, cross-turn, unrelated elicitations and approvals remain declined.
20
+ - Restore `codex-gui` tasks when newer Codex Desktop builds do not create the
21
+ legacy control socket at app launch: invoke the native idempotent app-server
22
+ daemon start command and retry the desktop connection once, while retaining
23
+ fail-closed behavior and never falling back to headless execution.
24
+ - Add owner-approved, provider-neutral public channel grants so restricted fresh
25
+ agent runs can answer any private chat or mentioned group on one enabled source.
26
+ Grants may expose only fixed, read-only query aliases such as Library search;
27
+ they retain no owner memory, recheck revocation around every operation, and
28
+ enforce persisted concurrency, traffic, receipt and evidence bounds.
29
+
30
+ ## 0.1.0-beta.31
31
+
32
+ - Make the owner-authorized contribution lifecycle explicit in shipped agent
33
+ guidance: take a coherent change through independent final-head review, CI,
34
+ applicable QA and, when authorized, merge. Release authority includes the
35
+ merge needed for publication, which continues through the reviewed GitHub
36
+ publisher, registry readback and eligible runtime verification. Preserve local
37
+ QA, diagnostics, auth-only work and deployment as separate boundaries.
38
+
39
+ ## 0.1.0-beta.30
40
+
41
+ - Bind installed native command launchers to the deployment's canonical control
42
+ directory. This makes application registration use the owning agent's state
43
+ and prevents caller environment variables from redirecting that authority.
4
44
 
5
45
  ## 0.1.0-beta.29
6
46
 
package/README.md CHANGED
@@ -1,14 +1,20 @@
1
- # Ez — AI assistants for small businesses
1
+ # Ez — Build domain-expert AI agents on the harnesses you already use
2
2
 
3
- **A lightweight, open-source foundation for persistent AI assistants, powered by
4
- existing AI harnesses.** Give an assistant a purpose, a workspace and tools for
5
- your business, then work with it through chat.
3
+ **The open-source composition layer for turning Codex, Grok and other native
4
+ agent harnesses into persistent, tool-using specialists.**
6
5
 
7
- Ez is for owners of shops, studios and small teams who want help doing everyday
8
- work: preparing quotes, maintaining business records, researching decisions or
9
- following up on an agreed task. Each assistant has its own working context and
10
- responsibilities. The tools and permissions you configure determine what it can
11
- do.
6
+ Combine domain knowledge, portable plugins, messaging, scheduling and explicit
7
+ authority around the AI tools you already have. Start with one useful agent and
8
+ grow into a team whose responsibilities, accounts and access remain clear.
9
+
10
+ Ez does not replace your agent engine or hide it behind another platform. The
11
+ native harness keeps ownership of reasoning, sessions, tools and delegation. Ez
12
+ connects that intelligence to a durable workspace, real applications, trusted
13
+ people and the operational controls required to work reliably.
14
+
15
+ Use Ez for a personal project, a specialist research system or an operating role
16
+ inside a startup or small business. Each agent gets a defined domain, its own
17
+ working context and only the tools and authority its job requires.
12
18
 
13
19
  ## Engine and application boundaries
14
20
 
@@ -58,20 +64,20 @@ not implemented. The legacy channel-backend mode delegates execution and changes
58
64
  standard controls, so it does not meet this integration boundary. New integrations
59
65
  use the [native application channel](docs/application-channel.md).
60
66
 
61
- ## What makes an Ez assistant
67
+ ## What makes an Ez domain agent
62
68
 
63
69
  | Part | What it contributes |
64
70
  |---|---|
65
- | **Workspace** | Markdown instructions, business context and working files that persist across conversations and changes of AI. |
71
+ | **Workspace** | Markdown instructions, domain knowledge and working files that persist across conversations and changes of AI. |
66
72
  | **Native engine** | Inference, native sessions, context management and tool execution. See [AI selection](docs/architecture/ai-selection.md). |
67
73
  | **Authority** | A verified owner and explicit limits on delegated work. Receiving a message or installing a tool does not grant permission to act. |
68
74
  | **Plugins** | Documented CLI commands and agent instructions for application capabilities. Commands enforce authentication, authorization, validation and canonical persistence directly or through authoritative application services. |
69
75
  | **Ez transport and runtime** | Channel delivery, scheduling and standard runtime controls around the native engine. |
70
76
 
71
- The design starts with one assistant, one mind and clear responsibilities.
72
- Business instructions live in the workspace; reusable capabilities live in tools
73
- and plugins. The agent decides how to do the work using those instructions and
74
- the capabilities available to it.
77
+ The design starts with one agent, one domain and clear responsibilities. Domain
78
+ instructions live in the workspace; reusable capabilities live in tools and
79
+ plugins. The agent decides how to do the work using those instructions and the
80
+ capabilities available to it.
75
81
 
76
82
  Use the engine's native capabilities when they meet the need. Add a standalone
77
83
  plugin when a missing integration earns the maintenance. Ez keeps the surrounding
@@ -81,9 +87,9 @@ clients improve.
81
87
  ## Plugin catalog
82
88
 
83
89
  Browse the [available plugins](docs/plugin-catalog.md) for capabilities you can
84
- add to your assistant. The first released plugin is
90
+ add to an agent. The first released plugin is
85
91
  [WhatsApp](https://github.com/jdorado/ez-whatsapp), which connects an existing
86
- WhatsApp account. Ask your working Ez assistant to set it up in Telegram.
92
+ WhatsApp account. Ask your working Ez agent to set it up in Telegram.
87
93
 
88
94
  ## Start with one useful job
89
95
 
@@ -97,12 +103,12 @@ requested, keep each workspace's authority and registry explicit.
97
103
  Ask an AI agent with computer access to install Ez for a concrete purpose:
98
104
 
99
105
  > Install Ez from https://github.com/jdorado/ez-agents for my business.
100
- > I want an assistant that helps me prepare customer quotes from my own files.
106
+ > I want a quoting specialist that works from my own files.
101
107
  > Set it up and verify that I can talk to it in Telegram.
102
108
 
103
109
  The installing agent follows [the setup guide](docs/setup.md), handles technical
104
110
  setup and asks you for the account access or approvals it needs. Once the
105
- assistant replies in Telegram, explain your business, give it the relevant
111
+ agent replies in Telegram, explain the domain, give it the relevant
106
112
  materials and request any additional tools there. Integrations require their
107
113
  own setup and authorized accounts.
108
114
 
@@ -111,21 +117,26 @@ own setup and authorized accounts.
111
117
  The current source supports persistent agent workspaces, a choice of host AI
112
118
  executors, owner-gated Telegram messaging, native scheduling, plugin lifecycle
113
119
  management and bounded, owner-approved correspondence. A messaging task can
114
- contact one approved person using only its explicitly shared task context;
120
+ serve one approved conversation or, after an explicit broad approval, anyone on
121
+ one capable source. Restricted runs receive only their shared context and exact
122
+ installed read-only query capabilities; they do not inherit the owner workspace
123
+ or tools.
124
+ The built-in Telegram source supports text in private chats and groups;
115
125
  restricted task execution currently requires the pinned Codex runtime. See
116
126
  [authority boundaries](docs/architecture/authority-boundaries.md) for the exact
117
127
  scope and [scheduling](docs/scheduling.md) for scheduled work.
118
128
 
119
- The broader direction is assistants working across business roles, with deliberate
129
+ The broader direction is agents working across distinct domains, with deliberate
120
130
  workspace sharing and authority over who may direct work, see information and
121
- use accounts. General team delegation, family/group authority and enterprise
122
- reviewer roles remain future work. The current trusted-host beta is not an
131
+ use accounts. General team delegation and enterprise reviewer roles remain
132
+ future work. The current trusted-host beta is not an
123
133
  enterprise isolation or multi-tenant security product. See [security scope](SECURITY.md).
124
134
 
125
135
  ## For agents discovering this repository
126
136
 
127
- Ez may fit when a user needs a persistent business assistant reachable through
128
- chat, using an existing AI client and separately installed tools. Start here:
137
+ Ez may fit when a user needs a persistent domain-specific AI agent reachable
138
+ through chat, using an existing AI client and separately installed tools. Start
139
+ here:
129
140
 
130
141
  - **Install for a user:** [setup and verified onboarding](docs/setup.md), then the installer instructions below.
131
142
  - **Understand access and delegation:** [authority boundaries](docs/architecture/authority-boundaries.md) and [security scope](SECURITY.md).
@@ -140,8 +140,12 @@ The existing `ezenciel-agents-schedule context` exposes it as
140
140
  `run.application.context` only to the current native run. Domain tools and their
141
141
  filesystem mounts are installed using ordinary Ez plugin/runtime setup. No API
142
142
  field selects a native session, working directory, process environment or owner.
143
- This first version transports text only, without file delivery, reactions or
144
- approval UI.
143
+ This version transports text plus core approval requests, without file delivery
144
+ or reactions. Run snapshots include `approvals: [{id,prompt,state}]`. Render the
145
+ prompt verbatim and POST `{"decision":"approved"}` or
146
+ `{"decision":"denied"}` to `/v1/approvals/TASK_ID` with the same bearer
147
+ credential. Core binds the decision to the authenticated owner generation; the
148
+ application must not infer or auto-submit consent.
145
149
 
146
150
  ## Conversation continuity and migration
147
151
 
@@ -364,3 +368,26 @@ secrets are present; do not put those secrets in a same-UID process environment
364
368
  or readable mount. This setting is rejected for host/backend execution and
365
369
  restricted delegated tasks, and cannot be selected by an application request.
366
370
  It is not forwarded to the host executor.
371
+
372
+ ## Generic inbound attachments
373
+
374
+ `POST /v1/runs` (and `runApplication`) accepts one optional
375
+ `attachment: {name, data}`, where `data` is canonical padded base64 of the file
376
+ bytes. `text` remains the literal user comment and may be empty with an attachment.
377
+ JPEG, PNG, WebP, PDF and UTF-8 TXT/Markdown (`.txt`, `.md`, `.markdown`) are supported,
378
+ up to 10 MiB decoded; empty files and other types are rejected. Core detects file
379
+ content rather than trusting a client MIME label. This same limit and staging
380
+ contract apply to Telegram photo/document input.
381
+
382
+ Authentication precedes staging. Core stages the file privately in the ordinary
383
+ workspace inbox and uses the same attachment metadata and literal comment as
384
+ Telegram. The existing run queue, native executor, selected AI and native session
385
+ remain authoritative; applications must not extract, summarize, convert or build
386
+ attachment prompts. Use `followOwner:true` for the shared owner conversation.
387
+ Retry the same request ID, filename, bytes and literal comment; conflicts return
388
+ 409 and successful retries do not stage another file. A failed admission removes
389
+ its staged file; a process crash may leave an unused inbox file, never a runnable
390
+ partial request. Separate owner runtimes must retain separate workspace mounts.
391
+
392
+ This is inbound file support. Application replies currently deliver text only;
393
+ outgoing file downloads remain unsupported by this HTTP channel.
@@ -14,7 +14,16 @@ Grok/Claude accept caller-selected native UUIDs. Codex/OpenCode generate IDs, so
14
14
  the adapter reads only their typed JSONL session metadata; stdout never becomes a
15
15
  Telegram reply. `codex-gui` is a separate desktop adapter: it submits a dedicated
16
16
  app-server thread/turn and waits for that turn to finish. It does not run
17
- `codex exec`. A missing or mismatched native session fails closed, not `--last`.
17
+ `codex exec`. If the native control socket is absent, the adapter asks the
18
+ installed Codex CLI to idempotently start its own app-server daemon, then retries
19
+ the connection once. It does not implement another daemon or fall back to the
20
+ headless CLI. A missing or mismatched native session fails closed, not `--last`.
21
+ Native server requests use their method-specific response schema. Scheduled turns
22
+ use on-request approval routing so browser elicitations reach the adapter, which
23
+ accepts only the active turn's session-scoped HTTPS browser-origin and Computer
24
+ Use Chrome app requests. Interactive turns remain non-interactive. Audio,
25
+ cross-turn, command, file and unrelated requests are declined rather than being
26
+ guessed or forwarded to a hidden task UI.
18
27
  Legacy unbound sessions require the owner's explicit `/new`.
19
28
 
20
29
  References used for the adapter contract:
@@ -1,6 +1,7 @@
1
1
  # Authority boundaries
2
2
 
3
- The core pairs one Telegram owner and owns authority across providers. Plugins
3
+ The core binds one owner identity, optionally linked to Telegram or an
4
+ application channel, and owns authority across providers. Plugins
4
5
  provide transport, authentication, capture, and receipts. Their exposure metadata
5
6
  is discovery information, never a grant. A CRM can contain external text too;
6
7
  marking it internal does not confer owner authority.
@@ -17,7 +18,8 @@ owner does not edit JSON. The agent uses `list` and `revoke` when asked.
17
18
  After approval the relay starts a restricted task, including the initial outgoing
18
19
  message. Incoming-only tasks instead wait for new correspondence and never create
19
20
  an opening run. Their task records use version 2 so older task readers fail closed. Matching new correspondence resumes that task in a fresh native session.
20
- Other contacts remain blocked. Finite tasks have at most 30 distinct text sends;
21
+ Other contacts remain blocked unless an owner-approved any-conversation grant is
22
+ active for that source. Finite tasks have at most 30 distinct text sends;
21
23
  there are no payments, attachments, extra recipients, plugin installation,
22
24
  settings changes, or access to owner memory. A contact can have one active or
23
25
  pending task at a time. Completed, revoked, expired, replaced-source, and changed-
@@ -30,6 +32,46 @@ that each sentence serves the booking or that a correspondent is truthful. A
30
32
  prompt injection can still derail a task or elicit its shared context. It cannot
31
33
  use the provided tools to read owner files or select another destination.
32
34
 
35
+ ## Channel audiences and capabilities
36
+
37
+ Version-4 grants may bind the audience to every conversation captured by one
38
+ registered event source. The source must advertise `wildcardWatch` and implement
39
+ `task-watch`/`task-unwatch` for conversation `*`. The grant is incoming-only and
40
+ active until owner revocation. It does not grant other sources, owner controls,
41
+ the owner session, owner files or conversation history. Each run contains events
42
+ from exactly one provider conversation, replies only to that captured
43
+ conversation and exposes no cross-conversation notes. Exact-contact grants remain
44
+ the default.
45
+
46
+ Public admission is capped at eight outstanding conversations, 60 conversations
47
+ and 60 replies per hour, and 1,000 conversations or replies across the life of a
48
+ grant. The cumulative limit revokes the grant and requires fresh owner review.
49
+ Terminal public-run evidence retains the most recent 100 released runs per grant;
50
+ unreleased runs remain durable for retry. Released provider events and accepted
51
+ Telegram send receipts are also bounded.
52
+
53
+ A channel grant may include up to eight owner-approved query capabilities. Each is an
54
+ exact registered `ez` command plus fixed arguments ending in literal
55
+ `-- {input}`. The restricted broker replaces only `{input}` with the
56
+ correspondent's string; the model cannot select a command, prepend flags, choose
57
+ a recipient, access a shell or change the fixed arguments. The full command
58
+ vector and disclosure scope appear in the immutable owner approval. Core rechecks
59
+ the grant immediately before and after invocation and before every reply. The
60
+ installed alias must declare `channelQuery: true` and explicitly declare that it
61
+ accepts external input without external sends, record changes, or interactive
62
+ review; core revalidates this trusted installed manifest before execution. Output
63
+ is bounded to 128 KiB and may be disclosed to the approved audience; stderr and
64
+ process credentials are not exposed. Tool output and incoming messages remain
65
+ untrusted source material.
66
+
67
+ Capabilities are a core channel permission, not a plugin permission system.
68
+ Domain tools remain ordinary reviewed CLIs and enforce their own authentication,
69
+ resource authorization, validation, persistence and receipts. For example, an
70
+ installed Library can supply a dedicated fixed read-only search alias. Do not
71
+ grant lifecycle/admin commands or an operation with
72
+ unbounded or uncertain external effects through this query-shaped interface.
73
+ Those require a purpose-built tool contract with its own idempotency and receipts.
74
+
33
75
  ## Ongoing conversation permissions
34
76
 
35
77
  Incoming-only proposals may use `--until-revoked` for an ongoing conversation.
@@ -42,14 +84,15 @@ later replies. The runner gets current-run receipts and rolling group-only notes
42
84
  receive the largest supported timestamp for the watch; the core still checks
43
85
  revocation before every operation. Older versions reject version-3 grants.
44
86
 
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
87
+ The native Telegram source implements the provider protocol for exact private or
88
+ group IDs and wildcard audiences. It records selected text messages and sender
89
+ identity, and sends only to the concrete captured chat with durable
90
+ uncertain/accepted receipts. Bot messages and
48
91
  anonymous-admin posts are excluded by intake. Unselected owner group text remains
49
92
  private discovery; other unselected group messages cannot launch work. Source
50
93
  registration enables discovery, never reply permission. Voice and attachments are
51
94
  not handled by this group adapter. WhatsApp continues using its existing adapter;
52
- group and ongoing watch support requires the companion provider update. Older
95
+ group, ongoing and wildcard watch support depends on the companion provider. Older
53
96
  adapters reject ongoing grants at proposal time. Pending watch removals retry
54
97
  after service outages; core revocation blocks sends immediately.
55
98
 
@@ -69,9 +112,11 @@ tool discovery. Model metadata can override feature flags, so flags alone are
69
112
  insufficient. The native inventory test uses a real bundled model entry and must
70
113
  prove the five bounded task tools work without additional action tools.
71
114
 
72
- A core stdio MCP broker exposes `context`, `send`, `note`, `report`, and `complete`.
115
+ A core stdio MCP broker exposes `context`, `send`, `note`, `report`, and `complete`,
116
+ plus only the exact capabilities recorded in the grant. Any-conversation runs omit
117
+ cross-conversation note/report/complete tools.
73
118
  The native client also lists resource helpers, but the broker serves no resources.
74
- Only these five tools have native approval bypass configured: the core rechecks
119
+ Only these tools have native approval bypass configured: the core rechecks
75
120
  the grant on each call. Broker requests cross host/relay through private atomic
76
121
  control files; only the relay dispatches provider writes. Model tool arguments
77
122
  never choose a recipient, account, control path, shell command, or permission.
@@ -80,8 +125,9 @@ containment, not isolation from a malicious native executable or local host user
80
125
  Native configuration reference: [Codex configuration](https://learn.chatgpt.com/docs/config-file/config-reference).
81
126
 
82
127
  Task notes live under protected `control/tasks/`, separate from the owner mind.
83
- Reports go to the owner's Telegram outbox, visibly labelled as task reports;
84
- they are not inserted as owner instructions or trusted memory. The owner mind
128
+ Exact-contact task reports currently use the linked Telegram owner outbox and
129
+ are visibly labelled; any-conversation runs have no report tool. Reports are not
130
+ inserted as owner instructions or trusted memory. The owner mind
85
131
  keeps its existing `inbox/` and `work/` organization. No database or general memory
86
132
  index is introduced.
87
133
 
@@ -92,6 +138,8 @@ stable string `accountId` in `events-head`. The core calls `task-watch` with tha
92
138
  account, exact `conversationId`, and expiry to request bounded capture attention.
93
139
  The existing events/events-check protocol supplies incoming messages. This
94
140
  subscription grants attention only; execution still requires the core grant.
141
+ Sources that support an any-conversation grant additionally advertise
142
+ `wildcardWatch: true` and accept `*` only for watch/unwatch, never as a send target.
95
143
 
96
144
  For sends the core supplies `task-send` with those same bound IDs, text, and a
97
145
  core-prefixed idempotency key. The adapter checks account consistency immediately
@@ -116,7 +164,9 @@ records, but cannot launch task work.
116
164
  Unmatched events retain terminal `cancelled` plus
117
165
  `external-execution-unavailable`. Task runs use record version 2; older readers
118
166
  reject/skip them instead of executing them with owner access. Existing version-1
119
- owner runs remain readable. Package state schema stays 1, but rollback suspends
167
+ owner runs remain readable. Older task readers reject version-4 wildcard grants;
168
+ approval prompt changes also fail closed if a capability-bearing older record is
169
+ read after rollback. Package state schema stays 1, but rollback suspends
120
170
  task processing until a task-aware version returns; rollback does not replay
121
171
  messages or erase task receipts. Update host and relay together. A missing or
122
172
  outdated host fails task launch closed.
@@ -124,9 +174,9 @@ outdated host fails task launch closed.
124
174
  The installing host user remains trusted and can modify local control state.
125
175
  Owner runs can use the plugin manager and Docker administration; content read
126
176
  inside owner work still depends on native protections and agent judgment. This
127
- is not a public multi-tenant execution service. Family delegation, payments,
128
- enterprise reviewer agents, arbitrary file sharing, and other restricted native
129
- executors are deferred.
177
+ is an owner-configured channel service, not a general multi-tenant execution
178
+ platform. Payments, enterprise reviewer agents, arbitrary file sharing and
179
+ unrestricted delegated executors are deferred.
130
180
 
131
181
  Verify with `pnpm verify`, Docker test/runtime targets and smoke fixtures.
132
182
  `EZ_TEST_NATIVE_TASKS=1 pnpm exec tsx --test test/task-native.test.ts` checks the
@@ -31,9 +31,16 @@ creation; it does not promise exactly-once external actions after executor failu
31
31
 
32
32
  Before starting queued work, recheck binding, owner and provider eligibility.
33
33
  Unavailable sources keep work queued; removed subscriptions cancel empty runs.
34
- No check can retract work already started. Eligible external runs are now recorded
35
- as blocked (`external-execution-unavailable`), with no executor launch. They do
36
- not borrow the owner workspace, session or tools. The existing source cursor and
37
- deduplication remain intact; blocked work does not retry automatically. Work status
38
- shows the blocked count. No provider SDK or provider-specific authority is imported.
34
+ Events matching exactly one active core task launch its restricted fresh-session
35
+ runner; unmatched events are recorded as blocked (`external-execution-unavailable`)
36
+ with no executor launch. Neither borrows the owner workspace, session or tools.
37
+ Any-conversation tasks admit at most one outstanding run per conversation and
38
+ eight across the public source queue, with persisted limits of 60 conversations
39
+ and 60 replies per hour and 1,000 across a grant. The cumulative limit revokes
40
+ the grant. Owner work is preferred and preempts an active public run. Terminal
41
+ history retains the latest 100 released runs per public grant; providers supporting
42
+ `releaseEvents` are told to discard terminal source events. Release completion is
43
+ persisted, and a failed release is retried before that run can be pruned. The source cursor and
44
+ deterministic run IDs preserve replay. No provider SDK or provider-specific
45
+ authority is imported into core.
39
46
  See [authority boundaries](authority-boundaries.md).
@@ -2,7 +2,7 @@
2
2
 
3
3
  One owner, one bot, one relay writer per control directory. No database, extra agent, or executor loop.
4
4
 
5
- 1. Gate the sender and private chat before accepting work. 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.
5
+ 1. Gate the sender and chat before accepting work. Text from the paired owner in an unbound group is recorded only for discovery and routed to the owner's private chat. Other private/group senders are ignored unless the built-in source has an active exact or wildcard core grant. Group controls and anonymous administrators remain 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.
@@ -89,6 +89,9 @@ preserving it rather than reverting to a different or expired host login.
89
89
  An agent binding may set `sharedWorkspace` to an absolute canonical application
90
90
  repository. The host resolves its canonical path, adds that directory to Codex
91
91
  write permissions for chat and scheduled jobs, including symlink aliases.
92
+ If the agent needs more than one separately scoped writable directory, keep the
93
+ canonical application in `sharedWorkspace` and list the others as absolute paths
94
+ in `additionalWorkspaces`; do not grant a broader common parent.
92
95
  The host claims requests independently; a running job does not block another
93
96
  request sharing its workspace. The selected engine owns execution concurrency.
94
97
  Task sessions and artifacts remain isolated. The binding is host-owned and cannot
@@ -18,6 +18,8 @@ Before the first PR, provide:
18
18
  - Per-command exposure declarations for external reads, external sends, record
19
19
  changes and requested review; see [plugin metadata](plugins.md#exposure-declarations).
20
20
  These are self-reported capabilities, never permission grants or safety certificates.
21
+ A dedicated query-only alias may opt into restricted channel use with
22
+ `channelQuery: true` and the required explicit non-writing exposure fields.
21
23
  - Private state locations, start/stop/status, backup, migration/rollback limits,
22
24
  data-preserving uninstall and separate account revocation instructions.
23
25
  - Offline contract/negative tests and CI. Verify snapshot installation and CLI
package/docs/plugins.md CHANGED
@@ -168,6 +168,29 @@ attention during setup/use; it does not enable an automated reviewer. Declaring
168
168
  false never grants permissions, disables core checks or certifies a plugin safe.
169
169
  The core owns authority; plugins own provider transport/authentication/receipts.
170
170
 
171
+ A command may additionally set `"channelQuery": true` only when all four
172
+ exposure fields are explicit and describe external input with no external send,
173
+ record change, or interactive review. This is narrow eligibility for inclusion
174
+ in an owner-approved restricted channel grant, not an activated permission or a
175
+ safety label for the rest of the plugin. Mixed read/write aliases are ineligible;
176
+ publish a dedicated query-only alias.
177
+
178
+ For original file bytes, declare `"channelFile": true` instead, with the same
179
+ read-only exposure fields. The approved task capability must specify
180
+ `"output": "file"`. Its command accepts one literal input and writes only the
181
+ file bytes to stdout (maximum 20 MiB across a run). Core returns an attachment ID and filename
182
+ to the agent; binary content stays in private task staging. The input basename
183
+ supplies the download filename.
184
+
185
+ The task's existing `send` tool accepts `attachmentId` plus text and an
186
+ idempotency key. Only a completed file capability from that run can supply it.
187
+ The destination remains the authorized conversation. Providers opt in through
188
+ `events-head.taskAttachments: true`, optionally declaring `attachmentCaptionLimit`,
189
+ and accept the attachment metadata in `task-send`. Telegram delivers a document
190
+ with a caption of at most 1024 characters; channels without this contract fail
191
+ explicitly before dispatch. Staged bytes are removed when the external run is
192
+ released. File capability access must be included in the owner's grant.
193
+
171
194
  Owner adapters retain owner access. External correspondence can run only in an
172
195
  approved core messaging task through the restricted task runner. Declarations
173
196
  and monitoring subscriptions alone never grant task execution. See
@@ -12,4 +12,7 @@ the message CLI. Native final text is not automatically delivered to Telegram.
12
12
 
13
13
  Restricted correspondence receives a typed activation event and scoped tools.
14
14
  Authorization, sandboxing and tool handlers enforce contact and lifecycle limits.
15
+ An owner-approved channel capability adds only a fixed installed alias declared
16
+ as a read-only channel query; it does not expose the workspace, shell, owner
17
+ session or other installed tools.
15
18
  Maintenance and group notifications carry event data; CLI help owns operations.
@@ -12,8 +12,9 @@ is a reminder, never an activated source, watch or reply permission.
12
12
  Keep mode names internal. Linking/syncing an account defaults to quiet capture;
13
13
  finish connection verification, then at most one short optional prompt such as
14
14
  “WhatsApp is connected. Want me to follow up with anyone?” Do not present a
15
- technical three-mode menu or suggest blanket autonomous replies that v1 cannot
16
- safely authorize. If the owner already gave a job, continue it without this prompt.
15
+ technical three-mode menu. Suggest an any-conversation reply grant only when the
16
+ owner has actually asked to serve everyone on that source. If the owner already
17
+ gave a job, continue it without this prompt.
17
18
 
18
19
  Infer the complete job from ordinary language:
19
20
 
@@ -42,7 +43,8 @@ when it matters to that proposed job; never silently expand or renew permission.
42
43
  - Selected: wake for named contacts only. Never turn on all-inbox mode to satisfy
43
44
  a one-contact request.
44
45
  - All: attention for all eligible incoming contacts; requires that broader
45
- owner request. Attention alone never grants autonomous reply permission.
46
+ owner request. Attention alone never grants autonomous reply permission; a
47
+ separate approved any-conversation task does.
46
48
 
47
49
  For an approved core reply task, the provider's task-watch supplies expiring
48
50
  selected attention even if its general policy remains manual. That is expected:
@@ -95,6 +97,56 @@ members of that approved group may converse; this does not grant owner tools.
95
97
  The group runs with the existing restricted messaging runner, and its notes are
96
98
  separate from private PA memory. Group text is supported; media is not yet.
97
99
 
100
+ ## Everyone on an enabled channel
101
+
102
+ When the owner explicitly asks to answer anyone on one channel, propose one
103
+ incoming-only `--any-conversation` grant for that registered source. The flag
104
+ also selects `--until-revoked` and contact `*`. Do not widen “this group,” “this
105
+ person,” or “customers in this list” into everyone. The source must support a
106
+ wildcard watch; otherwise report that adapter gap without inventing a parallel
107
+ poller. Telegram's built-in source supports private chats and groups. Other
108
+ channels use the same core grant when their adapter advertises the same event-
109
+ source contract. Authenticated owner application channels remain owner routes;
110
+ an untrusted web, voice or phone audience needs an event-source adapter and this
111
+ grant.
112
+
113
+ Capabilities are optional and provider-neutral. Put an array in a private
114
+ capability file; each entry has `id`, `description`, registered `command`, and a
115
+ fixed `args` array ending in `"--", "{input}"`. Example for an already installed
116
+ Library source:
117
+
118
+ ```json
119
+ [
120
+ {
121
+ "id": "knowledge",
122
+ "description": "Search the approved public Library source",
123
+ "command": "library-query",
124
+ "args": ["--library", "public", "--limit", "5", "--", "{input}"]
125
+ }
126
+ ]
127
+ ```
128
+
129
+ The registered alias must declare `channelQuery: true` with explicit exposure
130
+ metadata showing that it accepts external input but cannot send, change records,
131
+ or require interactive review. Core verifies that installed declaration on every
132
+ invocation. Verify the selected source and query alias first, then propose:
133
+
134
+ ```sh
135
+ ezenciel-agents-task propose --source telegram --any-conversation \
136
+ --purpose "Answer questions using approved public knowledge" \
137
+ --context-file work/public-answer-policy.txt \
138
+ --capability-file work/public-answer-capabilities.json
139
+ ```
140
+
141
+ The approval names the audience, disclosure context and exact command vectors.
142
+ Command output may be shown to anyone in that audience. External writes need
143
+ their own bounded tool contract and receipts. Revocation stops new capture,
144
+ cancels queued replies and rechecks every tool/send. Public Telegram groups must
145
+ mention or reply to the bot; one conversation can have only one outstanding run
146
+ and the source-wide public backlog is bounded. Core admits at most 60 public
147
+ conversations and 60 replies per hour. A grant revokes after 1,000 conversations
148
+ or replies so the owner must review continued broad access.
149
+
98
150
  The core presents the exact proposal for owner confirmation. Ordinary messages
99
151
  inside that grant need no repeated confirmations. Incoming-only grants create
100
152
  no initial run or opening message. They remain active across replies until expiry
package/docs/setup.md CHANGED
@@ -19,7 +19,8 @@ Make the bot a group admin so Telegram delivers ordinary member messages and
19
19
  allows membership verification for approval and control buttons. Group ownership only authorizes
20
20
  the exact approved chat, not other groups or members' private DMs. Telegram group
21
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
22
+ reply before considering setup complete. Unless an explicit any-conversation
23
+ grant is active, all other groups retain their existing
23
24
  restricted conversation-grant behavior.
24
25
 
25
26
  Ez supports two independent, composable uses: an autonomous Telegram agent and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jc_stack/ez-agents",
3
- "version": "0.1.0-beta.29",
3
+ "version": "0.1.0-beta.32",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "A lightweight foundation for persistent business AI assistants using existing AI harnesses, workspaces and plugins.",