task

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package task contains durable task state, exact repository observations, and short ownership-safe task locks. Provider calls deliberately do not live in this package: callers take a token, release the lock, call the provider, and use the token for the compare-and-swap completion.

Index

Constants

View Source
const (
	PhasePlanned             = "planned"
	PhasePlanReviewing       = "plan_reviewing"
	PhasePlanApproved        = "plan_approved"
	PhaseImplementing        = "implementing"
	PhaseNeedsInput          = "needs_input"
	PhaseImplementationReady = "implementation_ready"
	PhaseCodeReviewing       = "code_reviewing"
	PhaseApproved            = "approved"
	PhaseReviewNeeded        = "review_needed"
	PhaseFailed              = "failed"
)

Variables

View Source
var (
	ErrNotFound          = errors.New("task not found")
	ErrTaskExists        = errors.New("task already exists")
	ErrInvalidTaskID     = errors.New("invalid task id")
	ErrOperationInFlight = errors.New("task operation is already in flight")
	ErrStaleOperation    = errors.New("stale task operation")
	ErrInvalidPhase      = errors.New("invalid task phase")
	ErrScopeChanged      = errors.New("task scope changed during review barrier")
	ErrNotGitRepository  = errors.New("not inside a git worktree")
)

Functions

func CanonicalScope

func CanonicalScope(raw string) (string, error)

CanonicalScope normalizes comma/newline separated repository-relative paths/globs. The default scope is ** and excludes all RoleMux/Git state. An explicit scope may name only the tracked project artifacts under .rolemux/plans; tracking is enforced by the manifest observer.

func DiscoverRepository

func DiscoverRepository(start string) (string, error)

DiscoverRepository is the public repository boundary. It resolves nested working directories to the top level and fails closed for bare repositories and paths outside a Git worktree.

func HashManifest

func HashManifest(entries []FileEntry) string

HashManifest is derived solely from path, kind, worktree content/mode, and index blob/mode/stages. Git status labels, HEAD, timestamps, and ref paths cannot change this hash.

func IntegrationTaskID

func IntegrationTaskID(parentID string) string

func ManifestChanged

func ManifestChanged(before, after []FileEntry) bool

func NewToken

func NewToken() string

func ScopeMatches

func ScopeMatches(scope, repoPath string) bool

ScopeMatches uses slash-separated paths and supports * (one segment) and ** (zero or more segments). A literal directory matches descendants.

func ScopePatterns

func ScopePatterns(scope string) []string

func ScopeSpecHash

func ScopeSpecHash(scope string) string

func ScopesOverlap

func ScopesOverlap(a, b string) bool

ScopesOverlap is conservative and advisory only. It never rejects a different task ID or serializes a provider call.

func StateFingerprint

func StateFingerprint(st State) string

func UnmatchedScopePatterns

func UnmatchedScopePatterns(entries []FileEntry, scope string) []string

func ValidateScope

func ValidateScope(scope string) error

func ValidateWorkUnits

func ValidateWorkUnits(units []WorkUnit) error

func WorkTaskID

func WorkTaskID(parentID, unitID string) string

func WorkUnitWaves

func WorkUnitWaves(units []WorkUnit) ([][]string, error)

WorkUnitWaves returns deterministic topological layers. Every unit in one layer can be scheduled concurrently after all earlier layers are approved.

func WritePlan

func WritePlan(repoRoot, id, contents string) error

WritePlan performs a same-directory durable atomic plan write. The caller must pass a validated task ID; no arbitrary path is accepted.

Types

type AdvisoryLock

type AdvisoryLock struct {
	// contains filtered or unexported fields
}

func (*AdvisoryLock) Unlock

func (l *AdvisoryLock) Unlock() error

type ContentRef

type ContentRef struct {
	Digest string `json:"digest"`
	Path   string `json:"path"`
	Size   int64  `json:"size"`
}

ContentRef points at an immutable, content-addressed copy in private RoleMux state. Baseline and candidate roots are separate by construction.

type ContentState

type ContentState struct {
	Present bool        `json:"present"`
	Mode    string      `json:"mode,omitempty"`
	Hash    string      `json:"hash,omitempty"`
	Size    int64       `json:"size,omitempty"`
	Ref     *ContentRef `json:"ref,omitempty"`
}

type Diagnostic

type Diagnostic struct {
	Code     string   `json:"code"`
	Severity string   `json:"severity"`
	Message  string   `json:"message"`
	TaskID   string   `json:"task_id,omitempty"`
	Paths    []string `json:"paths,omitempty"`
}

Diagnostic is advisory. It never causes RoleMux to stash, revert, commit, merge, or globally serialize an unrelated task.

type FileEntry

type FileEntry struct {
	Path   string `json:"path"`
	Kind   string `json:"kind"`
	Status string `json:"status,omitempty"`
	Mode   string `json:"mode,omitempty"`
	Hash   string `json:"hash,omitempty"`
	Size   int64  `json:"size,omitempty"`

	Worktree ContentState `json:"worktree,omitempty"`
	Index    IndexState   `json:"index,omitempty"`
}

FileEntry is an exact worktree/index observation. Status is only a derived advisory label and is intentionally excluded from HashManifest. The legacy top-level fields are retained in JSON for small embedders that used the first preview API; new code should use Worktree and Index.

func CaptureContentRefs

func CaptureContentRefs(entries []FileEntry, repoRoot, privateRoot, label, taskID string) ([]FileEntry, error)

CaptureContentRefs stores baseline/candidate worktree bytes in separate immutable roots. It does not alter the entries supplied by another snapshot.

func CaptureIndexRefs

func CaptureIndexRefs(entries []FileEntry, repoRoot, privateRoot, label, taskID string) ([]FileEntry, error)

CaptureIndexRefs copies staged blobs from the index into a distinct immutable root. Deleted worktree entries can therefore still be reviewed after HEAD moves.

func ScopeEntries

func ScopeEntries(entries []FileEntry, scope string) []FileEntry

type Finding

type Finding struct {
	Severity string `json:"severity,omitempty"`
	Path     string `json:"path,omitempty"`
	Line     int    `json:"line,omitempty"`
	Message  string `json:"message"`
}

type InFlight

type InFlight struct {
	Token            string      `json:"token"`
	Operation        string      `json:"operation"`
	Role             string      `json:"role"`
	OwnerPID         int         `json:"owner_pid,omitempty"`
	StartedAt        time.Time   `json:"started_at"`
	KnownSession     bool        `json:"known_session"`
	SessionID        string      `json:"session_id,omitempty"`
	SnapshotManifest []FileEntry `json:"snapshot_manifest,omitempty"`
	PreviousPhase    string      `json:"previous_phase,omitempty"`
	Prompt           string      `json:"prompt,omitempty"`
	Findings         []Finding   `json:"findings,omitempty"`
	Scope            string      `json:"scope,omitempty"`
	Loop             string      `json:"loop,omitempty"`
}

type IndexStage

type IndexStage struct {
	Stage int         `json:"stage"`
	Mode  string      `json:"mode"`
	Blob  string      `json:"blob"`
	Ref   *ContentRef `json:"ref,omitempty"`
}

type IndexState

type IndexState struct {
	Present bool         `json:"present"`
	Mode    string       `json:"mode,omitempty"`
	Blob    string       `json:"blob,omitempty"`
	Stages  []int        `json:"stages,omitempty"`
	Ref     *ContentRef  `json:"ref,omitempty"`
	Entries []IndexStage `json:"entries,omitempty"`
}

type ManifestDeltaResult

type ManifestDeltaResult struct {
	Added, Removed, Changed []FileEntry
}

func ManifestDelta

func ManifestDelta(before, after []FileEntry) ManifestDeltaResult

func (ManifestDeltaResult) Paths

func (d ManifestDeltaResult) Paths() []string

type ProfileSnapshot

type ProfileSnapshot struct {
	Provider string `json:"provider"`
	Model    string `json:"model"`
	Effort   string `json:"effort,omitempty"`
	Speed    string `json:"speed,omitempty"`
}

type RetryState

type RetryState struct {
	Token            string      `json:"token"`
	Operation        string      `json:"operation"`
	Role             string      `json:"role"`
	PreviousPhase    string      `json:"previous_phase"`
	Prompt           string      `json:"prompt,omitempty"`
	Findings         []Finding   `json:"findings,omitempty"`
	Scope            string      `json:"scope,omitempty"`
	SessionID        string      `json:"session_id,omitempty"`
	KnownSession     bool        `json:"known_session"`
	Loop             string      `json:"loop,omitempty"`
	SnapshotManifest []FileEntry `json:"snapshot_manifest,omitempty"`
	CreatedAt        time.Time   `json:"created_at"`
}

type RuntimeSnapshot

type RuntimeSnapshot struct {
	ProviderType string         `json:"provider_type"`
	ProviderID   string         `json:"provider_id,omitempty"`
	Endpoint     string         `json:"endpoint,omitempty"`
	WireAPI      string         `json:"wire_api,omitempty"`
	AuthEnvRefs  []string       `json:"auth_env_refs,omitempty"`
	Auth         map[string]any `json:"auth,omitempty"`
	CLIPath      string         `json:"cli_path,omitempty"`
	SDKSettings  map[string]any `json:"sdk_settings,omitempty"`
}

RuntimeSnapshot stores routing metadata but never a credential value.

type State

type State struct {
	ID                   string     `json:"id"`
	RepoRoot             string     `json:"repo_root"`
	Phase                string     `json:"phase"`
	Round                int        `json:"round"` // compatibility alias; plan/code are authoritative.
	Task                 string     `json:"task,omitempty"`
	Prompt               string     `json:"prompt,omitempty"`
	Plan                 string     `json:"plan,omitempty"`
	PlanHash             string     `json:"plan_hash,omitempty"`
	ApprovedPlanHash     string     `json:"approved_plan_hash,omitempty"`
	ApprovedManifestHash string     `json:"approved_manifest_hash,omitempty"`
	ParentTaskID         string     `json:"parent_task_id,omitempty"`
	WorkUnitID           string     `json:"work_unit_id,omitempty"`
	PlannedScope         string     `json:"planned_scope,omitempty"`
	IntegrationReview    bool       `json:"integration_review,omitempty"`
	WorkGraph            bool       `json:"work_graph,omitempty"`
	WorkUnits            []WorkUnit `json:"work_units,omitempty"`

	PlannerSessionID      string `json:"planner_session_id,omitempty"`
	PlanReviewerSessionID string `json:"plan_reviewer_session_id,omitempty"`
	ImplementerSessionID  string `json:"implementer_session_id,omitempty"`
	CodeReviewerSessionID string `json:"code_reviewer_session_id,omitempty"`

	LastUsedAt time.Time `json:"last_used_at,omitempty"`
	UpdatedAt  time.Time `json:"updated_at"`

	Scope                 string      `json:"scope,omitempty"`
	ScopeSpecHash         string      `json:"scope_spec_hash,omitempty"`
	ScopedBaseline        []FileEntry `json:"scoped_baseline_manifest,omitempty"`
	ScopedBaselineHash    string      `json:"scoped_baseline_manifest_hash,omitempty"`
	CandidateManifest     []FileEntry `json:"candidate_manifest,omitempty"`
	CandidateManifestHash string      `json:"candidate_manifest_hash,omitempty"`
	ChangeManifest        []FileEntry `json:"change_manifest,omitempty"`
	// ReviewCheckpoint is the exact candidate from the last completed
	// changes-requested verdict. Re-review compares fixes against this point
	// instead of making the reviewer rediscover the full task delta.
	ReviewCheckpoint         []FileEntry                `json:"review_checkpoint_manifest,omitempty"`
	ReviewCheckpointHash     string                     `json:"review_checkpoint_manifest_hash,omitempty"`
	ReviewCheckpointFindings []Finding                  `json:"review_checkpoint_findings,omitempty"`
	ProfilesSnapshot         map[string]ProfileSnapshot `json:"profiles_snapshot,omitempty"`
	RuntimeSnapshot          map[string]RuntimeSnapshot `json:"runtime_snapshot,omitempty"`
	MaxRounds                int                        `json:"max_rounds,omitempty"`
	PlanRound                int                        `json:"plan_round,omitempty"`
	CodeRound                int                        `json:"code_round,omitempty"`
	PendingQuestion          string                     `json:"pending_question,omitempty"`
	PendingQuestionSource    string                     `json:"pending_question_source,omitempty"`
	PendingAnswer            string                     `json:"pending_answer,omitempty"`
	PromptInputs             []string                   `json:"prompt_inputs,omitempty"`
	ReturnPhase              string                     `json:"return_phase,omitempty"`
	InterruptedLoop          string                     `json:"interrupted_loop,omitempty"`
	Findings                 []Finding                  `json:"findings,omitempty"`
	Advisories               []Diagnostic               `json:"advisories,omitempty"`
	Diagnostics              []string                   `json:"diagnostics,omitempty"`
	Usage                    map[string]TokenUsage      `json:"usage,omitempty"`
	// ProviderUsageCumulative stores the last raw conversation-wide counters
	// for providers that report cumulative rather than per-turn usage.
	ProviderUsageCumulative map[string]TokenUsage `json:"provider_usage_cumulative,omitempty"`
	InFlight                *InFlight             `json:"in_flight,omitempty"`
	Retry                   *RetryState           `json:"retry,omitempty"`
}

State is the durable task record. Scope and its exact baseline are first established atomically by the first implement invocation.

type Store

type Store struct {
	Root string
	Dir  string
	// contains filtered or unexported fields
}

func NewStore

func NewStore(repoRoot string) *Store

func NewStoreAt

func NewStoreAt(dir string) *Store

func (*Store) Create

func (s *Store) Create(st State) error

Create rejects duplicate task IDs while holding the same task-scoped lock used by all subsequent state mutations.

func (*Store) Delete

func (s *Store) Delete(id string) error

func (*Store) List

func (s *Store) List() ([]State, error)

func (*Store) Load

func (s *Store) Load(id string) (State, error)

func (*Store) Lock

func (s *Store) Lock(id string) (*AdvisoryLock, error)

Lock holds only the requested task lock. The lock file is never unlinked, avoiding the classic create/delete race where one process removes another's lock. Callers must release it promptly and never across provider calls.

func (*Store) Save

func (s *Store) Save(st State) error

func (*Store) SaveOwned

func (s *Store) SaveOwned(st State, token string) error

func (*Store) Update

func (s *Store) Update(id string, update func(*State) error) (State, error)

Update performs a short atomic state mutation under the task-scoped lock. The callback must not invoke providers or inspect the worktree.

func (*Store) UpdateOwned

func (s *Store) UpdateOwned(id, token string, update func(*State) error) (State, error)

UpdateOwned performs a short atomic token/CAS mutation. The callback must not perform provider or repository operations.

type TokenUsage

type TokenUsage struct {
	Requests          int64 `json:"requests"`
	PromptBytes       int64 `json:"prompt_bytes"`
	InputTokens       int64 `json:"input_tokens,omitempty"`
	CachedInputTokens int64 `json:"cached_input_tokens,omitempty"`
	CacheWriteTokens  int64 `json:"cache_write_tokens,omitempty"`
	OutputTokens      int64 `json:"output_tokens,omitempty"`
	ReasoningTokens   int64 `json:"reasoning_tokens,omitempty"`
	TotalTokens       int64 `json:"total_tokens,omitempty"`
}

TokenUsage is accumulated per workflow role. Token fields are populated only when the provider reports them; requests and prompt bytes are measured by RoleMux for every provider invocation.

func (*TokenUsage) Add

func (u *TokenUsage) Add(turn TokenUsage)

func (TokenUsage) Empty

func (u TokenUsage) Empty() bool

type WorkUnit

type WorkUnit struct {
	ID                 string   `json:"id"`
	Objective          string   `json:"objective"`
	Scope              string   `json:"scope"`
	DependsOn          []string `json:"depends_on"`
	ExecutionPacket    string   `json:"execution_packet"`
	AcceptanceCriteria []string `json:"acceptance_criteria"`
	ValidationCommands []string `json:"validation_commands"`
}

WorkUnit is an execution-ready node in a planner-produced dependency graph. Scope is the node's exclusive write scope; the execution packet must carry all context the implementer needs without repeating broad repository research.

func NormalizeWorkUnits

func NormalizeWorkUnits(units []WorkUnit, plan string) ([]WorkUnit, error)

NormalizeWorkUnits canonicalizes scopes and validates graph safety. The single-node fallback preserves old provider sessions created before planner envelopes carried a graph.

type Worktree

type Worktree struct{ Root string }

Worktree exposes repository-relative exact observations.

func NewWorktree

func NewWorktree(root string) *Worktree

func (*Worktree) Head

func (w *Worktree) Head() (string, error)

func (*Worktree) Manifest

func (w *Worktree) Manifest() ([]FileEntry, error)

func (*Worktree) ManifestForScope

func (w *Worktree) ManifestForScope(scope string) ([]FileEntry, error)

ManifestForScope builds a HEAD-independent projection. It observes both worktree bytes and index mode/blob/stage entries, then adds structural ancestors required to explain paths. A directory's child-list hash includes only children that can affect the requested scope, so an unrelated sibling does not stale an approval.

func (*Worktree) Paths

func (w *Worktree) Paths() ([]string, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL