# internal/app/specsource

Package specsource loads exact Markdown source for agent-facing commands.

## ErrChanged

```go
var ErrChanged = errors.New("spec source changed during operation")
```

ErrChanged is returned when the canonical Markdown changes while a provider packet is being assembled. The caller must discard the packet and start from a new source snapshot.

## ErrUnavailable

```go
var ErrUnavailable = errors.New("spec source markdown unavailable")
```

ErrUnavailable is returned when a spec store cannot provide source Markdown.

## Load

```go
func Load(ctx context.Context, store any, taskID string) (spec.Source, error)
```

Load returns the exact Markdown source for taskID.

## MarkdownDigest

```go
func MarkdownDigest(source spec.Source) string
```

MarkdownDigest returns the digest of the exact canonical Markdown bytes. This is deliberately separate from spec.ContractDigest: lifecycle evidence can be projected from the ledger without changing the source contract, but a provider packet must never silently use an older source snapshot.

## ReloadUnchanged

```go
func ReloadUnchanged(ctx context.Context, store any, prior spec.Source) (spec.Source, error)
```

ReloadUnchanged reloads the canonical source and verifies that its path and exact bytes still match the snapshot used to assemble an agent packet.

## Loader

```go
type Loader interface {
	LoadSource(context.Context, string) (spec.Source, error)
}
```

Loader is implemented by stores that can return the parsed spec and its exact Markdown source in one operation.

- `LoadSource: func(context.Context, string) (spec.Source, error)`:
