Documentation
¶
Overview ¶
Package verb is satelle's single execution path. Every data operation is a named function taking JSON in and returning JSON out, registered here. Both the CLI and (later) the local web server dispatch to the same Invoke functions — there is exactly one implementation per verb, so the two surfaces cannot drift.
This is the architecture's one seam: CLI command / web handler → verb.Dispatch → domain store → sqlite. The OSS tier is always local, so dispatch is always in-process. Stores are wired in as package globals (SetWorkItemStore, SetLedgerStore, SetDocIndexStore) at bootstrap.
Ported from satellites' internal/verb, stripped of the MCP role tier and auth wiring (no auth on the local surface).
Index ¶
- Constants
- Variables
- func AddChangeNotifier(fn func(topic string))
- func AppendTelemetry(ctx context.Context, storyID, actor, kind string, data map[string]any) error
- func AttachItemDoc(ctx context.Context, item workitem.Item, name, typ, body string) (string, string, error)
- func Catalog() []string
- func ClearAgentsConfig()
- func ClearTagVocabulary()
- func CmpSemverExported(a, b string) int
- func Dispatch(ctx context.Context, name string, req json.RawMessage) (json.RawMessage, error)
- func EventTelemetry(e ledger.Entry) (agent, model, outcome string, tokensTotal int, durationMs int64)
- func Register(v *Verb)
- func SetAgentsConfig(agents config.AgentsConfig, vars map[string]string)
- func SetAuthoredDirs(dirs map[string]string)
- func SetBackupsDir(dir string)
- func SetChangeNotifier(fn func(topic string))
- func SetCreateReviewer(r CreateReviewer)
- func SetDataDir(dir string)
- func SetDocIndexStore(s *docindex.Store)
- func SetExecutorDispatcher(d ExecutorDispatcher)
- func SetLeaseStore(s *lease.Store)
- func SetLedgerStore(s *ledger.Store)
- func SetOpLog(l *oplog.Logger)
- func SetRetrospector(r Retrospector)
- func SetStepSummariser(s StepSummariser)
- func SetStoryDir(dir string)
- func SetStoryRetention(keepClosed, keepDays int)
- func SetSubstrateConfigDir(dir string)
- func SetTagVocabulary(cfg config.Config)
- func SetTaskDir(dir string)
- func SetTransitionGater(g TransitionGater)
- func SetWorkItemStore(s *workitem.Store)
- func SetWorkflowResolver(r WorkflowResolver)
- func SyncStoryBacklog(ctx context.Context, store *workitem.Store, now time.Time) (materialized, pruned int, err error)
- func SyncTasks(ctx context.Context, store *workitem.Store, now time.Time) (indexed, migrated int, err error)
- type ChangelogEntry
- type ChangelogResult
- type CreateDraft
- type CreateReviewer
- type DispatchResult
- type DocBody
- type ExecutorDispatcher
- type GateDecision
- type ProcessView
- type Retrospector
- type ReviewerVerdict
- type StepSummariser
- type StoryCost
- type StoryCostRow
- type StoryStepRow
- type StorySyncReport
- type SummaryResult
- type TransitionGater
- type Verb
- type VersionInfo
- type WorkflowResolver
Constants ¶
const ( TopicStories = "stories" TopicTasks = "tasks" TopicDocs = "docs" )
Realtime change topics — coarse, panel-level. A mutating verb publishes one after it commits so an open web page refetches just that panel.
const KindStoryDocAttached = "story_doc_attached"
KindStoryDocAttached records a document attachment on the story's ledger.
Variables ¶
var ErrStoreNotConfigured = errors.New("verb: store not configured")
ErrStoreNotConfigured is returned when a verb runs before its backing store was wired. The in-process bootstrap calls the SetXStore functions below at startup; a nil store means a wiring bug, not a user error.
Functions ¶
func AddChangeNotifier ¶ added in v0.0.279
func AddChangeNotifier(fn func(topic string))
AddChangeNotifier appends a sink on the shared change seam (e.g. the push publisher beside an existing SSE hub). Nil is ignored.
func AppendTelemetry ¶ added in v0.0.138
AppendTelemetry records one typed telemetry/quality event against a story — the generic write primitive (AC1) that also backs the dispatch engine's structured retry/failure/timeout capture (AC2) via agentstep.Engine.SetTelemetry. Best-effort at the ledger layer (nil store is a no-op, matching appendLedger), but VALIDATES data before writing — a caller-suppliable event must never carry a secret onto the ledger.
func AttachItemDoc ¶ added in v0.0.351
func AttachItemDoc(ctx context.Context, item workitem.Item, name, typ, body string) (string, string, error)
AttachItemDoc exposes the verb-owned typed attachment mechanism to the isolated-agent engine. The engine validates structured output first; this function writes it through the same path as `satelle story attach`.
func ClearAgentsConfig ¶ added in v0.0.184
func ClearAgentsConfig()
ClearAgentsConfig resets the engage precondition wiring (tests).
func ClearTagVocabulary ¶ added in v0.0.249
func ClearTagVocabulary()
ClearTagVocabulary resets the tag vocabulary wiring (tests).
func CmpSemverExported ¶ added in v0.0.219
CmpSemverExported is the package-external semver compare for drift gates.
func Dispatch ¶
func Dispatch(ctx context.Context, name string, req json.RawMessage) (json.RawMessage, error)
Dispatch invokes a verb by name with raw JSON. Both CLI and web transports call here — same code path, same response shape.
func EventTelemetry ¶ added in v0.0.141
func EventTelemetry(e ledger.Entry) (agent, model, outcome string, tokensTotal int, durationMs int64)
EventTelemetry is the verb-package façade over ledger.EventTelemetry so story-cost and the web timeline share one reader (sty_43d228e4). Ownership of the extraction lives in ledger so the push-fed web package need not import verb.
func Register ¶
func Register(v *Verb)
Register adds a verb to the global registry. Panics on duplicate names — verb names are a typed namespace and collisions are bugs.
func SetAgentsConfig ¶ added in v0.0.184
func SetAgentsConfig(agents config.AgentsConfig, vars map[string]string)
SetAgentsConfig wires the agents layer + [vars] KV for the engage precondition. Call with the result of requireAgents at CLI bootstrap. Pass zero values / omit the call in tests that do not need the check.
func SetAuthoredDirs ¶ added in v0.0.335
SetAuthoredDirs wires authored-markdown roots for the substrate change leg.
func SetBackupsDir ¶ added in v0.0.261
func SetBackupsDir(dir string)
SetBackupsDir wires the runtime backups root (<runtime>/backups).
func SetChangeNotifier ¶ added in v0.0.2
func SetChangeNotifier(fn func(topic string))
SetChangeNotifier replaces the notifier list with a single sink (or clears it when fn is nil). Prefer AddChangeNotifier when composing sinks.
func SetCreateReviewer ¶ added in v0.0.6
func SetCreateReviewer(r CreateReviewer)
SetCreateReviewer wires the required-structure reviewer. Pass nil to disable.
func SetDataDir ¶ added in v0.0.261
func SetDataDir(dir string)
SetDataDir wires the authored substrate root (toml, documents, workflows, …).
func SetDocIndexStore ¶
SetDocIndexStore wires the authored-doc index store.
func SetExecutorDispatcher ¶ added in v0.0.80
func SetExecutorDispatcher(d ExecutorDispatcher)
SetExecutorDispatcher wires the named-agent dispatch. Pass nil to disable.
func SetLeaseStore ¶ added in v0.0.211
SetLeaseStore wires the engagement-lease store (sty_8426b9c0).
func SetLedgerStore ¶
SetLedgerStore wires the evidence-ledger store.
func SetOpLog ¶ added in v0.0.19
SetOpLog wires the flat-file operation log. Pass nil to disable (tests).
func SetRetrospector ¶ added in v0.0.133
func SetRetrospector(r Retrospector)
SetRetrospector wires the retrospective dispatcher. Pass nil to disable.
func SetStepSummariser ¶ added in v0.0.6
func SetStepSummariser(s StepSummariser)
SetStepSummariser wires the per-transition summariser. Pass nil to disable.
func SetStoryDir ¶ added in v0.0.6
func SetStoryDir(dir string)
SetStoryDir wires the directory that holds per-story attachments.
func SetStoryRetention ¶ added in v0.0.91
func SetStoryRetention(keepClosed, keepDays int)
SetStoryRetention wires the archive-retention policy for the per-story attachment dirs under .satelle/stories. Resolved from satelle.toml at app init.
func SetSubstrateConfigDir ¶ added in v0.0.336
func SetSubstrateConfigDir(dir string)
SetSubstrateConfigDir wires the resolved data dir (typically <repo>/.satelle) so non-kind config (agents.toml, constitution.md, hooks/) is enumerable.
func SetTagVocabulary ¶ added in v0.0.249
SetTagVocabulary wires the repo's tag vocabulary for create/set validation. Call with a.Config at CLI bootstrap. Pass zero / omit in tests that do not need the check.
func SetTaskDir ¶ added in v0.0.33
func SetTaskDir(dir string)
SetTaskDir wires the directory that holds task work-definition files.
func SetTransitionGater ¶ added in v0.0.6
func SetTransitionGater(g TransitionGater)
SetTransitionGater wires the reviewer that gates status transitions. Pass nil to disable gating (tests / no-reviewer environments).
func SetWorkItemStore ¶
SetWorkItemStore wires the stories/tasks store. Pass nil to reset (tests).
func SetWorkflowResolver ¶ added in v0.0.12
func SetWorkflowResolver(r WorkflowResolver)
SetWorkflowResolver wires the governing-workflow resolver. Pass nil to disable stamping.
func SyncStoryBacklog ¶ added in v0.0.44
func SyncStoryBacklog(ctx context.Context, store *workitem.Store, now time.Time) (materialized, pruned int, err error)
SyncStoryBacklog regenerates the read-only OKF backlog reference under the stories dir (.satelle/stories): every status:backlog story rendered as a generated concept file plus the reserved index.md/log.md. An engaged story (any non-backlog status) is NOT in the folder — the folder is the backlog. The SQLite store stays the SOLE story store (sty_fa1e02e1) — these files are a disposable, gitignored VIEW that no control logic reads (epic/parent close and the gates re-source from the DB); they exist only so the agent can browse the backlog on disk. Per-story attachment subdirs (<id>/) are left untouched, and the legacy pre-mirror-removal sty_*.md leftovers are cleaned up. Best-effort; a nil store or unset dir is a no-op. Returns the stories materialized and views pruned.
func SyncTasks ¶ added in v0.0.33
func SyncTasks(ctx context.Context, store *workitem.Store, now time.Time) (indexed, migrated int, err error)
SyncTasks reconciles the task files under taskDir with the store: any store task lacking a file is first ADOPTED by writing its file (migrating legacy DB-only tasks, e.g. tasks created before tasks became substrate), then every tsk_*.md is parsed and upserted so the FILE wins — it is the source of truth. Embedded default tasks (config.EmbeddedDefaults kind=tasks) with no on-disk file are ingested into the store WITHOUT writing a seed file (sty_29e5a9a5 virtual sparse defaults). Archived tasks are excluded from the store List that drives adoption, so an archived record is never resurrected (sty_cd209b8a). Returns (indexed, migrated). A no-op when taskDir is unset or the store is nil.
Types ¶
type ChangelogEntry ¶ added in v0.0.218
type ChangelogEntry struct {
Version string `json:"version"`
Date string `json:"date,omitempty"`
Breaking bool `json:"breaking"`
Sections map[string][]string `json:"sections,omitempty"`
Raw string `json:"raw,omitempty"`
}
ChangelogEntry is one release section from CHANGELOG.md.
func ChangelogRange ¶ added in v0.0.219
func ChangelogRange(from, to string) ([]ChangelogEntry, error)
ChangelogRange returns entries with from < version <= to from CHANGELOG.md (on-disk preferred; embedded fallback). Used by the CLI drift gate.
type ChangelogResult ¶ added in v0.0.218
type ChangelogResult struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Breaking bool `json:"breaking"`
Entries []ChangelogEntry `json:"entries"`
}
ChangelogResult is the changelog verb response.
type CreateDraft ¶ added in v0.0.6
type CreateDraft struct {
Kind string `json:"kind"`
Title string `json:"title"`
Body string `json:"body,omitempty"`
AcceptanceCriteria string `json:"acceptance_criteria,omitempty"`
Priority string `json:"priority,omitempty"`
Category string `json:"category,omitempty"`
Tags []string `json:"tags,omitempty"`
}
CreateDraft is a proposed work item handed to the required-structure reviewer before it is persisted.
type CreateReviewer ¶ added in v0.0.6
type CreateReviewer interface {
ReviewCreate(ctx context.Context, draft CreateDraft) (GateDecision, error)
}
CreateReviewer judges a draft work item's required structure before creation, in an isolated subprocess. Implemented in internal/agentstep.
type DispatchResult ¶ added in v0.0.80
type DispatchResult struct {
Dispatched bool `json:"dispatched"`
Agent string `json:"agent,omitempty"`
Command string `json:"command,omitempty"`
// Model is the binding's resolved model id ({model}), recorded on the
// agent_invocation so the ledger shows WHICH model actually ran a step — the
// audit signal for per-step model mixing (e.g. a GLM planner vs an opus
// in-loop session, sty_5d48317b). The model id is not a secret; the binding's
// env (endpoint + token) is deliberately NEVER recorded.
Model string `json:"model,omitempty"`
// Token/wall-time cost of the dispatch (sty_a699ad14), recorded on the
// agent_invocation entry. Zero for a plain-text harness with no usage envelope.
TokensIn int `json:"-"`
TokensOut int `json:"-"`
TokensTotal int `json:"-"`
DurationMs int64 `json:"-"`
Skill string `json:"skill,omitempty"`
// Output is the dispatched agent's captured stdout (sty_890b86cb). For a task
// EXECUTION run, the verb layer writes it through as an OKF run-output document
// under the parent task's folder, so a run's evidence is discoverable per task
// rather than only in the central executor.log.
Output string `json:"output,omitempty"`
// ArtifactName/Type identify a Satelle-owned structured step artifact
// attached before the transition committed.
ArtifactName string `json:"artifact_name,omitempty"`
ArtifactType string `json:"artifact_type,omitempty"`
}
DispatchResult reports a named-agent executor dispatch (sty_fd427546): whether the target state was allocated to a named isolated agent and, when it was, which agent/harness performed it and under which rubric.
type DocBody ¶ added in v0.0.274
DocBody is one attachment's name/type/body for payload injection (sty_58fa970e). Exported so agentstep can resolve docs without reaching into unexported storyDir.
type ExecutorDispatcher ¶ added in v0.0.80
type ExecutorDispatcher interface {
DispatchExecutor(ctx context.Context, item workitem.Item, toStatus string) (DispatchResult, error)
}
ExecutorDispatcher runs the named isolated agent a workflow node allocates a step to (agent=<name> — sty_fd427546): agents.toml defines WHO, the workflow DOT defines WHERE, the binary only RUNS it. Called after the edge's gates accept and BEFORE the status is enacted — an error refuses the transition (status unchanged). Implemented in internal/agentstep.
type GateDecision ¶ added in v0.0.6
type GateDecision struct {
Gated bool // a reviewer skill judged this edge
Accept bool // accept enacts the transition; reject blocks it
Notes string // reviewer notes — pushback to the executor on reject
Reasoning string // optional free-form reasoning (verdict contract; may be empty)
Skill string // the deciding reviewer skill
Reviewers []ReviewerVerdict // per-reviewer verdicts in run order (empty for the legacy single-reviewer path)
// Command/Context describe an isolated AGENT invocation (LLM reviewer): the
// resolved harness command and the injected-context source (skill/rubric file).
// Empty for a deterministic functional-check gate, which invokes no agent
// (sty_fb3e0873). They mirror the deciding reviewer for the single-reviewer path.
Command string
Context string
Model string // the reviewer's resolved model id (sty_a699ad14) — for the cost view
// TokensIn/Out/Total and DurationMs are the invocation's cost (sty_a699ad14),
// recorded on the agent_invocation ledger entry so per-gate cost is auditable.
// Zero for a functional-check gate or a plain-text harness that emits no usage.
TokensIn int
TokensOut int
TokensTotal int
DurationMs int64
// Unresolved names gate skills this edge DECLARED that do not resolve in the
// substrate. Those gates degrade to advisory — the edge advances with no
// reviewer and no verdict — which is deliberate, so a fresh repo works before
// every gate is authored. It is EVIDENCE OF AN UNGATED ADVANCE, never a
// verdict: an advance recorded with a non-empty Unresolved was not judged,
// and without it that is indistinguishable from an edge carrying no gate at
// all (sty_d59ec6a9).
Unresolved []string
}
GateDecision is an isolated reviewer's verdict on a requested status transition. Gated reports whether a reviewer skill governed the edge at all — an ungated edge (no reviewer_skill, or its rubric not installed) is advisory and enacts directly, preserving the gateless baseline.
An edge may be judged by MORE THAN ONE reviewer: a transition can name an ordered list of reviewers, and an always-on system reviewer layer runs after them. Reviewers carries each reviewer's verdict in run order; the top-level Accept/Skill/Notes mirror the deciding reviewer (the first reject, or the last reviewer when all accept) so single-reviewer callers keep their contract.
type ProcessView ¶ added in v0.0.265
type ProcessView struct {
Items []substrate.Row `json:"items"`
Allocations []agentvalidate.GateAllocation `json:"allocations"`
AgentsError string `json:"agents_error,omitempty"`
}
ProcessView is the effective-process payload for CLI/web (sty_ba0eb5c6).
type Retrospector ¶ added in v0.0.133
type Retrospector interface {
Retrospect(ctx context.Context, item workitem.Item) (DispatchResult, error)
}
Retrospector dispatches the retrospective agent over a finished story to emit improvement proposals (sty_b53730e2). Implemented in internal/agentstep; verb holds only the seam.
type ReviewerVerdict ¶ added in v0.0.6
type ReviewerVerdict struct {
Skill string `json:"skill"`
Order int `json:"order"`
Accept bool `json:"accept"`
Notes string `json:"notes,omitempty"`
Reasoning string `json:"reasoning,omitempty"` // optional free-form reasoning (verdict contract)
System bool `json:"system,omitempty"`
// Command/Context name the agent invocation behind an LLM reviewer's verdict —
// the resolved harness command and the injected skill/rubric file — so the trail
// records HOW it was judged, not just the outcome. Empty for a functional check.
Command string `json:"command,omitempty"`
Context string `json:"context,omitempty"`
Model string `json:"model,omitempty"` // reviewer's resolved model id (sty_a699ad14)
// Token/wall-time cost of this reviewer's invocation (sty_a699ad14), recorded
// on its agent_invocation entry for the per-gate cost view.
TokensIn int `json:"tokens_in,omitempty"`
TokensOut int `json:"tokens_out,omitempty"`
TokensTotal int `json:"tokens_total,omitempty"`
DurationMs int64 `json:"duration_ms,omitempty"`
}
ReviewerVerdict is one reviewer's verdict within a transition's ordered review. Order is its position in the run (workflow-named reviewers first, then the always-on system layer); System marks a verdict from that layer.
type StepSummariser ¶ added in v0.0.6
type StepSummariser interface {
Summarise(ctx context.Context, item workitem.Item, from, to string) (SummaryResult, error)
// MandatorySummary reports whether item's active workflow declares a MANDATORY
// step-summary node — the gate for surfacing a missing-summary gap at done
// (sty_a1151fb0).
MandatorySummary(ctx context.Context, item workitem.Item) bool
}
StepSummariser produces a read-only prose recap of an enacted transition, recorded as a step_summary ledger row. Implemented in internal/agentstep.
type StoryCost ¶ added in v0.0.132
type StoryCost struct {
StoryID string `json:"story_id"`
Rows []StoryCostRow `json:"rows"`
Steps []StoryStepRow `json:"steps,omitempty"`
TotalTokens int `json:"total_tokens"`
TotalDurationMs int64 `json:"total_duration_ms"`
TotalWallMs int64 `json:"total_wall_ms,omitempty"`
}
StoryCost is the per-story rollup: the dispatched/reviewed invocations (Rows, the precise sub-process cost) AND the per-step report (Steps, every state's wall-time plus any self-reported in-loop tokens / per-step estimate). Together they make the full cost of a driven story legible — dispatched and in-loop (sty_a699ad14, sty_3b2e55f5).
func ComputeStoryCost ¶ added in v0.0.132
ComputeStoryCost reads the story's ledger and builds two complementary views:
- Rows: the dispatched/reviewer agent_invocation cost (precise tokens + agent wall-time), exactly as before — entries with no usage contribute zero.
- Steps: a per-step report. Each state's WALL-TIME is derived from the deltas between consecutive status_transition timestamps (so IN-LOOP steps, which spawn no measurable subprocess, still get a duration), and its self-reported actual tokens + per-step estimate are merged from any step_cost entry.
Rows stay oldest-first, matching the ledger order; Steps follow first-occurrence order across the lifecycle.
type StoryCostRow ¶ added in v0.0.132
type StoryCostRow struct {
From string `json:"from"`
To string `json:"to"`
Agent string `json:"agent"`
Skill string `json:"skill,omitempty"`
Model string `json:"model,omitempty"`
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
TokensTotal int `json:"tokens_total"`
DurationMs int64 `json:"duration_ms"`
}
StoryCostRow is one dispatched/reviewed step's recorded cost — the per-gate tokens + wall-time captured on an agent_invocation ledger entry (sty_a699ad14).
type StoryStepRow ¶ added in v0.0.135
type StoryStepRow struct {
Step string `json:"step"`
WallTimeMs int64 `json:"wall_time_ms"`
TokensTotal int `json:"tokens_total,omitempty"` // self-reported in-loop actual
HasTokens bool `json:"has_tokens,omitempty"` // false = unrecorded (a subprocess can't measure it), NOT free
EstTokens int `json:"est_tokens,omitempty"`
EstDurationMs int64 `json:"est_duration_ms,omitempty"`
}
StoryStepRow is one workflow STEP's cost report: the wall-time the story spent in that state (derived from the transition timestamps — this is how an IN-LOOP step, whose tokens a subprocess can't measure, still gets a recorded cost) plus, where `satelle story step-cost` recorded them, the step's self-reported actual tokens and its per-step estimate. This is the per-step est-vs-actual view (sty_3b2e55f5).
type StorySyncReport ¶ added in v0.0.70
type StorySyncReport struct {
Materialized int `json:"materialized"` // backlog views written/refreshed
Pruned int `json:"pruned"` // stale/non-backlog views removed
ArtifactDirs int `json:"artifact_dirs"` // <sty_id>/ dirs present
Orphaned []string `json:"orphaned,omitempty"` // artifact dirs with no DB story
Problems []string `json:"problems,omitempty"` // artifact frontmatter mismatches
}
StorySyncReport summarises one full .satelle/stories reconciliation (sty_8f7b2157): the view counts plus the artifact review — orphaned artifact dirs (story id absent from the DB) and artifact files whose frontmatter contradicts their location are REPORTED, never deleted (artifacts are authored evidence; the operator decides).
func SyncStories ¶ added in v0.0.6
func SyncStories(ctx context.Context, store *workitem.Store, now time.Time) (StorySyncReport, error)
SyncStories runs the full stories-dir reconciliation and REVIEWS the artifacts (sty_8f7b2157): the shared SyncStoryBacklog core (materialize the backlog-only views, prune stale, migrate legacy summaries) plus a review of every <sty_id>/ artifact dir against the database. The dedicated `satelle story sync` verb calls this; reindex/serve keep calling the core.
type SummaryResult ¶ added in v0.0.138
type SummaryResult struct {
Text string
Command string
Context string
Model string
TokensIn int
TokensOut int
TokensTotal int
DurationMs int64
}
SummaryResult is the step summariser's read-only recap plus the cost of the isolated agent invocation that produced it (sty_a699ad14): Command/Context/ Model/tokens/duration mirror a reviewer's ReviewerVerdict so the same agent_invocation payload shape covers both. Zero-value cost fields mean the summariser produced no billable invocation (e.g. it never ran).
type TransitionGater ¶ added in v0.0.6
type TransitionGater interface {
Gate(ctx context.Context, item workitem.Item, toStatus string) (GateDecision, error)
}
TransitionGater judges a requested status transition in an isolated, fresh-context subprocess. The implementation lives in internal/agentstep; verb holds only the seam so the dispatch layer stays free of the agent CLI.
type Verb ¶
type Verb struct {
Name string
Description string
Invoke func(ctx context.Context, req json.RawMessage) (json.RawMessage, error)
}
Verb is a named entry in the dispatch registry.
type VersionInfo ¶
type VersionInfo struct {
Version string `json:"version"`
Commit string `json:"commit"`
BuildTime string `json:"build_time"`
}
VersionInfo is the response shape for the version verb. It mirrors buildinfo.Info; kept as the verb's own type so the wire shape is stable independent of the buildinfo internals.
type WorkflowResolver ¶ added in v0.0.12
type WorkflowResolver interface {
WorkflowNameFor(ctx context.Context, category string) string
// WorkflowStates returns the lifecycle states the named workflow declares and
// whether the workflow resolves at all — the restamp validation seam. An empty
// state list on a resolved workflow means the lifecycle was not statically
// parseable; the caller skips the status-compatibility check rather than
// blocking the restamp.
WorkflowStates(ctx context.Context, name string) ([]string, bool)
}
WorkflowResolver names the workflow that governs a story of a given category, so the create path can STAMP the choice on the story (sty_3800ac23) and the restamp path can re-resolve it mid-flight (sty_ed3386cf). Wired independently of create-gating — a story is stamped whenever a workflow governs it. Implemented in internal/agentstep.
Source Files
¶
- changelog.go
- changerecord.go
- doc.go
- engage_validate.go
- engagement.go
- helpers.go
- ledger.go
- process.go
- review.go
- seat.go
- single_story.go
- stop_request.go
- story_cost.go
- storydocs.go
- storymd.go
- storyokf.go
- storyretention.go
- tagvocab.go
- taskarchive.go
- taskmd.go
- taskoutput.go
- telemetry.go
- transition_edge.go
- verb.go
- version.go
- wiring.go
- workitem.go