# internal/app/build

Package build advances phase-bounded execution and projects evidence back into specs.

## ErrCriterionNotFound

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrManualCriterionRequired

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrEvidenceDisposition

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrEvidenceDigest

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrEvidenceActor

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrEvidenceReason

```go
var (
	ErrCriterionNotFound       = errors.New("acceptance criterion not found")
	ErrManualCriterionRequired = errors.New("criterion is not manual")
	ErrEvidenceDisposition     = errors.New("evidence disposition must be pass or fail")
	ErrEvidenceDigest          = errors.New("evidence digest must be a SHA-256 hex digest")
	ErrEvidenceActor           = errors.New("evidence actor is required")
	ErrEvidenceReason          = errors.New("evidence reason is required")
)
```

## ErrSpecNotBuildable

```go
var ErrSpecNotBuildable = errors.New("build requires approved, active, blocked, or failed-review state")
```

ErrSpecNotBuildable is returned when execution is attempted before approval or after terminal state.

## NewManualEvidence

```go
func NewManualEvidence(criterionID, disposition, digest, actor, reason string) *ManualEvidence
```

NewManualEvidence returns nil when no manual disposition was supplied, preserving the normal build path.

## Run

```go
func Run(ctx context.Context, specs SpecStore, sessions SessionStore, workspace WorkspaceStatus, runner Runner, clock Clock, input Input) (Output, error)
```

Run advances the governed execution lifecycle. The first build call opens the first phase without running future acceptance. Later calls run evidence for the current phase, open the next phase, or move the task to review.

## Clock

```go
type Clock interface{ Now() time.Time }
```

Clock supplies build timestamps.

- `Now: func() time.Time`: 

## Input

```go
type Input struct {
	TaskID         string
	CWD            string
	Env            []string
	Timeout        time.Duration
	IdleTimeout    time.Duration
	ManualEvidence *ManualEvidence
}
```

Input describes the task and working directory to build.

- `TaskID: string`: 
- `CWD: string`: 
- `Env: []string`: 
- `Timeout: time.Duration`: 
- `IdleTimeout: time.Duration`: 
- `ManualEvidence: *ManualEvidence`: 

## ManualEvidence

```go
type ManualEvidence struct {
	CriterionID    string
	Disposition    string
	EvidenceDigest string
	Actor          string
	Reason         string
}
```

ManualEvidence is the operator-supplied disposition for one manual acceptance criterion. It is consumed as part of build, not as a separate lifecycle transition.

- `CriterionID: string`: 
- `Disposition: string`: 
- `EvidenceDigest: string`: 
- `Actor: string`: 
- `Reason: string`: 

## Output

```go
type Output struct {
	TaskID string        `json:"task_id"`
	Status spec.Status   `json:"status"`
	Phase  string        `json:"phase,omitempty"`
	Passed int           `json:"passed"`
	Failed int           `json:"failed"`
	Next   string        `json:"next"`
	Repair *gate.Failure `json:"repair,omitempty"`
}
```

Output summarizes one build lifecycle step.

- `TaskID: string` (json:"task_id"): 
- `Status: spec.Status` (json:"status"): 
- `Phase: string` (json:"phase,omitempty"): 
- `Passed: int` (json:"passed"): 
- `Failed: int` (json:"failed"): 
- `Next: string` (json:"next"): 
- `Repair: *gate.Failure` (json:"repair,omitempty"): 

## GateFailure

```go
func (o Output) GateFailure() *gate.Failure
```

GateFailure exposes blocked build repair details to the CLI envelope.

## Runner

```go
type Runner interface {
	Run(context.Context, execution.Request) (execution.Result, error)
}
```

Runner executes acceptance commands.

- `Run: func(context.Context, execution.Request) (execution.Result, error)`: 

## SessionStore

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

SessionStore is the session evidence port used by build.

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

## SpecStore

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

SpecStore is the spec persistence port used by build.

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

## WorkspaceStatus

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

WorkspaceStatus captures dirty workspace state when older sessions lack a task baseline.

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