99 lines
5.3 KiB
Markdown
99 lines
5.3 KiB
Markdown
# Autonomous Issue-to-Release Engine — MVP Specification
|
|
|
|
Linked issue: `stackchain/stackchain-dashboard#14`
|
|
|
|
## Purpose
|
|
|
|
Convert one eligible Gitea issue into a tested, traceable pull request without duplicate claims, unverified merges, or release spam.
|
|
|
|
## Inputs
|
|
|
|
- Gitea API base URL and token from environment.
|
|
- Repository key (`owner/repo`).
|
|
- Agent username.
|
|
- Optional explicit issue number; otherwise deterministic queue selection.
|
|
- Coding-agent command, parsed into an argument vector.
|
|
- Test command, parsed into an argument vector.
|
|
- Positive, independent coding-agent and test deadlines plus a termination grace period.
|
|
- Local repository path and durable state-file path.
|
|
|
|
## State machine
|
|
|
|
`discovered → claimed → agent_complete → tests_passed → pushed → pr_opened`
|
|
|
|
Terminal failure states include `claim_failed`, `agent_failed`, `agent_timed_out`, `tests_failed`, `tests_timed_out`, and `push_failed`. A rerun resumes from persisted state and never opens a duplicate PR.
|
|
|
|
Successful checkpoints are schema-versioned and bind the repository, issue,
|
|
deterministic branch, and exact commit SHA. On restart, the engine:
|
|
|
|
- resumes `agent_complete` at tests;
|
|
- resumes `tests_passed` at push; and
|
|
- resumes `pushed` at PR creation after verifying the remote branch SHA.
|
|
|
|
Before skipping any stage, it checks out the recorded branch, verifies its
|
|
local `HEAD`, and requires a clean worktree. Missing identity, an unsupported
|
|
schema, or any repository/issue/branch/SHA mismatch fails closed instead of
|
|
repeating or advancing delivery.
|
|
|
|
## Queue selection
|
|
|
|
1. Only open issues; pull requests are excluded.
|
|
2. An issue assigned to another actor is ineligible.
|
|
3. Explicit issue number wins when eligible.
|
|
4. Otherwise sort by priority label (`P0`, `P1`, `P2`, unlabeled) then issue number.
|
|
5. Select exactly one issue per invocation.
|
|
|
|
## Claiming
|
|
|
|
- PATCH the issue with the configured assignee.
|
|
- GET the issue and verify the live assignee matches.
|
|
- Abort before code execution if verification fails.
|
|
|
|
## Execution
|
|
|
|
- Branch format: `<agent>/<issue>-<slug>`.
|
|
- Coding and test commands are parsed with POSIX argument quoting and executed directly without a shell.
|
|
- Issue number, title, body, repo, and branch are supplied to the coding agent only through `RELEASE_ISSUE_NUMBER`, `RELEASE_ISSUE_TITLE`, `RELEASE_ISSUE_BODY`, `RELEASE_REPO`, and `RELEASE_BRANCH` environment variables. Gitea-controlled content is never interpolated into executable syntax.
|
|
- Shell operators, substitutions, and pipelines are not interpreted. Operators that are intentionally required must live in a separately reviewed wrapper script configured as the command.
|
|
- Empty or malformed commands abort before the issue claim.
|
|
- Non-zero coding-agent exit blocks tests and PR creation.
|
|
- Tests run using the configured command; stdout/stderr and exit code become evidence.
|
|
- Coding-agent and test commands each run in a new process session. Their deadlines default to 1800 and 900 seconds, respectively.
|
|
- On expiry, the engine sends `SIGTERM` to the command's entire process group, waits for the termination grace period (5 seconds by default), then sends `SIGKILL` to the group and reaps the command. This prevents descendants from keeping the worker wedged.
|
|
- Deadlines are configured with `--agent-timeout`, `--test-timeout`, and `--termination-grace`, or `RELEASE_AGENT_TIMEOUT`, `RELEASE_TEST_TIMEOUT`, and `RELEASE_TERMINATION_GRACE`. Non-positive values abort before issue discovery or claim.
|
|
- Timeout evidence is bounded in durable state. An agent timeout blocks tests; a test timeout blocks push and PR creation.
|
|
|
|
## PR and release gate
|
|
|
|
- Push only after tests pass.
|
|
- PR body includes `Closes #N`, test command, and evidence summary.
|
|
- Existing open PR for the same head branch is reused.
|
|
- The MVP does **not** auto-merge. CI plus human/agent review is the release gate.
|
|
- Existing main-branch workflow drafts the release candidate after merge.
|
|
|
|
## Safety and idempotency
|
|
|
|
- `--dry-run` performs discovery and planning only: no claim, git mutation, agent command, push, or PR.
|
|
- State is written atomically after each successful transition.
|
|
- Resumable state carries repository and commit identity; successful stages are
|
|
skipped only after local (and, after push, remote) Git verification.
|
|
- One invocation handles at most one issue.
|
|
- Missing token, dirty worktree, failed claim verification, failed tests, or missing evidence blocks PR creation.
|
|
|
|
## Acceptance tests
|
|
|
|
1. Priority selection chooses P0 before lower-priority tickets.
|
|
2. Tickets assigned to another human/agent are skipped.
|
|
3. Claim must be verified from Gitea before execution.
|
|
4. Agent failure stops the run before tests.
|
|
5. Test failure stops push and PR creation.
|
|
6. Passing tests produce a linked PR request with evidence.
|
|
7. Existing state/PR prevents duplicate work.
|
|
8. Dry-run against live Gitea returns a plan and performs no mutation.
|
|
9. A timed-out command terminates its descendants and returns within its deadline plus grace period.
|
|
10. Agent and test timeouts persist distinct terminal states and block every later delivery stage.
|
|
11. Non-positive deadline configuration aborts before issue claim.
|
|
12. Restarts from `agent_complete`, `tests_passed`, and `pushed` skip only the
|
|
completed stages and open exactly one linked PR.
|
|
13. Dirty or identity-mismatched checkpoints stop before push or PR creation.
|