stackchain-dashboard/docs/release-engine-spec.md
timmy 7d633e67e8
All checks were successful
CI / lint (pull_request) Successful in 29s
CI / build-frontend (pull_request) Successful in 5s
security: isolate release issue content from shell execution (#307)
2026-08-08 14:13:56 +00:00

3.3 KiB

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.
  • Local repository path and durable state-file path.

State machine

discovered → claimed → agent_complete → tests_passed → pushed → pr_opened

Terminal failure states are claim_failed, agent_failed, tests_failed, and push_failed. A rerun resumes from persisted state and never opens a duplicate PR.

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.

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.
  • 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.