Documentation
¶
Overview ¶
close_task.go wires `da workflow close-task`, the T1-molecule client command that composes the end-of-iteration primitive chain:
checkpoint --log-to-iter N → score iteration N → advance task to completed → plan update --focus <next eligible> → workflow commit
Each step is a T0 atom that already exists in this package; this file orchestrates them and surfaces wrapped errors naming which step blew so the operator does not have to bisect by hand.
tier: molecule calls:
- workflow-checkpoint-log-to-iter
- score-iteration
- workflow-advance
- workflow-plan-update
- workflow-commit
Per the skill-tiering-contract (T0 atom → T1 molecule → T2 compound → T3 cell), runtime agent judgment is bounded to picking among the declared atoms above. A future lint pass will read this block.
commit_cmd.go wires the `da workflow commit` subcommand. It composes the pure path-derivation in commit_pathset.go with a small interface seam over git so the orchestration is testable without a real worktree, and stages / commits only the derived set — the "never -A" rule the spec mandates.
commit_pathset.go derives the deterministic, scoped set of paths to stage for `da workflow commit`. It is the pure-function half of the workflow-commit-command spec (decision #3): "Deterministic, scoped path set — never `git add -A`."
The caller is responsible for actually running git status and shelling / go-git'ing the stage; this file owns only the derivation logic so it is testable from fixtures without a real worktree or subprocesses.
Package workflow's hook_outcome.go provides `da workflow hook-outcome write`, the CLI primitive R1.5 requires (per design D2/R2.1) so gates append outcome records to `.agents/active/iteration-log/iter-N.hook-outcomes.yaml` via this single bottleneck rather than writing the YAML by hand from gate.sh. Mirrors the shape of hook_sentinel.go (schema-validation, atomic temp+rename write, file-local seams for fault injection in tests).
iter_log_autoderive.go provides the thin orchestration helpers that the workflow-client-commands close-task uses to invoke `da workflow checkpoint --log-to-iter N --log-to-iter-role <role>` without operator-supplied N.
The actual iter-log writer (loadOrInitIterLogEntry → applyIterLogRole → writeIterLogEntry, plus the agent-block / git-diff / token-telemetry derivers) already exists in iter_log.go — this file does not duplicate any of that. It only picks (N, role) so callers do not have to.
start_task.go wires `da workflow start-task`, the T1-molecule client command that mirrors close-task on the start side of the iteration:
plan update --status active → plan update --focus T → plan derive-scope T → workflow commit
Each step is a T0 atom already in this package; this file orchestrates them and surfaces wrapped errors naming which step blew so the operator does not have to bisect by hand. fanout is intentionally NOT wired in this slice — the orchestrator typically wants to decide direct-vs-delegated explicitly, and `da workflow fanout` remains a separate primitive call.
tier: molecule calls:
- workflow-plan-update
- workflow-plan-derive-scope
- workflow-commit
Per the skill-tiering-contract (T0 atom → T1 molecule → T2 compound → T3 cell), runtime agent judgment is bounded to picking among the declared atoms above. A future lint pass will read this block.
Index ¶
- Constants
- Variables
- func DefaultIterationRole() string
- func DerivePathSet(status []StatusEntry, mutationSurface []string) []string
- func EvaluateBlocker(env BlockerEnv, status string) (bool, error)
- func InitTestDeps(d Deps)
- func IsBlockedOnStatus(status string) bool
- func IterationLogDir(projectPath string) string
- func NewCmd(d Deps) *cobra.Command
- func NewCmdForTest() *cobra.Command
- func NextIterationNumber(iterLogDir string) (int, error)
- func NormalizeResumeAs(override string) (string, error)
- func RegisterBlockerPredicate(kind string, pred blockerPredicate) error
- func ValidSignalKind(signal string) bool
- func WorkflowHookOutcomeSchema() (*jsonschema.Schema, error)
- type AggregateDriftReport
- type AnnotatedTask
- type BlockerDecay
- type BlockerEnv
- type BlockerRef
- type CanonicalPlan
- type CanonicalSlice
- type CanonicalSliceFile
- type CanonicalTask
- type CanonicalTaskFile
- type ContextMapping
- type CoordinationIntent
- type DelegationContract
- type DelegationContractMode
- type DelegationGateDecision
- type Deps
- type GlobalFlags
- type GraphBridgeAdapter
- type GraphBridgeConfig
- type GraphBridgeHealth
- type GraphBridgeQuery
- type GraphBridgeResponse
- type GraphBridgeResult
- type HookOutcomeRecord
- type HookOutcomeSidecar
- type HookSentinelContext
- type HookSentinelDoc
- type LocalGraphAdapter
- type ManagedProject
- type MergeBackSummary
- type MergeBackVerification
- type PlanScheduleResult
- type PlanScheduleTask
- type PlanScheduleWave
- type PollDetectorResult
- type PreconditionPolicy
- type Predicate
- type PredicateEvaluator
- type RepoDriftReport
- type ReviewDecisionDoc
- type ScopeEvidence
- type ScopeExcludedPath
- type ScopePath
- type ScopeQuery
- type ScopeQuerySummary
- type ScopeRequiredRead
- type ScopeSeeds
- type SignalSnapshot
- type SlotLedger
- type StatusEntry
- type SweepActionItem
- type SweepActionType
- type SweepLogEntry
- type SweepPlan
- type VerificationRecord
- type VerificationResultDoc
- type WorkflowCommitPrefs
- type WorkflowExecutionPrefs
- type WorkflowHealthSnapshot
- type WorkflowPlanningPrefs
- type WorkflowPreferences
- type WorkflowPreferencesFile
- type WorkflowReviewPrefs
- type WorkflowVerificationPrefs
Constants ¶
const ( // TaskStatusPending — task created, dependencies not yet satisfied or // not yet picked up by a worker. TaskStatusPending = "pending" // TaskStatusInProgress — a worker holds the task and is actively // implementing it. TaskStatusInProgress = "in_progress" // TaskStatusBlocked — task cannot proceed (external block, cascade, // or unrecoverable verify failure); manual recovery required. TaskStatusBlocked = "blocked" // TaskStatusCompleted — terminal success (e.g. PR merged on GitHub). TaskStatusCompleted = "completed" // TaskStatusCancelled — terminal manual abandonment. TaskStatusCancelled = "cancelled" // TaskStatusAwaitingAgentReview is the first sub-status of the // `awaiting_review` umbrella (§2.2): branch pushed, PR open, verifier // chain green; lens reviewers are dispatched or running. Counts // against max_parallel_tasks (§2.8) because lens dispatch can bounce // work back to in_progress. TaskStatusAwaitingAgentReview = "awaiting_agent_review" // TaskStatusAwaitingOwnerReview is the second sub-status of // `awaiting_review` (§2.2): lens verdicts accepted; the human // maintainer owns the merge decision. Frees its slot (§2.8) because // human-review latency is unbounded. TaskStatusAwaitingOwnerReview = "awaiting_owner_review" )
Task status vocabulary for canonical TASKS.yaml rows and the `da workflow advance --status` command. Centralized here so every predicate (eligibility, concurrency accounting, advance validation) reads from a single source of truth.
See .agents/workflow/specs/layered-pr-fanout/design.md §2.1, §2.2, §3.1, §3.2 for the state machine these constants encode.
const HookOutcomeSchemaVersion = 1
HookOutcomeSchemaVersion is the current schema version emitted by `da workflow hook-outcome write` and persisted at the top of each iter-N.hook-outcomes.yaml sidecar.
const HookSentinelSchemaVersion = 1
HookSentinelSchemaVersion is the current schema version emitted by `da workflow hook-sentinel write`.
const VerifierTypeMergeBack = "merge-back"
VerifierTypeMergeBack is the verifier_type / filename stem for worker merge-back results (`.agents/active/verification/<task_id>/merge-back.result.yaml`).
Variables ¶
var WorkflowHookOutcomeSchemaJSON []byte
WorkflowHookOutcomeSchemaJSON is the embedded twin of schemas/workflow-hook-outcome.schema.json (v1, per r1-5-hook-enforcement-telemetry design D2). The byte-equal guarantee between this embedded copy and the canonical file is enforced by TestWorkflowHookOutcomeEmbeddedSchemaMatchesCanonical so editors and JSON-schema tooling read the same contract the Go binary validates against.
Exported so the parallel t1-capture-outcomes worker (commands/workflow/hook_outcome.go) can reach the bytes if it ever needs the raw schema (e.g. for documentation emission). The expected callsite is WorkflowHookOutcomeSchema below, which returns a compiled validator instead of the raw bytes.
Functions ¶
func DefaultIterationRole ¶
func DefaultIterationRole() string
DefaultIterationRole returns the role close-task uses by default when no stronger context (a recent verifier record, a review-gate handoff) tells us to write a verifier or review entry instead.
Indirected through a function rather than a const so a future close-task enhancement (read the verify log; if the last record is a verifier with matching scope, write the verifier block) can land here without touching every caller.
func DerivePathSet ¶
func DerivePathSet(status []StatusEntry, mutationSurface []string) []string
DerivePathSet returns the sorted, deduplicated set of paths to stage. The derivation rules (from the spec's Decisions §3 and the wc-path-derivation task notes) are:
- Include every entry whose path is under one of the managed roots (.agents/workflow/, .agents/history/) — both tracked changes AND untracked entries. Anything under those roots is by convention a workflow artifact (a fresh PLAN.yaml from `da workflow plan create` is untracked on its first commit pass, so excluding untracked would orphan new plans).
- Include paths outside the managed roots only when the caller named them in MutationSurface. This is what implements the "pre-existing- untracked dirs" exclusion: the mutation surface is authoritative about which non-managed paths the session just touched, so an untracked `node_modules/` or `tmp/` that some other tool created never sneaks in.
- Always exclude submodule-pointer entries even if they fall under a managed root. A submodule pointer change is a separate kind of commit (submodule bump) and conflating it with workflow state silently mutates an SCM relationship.
- For rename / copy entries, stage both the new path and the original path so git captures the rename intent (R) or deletion (the index entry the old path leaves behind).
Determinism: the output is sorted lexicographically and deduplicated, so the same (status, surface) input pair always produces the same output.
func EvaluateBlocker ¶
func EvaluateBlocker(env BlockerEnv, status string) (bool, error)
EvaluateBlocker reports whether the blocker named by status has resolved (its auto-resume predicate is true). A status that is not a blocked-on state, a malformed ref, or a kind with no registered predicate returns an error; the caller leaves the task untouched on error.
func InitTestDeps ¶
func InitTestDeps(d Deps)
InitTestDeps wires workflow package dependencies for tests. Call from TestMain before m.Run().
func IsBlockedOnStatus ¶
IsBlockedOnStatus reports whether a persisted status string is a parameterized blocked-on:<ref> state.
func IterationLogDir ¶
IterationLogDir returns the canonical iter-log directory for a project. One place to compute it so close-task, the auto-derivers, and the existing runWorkflowCheckpointLogToIter all agree on the path.
func NewCmd ¶
NewCmd builds the `da workflow` command tree. Callers must supply Deps from package commands to avoid an import cycle.
func NewCmdForTest ¶
NewCmdForTest returns the workflow command tree using deps registered by InitTestDeps (see workflow_testutil_test.go init).
func NextIterationNumber ¶
NextIterationNumber returns the iteration number close-task should pass to `workflow checkpoint --log-to-iter`. If the iter-log directory has no existing iter-N.yaml entries (or does not exist yet), the next number is 1 — the schema's enforced minimum, matching the existing --log-to-iter validation that requires N >= 1. Otherwise it returns max(existing) + 1 so each close opens a fresh iteration entry.
A directory that exists but is empty is not an error; that is the expected state for a brand-new project's first close. Only filesystem errors (permission denied, parent missing, etc.) surface as errors.
func NormalizeResumeAs ¶
NormalizeResumeAs validates an optional --resume-as override and returns the status a resumed task should enter. An empty override yields the implicit default (in_progress, §3.4.5). An override outside {in_progress, pending} is rejected.
func RegisterBlockerPredicate ¶
RegisterBlockerPredicate installs or replaces the evaluator for a ref kind, keeping the registry pluggable per §3.4.5. It also marks the kind valid so parse accepts refs of that kind. A nil predicate or empty kind is rejected.
func ValidSignalKind ¶ added in v0.4.0
ValidSignalKind reports whether a signal kind resolves to a registered predicate evaluator (exact match or longest registered prefix, per evaluatorFor). It is the single source of truth the config-verify layer consults to reject a precondition_policies predicate that names a kind no evaluator handles — so a misregistration surfaces at `da config verify` time instead of only as a fail-closed gate at verify-transition time.
Exposing this small predicate (rather than having the verify command reach into the unexported registry) keeps the dependency edge one-directional: commands/config consults commands/workflow, and internal/config never imports any commands/* package. The checker reuses evaluatorFor so the set of valid kinds can never drift from the set the gate actually evaluates.
func WorkflowHookOutcomeSchema ¶
func WorkflowHookOutcomeSchema() (*jsonschema.Schema, error)
WorkflowHookOutcomeSchema returns the compiled validator for workflow-hook-outcome.schema.json (the sidecar at .agents/active/iteration-log/iter-N.hook-outcomes.yaml).
Exported for the parallel t1-capture-outcomes worker: t1's `da workflow hook-outcome write` CLI calls this to validate the sidecar payload before atomic-rename publish. Returning the compiled *jsonschema.Schema (rather than a doc-specific validate helper) keeps this slice free of any HookOutcomeDoc type — t1 owns that struct and the marshal/validate plumbing per the anti-scope split.
Cold-path callers should pass stdSchemaCompiler{}; tests can substitute a faulting compiler to drive error branches.
Types ¶
type AggregateDriftReport ¶
type AggregateDriftReport struct {
Timestamp string `json:"timestamp"`
TotalProjects int `json:"total_projects"`
ProjectsChecked int `json:"projects_checked"`
Reports []RepoDriftReport `json:"reports"`
HealthyCount int `json:"healthy_count"`
WarnCount int `json:"warn_count"`
UnreachableCount int `json:"unreachable_count"`
TopWarnings []string `json:"top_warnings"`
}
AggregateDriftReport summarizes drift across all managed projects.
type AnnotatedTask ¶
type AnnotatedTask struct {
ConflictsWith []string `json:"conflicts_with"`
HasEvidence bool `json:"has_evidence"`
EvidenceConfidence string `json:"evidence_confidence"`
WriteScopeDeclared bool `json:"write_scope_declared"`
// contains filtered or unexported fields
}
AnnotatedTask enriches a workflowNextTaskSuggestion with conflict detection and evidence fields populated by computeWriteScopeConflicts and the eligible command. All slice fields are initialized to []string{} (not nil) so they marshal to [] not null.
type BlockerDecay ¶
type BlockerDecay struct {
// Stale reports whether the task has been blocked past the threshold.
Stale bool
// Since is the RFC3339 timestamp the task entered the blocked state,
// echoed back for the blocker_stale_since annotation. Empty when Stale
// is false.
Since string
// Age is how long the task has been blocked, rounded to whole seconds.
Age time.Duration
}
BlockerDecay carries the §3.4.4 staleness verdict for a blocked task.
func EvaluateBlockerDecay ¶
func EvaluateBlockerDecay(blockedSince string, configuredDays int, now time.Time) (BlockerDecay, error)
EvaluateBlockerDecay computes the §3.4.4 eligibility-decay verdict for a task that entered its blocked state at blockedSince (RFC3339). configuredDays is the per-project threshold from .agentsrc.json (<=0 means "use default"). now is injected for deterministic tests. A blank or unparseable blockedSince yields a non-stale verdict (we cannot prove staleness without an entry time).
type BlockerEnv ¶
type BlockerEnv interface {
// SecretExists reports whether a repo/org secret with the given name is
// present (production: `gh secret list`).
SecretExists(name string) (bool, error)
// TaskStatus returns the persisted status of plan/task (production: read
// the canonical TASKS.yaml). The bool is false when the task is unknown.
TaskStatus(plan, task string) (string, bool)
// DecisionResolved reports whether maintainer decision id has landed
// (production: a resolved-decision record exists).
DecisionResolved(id string) (bool, error)
// EvalCondition evaluates a registered named condition predicate. The
// bool reports the predicate result; an error is returned for an
// unregistered predicate or an evaluator failure.
EvalCondition(predicate string) (bool, error)
}
BlockerEnv is the seam through which predicate evaluators reach external state (GitHub, the canonical task store, resolved-decision records). The concrete production implementation shells out to `gh` and reads canonical YAML; tests inject a fake so no network or filesystem access is required.
type BlockerRef ¶
BlockerRef is the parsed form of the `<ref>` portion of a `blocked-on:<ref>` status. Kind is one of the blockerKind* constants and Arg is the remainder after the first ':' (e.g. for `blocked-on:task:p1/t2` → Kind="task", Arg="p1/t2").
func ParseBlockedOnStatus ¶
func ParseBlockedOnStatus(status string) (BlockerRef, error)
ParseBlockedOnStatus parses a full persisted status string (`blocked-on:<kind>:<arg>`) into its BlockerRef. It returns an error when the status lacks the blocked-on: prefix or the ref body is malformed.
func (BlockerRef) String ¶
func (r BlockerRef) String() string
String renders the ref back to its canonical `<kind>:<arg>` form. It is the inverse of parseBlockerRef and is stable (round-trips).
type CanonicalPlan ¶
type CanonicalPlan struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
ID string `json:"id" yaml:"id"`
Title string `json:"title" yaml:"title"`
Status string `json:"status" yaml:"status"`
Summary string `json:"summary" yaml:"summary"`
CreatedAt string `json:"created_at" yaml:"created_at"`
UpdatedAt string `json:"updated_at" yaml:"updated_at"`
Owner string `json:"owner" yaml:"owner"`
SuccessCriteria string `json:"success_criteria" yaml:"success_criteria"`
VerificationStrategy string `json:"verification_strategy" yaml:"verification_strategy"`
CurrentFocusTask string `json:"current_focus_task" yaml:"current_focus_task"`
DefaultAppType string `json:"default_app_type,omitempty" yaml:"default_app_type,omitempty"`
}
CanonicalPlan is the PLAN.yaml schema for .agents/workflow/plans/<id>/PLAN.yaml
type CanonicalSlice ¶
type CanonicalSlice struct {
ID string `json:"id" yaml:"id"`
ParentTaskID string `json:"parent_task_id" yaml:"parent_task_id"`
Title string `json:"title" yaml:"title"`
Summary string `json:"summary" yaml:"summary"`
Status string `json:"status" yaml:"status"`
DependsOn []string `json:"depends_on" yaml:"depends_on"`
WriteScope []string `json:"write_scope" yaml:"write_scope"`
VerificationFocus string `json:"verification_focus" yaml:"verification_focus"`
Owner string `json:"owner" yaml:"owner"`
}
CanonicalSlice is one bounded sub-slice under a canonical task.
type CanonicalSliceFile ¶
type CanonicalSliceFile struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
PlanID string `json:"plan_id" yaml:"plan_id"`
Slices []CanonicalSlice `json:"slices" yaml:"slices"`
}
CanonicalSliceFile is the SLICES.yaml schema for .agents/workflow/plans/<id>/SLICES.yaml
type CanonicalTask ¶
type CanonicalTask struct {
ID string `json:"id" yaml:"id"`
Title string `json:"title" yaml:"title"`
Status string `json:"status" yaml:"status"`
DependsOn []string `json:"depends_on" yaml:"depends_on"`
Blocks []string `json:"blocks" yaml:"blocks"`
Owner string `json:"owner" yaml:"owner"`
WriteScope []string `json:"write_scope" yaml:"write_scope"`
VerificationRequired bool `json:"verification_required" yaml:"verification_required"`
Notes string `json:"notes" yaml:"notes"`
AppType string `json:"app_type,omitempty" yaml:"app_type,omitempty"`
}
CanonicalTask is one entry in TASKS.yaml
type CanonicalTaskFile ¶
type CanonicalTaskFile struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
PlanID string `json:"plan_id" yaml:"plan_id"`
Tasks []CanonicalTask `json:"tasks" yaml:"tasks"`
}
CanonicalTaskFile is the TASKS.yaml schema for .agents/workflow/plans/<id>/TASKS.yaml
type ContextMapping ¶
type CoordinationIntent ¶
type CoordinationIntent string
const ( CoordinationIntentNone CoordinationIntent = "" CoordinationIntentStatusRequest CoordinationIntent = "status_request" CoordinationIntentReviewRequest CoordinationIntent = "review_request" CoordinationIntentEscalationNotice CoordinationIntent = "escalation_notice" CoordinationIntentAck CoordinationIntent = "ack" )
type DelegationContract ¶
type DelegationContract struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
ID string `json:"id" yaml:"id"`
Mode DelegationContractMode `json:"mode,omitempty" yaml:"mode,omitempty"`
ParentPlanID string `json:"parent_plan_id" yaml:"parent_plan_id"`
ParentTaskID string `json:"parent_task_id" yaml:"parent_task_id"`
Title string `json:"title" yaml:"title"`
Summary string `json:"summary" yaml:"summary"`
WriteScope []string `json:"write_scope" yaml:"write_scope"`
SuccessCriteria string `json:"success_criteria" yaml:"success_criteria"`
VerificationExpectations string `json:"verification_expectations" yaml:"verification_expectations"`
MayMutateWorkflowState bool `json:"may_mutate_workflow_state" yaml:"may_mutate_workflow_state"`
Owner string `json:"owner" yaml:"owner"`
Status string `json:"status" yaml:"status"`
PendingIntent CoordinationIntent `json:"pending_intent,omitempty" yaml:"pending_intent,omitempty"`
CreatedAt string `json:"created_at" yaml:"created_at"`
UpdatedAt string `json:"updated_at" yaml:"updated_at"`
}
type DelegationContractMode ¶
type DelegationContractMode string
DelegationContractMode discriminates contracts written by `workflow fanout` (delegated to a sub-agent worker) from contracts materialized for direct orchestrator-owned work via `workflow contract create`.
Both modes share the same on-disk shape, advance through the same closeout pipeline (merge-back → delegation closeout → auto-advance), and contribute equally to the workflow audit trail. The distinction is documentation + downstream tooling (skills, lens routing) deciding which artifacts to expect.
const ( // DelegationContractModeDelegated is the legacy mode written by `workflow fanout`. // A sub-agent (loop-worker, codex helper, etc.) owns the write scope until merge-back. DelegationContractModeDelegated DelegationContractMode = "delegated" // DelegationContractModeDirect is the new mode written by `workflow contract create`. // The orchestrator itself owns the write scope; the contract pins guardrails // (write scope, success criteria, closeout discipline) so direct work flows // through the same audit trail as delegated work. DelegationContractModeDirect DelegationContractMode = "direct" )
type DelegationGateDecision ¶
type DelegationGateDecision struct {
SchemaVersion int `json:"schema_version"`
TaskID string `json:"task_id"`
PlanID string `json:"plan_id"`
DelegationID string `json:"delegation_id,omitempty"`
MergeBackPresent bool `json:"merge_back_present"`
ReviewDecisionPresent bool `json:"review_decision_present"`
ReviewOverallDecision string `json:"review_overall_decision,omitempty"`
Outcome string `json:"outcome"`
CloseoutAllowed bool `json:"closeout_allowed"`
PlanningRequired bool `json:"planning_required"`
Reason string `json:"reason"`
EscalationReason string `json:"escalation_reason,omitempty"`
}
DelegationGateDecision is the deterministic parent-gate readback for one task.
type Deps ¶
type Deps struct {
Flags GlobalFlags
ErrNoProject error
ErrorWithHints func(message string, hints ...string) error
UsageError func(message string, hints ...string) error
NoArgsWithHints func(hints ...string) cobra.PositionalArgs
ExactArgsWithHints func(n int, hints ...string) cobra.PositionalArgs
MaximumNArgsWithHints func(n int, hints ...string) cobra.PositionalArgs
ExampleBlock func(lines ...string) string
Store graphstore.Handle
}
Deps carries UX helpers and sentinels from package commands without an import cycle.
gcc3 / di-refactor OD-1: Store is a contract-typed handle whose provider owns pooling and serialization. The package-level deps singleton is justified as a holder of this contract-typed handle — it is NOT the concurrency story (the provider behind the contract is). graphstore.Handle's Store() accessor is nil-safe: when unset, callers fall back to their existing direct-open path (preserving today's behavior). End-to-end wiring from the singleton to every call site is the deferred follow-up tracked on di-refactor OD-1. See internal/graphstore/CONTRACT.md "Deps boundary".
type GlobalFlags ¶
GlobalFlags mirrors the subset of commands.Flags read by workflow subcommands at runtime.
type GraphBridgeAdapter ¶
type GraphBridgeAdapter interface {
Query(query GraphBridgeQuery) (GraphBridgeResponse, error)
Health() (GraphBridgeHealth, error)
}
type GraphBridgeConfig ¶
type GraphBridgeConfig struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
Enabled bool `json:"enabled" yaml:"enabled"`
GraphHome string `json:"graph_home" yaml:"graph_home"`
AllowedIntents []string `json:"allowed_intents" yaml:"allowed_intents"`
ContextMappings []ContextMapping `json:"context_mappings" yaml:"context_mappings"`
}
type GraphBridgeHealth ¶
type GraphBridgeHealth struct {
SchemaVersion int `json:"schema_version"`
Timestamp string `json:"timestamp"`
AdapterAvailable bool `json:"adapter_available"`
GraphHomeExists bool `json:"graph_home_exists"`
NoteCount int `json:"note_count"`
WarmStoreNodeCount int `json:"warm_store_node_count"`
WarmStoreNoteCount int `json:"warm_store_note_count"`
CodeLaneReady bool `json:"code_lane_ready"`
ContextLaneReady bool `json:"context_lane_ready"`
LastQueryTime string `json:"last_query_time,omitempty"`
LastQueryStatus string `json:"last_query_status,omitempty"`
Status string `json:"status"`
Note string `json:"note,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
type GraphBridgeQuery ¶
type GraphBridgeResponse ¶
type GraphBridgeResult ¶
type HookOutcomeRecord ¶
type HookOutcomeRecord struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
SentinelID string `json:"sentinel_id" yaml:"sentinel_id"`
Skill string `json:"skill" yaml:"skill"`
LifecyclePoint string `json:"lifecycle_point" yaml:"lifecycle_point"`
InterventionClass string `json:"intervention_class" yaml:"intervention_class"`
Result string `json:"result" yaml:"result"`
RuleID string `json:"rule_id" yaml:"rule_id"`
Platform string `json:"platform" yaml:"platform"`
TS string `json:"ts" yaml:"ts"`
ArchivedSentinelPath string `json:"archived_sentinel_path,omitempty" yaml:"archived_sentinel_path,omitempty"`
CorrelationID string `json:"correlation_id" yaml:"correlation_id"`
}
HookOutcomeRecord is one record in iter-N.hook-outcomes.yaml. Field names mirror the schema; tags are explicit so YAML and JSON shapes agree (the schema validates the JSON projection). No tag for the disallowed fields exists by construction — they are not modelled here.
type HookOutcomeSidecar ¶
type HookOutcomeSidecar struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
Records []HookOutcomeRecord `json:"records" yaml:"records"`
}
HookOutcomeSidecar is the iter-N.hook-outcomes.yaml top-level shape.
type HookSentinelContext ¶
type HookSentinelContext struct {
GitHeadAtStart string `json:"git_head_at_start,omitempty"`
WriteScope []string `json:"write_scope,omitempty"`
EligibleSnapshotLoaded *bool `json:"eligible_snapshot_loaded,omitempty"`
MaxBatch *int `json:"max_batch,omitempty"`
TracePathHint string `json:"trace_path_hint,omitempty"`
// Companion: operation discriminator and per-operation evidence.
Operation string `json:"operation,omitempty"`
DelegationPath string `json:"delegation_path,omitempty"`
BundlePath string `json:"bundle_path,omitempty"`
RequiredSidecarPath string `json:"required_sidecar_path,omitempty"`
EvidenceConfidence string `json:"evidence_confidence,omitempty"`
Decision string `json:"decision,omitempty"`
ExpectedArchiveArtifacts []string `json:"expected_archive_artifacts,omitempty"`
ExpectedCleanupPaths []string `json:"expected_cleanup_paths,omitempty"`
}
HookSentinelContext carries the skill-specific signals declared at sentinel write time. Fields are pointer-shaped where the zero value collides with a meaningful value (e.g. `eligible_snapshot_loaded: false` is a real ISP signal and must be distinguishable from "not declared"). Use `omitempty` on absent fields so the rendered JSON matches the schema's `additionalProperties: false` contract.
Companion-gate fields per T1 contract: the operation discriminator plus the evidence each pair is allowed to declare at write time. Names mirror the schema. No field carries transcript or tool-command body content.
type HookSentinelDoc ¶
type HookSentinelDoc struct {
SchemaVersion int `json:"schema_version"`
Skill string `json:"skill"`
RunID string `json:"run_id"`
StartedAt string `json:"started_at"`
PlanID string `json:"plan_id"`
TaskID string `json:"task_id"`
AgentType string `json:"agent_type"`
LifecyclePoint string `json:"lifecycle_point,omitempty"`
ExpectedArtifacts []string `json:"expected_artifacts,omitempty"`
Context *HookSentinelContext `json:"context,omitempty"`
}
HookSentinelDoc is the typed payload persisted at `.agents/active/hook-sentinels/<skill>-<run-id>.json`.
type LocalGraphAdapter ¶
type LocalGraphAdapter struct {
// contains filtered or unexported fields
}
func NewLocalGraphAdapter ¶
func NewLocalGraphAdapter(graphHome string) *LocalGraphAdapter
func (*LocalGraphAdapter) Health ¶
func (a *LocalGraphAdapter) Health() (GraphBridgeHealth, error)
func (*LocalGraphAdapter) Query ¶
func (a *LocalGraphAdapter) Query(query GraphBridgeQuery) (GraphBridgeResponse, error)
type ManagedProject ¶
ManagedProject is one entry from ~./agents/config.json loaded for drift checks.
type MergeBackSummary ¶
type MergeBackSummary struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
TaskID string `json:"task_id" yaml:"task_id"`
ParentPlanID string `json:"parent_plan_id" yaml:"parent_plan_id"`
Title string `json:"title" yaml:"title"`
Summary string `json:"summary" yaml:"summary"`
FilesChanged []string `json:"files_changed" yaml:"files_changed"`
VerificationResult MergeBackVerification `json:"verification_result" yaml:"verification_result"`
IntegrationNotes string `json:"integration_notes" yaml:"integration_notes"`
BlockersEncountered []string `json:"blockers_encountered,omitempty" yaml:"blockers_encountered,omitempty"`
CreatedAt string `json:"created_at" yaml:"created_at"`
}
type MergeBackVerification ¶
type PlanScheduleResult ¶
type PlanScheduleResult struct {
PlanID string `json:"plan_id"`
Waves []PlanScheduleWave `json:"waves"`
CriticalPathLength int `json:"critical_path_length"`
MaxIntraParallelism int `json:"max_intra_plan_parallelism"`
}
PlanScheduleResult is the full schedule output.
type PlanScheduleTask ¶
type PlanScheduleTask struct {
ID string `json:"id"`
Title string `json:"title"`
Status string `json:"status"`
WriteScope []string `json:"write_scope"`
}
PlanScheduleTask is a task entry in the schedule output.
type PlanScheduleWave ¶
type PlanScheduleWave struct {
Wave int `json:"wave"`
Tasks []PlanScheduleTask `json:"tasks"`
}
PlanScheduleWave is a single wave (parallel group) in the schedule.
type PollDetectorResult ¶ added in v0.4.0
PollDetectorResult is the aggregate outcome of one poll cycle: the transition decisions to persist (in deterministic task-id order) and the per-task SHA sets observed this cycle (so the caller can persist them as next cycle's LastSHAs for force-rebase detection).
type PreconditionPolicy ¶ added in v0.4.0
type PreconditionPolicy struct {
// Name is the policy's registry key (e.g. "default").
Name string
// Predicates is the set evaluated against a SignalSnapshot. Order does not
// affect satisfaction, only which failing reason surfaces first.
Predicates []Predicate
}
PreconditionPolicy is a named, unordered set of predicates. The gate opens only when every predicate is satisfied; there is no partial-green shortcut (§2.3).
type Predicate ¶ added in v0.4.0
type Predicate struct {
// Signal is the registered kind, e.g. "event.pr.open", "gate.quality.sonar".
Signal string
// Args are kind-specific parameters, e.g. {"equals":"green"}.
Args map[string]string
}
Predicate is one condition over a single registered event/signal kind.
type PredicateEvaluator ¶ added in v0.4.0
type PredicateEvaluator func(p Predicate, snap SignalSnapshot) (ok bool, reason string)
PredicateEvaluator decides whether one predicate is satisfied against a snapshot. reason is the operator hint surfaced when !ok.
type RepoDriftReport ¶
type RepoDriftReport struct {
Project ManagedProject `json:"project"`
Reachable bool `json:"reachable"` // false if path doesn't exist
MissingCheckpoint bool `json:"missing_checkpoint"` // no checkpoint file
StaleCheckpoint bool `json:"stale_checkpoint"` // checkpoint older than threshold
CheckpointAgeDays int `json:"checkpoint_age_days"` // -1 if no checkpoint
StaleProposalCount int `json:"stale_proposal_count"` // proposals older than threshold
MissingWorkflowDir bool `json:"missing_workflow_dir"` // no .agents/workflow/
MissingPlanStructure bool `json:"missing_plan_structure"` // no .agents/workflow/plans/
CompletedPlanIDs []string `json:"completed_plan_ids"` // plans with status==completed (hygiene signal)
InconsistentArchivedPlanIDs []string `json:"inconsistent_archived_plan_ids"` // plans with status==archived still in workflow/plans/ (error-level)
Warnings []string `json:"warnings"`
Status string `json:"status"` // healthy|warn|unreachable
}
RepoDriftReport captures drift conditions for one managed project.
type ReviewDecisionDoc ¶
type ReviewDecisionDoc struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
TaskID string `json:"task_id" yaml:"task_id"`
ParentPlanID string `json:"parent_plan_id" yaml:"parent_plan_id"`
DelegationID string `json:"delegation_id,omitempty" yaml:"delegation_id,omitempty"`
Phase1Decision string `json:"phase_1_decision" yaml:"phase_1_decision"`
Phase2Decision string `json:"phase_2_decision" yaml:"phase_2_decision"`
OverallDecision string `json:"overall_decision" yaml:"overall_decision"`
FailedGates []string `json:"failed_gates" yaml:"failed_gates"`
EscalationReason string `json:"escalation_reason,omitempty" yaml:"escalation_reason,omitempty"`
ReviewerNotes string `json:"reviewer_notes,omitempty" yaml:"reviewer_notes,omitempty"`
RecordedAt string `json:"recorded_at" yaml:"recorded_at"`
RecordedBy string `json:"recorded_by,omitempty" yaml:"recorded_by,omitempty"`
}
ReviewDecisionDoc is the typed payload for `.agents/active/verification/<task_id>/review-decision.yaml`.
type ScopeEvidence ¶
type ScopeEvidence struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
PlanID string `json:"plan_id" yaml:"plan_id"`
TaskID string `json:"task_id" yaml:"task_id"`
Status string `json:"status" yaml:"status"`
Mode string `json:"mode,omitempty" yaml:"mode,omitempty"`
Goal string `json:"goal,omitempty" yaml:"goal,omitempty"`
Confidence string `json:"confidence" yaml:"confidence"`
DecisionLocks []string `json:"decision_locks" yaml:"decision_locks"`
RequiredReads []ScopeRequiredRead `json:"required_reads" yaml:"required_reads"`
Seeds *ScopeSeeds `json:"seeds,omitempty" yaml:"seeds,omitempty"`
Queries []ScopeQuery `json:"queries" yaml:"queries"`
RequiredPaths []ScopePath `json:"required_paths" yaml:"required_paths"`
OptionalPaths []ScopePath `json:"optional_paths" yaml:"optional_paths"`
ExcludedPaths []ScopeExcludedPath `json:"excluded_paths" yaml:"excluded_paths"`
Provides []string `json:"provides" yaml:"provides"`
Consumes []string `json:"consumes" yaml:"consumes"`
FinalWriteScope []string `json:"final_write_scope" yaml:"final_write_scope"`
VerificationFocus []string `json:"verification_focus" yaml:"verification_focus"`
AllowedLocalChoices []string `json:"allowed_local_choices" yaml:"allowed_local_choices"`
StopConditions []string `json:"stop_conditions" yaml:"stop_conditions"`
OpenGaps []string `json:"open_gaps" yaml:"open_gaps"`
}
ScopeEvidence is the Go representation of a .scope.yaml sidecar file located at .agents/workflow/plans/<plan_id>/evidence/<task_id>.scope.yaml. All slice fields use []string{} (not nil) so JSON marshals to [] not null.
func NewScopeEvidence ¶
func NewScopeEvidence(planID, taskID string) *ScopeEvidence
NewScopeEvidence returns a ScopeEvidence with all slice fields initialized to empty slices so they marshal to [] rather than null.
type ScopeExcludedPath ¶
type ScopeExcludedPath struct {
Path string `json:"path" yaml:"path"`
Rationale []string `json:"rationale" yaml:"rationale"`
}
ScopeExcludedPath is a path intentionally excluded from write_scope.
type ScopePath ¶
type ScopePath struct {
Path string `json:"path" yaml:"path"`
Because []string `json:"because" yaml:"because"`
}
ScopePath is a required or optional path entry with explanatory reasons.
type ScopeQuery ¶
type ScopeQuery struct {
Tool string `json:"tool" yaml:"tool"`
Kind string `json:"kind" yaml:"kind"`
Intent string `json:"intent" yaml:"intent"`
Subject string `json:"subject" yaml:"subject"`
Summary *ScopeQuerySummary `json:"summary,omitempty" yaml:"summary,omitempty"`
}
ScopeQuery represents a single graph query run during scope derivation.
type ScopeQuerySummary ¶
type ScopeQuerySummary struct {
Files []string `json:"files" yaml:"files"`
}
ScopeQuerySummary holds the result files returned by a graph query.
type ScopeRequiredRead ¶
type ScopeRequiredRead struct {
Path string `json:"path" yaml:"path"`
Why string `json:"why" yaml:"why"`
}
ScopeRequiredRead is an entry in ScopeEvidence.RequiredReads.
type ScopeSeeds ¶
type ScopeSeeds struct {
Symbols []string `json:"symbols,omitempty" yaml:"symbols,omitempty"`
Paths []string `json:"paths,omitempty" yaml:"paths,omitempty"`
Rationale []string `json:"rationale,omitempty" yaml:"rationale,omitempty"`
}
ScopeSeeds captures the starting symbols or paths the planner identified.
type SignalSnapshot ¶ added in v0.4.0
SignalSnapshot is the observed signal set the verifier evaluates a policy against: kind → observed value, e.g. "signal.ci.rollup":"green". The producer (lpf PR-producer / poll-detector) fills it; this package only consumes it.
type SlotLedger ¶
type SlotLedger struct {
Occupied int `json:"occupied"`
AwaitingOwner int `json:"awaiting_owner"`
Blocked int `json:"blocked"`
Pending int `json:"pending"`
Terminal int `json:"terminal"`
MaxParallel int `json:"max_parallel"`
// Available is MaxParallel - Occupied, floored at zero: how many new tasks
// could start a slot right now.
Available int `json:"available"`
}
SlotLedger is the §2.8 / §3.4.3 accounting snapshot across one or more plans. Occupied is the live count against MaxParallel; the remaining buckets make the freed-slot reasons (owner-review backlog, blocked pathology) inspectable.
type StatusEntry ¶
StatusEntry is one line of `git status --porcelain=v2 -z` after parsing. XY is the 2-char status code; OrigPath is non-empty only for renames / copies. Submodule reflects whether porcelain v2 reported the entry with the "S" sub-state marker (field 3 starts with 'S' instead of 'N').
func ParseStatus ¶
func ParseStatus(raw []byte) ([]StatusEntry, error)
ParseStatus parses `git status --porcelain=v2 -z` output into StatusEntry slices. The v2 format keeps fields fixed-width and NUL-terminates each entry, so the parser is straightforward; v1 is intentionally not supported because v1 cannot reliably distinguish submodule sub-states from regular modifications.
Reference: https://git-scm.com/docs/git-status#_porcelain_format_version_2
type SweepActionItem ¶
type SweepActionItem struct {
Project ManagedProject `json:"project"`
Action SweepActionType `json:"action"`
Description string `json:"description"`
RequiresConfirmation bool `json:"requires_confirmation"`
PlanID string `json:"plan_id,omitempty"`
}
SweepActionItem is one actionable fix in a sweep plan.
type SweepActionType ¶
type SweepActionType string
SweepActionType enumerates the kinds of fixes the sweep can apply.
const ( SweepActionScaffoldWorkflowDir SweepActionType = "scaffold_workflow_dir" SweepActionCreatePlanStructure SweepActionType = "create_plan_structure" SweepActionCreateCheckpointReminder SweepActionType = "create_checkpoint_reminder" SweepActionFlagStaleProposals SweepActionType = "flag_stale_proposals" SweepActionArchiveCompletedPlans SweepActionType = "archive_completed_plans" )
type SweepLogEntry ¶
type SweepLogEntry struct {
Timestamp string `json:"timestamp"`
Project string `json:"project"`
Action SweepActionType `json:"action"`
Description string `json:"description"`
Applied bool `json:"applied"`
DryRun bool `json:"dry_run"`
}
SweepLogEntry is one record in sweep-log.jsonl.
type SweepPlan ¶
type SweepPlan struct {
CreatedAt string `json:"created_at"`
Actions []SweepActionItem `json:"actions"`
}
SweepPlan is the collection of planned actions for a sweep run.
type VerificationRecord ¶
type VerificationRecord struct {
SchemaVersion int `json:"schema_version"`
Timestamp string `json:"timestamp"`
Kind string `json:"kind"`
Status string `json:"status"`
Command string `json:"command"`
Scope string `json:"scope"`
Summary string `json:"summary"`
Artifacts []string `json:"artifacts"`
RecordedBy string `json:"recorded_by"`
}
VerificationRecord is one line in verification-log.jsonl
type VerificationResultDoc ¶
type VerificationResultDoc struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
TaskID string `json:"task_id" yaml:"task_id"`
ParentPlanID string `json:"parent_plan_id" yaml:"parent_plan_id"`
VerifierType string `json:"verifier_type" yaml:"verifier_type"`
Status string `json:"status" yaml:"status"`
Summary string `json:"summary" yaml:"summary"`
RecordedAt string `json:"recorded_at" yaml:"recorded_at"`
DelegationID string `json:"delegation_id,omitempty" yaml:"delegation_id,omitempty"`
RecordedBy string `json:"recorded_by,omitempty" yaml:"recorded_by,omitempty"`
Commands []string `json:"commands,omitempty" yaml:"commands,omitempty"`
ArtifactPaths []string `json:"artifact_paths,omitempty" yaml:"artifact_paths,omitempty"`
}
VerificationResultDoc is the typed payload for `.agents/active/verification/<task_id>/<verifier_type>.result.yaml`.
type WorkflowCommitPrefs ¶
type WorkflowCommitPrefs struct {
Disable *bool `json:"disable,omitempty" yaml:"disable,omitempty"`
}
WorkflowCommitPrefs gates the `da workflow commit` and iteration-close auto-commit behaviour. Disable=true short-circuits both to a documented no-op for repos that manage workflow-state commits elsewhere.
type WorkflowExecutionPrefs ¶
type WorkflowExecutionPrefs struct {
PackageManager *string `json:"package_manager,omitempty" yaml:"package_manager,omitempty"`
Formatter *string `json:"formatter,omitempty" yaml:"formatter,omitempty"`
MaxParallelWorkers *int `json:"max_parallel_workers,omitempty" yaml:"max_parallel_workers,omitempty"`
}
type WorkflowHealthSnapshot ¶
type WorkflowHealthSnapshot struct {
SchemaVersion int `json:"schema_version"`
Timestamp string `json:"timestamp"`
Git struct {
InsideRepo bool `json:"inside_repo"`
Branch string `json:"branch"`
DirtyFileCount int `json:"dirty_file_count"`
} `json:"git"`
Workflow struct {
HasActivePlan bool `json:"has_active_plan"`
HasCheckpoint bool `json:"has_checkpoint"`
PendingProposals int `json:"pending_proposals"`
CanonicalPlanCount int `json:"canonical_plan_count"`
CompletedPlansPendingArchive int `json:"completed_plans_pending_archive"`
} `json:"workflow"`
Tooling struct {
MCP string `json:"mcp"`
Auth string `json:"auth"`
Formatter string `json:"formatter"`
} `json:"tooling"`
Status string `json:"status"`
Warnings []string `json:"warnings"`
}
WorkflowHealthSnapshot is the health.json schema
type WorkflowPlanningPrefs ¶
type WorkflowPreferences ¶
type WorkflowPreferences struct {
Verification WorkflowVerificationPrefs `json:"verification" yaml:"verification"`
Planning WorkflowPlanningPrefs `json:"planning" yaml:"planning"`
Review WorkflowReviewPrefs `json:"review" yaml:"review"`
Execution WorkflowExecutionPrefs `json:"execution" yaml:"execution"`
Commit WorkflowCommitPrefs `json:"commit" yaml:"commit"`
}
type WorkflowPreferencesFile ¶
type WorkflowPreferencesFile struct {
SchemaVersion int `json:"schema_version" yaml:"schema_version"`
WorkflowPreferences `yaml:",inline" json:",inline"`
}
type WorkflowReviewPrefs ¶
type WorkflowVerificationPrefs ¶
type WorkflowVerificationPrefs struct {
TestCommand *string `json:"test_command,omitempty" yaml:"test_command,omitempty"`
LintCommand *string `json:"lint_command,omitempty" yaml:"lint_command,omitempty"`
RequireRegressionBeforeHandoff *bool `json:"require_regression_before_handoff,omitempty" yaml:"require_regression_before_handoff,omitempty"`
}
Source Files
¶
- app_types.go
- archive_orphans.go
- base_resolution.go
- base_resolver.go
- blocked_on.go
- bundle.go
- close_task.go
- cmd.go
- commit_cmd.go
- commit_pathset.go
- contract.go
- contract_core.go
- delegation.go
- deps.go
- drift.go
- eligible_accounting.go
- fs.go
- graph.go
- health.go
- hook_outcome.go
- hook_sentinel.go
- iter_log.go
- iter_log_autoderive.go
- iter_log_schema.go
- plan_task.go
- preconditions.go
- prefs.go
- profile_prompt.go
- review_decision_schema.go
- review_gate.go
- seams.go
- start_task.go
- state.go
- sweep.go
- task_status.go
- transitions.go
- types.go
- verification.go
- verification_result_schema.go
- workflow_hook_outcome_schema.go