@jc_stack/ez-agents 0.1.0-beta.12 → 0.1.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +4 -0
- package/.env.example +16 -1
- package/AGENTS.md +16 -4
- package/CHANGELOG.md +71 -0
- package/CONTRIBUTING.md +37 -4
- package/README.md +114 -9
- package/SECURITY.md +7 -1
- package/bin/ezenciel-agents-schedule +2 -0
- package/bin/ezenciel-agents-schedule.mjs +16 -0
- package/bin/ezenciel-agents-task +2 -0
- package/bin/ezenciel-agents-task.mjs +16 -0
- package/compose.yaml +10 -2
- package/docker/recovery.ts +2 -2
- package/docker/run.ts +2 -2
- package/docs/architecture/ai-selection.md +8 -0
- package/docs/architecture/authority-boundaries.md +137 -12
- package/docs/architecture/event-sources.md +12 -7
- package/docs/architecture/telegram-intake.md +1 -1
- package/docs/channel-backend.md +36 -0
- package/docs/docker-runtime.md +35 -0
- package/docs/host-service.md +19 -0
- package/docs/local-qa.md +45 -0
- package/docs/pagerduty.md +42 -0
- package/docs/plugin-catalog.md +71 -0
- package/docs/plugin-contributions.md +12 -0
- package/docs/plugins.md +61 -1
- package/docs/releasing.md +20 -9
- package/docs/repair.md +41 -0
- package/docs/scheduling.md +153 -0
- package/docs/selective-monitoring.md +114 -0
- package/docs/setup.md +46 -0
- package/docs/standalone-cli.md +62 -0
- package/docs/trusted-publishing.md +140 -0
- package/docs/upgrades.md +24 -4
- package/package.json +12 -4
- package/scripts/generate-publish-caller.mjs +60 -0
- package/scripts/smoke-busy-reply.ts +58 -0
- package/scripts/smoke-scheduler.ts +90 -0
- package/scripts/stage-qa.mjs +42 -0
- package/scripts/trusted-beta.mjs +289 -0
- package/src/agent-guidance.ts +5 -0
- package/src/ai-cli.ts +2 -1
- package/src/ai.ts +15 -5
- package/src/channel-backend.ts +46 -0
- package/src/client-defaults.ts +29 -13
- package/src/codex-session.ts +98 -0
- package/src/config.ts +35 -2
- package/src/control-state.ts +24 -7
- package/src/desktop-bridge.ts +37 -12
- package/src/event-sources.ts +2 -1
- package/src/execution-authority.ts +25 -0
- package/src/executor.ts +97 -21
- package/src/failure.ts +32 -0
- package/src/host-executor.ts +48 -19
- package/src/identity.ts +8 -3
- package/src/inbox.ts +11 -3
- package/src/index.ts +315 -91
- package/src/install-tools.mjs +2 -2
- package/src/menu.ts +6 -4
- package/src/model-policy.ts +15 -0
- package/src/owner.ts +3 -3
- package/src/pagerduty.ts +109 -0
- package/src/plugins/exposure.mjs +13 -0
- package/src/plugins/manager.mjs +74 -20
- package/src/plugins/shared.mjs +76 -0
- package/src/process-tree.ts +33 -0
- package/src/repair-policy.ts +13 -0
- package/src/reply-context.ts +67 -0
- package/src/reply-executor.ts +54 -0
- package/src/reply-mcp.ts +23 -0
- package/src/runs.ts +63 -19
- package/src/schedule-cli.ts +98 -0
- package/src/schedule-time.ts +85 -0
- package/src/scheduler.ts +130 -0
- package/src/setup.ts +2 -1
- package/src/software-status.ts +5 -5
- package/src/source-cli.ts +1 -1
- package/src/task-cli.ts +16 -0
- package/src/task-executor.ts +65 -0
- package/src/task-mcp.ts +36 -0
- package/src/task-rpc.ts +45 -0
- package/src/task-workspace.ts +22 -0
- package/src/tasks.ts +210 -0
- package/src/telegram-source.ts +94 -0
- package/src/updates/artifact.mjs +16 -0
- package/src/updates/binding.mjs +4 -1
- package/src/updates/control.mjs +4 -4
- package/src/updates/runtime.mjs +3 -1
- package/src/updates/status.mjs +7 -1
- package/templates/agent/AGENTS.md +10 -2
- package/templates/agent/TOOLS.md +60 -1
- package/templates/agent-guidance.md +13 -0
- package/templates/failure-review.md +9 -0
- package/templates/maintainer-purpose.md +15 -0
- package/templates/standalone-tools.md +20 -0
- package/templates/updates.md +2 -2
- package/test/agent-guidance.test.ts +110 -0
- package/test/ai-cli.test.ts +7 -6
- package/test/ai.test.ts +41 -0
- package/test/busy-reply-relay.test.ts +41 -0
- package/test/channel-backend.test.ts +100 -0
- package/test/client-defaults.test.ts +37 -5
- package/test/codex-context.test.ts +39 -1
- package/test/codex-session.test.ts +51 -0
- package/test/config.test.ts +31 -2
- package/test/desktop-bridge.test.ts +19 -0
- package/test/event-sources.test.ts +47 -11
- package/test/execution-authority.test.ts +42 -0
- package/test/executor.test.ts +53 -2
- package/test/failure.test.ts +250 -0
- package/test/group-owner.test.ts +36 -0
- package/test/helpers/owner-run.ts +13 -0
- package/test/host-executor.test.ts +47 -10
- package/test/intake-relay.test.ts +141 -4
- package/test/local-qa.test.mjs +38 -0
- package/test/model-policy.test.ts +61 -0
- package/test/pagerduty.test.ts +104 -0
- package/test/plugin-manager.test.mjs +73 -3
- package/test/relay.test.ts +2 -2
- package/test/repair-policy.test.ts +23 -0
- package/test/reply.test.ts +131 -0
- package/test/schedule-cli.test.ts +55 -0
- package/test/scheduler-host.test.ts +55 -0
- package/test/scheduler-relay.test.ts +67 -0
- package/test/scheduler.test.ts +104 -0
- package/test/shared-services.test.mjs +98 -0
- package/test/software-status.test.ts +5 -5
- package/test/task-native.test.ts +87 -0
- package/test/tasks.test.ts +187 -0
- package/test/telegram-source.test.ts +75 -0
- package/test/trusted-beta.test.mjs +224 -0
- package/test/updates.test.mjs +35 -3
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,153 @@
|
|
|
1
|
+
# Scheduling and background work
|
|
2
|
+
|
|
3
|
+
Ask the agent naturally: “Remind me on September 9 next year at 09:00 Dubai time”
|
|
4
|
+
or “Every Tuesday at 09:00, prepare the report.” The agent translates this into a
|
|
5
|
+
core CLI request. No plugin, database or operating-system cron setup is required.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
ezenciel-agents-schedule create --name Reminder \
|
|
9
|
+
--at 2027-09-09T09:00:00+04:00 --text 'Remind the owner about the renewal.'
|
|
10
|
+
ezenciel-agents-schedule create --name Weekdays \
|
|
11
|
+
--cron '0 9 * * 1-5' --timezone Asia/Dubai --text 'Prepare the daily report.'
|
|
12
|
+
ezenciel-agents-schedule create --name Research --now \
|
|
13
|
+
--text '/goal Complete the authorized research objective. Save evidence, verify the outcome, and send the owner the result.'
|
|
14
|
+
ezenciel-agents-schedule list
|
|
15
|
+
ezenciel-agents-schedule runs
|
|
16
|
+
ezenciel-agents-schedule pause SCHEDULE_ID
|
|
17
|
+
ezenciel-agents-schedule resume SCHEDULE_ID
|
|
18
|
+
ezenciel-agents-schedule remove SCHEDULE_ID
|
|
19
|
+
ezenciel-agents-schedule cancel RUN_ID
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Use `--text-file` for longer instructions. `edit ID` replaces the complete schedule
|
|
23
|
+
with a new revision; use the same trigger/name/text flags as `create`.
|
|
24
|
+
Intervals use `--every-seconds` (minimum 60), optional `--start`, and optional
|
|
25
|
+
`--until`. Cron also supports start/end bounds. All absolute timestamps require
|
|
26
|
+
an explicit offset. `--now` starts on the next relay tick, not synchronously.
|
|
27
|
+
|
|
28
|
+
Cron accepts five numeric fields, comma lists, ranges and steps; Sunday is 0 or 7.
|
|
29
|
+
Restricted day-of-month and weekday fields use standard OR semantics. Set just
|
|
30
|
+
weekday for “Tuesdays.” Calendar jobs retain their explicit IANA timezone when
|
|
31
|
+
the host changes zones. Nonexistent DST wall times are skipped; repeated wall
|
|
32
|
+
times fire once, at the earlier instant. Search is bounded to eight years.
|
|
33
|
+
Public-holiday calendars and arbitrary RRULE syntax are not implemented.
|
|
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
|
+
Use `--cli`, `--model`, and `--effort` to specify another choice; reasoning
|
|
38
|
+
explicitly selected above `high` is rejected for every model. Non-Codex adapters
|
|
39
|
+
inherit native effort when unset. Editing preserves the existing AI
|
|
40
|
+
choice unless those flags override it. Stored choices are checked again at
|
|
41
|
+
launch, including schedules saved before the cap.
|
|
42
|
+
|
|
43
|
+
## Execution and authority
|
|
44
|
+
|
|
45
|
+
The relay checks due work once per second. Each occurrence enters the durable
|
|
46
|
+
run queue with a stable ID. Background work runs in a fresh native CLI session
|
|
47
|
+
and `work/tasks/RUN_ID/`, with snapshots of the agent's SOUL, USER and TOOLS files.
|
|
48
|
+
Instructions must include any needed context or source paths; full chat history
|
|
49
|
+
is not copied. Task folders remain for inspection and artifact delivery.
|
|
50
|
+
|
|
51
|
+
One writer runs per task directory. Up to four background tasks can run alongside
|
|
52
|
+
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
|
|
53
|
+
or active occurrence. Agents should delegate long work with `create --now`, return
|
|
54
|
+
to chat, and inspect `runs` or task progress when asked. Native subagents can be
|
|
55
|
+
used inside the worker. Sharing provider profiles does not make concurrent CRM,
|
|
56
|
+
file or browser writes safe: the agent must coordinate those resources.
|
|
57
|
+
|
|
58
|
+
Production relay/host execution has no wall-clock timeout. The old
|
|
59
|
+
`EZ_EXECUTOR_TIMEOUT_SECONDS` setting is ignored. Individual network/tool waits
|
|
60
|
+
still have their own limits; those are not overall task deadlines. Native goals
|
|
61
|
+
are an executor capability, configured through instructions. Ez has no goal API,
|
|
62
|
+
continuation loop or rule equating a process exit with goal achievement.
|
|
63
|
+
|
|
64
|
+
Scheduled Codex CLI tasks use a dedicated native app-server session, tested with
|
|
65
|
+
CLI 0.153.4. A leading `/goal` in the instruction text maps to the same native
|
|
66
|
+
goal command used by the interactive CLI. Codex automatically starts subsequent
|
|
67
|
+
turns; the transport stays connected until the native goal is complete or stops
|
|
68
|
+
for attention. It sends no continuation prompts and stores no Ez goal state.
|
|
69
|
+
Goals created by the agent's native tools also keep the session alive. Ordinary
|
|
70
|
+
tasks finish after their turn. A blocked, paused or limited goal is not reported
|
|
71
|
+
as successful. Native RPC requests have a response deadline; running tasks do not.
|
|
72
|
+
Each scheduled task has its own Codex state under `control/cli/codex/tasks/RUN_ID`,
|
|
73
|
+
with a snapshot of the agent's Codex configuration and the existing auth link.
|
|
74
|
+
Foreground chat and background tasks do not initialize or migrate one shared
|
|
75
|
+
native database concurrently.
|
|
76
|
+
|
|
77
|
+
The foreground chat still uses `codex exec`. That invocation exits after one
|
|
78
|
+
requested turn even if a goal is active, so delegate persistent work to the
|
|
79
|
+
scheduler. Desktop and other executor goal lifecycles need separate validation.
|
|
80
|
+
|
|
81
|
+
The CLI binds jobs to the paired owner and the task AI choice. Queued/scheduled
|
|
82
|
+
work retains that choice after the chat switches AI. Revoking/re-pairing an
|
|
83
|
+
owner invalidates their old schedules, including re-pairing the same Telegram ID.
|
|
84
|
+
External event turns cannot use the scheduling CLI. Credentials still pass only
|
|
85
|
+
through the existing whitelist and installed host binding.
|
|
86
|
+
|
|
87
|
+
## Restart, pause and cancellation
|
|
88
|
+
|
|
89
|
+
Schedule definitions and cursors use protected atomic JSON files. A restart
|
|
90
|
+
between queue creation and cursor persistence does not duplicate an occurrence.
|
|
91
|
+
An overdue one-time job runs on return. Missed recurring occurrences coalesce into
|
|
92
|
+
one pending run; future runs resume at the next eligible time. A paused queued
|
|
93
|
+
occurrence waits for resume. Editing/removing a schedule invalidates its old
|
|
94
|
+
queued occurrence; already-running work continues until explicitly cancelled.
|
|
95
|
+
|
|
96
|
+
`/stop` stops all active work; `cancel RUN_ID` stops one background task. `/cancel`
|
|
97
|
+
clears queued work. Pause/remove a recurring schedule to prevent future runs.
|
|
98
|
+
Stopping the relay also stops its workers. A crashed or interrupted execution is
|
|
99
|
+
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
|
|
100
|
+
`interrupted: true`; their schedule revision stays held until the agent inspects
|
|
101
|
+
the evidence and explicitly edits the schedule. Inspect the task's files, native session and delivery
|
|
102
|
+
receipts before deciding whether to resume. A clock cannot reconstruct an
|
|
103
|
+
in-flight process or prove whether an external side effect happened.
|
|
104
|
+
|
|
105
|
+
The host and relay must be online. Paused/completed schedule definitions and task
|
|
106
|
+
artifacts are retained. The agent sends through the normal Telegram outbox;
|
|
107
|
+
`completed` means executor exit, while provider delivery is recorded separately.
|
|
108
|
+
A timeout or ambiguous send must not cause blind replay of the whole task.
|
|
109
|
+
|
|
110
|
+
## QA
|
|
111
|
+
|
|
112
|
+
`pnpm verify` covers recurrence/DST, restart deduplication, authority revocation,
|
|
113
|
+
corrupt state, paths, cancellation and a chat response while a synthetic worker
|
|
114
|
+
is active. Docker tests exercise the packaged host transport and isolation.
|
|
115
|
+
|
|
116
|
+
For an opt-in real CLI probe (consumes model usage):
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
pnpm smoke:scheduler -- 1860 codex
|
|
120
|
+
# Native goal must finish a first turn and continue without another prompt:
|
|
121
|
+
pnpm smoke:scheduler -- 45 codex goal
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
This uses temporary workspaces and a synthetic Telegram provider, never live
|
|
125
|
+
contacts. A real CLI waits 31 minutes while a second invocation answers 17 × 19.
|
|
126
|
+
It checks responsiveness again after six minutes and requires the worker's final
|
|
127
|
+
message. Evidence is saved in the printed temporary directory. Use `75 codex`
|
|
128
|
+
for a shorter iteration; it does not prove the full duration.
|
|
129
|
+
|
|
130
|
+
Before enabling on a real installation, repeat through its Telegram bot: request
|
|
131
|
+
the 31-minute task, ask the arithmetic question and request status after six
|
|
132
|
+
minutes. Verify `finished.txt` and exactly one completion in Telegram. Separately
|
|
133
|
+
exercise cancellation, downtime catch-up and an explicitly requested native goal
|
|
134
|
+
that needs more than one turn. Synthetic provider evidence does not prove real
|
|
135
|
+
Telegram delivery, and a sleep test does not prove native goal persistence.
|
|
136
|
+
|
|
137
|
+
Busy-chat regression probe (real Codex, synthetic Telegram):
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
pnpm exec tsx scripts/smoke-busy-reply.ts --transport
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The probe holds a writer on a shared workspace, asks an owner question through
|
|
144
|
+
the relay and host transport, and requires the restricted reply to complete
|
|
145
|
+
while the writer remains active. It sends no real Telegram messages.
|
|
146
|
+
|
|
147
|
+
## Optional failure review
|
|
148
|
+
|
|
149
|
+
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.
|
|
150
|
+
|
|
151
|
+
`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.
|
|
152
|
+
|
|
153
|
+
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.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Selective monitoring and replies
|
|
2
|
+
|
|
3
|
+
An owner saying “monitor and answer messages from CONTACT” has selected that
|
|
4
|
+
contact and authorized ordinary replies within the stated scope. Do not ask
|
|
5
|
+
whether they meant selected contacts or demand a special phrase. “If they send,
|
|
6
|
+
reply” means wait for incoming messages; it does not authorize an opening send.
|
|
7
|
+
Resolve only missing identity or disclosure scope. A saved Markdown instruction
|
|
8
|
+
is a reminder, never an activated source, watch or reply permission.
|
|
9
|
+
|
|
10
|
+
## Speak in jobs, not modes
|
|
11
|
+
|
|
12
|
+
Keep mode names internal. Linking/syncing an account defaults to quiet capture;
|
|
13
|
+
finish connection verification, then at most one short optional prompt such as
|
|
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.
|
|
17
|
+
|
|
18
|
+
Infer the complete job from ordinary language:
|
|
19
|
+
|
|
20
|
+
- “Find out whether they have a table” or “Book me a restaurant”: send the inquiry,
|
|
21
|
+
watch replies from that contact, continue the multi-turn negotiation and report
|
|
22
|
+
the outcome. A send receipt is not completion. Do not ask if follow-up is wanted.
|
|
23
|
+
- Twelve inquiries mean twelve task-scoped contacts, not all-inbox monitoring.
|
|
24
|
+
Maintain one scoped task per correspondent; the same core checks apply to each.
|
|
25
|
+
- “Just send this; I will reply”: one-off send under the explicit owner instruction,
|
|
26
|
+
no new watch or conversational mandate. Use the provider's ordinary send and
|
|
27
|
+
receipt interface; do not create a messaging task that would auto-follow up.
|
|
28
|
+
- “Monitor this person and answer if they message”: incoming-only reply task;
|
|
29
|
+
no opening message and no unrelated contact attention.
|
|
30
|
+
- “Keep these messages for me”: quiet capture/read-on-request. If “monitor” alone
|
|
31
|
+
leaves action intent unclear, ask one plain question: “Should I reply for you,
|
|
32
|
+
or just keep the messages for you to review?” Do not ask when the job resolves it.
|
|
33
|
+
|
|
34
|
+
Apply the required core confirmation to the concrete proposal, not an extra
|
|
35
|
+
questionnaire. Use the owner's existing contact, purpose and disclosure limits.
|
|
36
|
+
For an ongoing incoming-only conversation, use `--until-revoked`; finite tasks remain bounded. Explain the expiry only
|
|
37
|
+
when it matters to that proposed job; never silently expand or renew permission.
|
|
38
|
+
|
|
39
|
+
## Three capture modes, separate reply authority
|
|
40
|
+
|
|
41
|
+
- Manual: capture for explicit reads, with no general wake-up subscription.
|
|
42
|
+
- Selected: wake for named contacts only. Never turn on all-inbox mode to satisfy
|
|
43
|
+
a one-contact request.
|
|
44
|
+
- All: attention for all eligible incoming contacts; requires that broader
|
|
45
|
+
owner request. Attention alone never grants autonomous reply permission.
|
|
46
|
+
|
|
47
|
+
For an approved core reply task, the provider's task-watch supplies expiring
|
|
48
|
+
selected attention even if its general policy remains manual. That is expected:
|
|
49
|
+
verify the actual task watch and core grant, not only the general policy label.
|
|
50
|
+
Monitoring-only requests grant no sends. Unsupported wake-only reasoning modes
|
|
51
|
+
must be reported as unsupported, not run with owner authority.
|
|
52
|
+
|
|
53
|
+
## Complete the setup under the owner's request
|
|
54
|
+
|
|
55
|
+
Use the current installed plugin skill and `ez plugins list`/`status`/provider
|
|
56
|
+
doctor to confirm the existing linked account. Installation, source plumbing,
|
|
57
|
+
contact attention and permission are separate checks. A missing source is
|
|
58
|
+
technical work for the agent, not a reason to stop at “saved your instruction.”
|
|
59
|
+
Do not request a second provider instance or re-pair an already linked account.
|
|
60
|
+
|
|
61
|
+
The relay must be able to reach the registered provider service socket. Inspect
|
|
62
|
+
the registered deployment/compose, actual named IPC volume, and relay mounts.
|
|
63
|
+
For the supplied WhatsApp adapter the socket is /plugins/whatsapp/service.sock;
|
|
64
|
+
main compose.whatsapp.yaml supplies a read-only IPC/client override. Use the
|
|
65
|
+
registered plugin's real volume names, preserve existing docker.env/Compose
|
|
66
|
+
settings, and attach only its declared IPC/client volumes (never its profile or
|
|
67
|
+
credentials). Recreate the relay with the existing deployment after a required
|
|
68
|
+
mount change; verify it comes back. Do not expose the Docker socket to it.
|
|
69
|
+
|
|
70
|
+
Register the source INSIDE that relay container using the installed
|
|
71
|
+
`ezenciel-agents-source --name NAME --socket ABSOLUTE_SOCKET` command. Read back
|
|
72
|
+
registration and provider events-head account identity. A socket inside a
|
|
73
|
+
provider command container is not proof the relay can reach it. Do not edit core
|
|
74
|
+
source/grant JSON directly. Other adapters use their declared socket paths;
|
|
75
|
+
provider names do not change authority checks.
|
|
76
|
+
|
|
77
|
+
## Propose, confirm, verify
|
|
78
|
+
|
|
79
|
+
For an outbound job such as a booking, use `ezenciel-agents-task propose` WITHOUT
|
|
80
|
+
`--incoming-only`: it starts the inquiry and then watches replies. For “answer if
|
|
81
|
+
they message,” use `ezenciel-agents-task propose --incoming-only` with the
|
|
82
|
+
registered source, canonical contact, purpose, explicitly shareable context file
|
|
83
|
+
and expiry. No need to invent a booking objective: “conversational replies to
|
|
84
|
+
this contact, no private disclosures or commitments” is a legitimate purpose.
|
|
85
|
+
If no private facts may be shared, say so in the context file; do not include
|
|
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.
|
|
97
|
+
|
|
98
|
+
The core presents the exact proposal for owner confirmation. Ordinary messages
|
|
99
|
+
inside that grant need no repeated confirmations. Incoming-only grants create
|
|
100
|
+
no initial run or opening message. They remain active across replies until expiry
|
|
101
|
+
or owner revocation; the worker cannot close a watch by calling `complete`.
|
|
102
|
+
After handling a message, save a task note and finish the run. After approval, verify active core state,
|
|
103
|
+
contact and expiry, source reachability, and the provider's task watch. With
|
|
104
|
+
`--incoming-only`, an empty conversation is correctly idle until a new message.
|
|
105
|
+
If approval is still pending, say pending; if setup failed, name the actual
|
|
106
|
+
failure and continue repair within scope. Never report “active” based on notes,
|
|
107
|
+
installation, connected status or subscription alone.
|
|
108
|
+
|
|
109
|
+
After an authorized test message, inspect the corresponding task run and send
|
|
110
|
+
receipt and compare recipient readback. An accepted send is not proof of delivery.
|
|
111
|
+
After revocation/expiry no subsequent reply may dispatch. Keep these checks
|
|
112
|
+
agent-owned: the owner supplies only necessary confirmation, QR scan if needed,
|
|
113
|
+
and the test contact/message. Do not bypass a missing grant by polling the inbox
|
|
114
|
+
in an unrestricted scheduled owner session or sending through the raw CLI.
|
package/docs/setup.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
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
|
+
|
|
25
|
+
Ez supports two independent, composable uses: an autonomous Telegram agent and
|
|
26
|
+
workspace-scoped plugins called by your existing local CLI/GUI executor.
|
|
27
|
+
For CLI-only requests, follow [standalone setup](standalone-cli.md): no Telegram
|
|
28
|
+
pairing, relay or host executor is required. The main-first Telegram onboarding
|
|
29
|
+
rules below apply only when installing the autonomous relay. When both are
|
|
30
|
+
requested, keep each workspace's authority and registry explicit.
|
|
31
|
+
|
|
3
32
|
The user starts in their existing CLI and says “install Ezenciel”, then “create
|
|
4
33
|
an agent as my family shopper”. The installing agent does the technical work.
|
|
5
34
|
Keep that host CLI and login for every agent; do not request another CLI login.
|
|
@@ -23,6 +52,23 @@ owner request for standalone plugin development is a separate workflow.
|
|
|
23
52
|
|
|
24
53
|
## Defaults and host prerequisites
|
|
25
54
|
|
|
55
|
+
New agents using `codex` or `codex-gui` start with `gpt-5.6-terra` and `high`
|
|
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 at or below high are preserved; use the AI settings to choose another model or effort.
|
|
59
|
+
Ez rejects explicit reasoning above `high` for every model at selection and execution,
|
|
60
|
+
including old saved or queued choices. Unset Codex model/effort resolves to
|
|
61
|
+
Terra/high at launch. This governs Ez-managed launches; it is not an account-wide
|
|
62
|
+
limit on independently launched native clients or executor-created native subagents.
|
|
63
|
+
Other adapters inherit their native effort when none is selected in Ez. That
|
|
64
|
+
inherited configuration is not capped by Ez; explicit above-high Ez selections
|
|
65
|
+
are still rejected. Only Codex adapters receive the default `high` effort.
|
|
66
|
+
|
|
67
|
+
New scheduled and one-off background tasks default to Codex Terra/high independently
|
|
68
|
+
of the creating chat. Use scheduler `--cli`, `--model`, and `--effort` flags for
|
|
69
|
+
explicit overrides. Editing a schedule preserves its settings unless overridden.
|
|
70
|
+
Restricted messaging tasks also use Terra/high when no settings are supplied.
|
|
71
|
+
|
|
26
72
|
Use the existing owner's host account. Unless a layout was supplied, use
|
|
27
73
|
`${XDG_DATA_HOME:-$HOME/.local/share}/ez/packages/<version>/` for extracted main
|
|
28
74
|
packages and `${XDG_DATA_HOME:-$HOME/.local/share}/ez/agents/` for private deployments.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Use Ez from your existing executor
|
|
2
|
+
|
|
3
|
+
The plugin manager and its Docker plugins work independently of the Telegram
|
|
4
|
+
relay. Use the same absolute launcher from any local executor to share a chosen
|
|
5
|
+
workspace's tools and accounts. The executor owns reasoning and conversation;
|
|
6
|
+
Ez owns the plugin registry and command transport. No provider-specific adapter,
|
|
7
|
+
new model login or GUI plugin installation is involved.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
Install the main package and its dependencies in a permanent location using the
|
|
12
|
+
artifact steps in [setup](setup.md). Node 22+ is needed for the manager; Docker
|
|
13
|
+
and Compose are needed for executable plugins. Do not build/start the relay,
|
|
14
|
+
create a bot, pair an owner or configure a host executor for CLI-only use.
|
|
15
|
+
Create a private tools directory and select the existing company/project workspace:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
node /absolute/package/bin/ezenciel-agents-tools.mjs init --standalone \
|
|
19
|
+
--home /absolute/private/company-tools --workspace /absolute/company-workspace
|
|
20
|
+
/absolute/private/company-tools/bin/ez --help
|
|
21
|
+
/absolute/private/company-tools/bin/ez status
|
|
22
|
+
/absolute/private/company-tools/bin/ez plugins list
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Init starts nothing, uses an empty catalog by default, preserves existing
|
|
26
|
+
TOOLS.md notes and appends the registry's discovery instructions. A registry
|
|
27
|
+
cannot be replaced by rerunning init. Keep the package at its original path:
|
|
28
|
+
the launcher imports it. Status reports `main: null` without a relay binding;
|
|
29
|
+
automated software upgrades currently require a relay deployment.
|
|
30
|
+
|
|
31
|
+
Have each executor read the workspace's TOOLS.md and the installed plugin skills.
|
|
32
|
+
Add that instruction to its existing project instructions without replacing them.
|
|
33
|
+
Use the absolute launcher, or prepend its bin directory to that session's PATH.
|
|
34
|
+
Never overwrite another global `ez`; it may belong to a different installation.
|
|
35
|
+
A company registry remains explicit even when invoked from a different directory.
|
|
36
|
+
Other projects/accounts should use separate registries and private plugin state.
|
|
37
|
+
|
|
38
|
+
## Install and verify a capability
|
|
39
|
+
|
|
40
|
+
The current conversation owns authorized plugin onboarding. Follow the
|
|
41
|
+
[plugin contract](plugins.md#installation-completion-contract), using the bound
|
|
42
|
+
launcher for `plugins inspect <id> --source /absolute/package`, then
|
|
43
|
+
`plugins install <id> --source /absolute/package --revision <inspected-hash>`.
|
|
44
|
+
Read the skill, start the plugin, complete its provider authentication and verify
|
|
45
|
+
the intended account with a supported operation. Deliver any necessary consent
|
|
46
|
+
link or QR in the current client. No Telegram handoff is required.
|
|
47
|
+
|
|
48
|
+
Run `tools list`, the registered alias's help and a harmless account operation
|
|
49
|
+
from each actual executor. Host-shell access alone does not prove a sandboxed
|
|
50
|
+
session can access Docker or the registry. Client permissions still apply.
|
|
51
|
+
Native client plugins/connectors are not converted into Ez plugins automatically.
|
|
52
|
+
|
|
53
|
+
## Combine with an autonomous agent
|
|
54
|
+
|
|
55
|
+
A relay can coexist with CLI-only registries on the same machine. It retains its
|
|
56
|
+
own pairing, single-writer queue, mind and plugin registry. Calling its existing
|
|
57
|
+
bound launcher explicitly reuses that registry and its accounts; never initialize
|
|
58
|
+
over it or silently select it from another workspace. Coordinate writes with its
|
|
59
|
+
active jobs. Separate registries do not automatically share credentials or data.
|
|
60
|
+
|
|
61
|
+
Continuous monitoring requires a configured event consumer/relay and the plugin's
|
|
62
|
+
supported watcher. CLI-only installation does not create background agent turns.
|
|
@@ -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.
|