Documentation
¶
Overview ¶
Package intent reads the Git-tracked intent store of SPEC §3.1 (`.taskman/`), resolves the primary worktree (§3.1, §3.4) and the intent worktree that holds the projection (CTW-V0), and computes the intent tree digest and publication facts. Everything here is read-only: no file is opened for writing, no directory is created, no lock is taken and no subprocess (including git) is run.
Index ¶
- Constants
- Variables
- func BoundFor(path string) (int, bool)
- func CheckNoSymlink(path string) error
- func ConfigRefValue(c *ConfigRef) wire.Value
- func DigestOfFiles(files []File) wire.Digest
- func Divergence(path string, file wire.Digest, latestPost wire.Digest, pendingPre *wire.Digest) error
- func HandoffPolicyCompatible(original, current []byte, pool, member string) (bool, error)
- func PolicyGrantable(role string) []string
- func Publication(file, headBlob, journalPost wire.Digest) string
- func ReadDirNames(d *os.File, full, label string, max int) ([]string, error)
- func ReadFile(path string, max int) ([]byte, error)
- func ReadFileFromRoot(root *os.Root, label, name string, max int) ([]byte, error)
- func ShellQuote(s string) string
- func ValidRepositoryName(name string) bool
- type CapacityClass
- type ConfigRef
- type ExecutionCutover
- type ExternalReviewDefinition
- type File
- type GateDefinition
- type ImportEntry
- type ImportMap
- type LaneBudget
- type LoopDetection
- type MemberConfig
- type Policy
- func (p *Policy) ExternalReview(gateID string) *ExternalReviewDefinition
- func (p *Policy) Gate(gateID string) *GateDefinition
- func (p *Policy) GateDefinitionSha256(gateID string) wire.Digest
- func (p *Policy) GateIDs() map[string]bool
- func (p *Policy) MemberDefinition(id, member string) wire.Digest
- func (p *Policy) PolicySha256() wire.Digest
- func (p *Policy) Pool(id string) *Pool
- type Pool
- type PoolCommand
- type Queue
- type Repository
- type RuntimeEntry
- type SafeReuse
- type Store
- type SupervisionPolicy
- type Tree
- type WriteBarrier
Constants ¶
const ( Published = "PUBLISHED" Unpublished = "UNPUBLISHED" Diverged = "DIVERGED" )
Publication values (TM-V0-007).
const ( Dir = ".taskman" QueueFile = "queue.json" PolicyFile = "policy.json" ImportMapFile = "import-map.json" TicketsDir = "tickets" ReleasesDir = "releases" )
Layout of the intent store (§3.1).
const ( // DirChunk is the number of names materialized per Readdirnames call // while a store directory is enumerated: a flooded directory never // allocates more than the bound plus one chunk of names before the // count bound fires. DirChunk = 256 // MaxIntentRootEntries is the number of entries the flat, closed // intent store root can hold: queue.json, policy.json, // import-map.json and tickets/. A fifth entry, whatever its name, // exceeds the bound. MaxIntentRootEntries = 5 )
Directory enumeration bounds (§3.1 "Digest preimages", §3.5).
const ( SupervisedHostClaudeCode = "claude-code" SupervisedHostOpenCode = "opencode" )
SupervisedHostClaudeCode and SupervisedHostOpenCode are the non-default supervised hosts a policy may select (CAL-V0-074, CAL-V0-076); an absent host is Codex.
const DefaultStageWallMinutes = 60
DefaultStageWallMinutes is the per-stage wall bound when the policy does not declare stageWallMinutes; it preserves the original one-hour cap.
const MaxExternalReviewDefinitions = 16
MaxExternalReviewDefinitions bounds policy externalReviews (ERG-V0-009).
const MaxLoopDetectionBound = 256
MaxLoopDetectionBound caps both loopDetection bounds.
const MaxPoolMembers = 256
const MaxStageContinuations = 16
MaxStageContinuations bounds the optional checkpointed continuations of one supervised stage run (CAL-V0-089). Each continuation is another dispatched turn, so the lane turn cap and the program turn and wall caps still bound the total.
const MaxStageWallMinutes = wire.MaxLaneWallMinutes
MaxStageWallMinutes bounds the optional per-stage wall allowance. It equals the lane wallClockMinutes ceiling, because the active stage deadline is never longer than the lane cap (CAL-V0-063); a larger value would have no effect.
const MaxSupervisedRepositories = 8
MaxSupervisedRepositories bounds the extra repositories one policy may declare for supervised multi-repository programs (CAL-V0-071).
const ProfileImportMap = "taskman-import-map/0"
ProfileImportMap is the import identity map profile (§3.1).
const ProfilePolicy = "taskman-policy/0"
ProfilePolicy is the policy profile (§3.1).
const ProfileQueue = "taskman-queue/0"
ProfileQueue is the queue manifest profile (§3.1).
Variables ¶
var DefaultRoleMatrix = map[string][]string{ "OWNER": Operations, "OPERATOR": {"CREATE", "REFINE", "PRIORITIZE", "SET_DEPENDENCIES", "SET_GATES", "SET_EFFECTS", "HOLD", "RELEASE_HOLD", "REOPEN", "ARCHIVE", "RESTORE", "COMPLETE_MANUAL", "GRANT_APPROVAL", "REVOKE_APPROVAL", "RELEASE_CREATE", "RELEASE_UPDATE", "RELEASE_CANDIDATE", "RELEASE_EXTERNAL_ATTEST"}, "IMPORTER": {"CREATE", "REFINE"}, "WORKER": {"REFINE"}, "SYSTEM": {"HOLD"}, "REVIEWER": {}, }
DefaultRoleMatrix is the §3.2 role matrix; policy may remove rows, never add them.
var ExplicitGrantOperations = map[string][]string{"OPERATOR": {"NOTE_SET", "NOTE_CLEAR", "ESCALATE", "ANSWER", "ATTACH_EVIDENCE"}}
ExplicitGrantOperations are operations a policy row may name for a role although that role's default row omits them: an OPERATOR gets a note verb (ON-V0-004) or an escalation verb (ESC-V0-001, ESC-V0-004) only through an explicit policy.roles.OPERATOR row, never by default; the same holds for ATTACH_EVIDENCE (TEA-V0-001). No other role may be granted them.
var ExternalReviewRecorderRoles = []string{"OWNER", "OPERATOR", "REVIEWER"}
ExternalReviewRecorderRoles are the roles a definition may let record a verdict. WORKER is never a recorder (ERG-V0-001).
var LaneBudgetNames = []string{"cacheCreationTokens", "cacheReadTokens", "inputTokens", "outputTokens", "turns", "wallClockMinutes"}
LaneBudgetNames are the lane budget field names (§3.1), sorted.
var Operations = []string{
"CREATE", "REFINE", "PRIORITIZE", "SET_DEPENDENCIES", "SET_GATES", "SET_EFFECTS",
"HOLD", "RELEASE_HOLD", "REOPEN", "ARCHIVE", "RESTORE", "COMPLETE_MANUAL", "GRANT_APPROVAL", "REVOKE_APPROVAL",
"RELEASE_CREATE", "RELEASE_UPDATE", "RELEASE_CANDIDATE", "RELEASE_EXTERNAL_ATTEST", "RELEASE_MANUAL_ATTEST", "RELEASE_PROMOTE",
"ESCALATE", "ANSWER", "NOTE_SET", "NOTE_CLEAR", "REVIEW_RECORD", "REVIEW_RESUBMIT",
"ATTACH_EVIDENCE",
}
Operations is the mutation operation vocabulary (§3.3).
var Roles = []string{"OWNER", "OPERATOR", "WORKER", "REVIEWER", "IMPORTER", "SYSTEM"}
Roles is the actor role vocabulary (§3.3).
var RuntimeRoles = []string{"BUILDER", "REVIEWER", "VERIFIER", "REPAIR", "DOCS"}
RuntimeRoles is the runtime role vocabulary (§3.1).
var StageRoles = []string{"implement", "review", "integrate"}
var SupervisedEfforts = []string{"high", "low", "medium"}
SupervisedEfforts are the Codex reasoning efforts an owner may allow.
var SupervisedStages = []string{"implement", "integrate", "review"}
SupervisedStages are the native supervised stages a policy effort allowlist may name (CAL-V0-062).
var TicketKinds = []string{"FEATURE", "BUG", "CHORE", "SPIKE", "DOC", "MANUAL", "EXTERNAL"}
TicketKinds mirrors ticket.Kinds for policy kind lists.
Functions ¶
func BoundFor ¶
BoundFor returns the §1 byte bound of an admissible store-relative intent path and false for any path the flat, closed layout does not admit.
func CheckNoSymlink ¶
CheckNoSymlink refuses any symlink component in an absolute path (§3.4: symlinks in the resolved path fail UNSUPPORTED_FILESYSTEM). A not-yet-existing tail is not a symlink.
func ConfigRefValue ¶
func DigestOfFiles ¶
DigestOfFiles computes the intent tree digest frozen in SPEC §3.1 (R3): SHA-256 over `path || 0x00 || hex(sha256(bytes)) || 0x0A` for every file in byte-sorted path order. The input order does not matter.
func Divergence ¶
func Divergence(path string, file wire.Digest, latestPost wire.Digest, pendingPre *wire.Digest) error
Divergence applies the TM-V0-007 guard: the file's current digest must equal the journal's latest post digest for the path, or the pre digest of a receipt that is still redo-pending. pendingPre is nil when no receipt is pending. It returns nil or INTENT_DIVERGED.
func HandoffPolicyCompatible ¶
HandoffPolicyCompatible is the narrow release-only projection. DecodePolicy validates both profiles, but its sorted Pools are not the comparison input: independently parsed wire trees preserve every array and optional member.
func PolicyGrantable ¶
PolicyGrantable is the closed set a policy row for role may list: its default row plus its explicit-only grants.
func Publication ¶
Publication derives the TM-V0-007 publication status of one intent file from three digests: the working-tree file, the HEAD blob and the journal's latest post digest for that path. It is a pure function; the journal and HEAD readers that supply the inputs arrive with TCP-02.
PUBLISHED HEAD blob = file = journal post UNPUBLISHED file = journal, HEAD differs (or no HEAD blob) DIVERGED file ≠ journal
func ReadDirNames ¶
ReadDirNames enumerates an open directory in chunks of DirChunk names and fails LIMIT_EXCEEDED as soon as more than max entries have been seen: before the listing completes, before the names are sorted or validated, and before any entry is stat'ed or opened. Every entry counts, whatever its name, so skipped temp files and unexpected names are bounded too. Names are returned sorted. It reads nothing but the listing; the caller owns and closes d.
func ReadFile ¶
ReadFile is the exported bounded read-only file reader used by every read verb: it never creates, truncates or locks.
func ReadFileFromRoot ¶
ReadFileFromRoot reads one basename beneath an already pinned parent. The label is diagnostic only; validation, identity checks and byte bounds match ReadFile. The caller owns the parent lifetime and its named-path binding.
func ShellQuote ¶
ShellQuote quotes s as one POSIX shell word: it is wrapped in single quotes and each embedded single quote closes the word, is backslash-escaped and reopens it. Repair commands quote paths and branches this way so `$`, backticks and spaces are pasted literally.
func ValidRepositoryName ¶
ValidRepositoryName reports whether name is a supervised repository name: a lowercase ASCII letter followed by at most 31 lowercase letters, digits or hyphens. The name becomes a composite tree entry and a worktree suffix.
Types ¶
type CapacityClass ¶
CapacityClass is one capacity class.
type ExecutionCutover ¶
ExecutionCutover is the owner's cutover record.
type ExternalReviewDefinition ¶
type ExternalReviewDefinition struct {
GateID string
RecorderRoles []string
ReviewStages, AuthorStages []string
RequireReviewerLease bool
// Sha256 is the definitionSha256: the digest of the canonical bytes of
// this entry in the policy's externalReviews array.
Sha256 wire.Digest
}
ExternalReviewDefinition is one routing-only external review gate (ERG-V0-009). It grants nothing by default: a gate absent from policy refuses every record, and only the listed roles and stages are admitted.
type File ¶
type File struct {
Path string // e.g. "tickets/AT-07.json"
Sha256 wire.Digest
Bytes int
Raw []byte
}
File is one intent file: its store-relative path, digest, size and, when it was read from disk by TreeDigest, the exact bytes that were hashed. Raw is nil for a File rebuilt from an archive manifest.
type GateDefinition ¶
type GateDefinition struct {
GateID string
Kind string
Argv []string
Cwd string
Env []string
TimeoutSeconds wire.Count
ExpectedExit *wire.Count
Reducer *string
Evidence []string
Inputs []string
Reusable bool
Required bool
}
GateDefinition is one policy gate (§3.1).
type ImportEntry ¶
type ImportEntry struct {
SourceQueueID string
SourceItemID string
TicketID wire.TicketID
SourceRevisionSha256 *wire.Digest
AppliedSeq wire.Size
}
ImportEntry is one import-map entry.
type ImportMap ¶
type ImportMap struct {
QueueID wire.QueueID
Entries []ImportEntry
}
ImportMap is a validated taskman-import-map/0.
func DecodeImportMap ¶
DecodeImportMap parses and validates import-map.json (≤8 MiB, ≤10,000 entries, sorted, no duplicate (sourceQueueId, sourceItemId)).
type LaneBudget ¶
type LaneBudget struct {
InputTokens wire.Size
CacheCreationTokens wire.Size
CacheReadTokens wire.Size
OutputTokens wire.Size
Turns wire.Count
WallClockMinutes wire.Count
}
LaneBudget is the per-lane cap set: the four token fields are Size and turns and wallClockMinutes are Count (§2 and §3.1, aligned by the B1 resolution; witness TestTMV0002_AS10_LaneBudgetPrimitives).
type LoopDetection ¶
LoopDetection bounds the CAL-V0-102 no-progress loop signals: the consecutive no-progress clean hand-offs and the alternating implement/REVIEW_RETURNED pairs one acceptance revision may record before a derived LOOP_DETECTED hold. Each bound is 1..MaxLoopDetectionBound.
type MemberConfig ¶
type MemberConfig struct {
ConfigRef *ConfigRef
Health, Cleanup *PoolCommand
SafeReuse *SafeReuse
}
type Policy ¶
type Policy struct {
Supervision *SupervisionPolicy
Pools []Pool
PolicyVersion wire.Size
Roles map[string][]string
MaxActiveAttempts wire.Count
MaxWorkersTotal wire.Count
Classes []CapacityClass
Lane LaneBudget
TicketMultiplier wire.Count
RequireEnforcedFields []string
AdmissionsPerRevision wire.Count
RepairRounds wire.Count
MalformedReviewRetry wire.Count
GateRerunOnStale wire.Count
ReconcileAttempts wire.Count
EvidenceDays wire.Count
Gates []GateDefinition
SerialFallback string
IntegrationRequiredKinds []string
AllowEmptyObligationsKinds []string
ReviewLaneRequired bool
DocsLaneRequired bool
CemRequired bool
OcmRequired bool
Runtimes []RuntimeEntry
AllowedEnvKeys []string
// ExternalReviews are the optional routing-only review gate definitions
// (ERG-V0-009); absent means no external review gate exists.
ExternalReviews []ExternalReviewDefinition
// LoopDetection is the optional CAL-V0-102 no-progress loop policy;
// nil (the key absent) disables loop detection.
LoopDetection *LoopDetection
Raw []byte
}
Policy is a validated taskman-policy/0. Raw holds the exact file bytes; the policy identity is derived from them.
func DecodePolicy ¶
DecodePolicy parses and validates policy.json (≤256 KiB) including the §1 policy caps (max columns and min columns are rejected at load).
func (*Policy) ExternalReview ¶
func (p *Policy) ExternalReview(gateID string) *ExternalReviewDefinition
ExternalReview returns the definition of gateID, or nil.
func (*Policy) Gate ¶
func (p *Policy) Gate(gateID string) *GateDefinition
Gate returns the definition of gateId, or nil.
func (*Policy) GateDefinitionSha256 ¶
GateDefinitionSha256 is the SHA-256 of the canonical bytes of gateId's entry in the policy's gates array, the §7.1 definitionSha256. It is empty when the policy defines no such gate.
func (*Policy) PolicySha256 ¶
PolicySha256 is the policy identity `policy:sha256:*` digest: the WQO §4.3 content identity over the canonical body (file bytes minus LF).
type PoolCommand ¶
type Queue ¶
type Queue struct {
QueueID wire.QueueID
RepositoryAuthorityID string
Prefix string
NextSerial wire.Count
SchemaVersion string
CanonicalWriter string
ForeignAdapterID *string
IntentBranch string
Fixture bool
ExecutionCutover *ExecutionCutover
ImportMapSha256 *wire.Digest
WriteBarrier WriteBarrier
}
Queue is a validated taskman-queue/0.
func DecodeQueue ¶
DecodeQueue parses and validates queue.json (≤1 MiB).
type Repository ¶
type Repository struct {
// CommonDir is the Git common directory (`<primary>/.git`).
CommonDir string
// PrimaryWorktree is the worktree whose `.git` is the common directory
// itself (§3.1). Linked worktrees are never the primary.
PrimaryWorktree string
// StateDir is `<git-common-dir>/taskman` (§3.4); it may not exist.
StateDir string
// LockPath is `<git-common-dir>/taskman.lock`; reads never open it.
LockPath string
// FromLinkedWorktree is true when cwd was inside a linked worktree.
FromLinkedWorktree bool
// IntentWorktree is the worktree whose `.taskman/` is the intent
// projection (CTW-V0-001); read it through IntentRoot.
IntentWorktree string
// IntentGitDir is the Git directory holding the intent worktree's HEAD:
// CommonDir for the primary, `<common>/worktrees/<id>` for a linked one.
IntentGitDir string
// IntentFix is the repair text resolution recorded when the primary is not
// on the intent branch and no linked worktree was admitted (CTW-V0-005,
// CTW-V0-006); empty otherwise.
IntentFix string
}
Repository is the resolved repository authority of a working directory.
func Resolve ¶
func Resolve(cwd string) (*Repository, error)
Resolve walks up from cwd to the first `.git` and resolves the common directory exactly as §3.4 prescribes: a `.git` directory is the common dir; a `.git` file names a `gitdir:` whose `commondir` file, if present, names the common dir. Symlinks above the primary worktree are resolved; one at or below it is refused. Windows is unsupported; no environment variable or flag relocates the state dir.
func (*Repository) IntentHEAD ¶
func (r *Repository) IntentHEAD() string
IntentHEAD is the HEAD file of the intent root: `<common>/HEAD` for the primary and `<common>/worktrees/<id>/HEAD` for a linked intent worktree.
func (*Repository) IntentLinked ¶
func (r *Repository) IntentLinked() bool
IntentLinked reports whether the intent root is a linked worktree.
func (*Repository) IntentRepair ¶
func (r *Repository) IntentRepair(detailCode string) string
IntentRepair is the repair text a refusal with the given code carries under CTW-V0-007. It is empty unless resolution recorded a fix or selected a linked intent worktree, so the intent-branch primary keeps its exact refusals (CTW-V0-009).
func (*Repository) IntentRoot ¶
func (r *Repository) IntentRoot() string
IntentRoot is the worktree whose `.taskman/` is the intent projection (CTW-V0-001): the primary worktree unless the intent worktree rule selected a linked worktree. A Repository built without resolution uses the primary.
func (*Repository) PrimaryWorktreeSha256 ¶
func (r *Repository) PrimaryWorktreeSha256() wire.Digest
PrimaryWorktreeSha256 is the SHA-256 of the primary worktree's exact absolute path bytes (the WQO ExecutableIdentity.pathSha256 convention; SPEC §3.3 names the field but not the preimage, see docs/ROADMAP.md).
func (*Repository) WithIntentRepair ¶
func (r *Repository) WithIntentRepair(err error) error
WithIntentRepair returns err with IntentRepair appended to its message when err is an INTENT_BRANCH_MISMATCH or INTENT_DIVERGED wire error and a repair applies. The code and location are preserved; any other error is returned unchanged.
type RuntimeEntry ¶
type RuntimeEntry struct {
RuntimeID string
PathSha256 wire.Digest
FileSha256 wire.Digest
Mode string
ArgvPrefix []string
CapabilityProfileSha256 wire.Digest
ObservedBudgetFields []string
Roles []string
MaxWorkers wire.Count
Enabled bool
}
RuntimeEntry is one policy runtime (§3.1).
type SafeReuse ¶
type SafeReuse struct {
Reset, Verify PoolCommand
EnvFile string
TimeoutSeconds, MaxAttempts, ExpectExit wire.Count
ExpectStdout string
}
SafeReuse is an operator-declared local reset/verify procedure, not physical authority.
type Store ¶
type Store struct {
Root string // <primary>/.taskman
Queue *Queue
Policy *Policy
ImportMap *ImportMap // nil when absent
Tickets []*ticket.Record
Releases []*release.Record
Inventory *ticket.Inventory
Tree Tree
// Digests of the individual files, keyed by store-relative path.
Digests map[string]wire.Digest
}
Store is the loaded, validated intent store of the primary worktree.
func Load ¶
Load reads and validates the whole intent store of a primary worktree. It is a pure read: nothing is created, locked or modified. Every record is decoded from the same captured bytes that produced the tree digest.
func LoadExpecting ¶
LoadExpecting is Load pinned to a tree digest observed earlier under the TM-V0-008 protocol: when the captured tree's digest differs from want the load fails SNAPSHOT_MOVED before decoding, so a reader can never decode bytes from one snapshot under the digest of another. An empty want pins nothing.
type SupervisionPolicy ¶
type SupervisionPolicy struct {
MaxRepairCycles, Turns, WallClockMinutes wire.Count
InputTokens, OutputTokens wire.Size
// Efforts is the owner's per-stage effort allowlist (CAL-V0-062). A
// stage without an entry allows only "low".
Efforts map[string][]string
// StageWallMinutes bounds one supervised stage's configured wall time
// (CAL-V0-063); empty means DefaultStageWallMinutes.
StageWallMinutes wire.Count
// Repositories are the owner-declared extra repositories a supervised
// program may span (CAL-V0-071): name -> sha256 of the absolute
// checkout path. Empty means single-repository programs only.
Repositories map[string]wire.Digest
// Host is the owner-selected supervised host the pinned runtime speaks
// (CAL-V0-074, CAL-V0-076): "claude-code", "opencode", or empty for Codex.
Host string
// Continuations is how many times one stage run that reaches its stage
// wall may continue its preserved session and worktree (CAL-V0-089);
// empty means none, so a wall interruption waits for an operator.
Continuations wire.Count
}
func (*SupervisionPolicy) AllowsEffort ¶
func (p *SupervisionPolicy) AllowsEffort(stage, effort string) bool
AllowsEffort reports whether the policy admits effort for stage. A nil policy, or a stage without an allowlist, admits only "low".
func (*SupervisionPolicy) StageContinuations ¶
func (p *SupervisionPolicy) StageContinuations() int
StageContinuations is the policy's checkpointed continuation bound for one stage run; a nil policy or an absent key allows none.
func (*SupervisionPolicy) StageWallSeconds ¶
func (p *SupervisionPolicy) StageWallSeconds() int
StageWallSeconds is the largest configured wall time one stage may use.
func (*SupervisionPolicy) SupervisedHost ¶
func (p *SupervisionPolicy) SupervisedHost() string
SupervisedHost is the policy's supervised host; a nil policy or an absent host is Codex ("").
type Tree ¶
Tree is the inventory of intent files with the intent tree digest.
func TreeDigest ¶
TreeDigest reads the intent store of a primary worktree through a root-confined descriptor (os.Root) and returns every file's bytes with the SPEC §3.1 tree digest. The flat, closed layout, the per-file §1 bounds, the ticket count bound and the 256 MiB tree bound are all enforced from directory listings and Lstat results before any byte is read or buffered; symlinks, nested directories, non-regular entries, empty files and unknown names fail closed. Records are not validated here; Load does that from the same captured bytes.
type WriteBarrier ¶
WriteBarrier is the queue's write barrier on the old source.