Skip to content

[Feature]: Supported run-scoped access to a workflow run's definition #4792

Description

@markuswondrak

Problem Statement

Integrations that drive or visualise Spec Kit workflows (for example, a GitHub Action that renders workflow progress and human review gates in issue comments) need the workflow definition that a run was created with, not just its runtime state.

Today:

  • specify workflow status <run_id> --json returns runtime state only (run_id, workflow_id, status, current_step_index, per-step statuses, timestamps). It does not include the step tree, step types, or gate configuration (message, options, on_reject, ...).
  • specify workflow info <workflow_id> resolves the currently installed workflow by ID, has no --json output, and only lists top-level step IDs and types.
  • The only way to get the exact definition used by a run is to read .specify/workflows/runs/<run_id>/workflow.yml directly. The engine already writes this snapshot at run start, and workflow resume prefers it over the installed workflow. However, the file is an internal run-state detail, not a supported contract.

As a result, integrations either depend on Spec Kit's internal storage layout and file format, or they load the installed workflow by ID. The second option breaks as soon as the workflow is updated or removed after the run started.

Proposed Solution

Add a supported, run-scoped view of the workflow definition. It should be separate from workflow status, which stays focused on execution progress.

The exact surface is open for assessment. One option is a CLI command with JSON output, for example specify workflow definition <run_id> --json (or a --definition flag on an existing command), backed by a library function that integrations can call directly.

The view should return:

  • workflow metadata (id, name, version, and other top-level fields as appropriate);
  • the step tree, including nested steps (e.g. inside if / switch / loop / fan-out constructs);
  • gate configuration: message, options, verdict/on_reject behaviour;
  • the definition exactly as persisted for the run, resolved from the run and not from the currently installed workflow.

Illustrative shape (from the discussion, not final):

{
  "run_id": "662bf791",
  "definition": {
    "workflow": {"id": "spec-review", "name": "Spec review", "version": "1.0.0"},
    "steps": [
      {"id": "draft", "type": "command", "command": "speckit.specify"},
      {
        "id": "approve",
        "type": "gate",
        "message": "Review the specification.",
        "options": ["approve", "reject"],
        "on_reject": "abort"
      }
    ]
  }
}

This should be a stable abstraction over the run's definition, not a raw dump of the underlying YAML.

Alternatives Considered

  • Reading .specify/workflows/runs/<run_id>/workflow.yml directly. This is the current interim approach. It works, but it couples integrations to internal layout and format.
  • Loading the installed workflow by workflow_id (e.g. via workflow info). This is inaccurate once the installed workflow changes or is removed after the run started.
  • Extending workflow status --json with the full definition. This mixes execution state with static definition data and bloats every status poll.

Component

Specify CLI (initialization, commands)

AI Agent (if applicable)

Not applicable

Use Cases

  1. A GitHub Action posts an issue comment that shows every step of a workflow run with its current status. It needs the full step tree, including steps that have not yet started, and the status alone does not provide these.
  2. At a human review gate, the Action renders the gate's message and available options (e.g. approve / reject) so reviewers can respond from the issue.
  3. After a workflow is updated or removed, the Action still renders historical or in-flight runs accurately against the definition they were started with.

Acceptance Criteria

  • A supported interface (CLI with --json and/or library API) returns the workflow definition for a given run_id
  • The definition is resolved from the run's persisted snapshot, not from the installed workflow
  • Output includes workflow metadata, the full step tree (including nested steps), and gate configuration
  • Clear error behaviour for unknown run IDs and runs without a persisted definition (JSON errors routed to stderr, consistent with workflow status --json)
  • Positive and negative tests, including: definition still returned after the installed workflow is modified or removed; nested steps; gate fields
  • Documentation of the output contract

Additional Context

AI Disclosure

Drafted with opencode using Claude Opus 5.5 (github-copilot/claude-opus-5.5), default reasoning settings, human-supervised. The agent wrote the issue text from discussion #4727 and a read of the workflow engine source (workflows/engine.py, command_status.py, command_info.py). It was reviewed and submitted by a human on behalf of the original discussion author.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions