Documentation
¶
Overview ¶
Package adh is the foundational domain package for the agentic-dev-harness CLI: the shared language every other package speaks. It holds the core domain types, the effectful interfaces, and the Error type with its code vocabulary. It imports no sibling application package and no third-party library; every other package imports it.
Index ¶
- Constants
- func CanClose(arc *Arc, hasProof bool) error
- func ErrorCode(err error) string
- func ErrorMessage(err error) string
- type Arc
- type CriticInput
- type Direction
- type Error
- type Finding
- type FindingClass
- type FindingKind
- type KPI
- type Pending
- type Resolution
- type Stage
- type Status
- type Unrunnable
Constants ¶
const ( ECONFLICT = "conflict" // action cannot be performed in the current state EINTERNAL = "internal" // an unexpected internal error EINVALID = "invalid" // input or state failed validation ENOTFOUND = "not_found" // requested entity does not exist EUNAUTHORIZED = "unauthorized" // caller lacks the required authority )
Error codes are machine-readable classifications set on leaf errors. They are the vocabulary the CLI's `reason` token is drawn from (SPEC §8), so a caller branches on these rather than on message text.
Variables ¶
This section is empty.
Functions ¶
func CanClose ¶
CanClose reports whether an arc may close under NO-PROOF-NO-CLOSE (SPEC §5.4): an arc closes only with resolution-matched proof present. It returns EINVALID when the resolution is unset or unknown and ECONFLICT when proof is missing.
func ErrorCode ¶
ErrorCode returns the machine-readable code of the first *Error in the chain that carries one, EINTERNAL for any other non-nil error, and "" for nil. Call this instead of type-asserting *Error at a call site.
**It classifies adh's own errors and nothing else, which is narrower than it was.** The predecessor also understood errors coded by the toerr `errcode` package, because it lived in the shared library and had to read both representations. Keeping that here would put a third-party import in the domain package, which is the one thing this package does not do — so a library error classifies as EINTERNAL, and the translation happens where such errors enter adh. Today that is cmd/root, which owns the `reason` vocabulary; see reasonForCodedError there.
func ErrorMessage ¶
ErrorMessage returns the human-readable message of the first *Error in the chain that carries one, a generic message for any other non-nil error, and "" for nil. It has the same narrowed scope as ErrorCode.
Types ¶
type Arc ¶
type Arc struct {
ID string `json:"id"`
Title string `json:"title"`
Stage Stage `json:"stage"`
Status Status `json:"status"`
Resolution Resolution `json:"resolution,omitempty"`
History []string `json:"history,omitempty"`
Pending *Pending `json:"pending,omitempty"`
// Labels and Paths are the arc's routing footprint (SPEC-ADDITIONS §10, §19.1):
// its labels and the repository paths it touches. They ground the cold critic
// by selecting the context units routed to the review; an arc that declares
// them but routes nothing records a routing gap (§19.1).
Labels []string `json:"labels,omitempty"`
Paths []string `json:"paths,omitempty"`
// Context is the IDs of the context units the last stage loaded as its working
// set (SPEC-ADDITIONS §10.3), recorded so a self-eval can tell a missed
// requirement that was never routed (a context gap) from one routed and ignored.
Context []string `json:"context,omitempty"`
// Proof is the repository-relative path to the proof packet manifest the
// builder left (SPEC §5.4). Empty until Execution records one; the critic
// reviews against it when present (§19.1).
Proof string `json:"proof,omitempty"`
// Findings are the cold critic's hypotheses awaiting adjudication by the
// Evaluation stage (§19.2). Set when the critic turn resumes; cleared once
// Evaluation has disposed of them.
Findings []Finding `json:"findings,omitempty"`
// Unexamined is what the critic declared it did not look at (§19.2). It is the
// critic's own testimony, never a derived fact — a mechanically-known gap, such
// as a review that ran with no routed context, is reported by the harness and
// deliberately not written here.
//
// Advisory always: nothing may block because an entry is present, or a critic
// learns to declare none and the corpus loses both the gap and the finding.
// Cleared wherever Findings is cleared; a stale gap would be declared against a
// review that never made it.
Unexamined []finding.Unexamined `json:"unexamined,omitempty"`
// Bar is identity.Hash of the acceptance bar the arc was planned against,
// recorded when Strategy completes (§19.2).
//
// **It is a pre-registration, not a copy.** The bar itself is derived from config
// by resolution and is recoverable at any time; what is not recoverable is what it
// said when the plan was made. Two things can move it between Strategy and
// Evaluation — an edit to the config, and a change to the arc's Resolution, which
// selects the contract — and neither leaves a trace today.
//
// The discipline it buys is `ruflo`'s: it rejected changes carrying large
// favourable metrics because a *named* guard moved, under a hypothesis marked
// "frozen before evaluation began; not modified after seeing results." A bar that
// can move after the numbers arrive is a note, not a pre-registration.
//
// Empty means an arc planned before this shipped, or one that never reached
// Strategy. It must read as **unknown**, never as changed — reporting drift on
// every pre-existing arc would teach a reader to ignore the report.
Bar string `json:"bar,omitempty"`
// Reworks counts the times Evaluation confirmed a finding and returned this arc
// to Execution (SPEC §4.1). It bounds the rework loop: once it reaches the
// evaluation budget the arc fails terminally (StatusFailed) rather than looping.
Reworks int `json:"reworks,omitempty"`
}
Arc is a unit of work driven through the loop.
type CriticInput ¶
type CriticInput string
CriticInput names one input a critic's view can carry.
const ( InputUnset CriticInput = "" // InputTranscript is the builder's turn history. It is the one input cold review // withholds (§19.1), and the only one the renderer can currently enforce. InputTranscript CriticInput = "transcript" // The grounding a critic reviews, as critic.Grounding assembles it. InputDiff CriticInput = "diff" InputProof CriticInput = "proof" InputAcceptanceBar CriticInput = "acceptance_bar" InputContext CriticInput = "context" InputPaths CriticInput = "paths" InputTools CriticInput = "tools" InputCoverage CriticInput = "coverage" InputNoisy CriticInput = "noisy" )
The inputs a critic's view can name (SPEC-ADDITIONS §19.4).
They exist so `[critic] ground_from` and `deny` are checked against a closed set rather than being free-form strings nobody validates. A mistyped input name in either list used to be a line that silently did nothing — which is the whole defect this vocabulary was added to end, and it is worse in a field a reader believes hardens the critic.
InputUnset is the zero value and names no input, so a value nobody populated cannot be mistaken for a real one.
func CriticInputs ¶
func CriticInputs() []CriticInput
CriticInputs is every input a critic's view can name, sorted.
Requires: nothing. Ensures: sorted, so a diagnostic listing them is reproducible. Pure.
func (CriticInput) Deniable ¶
func (c CriticInput) Deniable() bool
Deniable reports whether the renderer can enforce a denial of this input.
Requires: nothing. Ensures: true only for InputTranscript today.
**adh does not filter a critic's grounding**, and this method is where that fact is enforced rather than assumed. The critic's view omits the transcript structurally — the renderer never populates it — so a denial of it is an assertion the renderer can check. Every other input is assembled by `critic.Ground` and handed over whole; denying one would be a request to filter, which is a capability nobody has built.
Accepting such a name silently is what the config used to do. Refusing it names the gap, and the day filtering exists this method is the one place that changes.
func (CriticInput) Known ¶
func (c CriticInput) Known() bool
Known reports whether c names an input this build understands.
Requires: nothing. Ensures: false for InputUnset, so an unpopulated value never validates.
type Direction ¶
type Direction string
Direction names which side of a KPI threshold is degradation (§16/§18).
const ( WorseWhenAbove Direction = "above" // higher is worse (error rate, duration) WorseWhenBelow Direction = "below" // lower is worse (acceptance rate) )
Direction values name which side of a KPI's threshold is degradation (SPEC-ADDITIONS §16/§18): a higher value is worse for an error/duration metric, a lower value for an acceptance metric.
type Error ¶
type Error struct {
Code string // machine-readable; set only on leaf errors
Message string // human-readable; set only on leaf errors
Op string // "package.Type.Method"; set only on wrapping errors
Err error // nested cause; set only on wrapping errors
}
Error is adh's one error type. A leaf error carries Code and Message; a wrapping error carries Op and Err. The two forms are never mixed on one value: leaves classify, wrappers build a single-line logical stack trace.
**It is defined here rather than borrowed.** It used to be `= skillet/errs.Error`, an alias kept in the shared library for adh's benefit alone — no other consumer of that library ever imported the package. A type with one consumer belongs to that consumer, and the layout this repository follows puts the Error type in the root domain package beside the types it classifies failures for.
A plain struct, deliberately: 203 sites compose it as a literal, and the typed CLI refusals in cmd/root reach it through Unwrap, which needs a concrete type for errors.As to find.
type Finding ¶
type Finding struct {
Summary string `json:"summary"`
Kind FindingKind `json:"kind"`
// Ref names the artifact that would confirm the finding, and for a confirmed one it
// is also the next action: re-running it is what settles the finding, so a caller
// has the command without inferring it. That is why no remediation vocabulary
// exists here -- a third closed set beside Class and FindingKind would classify the
// same space twice, and "re-run the ref" covers the case anyone has named.
Ref string `json:"ref,omitempty"`
Class FindingClass `json:"class,omitempty"`
}
Finding is a critic's hypothesis about the change under review (§19.2): a summary and the repository artifact (Kind + Ref) whose run would confirm it. The Evaluation stage adjudicates it; the harness never blocks on its text.
func (*Finding) IsStructural ¶
IsStructural reports whether the finding needs a design change rather than a bounded edit (§19.2), so a confirmed one escalates instead of reworking.
type FindingClass ¶
type FindingClass string
FindingClass triages how a confirmed finding is resolved (§19.2): fixable by a bounded edit or structural (a design change that escalates).
const ( FixableFinding FindingClass = "fixable" // a bounded edit resolves it (rework) StructuralFinding FindingClass = "structural" // needs a design change (escalate) )
FindingClass values triage a confirmed finding by how it is resolved (SPEC-ADDITIONS §19.2): a fixable finding is a bounded edit the rework loop can close; a structural finding needs a design change, so it escalates to a human instead of burning rework cycles. An empty class defaults to fixable — the common case.
func (FindingClass) Valid ¶
func (c FindingClass) Valid() bool
Valid reports whether c is a known finding class (§19.2). An empty class is valid: it defaults to fixable, the common case, so a critic need not set it.
type FindingKind ¶
type FindingKind string
FindingKind is the kind of repository artifact a critic finding names (§19.2).
const ( FindingOracle FindingKind = "oracle" // a differential-oracle divergence FindingInvariant FindingKind = "invariant" // a property/invariant check FindingDevice FindingKind = "device" // an on-device (adb) check (§2.4) FindingNFR FindingKind = "nfr" // a nonfunctional-requirement check (§10) FindingContract FindingKind = "contract" // a named local contract (e.g. a proof packet) )
FindingKind values name the repository artifact whose run would confirm a critic finding (SPEC-ADDITIONS §19.2). The Evaluation stage runs that artifact; a finding is never trusted on the critic's text alone.
func FindingKinds ¶
func FindingKinds() []FindingKind
FindingKinds returns every known finding kind (§19.2), the single owner of the list — so callers (e.g. the critic coverage check) iterate the full set without re-declaring it.
func (FindingKind) Valid ¶
func (k FindingKind) Valid() bool
Valid reports whether k is a known finding kind (§19.2). A validated kind lets callers switch on it without a default-panic path.
type KPI ¶
type KPI struct {
Metric string `json:"metric"`
Threshold float64 `json:"threshold"`
Direction Direction `json:"direction"`
}
KPI is a declared performance indicator on a tool or context unit (§16/§18): a Metric, the Threshold that bounds acceptable performance, and the Direction of degradation. A crossed threshold proposes a config change — never auto-adopted, and only after the breach replicates (§18.2). It is declared data; the kpi package evaluates observed values against it.
type Pending ¶
Pending is an outstanding model turn: a stage's prompt emitted to an operator whose reply is supplied out-of-band (the relay, SPEC §1-2), awaiting a resume. It is nil unless the arc is parked mid-turn between an emit and its response.
type Resolution ¶
type Resolution string
Resolution is how an arc closes; a non-change arc need not run the build stages.
const ( ResolutionChange Resolution = "change" // a merged/deployed code change ResolutionInvestigation Resolution = "investigation" // an analysis or answer, no code ResolutionExperiment Resolution = "experiment" // an instrumented painted-door surface ResolutionDecision Resolution = "decision" // a recorded decision, often "do not build" )
Resolution values (SPEC-ADDITIONS §12); each carries its own proof contract.
func ParseResolution ¶
func ParseResolution(s string) (Resolution, error)
ParseResolution validates a resolution string, returning the typed value or EINVALID for an unknown one.
func (Resolution) ProofKind ¶
func (r Resolution) ProofKind() string
ProofKind is the built-in default acceptance-bar text a resolution's proof must satisfy to close (SPEC-ADDITIONS §12). It is generic — the `change` bar is code-level, not domain-specific — and a deployment overrides it per resolution via config `[proof.contract]` (§SPEC 3.1). An unknown resolution has no text.
func (Resolution) Valid ¶
func (r Resolution) Valid() bool
Valid reports whether r is a known resolution (SPEC-ADDITIONS §12). Validity is a domain fact; the *acceptance-bar text* a resolution requires is deployment policy (config `[proof.contract]`, overriding the ProofKind default), not the domain's concern.
type Stage ¶
type Stage string
Stage is one station of the five-stage arc loop.
type Unrunnable ¶
type Unrunnable string
Unrunnable is why an artifact named by a finding did not run.
const ( UnrunnableUnset Unrunnable = "" // UnrunnableNoRef: the finding named no artifact at all. The critic asserted // something and pointed at nothing, so there was never anything to run. Noise // rather than a refusal. UnrunnableNoRef Unrunnable = "no-ref" // UnrunnableUnknownRef: the finding named an artifact the repository does not // declare. Also noise — and distinct from NoRef, because it is a critic naming a // tool that never existed rather than one omitting the field. UnrunnableUnknownRef Unrunnable = "unknown-ref" // UnrunnableToolFailed: the finding named a **registered** tool and that tool // could not start — missing binary, unbuilt, wrong commit. // // This is the honest refusal, and the only one of the three that is evidence // about the repository rather than about the critic. §19.2's blocking decision // was deferred because the three were indistinguishable; they are not. UnrunnableToolFailed Unrunnable = "tool-failed" )
Why a named artifact did not run (§19.2).
UnrunnableUnset is the zero value and names no reason, so an Adjudicated nobody populated does not claim one. It is also what a finding that *did* run carries, which is correct: there is no reason, because there was no failure to explain.
func (Unrunnable) Trustworthy ¶
func (u Unrunnable) Trustworthy() bool
Trustworthy reports whether this reason is a refusal by the repository rather than a defect in the finding that named it.
Requires: nothing. Ensures: true only for UnrunnableToolFailed. The zero value is false, so a reason nobody set never reads as a trustworthy refusal.
It exists as a method rather than a comparison at each call site because it is the predicate §19.2's blocking decision would turn on if it is ever revisited, and one place should own what "trustworthy" means when that happens.