Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2a0694c
feat: define scheduler handoff v4 artifact
kebabman9001 Jul 19, 2026
1405312
ci: pin handoff v4 scheduler contract
kebabman9001 Jul 19, 2026
c613f31
fix: require explicit handoff v4 capabilities
kebabman9001 Jul 19, 2026
e6f9dc5
ci: test final scheduler review commit
kebabman9001 Jul 19, 2026
cd1298a
fix: close handoff v4 release gaps
kebabman9001 Jul 19, 2026
597e955
test: honor exact handoff v4 negotiation
kebabman9001 Jul 19, 2026
aebb6bc
fix: bind scheduler routing controls
kebabman9001 Jul 19, 2026
3bd1aab
fix: preserve v4 compile environment
kebabman9001 Jul 19, 2026
cce0e40
fix: close final handoff v4 review gaps
amittell Jul 19, 2026
656abee
ci: pin final handoff v4 scheduler
amittell Jul 19, 2026
1f160d2
fix: close late handoff v4 review gaps
kebabman9001 Jul 19, 2026
7e22011
fix: bind watchdog execution controls
kebabman9001 Jul 19, 2026
7c8688c
fix: close final handoff v4 review gaps
kebabman9001 Jul 19, 2026
660ebe3
fix: preserve handoff v4 runtime bindings
kebabman9001 Jul 19, 2026
9d9fa89
ci: pin final Scheduler handoff candidate
kebabman9001 Jul 19, 2026
4ff8272
fix: close final handoff v4 integrity gaps
kebabman9001 Jul 19, 2026
484fdaa
fix: verify v4 job binding before rebind
kebabman9001 Jul 19, 2026
0314a13
fix: fail closed on invalid proof clocks
kebabman9001 Jul 19, 2026
047ec5a
fix: reject out-of-range proof timestamps
kebabman9001 Jul 19, 2026
e35478d
fix: close v4 fail-closed review gaps
kebabman9001 Jul 19, 2026
92eb60f
ci: pin final handoff v4 scheduler
kebabman9001 Jul 19, 2026
176ef20
Fix final handoff v4 validation gaps
kebabman9001 Jul 19, 2026
a7e8194
Pin final handoff v4 Scheduler revision
kebabman9001 Jul 19, 2026
4c9a7fd
Bind persisted v4 evidence hashes
kebabman9001 Jul 19, 2026
ec52b60
Gate v4 scheduler artifact discovery
kebabman9001 Jul 19, 2026
3d710f3
Harden remaining handoff v4 bindings
kebabman9001 Jul 19, 2026
3c85978
Harden final handoff v4 verification bindings
kebabman9001 Jul 19, 2026
6fe2790
Harden final v4 validation compatibility
kebabman9001 Jul 19, 2026
24e25dd
Pin final v4 scheduler release candidate
kebabman9001 Jul 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ jobs:
matrix:
node-version: ['22.13.0', '24.x']
env:
OPENCLAW_SCHEDULER_REF: ac9ea643a8efc68e9f81c8d93125467ca62140b5
OPENCLAW_SCHEDULER_REF: dbd353e9eef4342fe4b5cdeb63e2ffa2006a5119
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Check out pinned openclaw-scheduler
uses: actions/checkout@v5
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: amittell/openclaw-scheduler
ref: ac9ea643a8efc68e9f81c8d93125467ca62140b5
ref: dbd353e9eef4342fe4b5cdeb63e2ffa2006a5119
path: openclaw-scheduler
- name: Configure scheduler fixture path
run: echo "SCHEDULER_PATH=$RUNNER_TEMP/openclaw-scheduler" >> "$GITHUB_ENV"
- uses: actions/setup-node@v5
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
Expand All @@ -47,6 +47,9 @@ jobs:
node bin/openclaw-scheduler.js --json capabilities > /dev/null
- run: npm run lint
- run: npm test
- name: Verify shared handoff v4 fixture parity
run: cmp fixtures/handoff-v4/conformance.json "$SCHEDULER_PATH/fixtures/handoff-v4/conformance.json"
- run: npm run verify:package

lint-test:
name: lint-test
Expand Down
66 changes: 59 additions & 7 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,40 @@ on:
push:
tags: ['v*']

concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
env:
OPENCLAW_SCHEDULER_REF: ac9ea643a8efc68e9f81c8d93125467ca62140b5
OPENCLAW_SCHEDULER_REF: dbd353e9eef4342fe4b5cdeb63e2ffa2006a5119
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Verify tagged commit is contained in main
run: |
git fetch --no-tags origin '+refs/heads/main:refs/remotes/origin/main'
TAG_COMMIT="$(git rev-list -n 1 "$GITHUB_REF_NAME")"
if ! git merge-base --is-ancestor "$TAG_COMMIT" refs/remotes/origin/main; then
echo "Tag $GITHUB_REF_NAME points to $TAG_COMMIT, which is not contained in origin/main"
exit 1
fi
- name: Check out pinned openclaw-scheduler
uses: actions/checkout@v5
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: amittell/openclaw-scheduler
ref: ac9ea643a8efc68e9f81c8d93125467ca62140b5
ref: dbd353e9eef4342fe4b5cdeb63e2ffa2006a5119
path: openclaw-scheduler
- name: Configure scheduler fixture path
run: echo "SCHEDULER_PATH=$RUNNER_TEMP/openclaw-scheduler" >> "$GITHUB_ENV"
- uses: actions/setup-node@v5
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'
cache: npm
Expand All @@ -40,21 +55,58 @@ jobs:
node bin/openclaw-scheduler.js --json capabilities > /dev/null
- run: npm run lint
- run: npm test
- name: Verify shared handoff v4 fixture parity
run: cmp fixtures/handoff-v4/conformance.json "$SCHEDULER_PATH/fixtures/handoff-v4/conformance.json"
- run: npm run verify:package

publish:
needs: test
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
id-token: write
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Verify tagged commit is contained in main
run: |
git fetch --no-tags origin '+refs/heads/main:refs/remotes/origin/main'
TAG_COMMIT="$(git rev-list -n 1 "$GITHUB_REF_NAME")"
if ! git merge-base --is-ancestor "$TAG_COMMIT" refs/remotes/origin/main; then
echo "Tag $GITHUB_REF_NAME points to $TAG_COMMIT, which is not contained in origin/main"
exit 1
fi
- name: Require successful main CI for tagged commit
env:
GH_TOKEN: ${{ github.token }}
run: |
tag_commit="$(git rev-list -n 1 "$GITHUB_REF_NAME")"
deadline=$((SECONDS + 1800))
while [ "$SECONDS" -lt "$deadline" ]; do
run_json="$(gh api "repos/${GITHUB_REPOSITORY}/actions/workflows/ci.yml/runs?event=push&head_sha=${tag_commit}&per_page=20")"
status="$(printf '%s' "$run_json" | jq -r '[.workflow_runs[] | select(.head_branch == "main")] | sort_by(.run_number) | last | .status // "missing"')"
conclusion="$(printf '%s' "$run_json" | jq -r '[.workflow_runs[] | select(.head_branch == "main")] | sort_by(.run_number) | last | .conclusion // "pending"')"
if [ "$status" = "completed" ] && [ "$conclusion" = "success" ]; then
exit 0
fi
if [ "$status" = "completed" ] && [ "$conclusion" != "success" ]; then
echo "Main CI for $tag_commit completed with conclusion $conclusion"
exit 1
fi
sleep 10
done
echo "Timed out waiting for successful main CI for $tag_commit"
exit 1
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'
cache: npm
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run verify:package
- name: Verify tag matches package.json version
env:
TAG_REF: ${{ github.ref_name }}
Expand Down
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
# Changelog

## 0.5.0 (2026-07-19)

- scheduler: added handoff v4 canonical artifacts with explicit artifact,
canonicalization, execution-binding, and scheduler-binding versions
- discovery: added Draft 2020-12 schema access for the complete handoff v4
artifact through CLI, JSON-RPC, and the public handoff module
- validation: handoff v4 artifacts now reject missing required identity fields,
invalid nested types, and unknown properties before semantic verification
- negotiation: v4 now requires scheduler schema 29 or newer plus an exact live
artifact, canonicalization, digest, and binding contract; partial or
mismatched runtimes, including contracts with extra keys, fall back to v3
- negotiation: every apply, including basic v0.1 manifests, probes the live
runtime so v4 coverage is complete; static fallback enforcement features are
disabled until explicitly advertised
- scheduler: complete non-lossy create, replace-style update, null clear, and
adopt projections now carry the immutable artifact payload and digest
- scheduler: adoption rebinds the artifact after the final origin is selected,
and apply preserves direct-compile hashes for the caller's explicit compile
environment while host variables are merged only for scheduler process spawn
- scheduler: direct main and isolated delegation negotiates v4 before compiling
and binds its one-off lifecycle before artifact construction; v4 JSON columns
use the same undefined-to-null canonicalization as their artifact binding
- scheduler: update and adoption validate the persisted v4 artifact, compiled
identity, and current execution projection before preserving runtime
overrides; the CLI adapter requests opt-in artifact hydration only after
exact v4 negotiation, while legacy-safe listing remains flag-free
- security: JWT, detached-signature, and certificate proofs bind the exact v4
artifact, replay identifier, validity, key, and revocation result
- security: v4 proofs reject inverted validity intervals, bind asserted key IDs
to the key or certificate that actually verified, and require an explicit
not-revoked result from the runtime checker
- security: JWT artifact claims and trusted context now require the exact
lowercase `sha256:<64 hex>` representation before v4 binding can succeed
- security: detached-signature and certificate artifact bindings now require
the same canonical digest representation, and every v4 proof method accepts
replay claims only from an explicit, non-conflicting claimed result
- security: JWKS-provided raw JWK objects are normalized before stable public
key identity derivation, while private JWK material remains forbidden
- security: credential handoff compiles to exactly one runtime medium without
persisting values, and delegation binds the exact source run and scope
- evidence: the complete AgentCLI evidence payload and verification envelope
are available to the scheduler runtime for signed or provider-verified
terminal evidence
- evidence: payload and provider-configuration hashes are explicit required
nullable fields and are retained in the sanitized scheduler declaration for
exact artifact parity while raw provider configuration remains absent
- evidence: persisted declarations must match artifact evidence semantics and
hashes; explicitly v4 evidence records require a canonical artifact digest,
child records require complete source-run lineage, and terminal status and
structured-output hashes must exactly match the surrounding audit record
- validation: v4 command argument counts and aggregate argument digests are
recomputed, and every declared evidence block requires a canonical payload
hash even when the authored profile omits an explicit payload object
- inspect: added immutable artifacts, runtime events, provider sessions, and
credential presentations to the scheduler inspection surface, with every
entity enumerated in JSON help and structured command discovery
- conformance: added shared positive and negative v4 fixtures and exact digest
parity tests with OpenClaw Scheduler
- examples: added a public scheduler manifest for exercising negotiated v4
apply and schema discovery
- compatibility: handoff versions 1 through 3 and manifest versions 0.1 and 0.2
retain their existing behavior

## 0.4.1 (2026-07-13)

- scheduler: post-success verification for shell tasks now runs from the task working directory while retaining the runtime-provided execution environment, and expanded verifier commands are checked against the scheduler's storage limit before apply
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ Use `agentcli signing providers` to list the registered signing providers and th
| `version` | Show package and manifest spec version. |
| `init [--tool program] [--output path] [--workflow-id id] [--task-id id]` | Initialize agentcli home directory with starter manifests. |
| `paths` | Show resolved agentcli home, manifest, output, state, and audit paths. |
| `schema [target] [--legacy]` | Emit Draft 2020-12 JSON Schema for manifest, workflow, task, schedulerJob, standalonePlan, rpcRequest, or rpcResponse. `--legacy` opts into the older agentcli descriptor format. |
| `schema [target] [--legacy]` | Emit Draft 2020-12 JSON Schema for manifest, workflow, task, schedulerJob, standalonePlan, handoffV4, rpcRequest, or rpcResponse. The `handoff-v4` alias exposes the immutable scheduler artifact contract. `--legacy` opts into the older agentcli descriptor format. |
| `describe [target]` | Describe manifest, workflow, task, targets, commands, or rpc surfaces as structured JSON. |
| `targets` | List available compilation targets. |
| `skill-path` | Print the path to the agentcli skill manifest for MCP tool registration. |
Expand Down Expand Up @@ -426,7 +426,7 @@ Approvals are single-use and consumed before `spawnSync` (fail-closed: a crashed

| Command | Description |
|---|---|
| `inspect <jobs\|runs\|queue\|approvals> [--db path] [--fields a,b,c] [--limit n] [--sanitize basic] [--ndjson]` | Inspect scheduler runtime state with field masks and sanitization. |
| `inspect <jobs\|runs\|queue\|approvals\|evidence\|artifacts\|events\|provider_sessions\|credential_presentations> [--db path] [--fields a,b,c] [--limit n] [--sanitize basic] [--ndjson]` | Inspect scheduler runtime state with field masks and sanitization. |
| `audit [--limit n]` | Display recent audit records from the append-only log. |
| `verify <execution-id> [--allowed-signers path]` | Verify execution evidence for a completed run. |
| `signing providers` | List registered signing providers and their attestation methods. |
Expand Down Expand Up @@ -481,7 +481,7 @@ See [docs/protocol.md](docs/protocol.md) for the full protocol specification.
| Target | Description |
|---|---|
| `standalone` | Portable plan for authoring, validation, explanation, and protocol use. No durable runtime required. |
| `openclaw-scheduler` | Compiler target for the durable scheduler runtime. Apply uses live runtime capabilities when reported and conservative static fallback values otherwise. Governed root approvals, approver scopes, structured output, and v3 handoff fields require explicit runtime support. |
| `openclaw-scheduler` | Compiler target for the durable scheduler runtime. Apply uses live runtime capabilities when reported and conservative static fallback values otherwise. Handoff v4 adds immutable canonical execution artifacts, artifact-bound proofs and evidence, exact source-run delegation, provider sessions, credential presentation, and runtime events. Handoff versions 1 through 3 remain compatible. |

```bash
# Compile for standalone use
Expand All @@ -493,8 +493,18 @@ agentcli compile my-workflow.json --target openclaw-scheduler --explain
# Apply to the scheduler (creates or updates jobs)
agentcli apply my-workflow.json --dry-run
agentcli apply my-workflow.json

# Discover and exercise the handoff v4 contract
agentcli schema handoff-v4
agentcli apply examples/handoff-v4.json --check-capabilities
```

AgentCLI emits v4 only when the live scheduler advertises schema version 29 or
newer, every required v4 feature, and an exact `handoff_contract` match for the
artifact schema, canonicalization, digest, undefined-value handling, execution
binding, and scheduler job binding. Missing or mismatched contract metadata
falls back to handoff v3, so partial v4 support is never persisted.

## Migration from v0.1

v0.1 manifests continue to work unchanged. The validator accepts both versions, and the execution path for v0.1 manifests is preserved.
Expand Down
2 changes: 1 addition & 1 deletion docs/adoption.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ The main current risks are:

- the standard is still draft
- only one production-grade runtime adapter exists today
- runtime compatibility depends on explicit capability negotiation, especially for root approvals, approver scope, structured output, and handoff v3
- runtime compatibility depends on explicit capability negotiation, especially for root approvals, approver scope, structured output, and handoff v4

### Avoiding heavy single-prompt jobs

Expand Down
17 changes: 17 additions & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ Feature keys include `approvals`, `model_policy`, `execution_intent`, `output_hi

During scheduler apply, a live runtime value is authoritative for every known feature it reports, including `false`. Static target values are used only when the capability command is unavailable or omits a known key. This prevents a stale optimistic declaration from overriding the runtime's observed behavior.

Security-relevant static fallback values are false. This includes runtime
execution, identity resolution, trust, proof, authorization, evidence,
approval, structured output, credential handoff, and every v4 gate. A live
response must explicitly enable each enforcement feature. AgentCLI probes the
runtime on every apply, including basic v0.1 manifests, so a v4-capable runtime
can provide immutable artifacts without weakening offline fallback behavior.

Handoff v4 additionally requires scheduler schema version 29 or newer and an
exact `handoff_contract` object. The contract identifies artifact schema
`openclaw.scheduler.handoff-artifact` version 1, canonicalization
`json-sort-v1` version 1, SHA-256 digests, undefined values normalized to null,
execution binding version 2, and scheduler job binding version 1. AgentCLI
falls back to v3 when any contract field or required v4 feature is missing or
mismatched. Static target declarations never authorize v4 emission.

## Current Target Matrix

### `standalone`
Expand Down Expand Up @@ -119,6 +134,8 @@ Interpretation:
- output hints compile into scheduler output preview/offload budgets
- queue, approval, and fan-out budgets compile into runtime guardrails
- handoff version 3 is required to preserve approval risk, approver scope, and output format fields
- handoff version 4 is selected only through exact live contract negotiation
- `agentcli schema handoff-v4` exposes the complete immutable artifact schema
- root manual approvals require `root_approval_gate`; approver scopes require `approval_scope_enforcement`; output formats require `structured_output_format`
- `auto-reject` jobs compile disabled so an older dispatcher cannot accidentally run them
- inline `shell.env` and `shell.stdin` are rejected because scheduler persistence is not a secret store
Expand Down
3 changes: 3 additions & 0 deletions docs/conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ Must:
- document backend-specific constraints
- preserve task ordering and trigger semantics
- expose or document an explicit capability map for security-relevant runtime behavior
- advertise the exact artifact, canonicalization, digest, and binding contract
before accepting handoff v4

Should:

- expose a manifest apply or upsert path
- expose runtime inspection
- document delivery, retry, and approval behavior separately from the core manifest
- fail closed when a compiled contract requires an enforcement capability the runtime does not advertise
- reject missing required fields and unknown properties in handoff v4 artifacts

## Reference Implementation

Expand Down
Loading
Loading