Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install \
ruff \
ruff==0.15.22 \
mdformat==1.0.0 \
mdformat-gfm \
mdformat-frontmatter \
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ summary: Chronological history of repository and skill changes.

# Changelog

## 2026-07-25 — Added coordinator-neutral delegated ticket execution

- fix: pin CI to the established Ruff rule set so dependency drift cannot
redefine the repository-wide lint gate
- feat: add a versioned delegated-execution contract for `implement-ticket`
(`b53efa674e929c181bdaac63ff0306cb756386db`)

## 2026-07-21 — Completed carve-changesets and integrated ticket publication

- feat: package the workflow suite as a plugin
(`b7ec1b593b9d211cd91101d94d0406c355b2ecd7`)
- fix: fail closed on invalid carved handoffs
(`dc4f5c1f3e33c25ad6258f7365506bd33255ed82`)
- feat: integrate carved ticket publication
Expand Down
37 changes: 37 additions & 0 deletions skills/implement-ticket/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ create a third shared workflow abstraction.
oversized, and again before transferring candidate ownership.
- Always read [cleanup and result](references/cleanup-and-result.md) before a
merge or terminal handoff.
- When a caller supplies delegated-execution input, read and follow the
[delegated execution contract](references/delegated-execution/CONTRACT.md)
before any mutation.

For cross-system work, record which system owns issue status, dependency state,
source code, pull requests, checks, reviews, and merge. Never substitute a
Expand Down Expand Up @@ -112,6 +115,40 @@ manual transition. State that consequence before publication or merge. Do not
use automatic closing syntax when its effect conflicts with the resolved
completion policy.

## Honor delegated execution when supplied

Delegated execution is optional. Standalone behavior remains the default.

When a caller supplies a delegated invocation:

1. Validate it with the bundled delegated-execution validator before mutation.
Reject unsupported versions, unknown fields, excluded terminal states, or an
unusable checkpoint command.
2. Treat its authority as an additional ceiling. It may narrow the ordinary
operating contract but never widen repository, user, host, or provider
authority.
3. Run the caller's checkpoint command immediately before every action in the
contract's consequential-mutation vocabulary. Supply the exact current ticket
observation, candidate identity, sequence, and continuation token. Start at
exactly one greater than the invocation's `last_sequence`. Perform only the
one allowed action, rotate to the returned token, and retain every consumed
allowance for the terminal `authority_used` report.
4. Immediately after every candidate push or advancement, verify the full remote
ref and exact SHA, then run `candidate_published`. Do not continue until the
caller acknowledges that exact SHA.
5. If a checkpoint is denied, unavailable, malformed, ambiguous, or mismatched,
stop the proposed action and return `blocked`. Preserve already-published
implementation as a transferable handoff even when publication
acknowledgement failed. A denial preserves the prior sequence and token.
6. Validate the terminal result against the invocation and the caller's durable
ledger tail. Never return stale checkpoint state, a state the caller
excluded, or a claim that a local-only candidate is transferable. A material
ticket observation change blocks this invocation; reevaluation starts a fresh
one.

The checkpoint command is the coordinator boundary. Do not infer its product,
contact a server on its behalf, or add coordinator-specific behavior.

After applying the whole-epic scope guard, and before creating a branch,
worktree, or other implementation state for a ticket, verify that both
`review-code-change` and `babysit-pr` are available and readable by stable name
Expand Down
18 changes: 15 additions & 3 deletions skills/implement-ticket/references/cleanup-and-result.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ unblocked work. Report newly ready work only as context.
## Result fields

Return a concise documented handoff. Do not require a machine-readable schema
unless the caller has one. Include every applicable field:
unless the caller supplies the versioned delegated-execution contract. In that
mode, validate the structured result against both its schema and invocation
before return. Otherwise include every applicable field:

- `terminal_state`: `ready_pr`, `ready_prs`, `merged`, `blocked`, or
`requires_epic`;
Expand Down Expand Up @@ -96,8 +98,11 @@ a remaining gate on a terminal `ready_pr`.
For `ready_prs`, require a verified `carve-changesets: prs_open` result for the
still-current ordered stack. Every PR must be open, correctly based, mergeable,
and at its applicable non-merge gate; whole-chain equivalence and final-only
closing syntax must be verified. The only withheld actions are merge and
propagation. Do not list ordinary pending CI or review as a remaining gate.
closing syntax must be verified. Report each exact base ref, base SHA, head ref,
and head SHA so the first PR starts at the candidate base, each later PR starts
at the prior PR head, and the final PR head equals the candidate. The only
withheld actions are merge and propagation. Do not list ordinary pending CI or
review as a remaining gate.

For `merged`, require a verified `babysit-pr: merged` or
`carve-changesets: all_merged` result plus the independent mainline,
Expand All @@ -115,3 +120,10 @@ For `requires_epic`, require all of:

If the incoming handoff already contains the same marker, return `blocked` with
`routing cycle detected` rather than another `requires_epic` result.

For delegated execution, a blocked result distinguishes `none`, `local`, and
`published` implementation state. Published state includes the verified remote
URL, full ref, exact head, and publication topology and is transferable. Local
state is explicitly non-transferable and includes the reason publication could
not safely occur. Never substitute a workspace path or local-only SHA for a
durable handoff.
188 changes: 188 additions & 0 deletions skills/implement-ticket/references/delegated-execution/CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Delegated execution contract

This optional contract lets an external coordinator invoke `implement-ticket`
while retaining authority over consequential external mutations. It is generic:
the coordinator is opaque to Agent Scripts, and no Atelier concept appears in
the protocol.

The capability identifier is
`agent-scripts.implement-ticket/delegated-execution/v1`.

## Contract ownership

- `capability.json` is the discovery manifest and is validated by
`capability.schema.json`.
- `invocation.schema.json` owns the invocation shape.
- `checkpoint-request.schema.json` and `checkpoint-response.schema.json` own the
synchronous fencing exchange.
- `result.schema.json` owns the terminal result shape.
- `validate.py` validates schemas and cross-field semantics without third-party
dependencies.
- This document owns process semantics that JSON Schema cannot express.

All objects reject unknown fields. An unsupported version, malformed object,
failed validator, failed checkpoint command, or ambiguous response blocks
execution.

## Invocation

The caller validates and supplies one invocation object before any mutation. It
binds the run to:

- one ticket and tracker;
- one repository, exact base ref, and exact base SHA;
- one caller-owned work identifier and revision;
- opaque caller-owned approval evidence;
- intent, scope, non-goals, constraints, and done definition;
- required validation and review expectations;
- a finite authority ceiling;
- one desired delivery outcome;
- the terminal states the caller can consume;
- an argv-style checkpoint command;
- the caller's last consumed checkpoint sequence; and
- an opaque continuation token.

The checkpoint command is an array of executable and argument strings. Agent
Scripts sends one JSON checkpoint request on standard input and requires exactly
one JSON checkpoint response on standard output. It does not invoke a shell,
interpret extra output, persist credentials, or inspect the continuation token.
The first request sequence is exactly one greater than the invocation's
`last_sequence`, so a new delegate can continue an existing caller-owned claim.

The generic terminal states remain `ready_pr`, `ready_prs`, `merged`, `blocked`,
and `requires_epic`. A caller may narrow this set. `implement-ticket` must not
select an outcome the invocation excludes. If its only correct outcome is
excluded, it returns `blocked` without performing the excluded action.

## Consequential mutation checkpoint

Immediately before every consequential external mutation, `implement-ticket`
sends a `pre_external_mutation` request. The finite action vocabulary is:

- `repository.candidate.create`
- `repository.candidate.push`
- `pull_request.create`
- `pull_request.update`
- `review.reply`
- `review.resolve`
- `ticket.update`
- `ticket.dependencies.update`
- `ticket.followup.create`
- `changeset.carve`
- `pull_request.merge`
- `repository.branch.delete`
- `deployment.execute`
- `production.mutate`
- `destructive.execute`

The request includes the invocation identity, current continuation token,
strictly increasing sequence, action, exact current ticket observation, exact
candidate when one exists, and a concise proposed-effect description.

Candidate push, pull-request, review, carving, merge, and candidate-branch
deletion checkpoints require the exact candidate. A push checkpoint describes
the proposed remote URL, full ref, base SHA, and head SHA before publication.

The coordinator must reread its authoritative state and return `allow` or
`deny`. `allow` must name the same invocation and request sequence and return a
new opaque continuation token. `deny` echoes the request's continuation token;
it does not advance durable sequence or token state. Identity mismatch, sequence
mismatch, token mismatch, malformed output, command failure, or unavailable
coordinator blocks the mutation.

An `allow` decision authorizes only that one proposed mutation. It does not
cache authority for a later action.

The bundled validator is stateless. The checkpoint command must atomically
compare the expected sequence and current continuation token with its durable
state before returning `allow`, then persist the returned sequence and token.
For an allowed request it must also persist the invocation ID, phase, action,
proposed effect, exact candidate identity, and acknowledgement before returning.
These records are an append-only authorization ledger; they let the caller
compare the terminal `authority_used` report with every consumed allowance.
Replaying a consumed request must fail. The validator's
`validate_checkpoint_progress` helper checks the sequence and token transition,
but the caller owns atomic persistence and the authorization ledger.

## Candidate publication acknowledgement

Immediately after every successful remote candidate publication or advancement,
`implement-ticket` sends a `candidate_published` checkpoint before any later
mutation or terminal result.

The request contains the verified remote URL, full remote ref, base SHA, and
published head SHA. The coordinator returns `allow` only after it has durably
acknowledged that exact candidate. Its response must repeat the acknowledged
head SHA. A missing or different SHA blocks continuation.

This post-publication acknowledgement closes the unavoidable interval between a
Git push and the coordinator's durable record. The pushed candidate remains a
recoverable project artifact even when acknowledgement fails. A blocked result
may report that verified published candidate whether acknowledgement succeeded
or failed. It becomes shared coordinator state only after the caller records it
in a later verified transition.

## Terminal result

The terminal result is always validated before return. It records:

- terminal state and exact identities;
- whether implementation state is `none`, `local`, or `published`;
- a remotely reachable candidate and publication topology when one exists;
- whether the handoff is transferable;
- checkpoint sequence and final continuation token;
- validation and review observations;
- authority actually used;
- unresolved obligations; and
- one next action or blocking reason.

`ready_pr`, `ready_prs`, and `merged` require published, transferable candidate
state. `ready_pr` requires exactly one PR; `ready_prs` requires a stack.
`requires_epic` requires no implementation state.

Delivery terminals must report every required validation command as passed at
the exact candidate, satisfy requested independent review, and report zero
unresolved material feedback when requested.

Published implementation must report the candidate push in `authority_used`. A
result containing a pull request must also report the corresponding pull-request
create or update action. Validation and review observation names are unique;
duplicate observations cannot override one another by array order. An ordered
`ready_prs` stack contains distinct pull request identities, URLs, and heads,
and its final pull request head equals the reported candidate head. Each PR
records its exact base ref, base SHA, head ref, and head SHA. The first base ref
and SHA equal the invocation base; every later base ref and SHA equal the
previous PR head ref and SHA.

A blocked run with published implementation must return its transferable
candidate. It may have zero pull requests when execution blocked after the push
but before PR creation, including when candidate acknowledgement failed. A
blocked run with only local implementation returns no candidate, sets
`transferable` to false, and explains why no durable handoff exists. It must
never describe a local-only SHA as transferable.

The caller must validate every terminal result against the durable checkpoint
ledger tail, not merely the invocation's starting position. The bundled
`validate_result_checkpoint_state` helper requires the terminal sequence and
continuation token to equal that caller-supplied tail. A stale terminal
checkpoint blocks handoff.

A material ticket-observation change always causes the caller to deny the
current invocation. Eligibility may be reevaluated only before starting a fresh
invocation with a newly observed ticket contract. The current invocation's
terminal result therefore continues to identify its original ticket observation
truthfully.

## Compatibility and failure

Standalone invocations remain unchanged and may return the documented human
handoff. Delegated execution applies only when the caller supplies a valid v1
invocation.

There is no daemon, callback server, or background lease. The checkpoint command
is synchronous and caller-owned. If the caller disappears, execution fails
closed at the next checkpoint and preserves any already-published candidate.

The coordinator identity is cooperative attribution, not authentication.
Operating-system permissions, repository access, and provider controls remain
the enforcement boundaries.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"schema": "agent-scripts.implement-ticket/capability-manifest/v1",
"id": "agent-scripts.implement-ticket/delegated-execution/v1",
"contract": "CONTRACT.md",
"invocation_schema": "invocation.schema.json",
"checkpoint_request_schema": "checkpoint-request.schema.json",
"checkpoint_response_schema": "checkpoint-response.schema.json",
"result_schema": "result.schema.json",
"validator": "validate.py",
"terminal_states": [
"ready_pr",
"ready_prs",
"merged",
"blocked",
"requires_epic"
],
"checkpoint_phases": [
"pre_external_mutation",
"candidate_published"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Agent Scripts delegated implement-ticket capability manifest",
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"id",
"contract",
"invocation_schema",
"checkpoint_request_schema",
"checkpoint_response_schema",
"result_schema",
"validator",
"terminal_states",
"checkpoint_phases"
],
"properties": {
"schema": {
"const": "agent-scripts.implement-ticket/capability-manifest/v1"
},
"id": {
"const": "agent-scripts.implement-ticket/delegated-execution/v1"
},
"contract": {
"const": "CONTRACT.md"
},
"invocation_schema": {
"const": "invocation.schema.json"
},
"checkpoint_request_schema": {
"const": "checkpoint-request.schema.json"
},
"checkpoint_response_schema": {
"const": "checkpoint-response.schema.json"
},
"result_schema": {
"const": "result.schema.json"
},
"validator": {
"const": "validate.py"
},
"terminal_states": {
"type": "array",
"const": [
"ready_pr",
"ready_prs",
"merged",
"blocked",
"requires_epic"
]
},
"checkpoint_phases": {
"type": "array",
"const": [
"pre_external_mutation",
"candidate_published"
]
}
}
}
Loading
Loading