# internal/app/status

Package status reads the current task state and suggested next action.

## ErrTaskIDRequired

```go
var ErrTaskIDRequired = errors.New("status requires a task_id")
```

ErrTaskIDRequired identifies a taskless status probe that found work but cannot safely choose a task in a shared workspace.

## Run

```go
func Run(ctx context.Context, specs SpecStore, sessions SessionStore, taskID string, workspaces ...WorkspaceStatus) (Output, error)
```

Run reads status for taskID.

## RunTaskless

```go
func RunTaskless(ctx context.Context, specs SpecLister) (Output, error)
```

RunTaskless reports the only safe result for status without a task ID. It refuses to choose among current tasks in a shared workspace.

## RunWithOptions

```go
func RunWithOptions(ctx context.Context, specs SpecStore, sessions SessionStore, taskID string, opts Options, workspaces ...WorkspaceStatus) (Output, error)
```

RunWithOptions reads status for taskID with output shaping options.

## CompletionInfo

```go
type CompletionInfo struct {
	Status        string   `json:"status"`
	Kind          string   `json:"kind"`
	Provider      string   `json:"provider,omitempty"`
	Verdict       string   `json:"verdict,omitempty"`
	Reason        string   `json:"reason,omitempty"`
	Actual        string   `json:"actual,omitempty"`
	Summary       string   `json:"summary,omitempty"`
	ReviewEvent   string   `json:"review_event,omitempty"`
	ReceiptEvent  string   `json:"receipt_event,omitempty"`
	CompleteEvent string   `json:"complete_event,omitempty"`
	Evidence      []string `json:"evidence,omitempty"`
}
```

CompletionInfo describes the terminal review authority for completed tasks.

- `Status: string` (json:"status"): 
- `Kind: string` (json:"kind"): 
- `Provider: string` (json:"provider,omitempty"): 
- `Verdict: string` (json:"verdict,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 
- `Actual: string` (json:"actual,omitempty"): 
- `Summary: string` (json:"summary,omitempty"): 
- `ReviewEvent: string` (json:"review_event,omitempty"): 
- `ReceiptEvent: string` (json:"receipt_event,omitempty"): 
- `CompleteEvent: string` (json:"complete_event,omitempty"): 
- `Evidence: []string` (json:"evidence,omitempty"): 

## NextAction

```go
type NextAction struct {
	Role         string             `json:"role,omitempty"`
	Action       string             `json:"action,omitempty"`
	Command      string             `json:"command,omitempty"`
	Reason       string             `json:"reason,omitempty"`
	AfterCommand string             `json:"after_command,omitempty"`
	ThenCommand  string             `json:"then_command,omitempty"`
	RepairAction *gate.RepairAction `json:"repair_action,omitempty"`
}
```

NextAction gives wrappers and trigger agents the next deterministic role and command without requiring them to interpret prose handoffs.

- `Role: string` (json:"role,omitempty"): 
- `Action: string` (json:"action,omitempty"): 
- `Command: string` (json:"command,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 
- `AfterCommand: string` (json:"after_command,omitempty"): 
- `ThenCommand: string` (json:"then_command,omitempty"): 
- `RepairAction: *gate.RepairAction` (json:"repair_action,omitempty"): 

## Options

```go
type Options struct {
	SuppressContext bool
}
```

Options configures status projection output.

- `SuppressContext: bool`: 

## Output

```go
type Output struct {
	TaskID          string          `json:"task_id"`
	Status          spec.Status     `json:"status"`
	Title           string          `json:"title"`
	Next            string          `json:"next"`
	NextAction      NextAction      `json:"next_action,omitempty"`
	Gate            string          `json:"gate,omitempty"`
	TrustedState    string          `json:"trusted_state,omitempty"`
	AllowedFollowUp string          `json:"allowed_follow_up,omitempty"`
	SessionOK       bool            `json:"session_ok"`
	SpecSource      *SpecSource     `json:"spec_source,omitempty"`
	Repair          *gate.Failure   `json:"repair,omitempty"`
	Review          ReviewInfo      `json:"review,omitempty"`
	Completion      *CompletionInfo `json:"completion_authority,omitempty"`
	TaskMaterial    *TaskMaterial   `json:"task_material,omitempty"`
	Reason          string          `json:"reason,omitempty"`
}
```

Output describes the task status projection.

- `TaskID: string` (json:"task_id"): 
- `Status: spec.Status` (json:"status"): 
- `Title: string` (json:"title"): 
- `Next: string` (json:"next"): 
- `NextAction: NextAction` (json:"next_action,omitempty"): 
- `Gate: string` (json:"gate,omitempty"): 
- `TrustedState: string` (json:"trusted_state,omitempty"): 
- `AllowedFollowUp: string` (json:"allowed_follow_up,omitempty"): 
- `SessionOK: bool` (json:"session_ok"): 
- `SpecSource: *SpecSource` (json:"spec_source,omitempty"): 
- `Repair: *gate.Failure` (json:"repair,omitempty"): 
- `Review: ReviewInfo` (json:"review,omitempty"): 
- `Completion: *CompletionInfo` (json:"completion_authority,omitempty"): 
- `TaskMaterial: *TaskMaterial` (json:"task_material,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 

## ReviewAttemptInfo

```go
type ReviewAttemptInfo struct {
	AttemptID      string `json:"attempt_id,omitempty"`
	Running        bool   `json:"running"`
	Stale          bool   `json:"stale,omitempty"`
	Status         string `json:"status"`
	LeaseExpiresAt string `json:"lease_expires_at,omitempty"`
	Reason         string `json:"reason,omitempty"`
}
```

ReviewAttemptInfo describes the latest provider attempt separately from the latest accepted review verdict.

- `AttemptID: string` (json:"attempt_id,omitempty"): 
- `Running: bool` (json:"running"): 
- `Stale: bool` (json:"stale,omitempty"): 
- `Status: string` (json:"status"): 
- `LeaseExpiresAt: string` (json:"lease_expires_at,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 

## ReviewInfo

```go
type ReviewInfo struct {
	Verdict                  string                      `json:"verdict,omitempty"`
	Mode                     corereview.Mode             `json:"mode,omitempty"`
	Summary                  string                      `json:"summary,omitempty"`
	Findings                 []corereview.Finding        `json:"findings,omitempty"`
	OpenBlockers             int                         `json:"open_blockers,omitempty"`
	AttackLog                []corereview.AttackLogEntry `json:"attack_log,omitempty"`
	Budget                   corereview.Budget           `json:"budget,omitempty"`
	Provider                 string                      `json:"provider,omitempty"`
	Model                    string                      `json:"model,omitempty"`
	OutputFormat             string                      `json:"output_format,omitempty"`
	Normalizations           []string                    `json:"normalizations,omitempty"`
	Attempt                  *ReviewAttemptInfo          `json:"attempt,omitempty"`
	Running                  bool                        `json:"running,omitempty"`
	AttemptStatus            string                      `json:"attempt_status,omitempty"`
	Progress                 *ReviewProgressInfo         `json:"progress,omitempty"`
	Reason                   string                      `json:"reason,omitempty"`
	RerunBlocked             bool                        `json:"rerun_blocked,omitempty"`
	OperatorDecisionRequired bool                        `json:"operator_decision_required,omitempty"`
	BlockerFingerprints      []string                    `json:"blocker_fingerprints,omitempty"`
}
```

ReviewInfo is the latest review evidence visible from status.

- `Verdict: string` (json:"verdict,omitempty"): 
- `Mode: corereview.Mode` (json:"mode,omitempty"): 
- `Summary: string` (json:"summary,omitempty"): 
- `Findings: []corereview.Finding` (json:"findings,omitempty"): 
- `OpenBlockers: int` (json:"open_blockers,omitempty"): 
- `AttackLog: []corereview.AttackLogEntry` (json:"attack_log,omitempty"): 
- `Budget: corereview.Budget` (json:"budget,omitempty"): 
- `Provider: string` (json:"provider,omitempty"): 
- `Model: string` (json:"model,omitempty"): 
- `OutputFormat: string` (json:"output_format,omitempty"): 
- `Normalizations: []string` (json:"normalizations,omitempty"): 
- `Attempt: *ReviewAttemptInfo` (json:"attempt,omitempty"): 
- `Running: bool` (json:"running,omitempty"): 
- `AttemptStatus: string` (json:"attempt_status,omitempty"): 
- `Progress: *ReviewProgressInfo` (json:"progress,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 
- `RerunBlocked: bool` (json:"rerun_blocked,omitempty"): 
- `OperatorDecisionRequired: bool` (json:"operator_decision_required,omitempty"): 
- `BlockerFingerprints: []string` (json:"blocker_fingerprints,omitempty"): 

## ReviewProgressInfo

```go
type ReviewProgressInfo struct {
	Stage      string `json:"stage,omitempty"`
	Status     string `json:"status,omitempty"`
	Reason     string `json:"reason,omitempty"`
	RecordedAt string `json:"recorded_at,omitempty"`
}
```

ReviewProgressInfo describes the latest coarse review stage recorded in the ledger. It is progress telemetry only; reviewgate authority ignores it.

- `Stage: string` (json:"stage,omitempty"): 
- `Status: string` (json:"status,omitempty"): 
- `Reason: string` (json:"reason,omitempty"): 
- `RecordedAt: string` (json:"recorded_at,omitempty"): 

## SessionStore

```go
type SessionStore interface {
	Load(context.Context, string) (session.Session, error)
}
```

SessionStore is the session loading port used by status.

- `Load: func(context.Context, string) (session.Session, error)`: 

## SpecLister

```go
type SpecLister interface {
	List(context.Context) ([]spec.Record, error)
}
```

SpecLister is the optional listing port used by taskless status probes.

- `List: func(context.Context) ([]spec.Record, error)`: 

## SpecSource

```go
type SpecSource struct {
	Path            string `json:"path"`
	SHA256          string `json:"sha256"`
	Bytes           int    `json:"bytes"`
	Markdown        string `json:"markdown,omitempty"`
	MarkdownOmitted bool   `json:"markdown_omitted,omitempty"`
}
```

SpecSource describes the canonical Markdown contract behind status.

- `Path: string` (json:"path"): 
- `SHA256: string` (json:"sha256"): 
- `Bytes: int` (json:"bytes"): 
- `Markdown: string` (json:"markdown,omitempty"): 
- `MarkdownOmitted: bool` (json:"markdown_omitted,omitempty"): 

## SpecStore

```go
type SpecStore interface {
	Load(context.Context, string) (spec.Model, string, error)
}
```

SpecStore is the spec loading port used by status.

- `Load: func(context.Context, string) (spec.Model, string, error)`: 

## TaskMaterial

```go
type TaskMaterial = reviewmaterial.Projection
```

TaskMaterial describes the task-owned workspace surface visible to status.

## WorkspaceStatus

```go
type WorkspaceStatus interface {
	ChangedFiles(context.Context) ([]string, error)
	ResolveHead(context.Context) (string, bool, error)
}
```

WorkspaceStatus captures the current Git-visible workspace state for read-only review-gate projection.

- `ChangedFiles: func(context.Context) ([]string, error)`: 
- `ResolveHead: func(context.Context) (string, bool, error)`:
