conclusion

package
v0.629.4 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package conclusion implements the delegated-task conclusion protocol: parsing the sentinel <pando:conclusion> block emitted by a subagent and enriching it with software-owned launch metadata.

The package intentionally depends only on the domain models (plus stdlib and a YAML parser) so it can be reused by the orchestrator and app wiring without creating import cycles with internal/config or internal/project. Config and project resolution are threaded in via plain function/struct values.

Index

Constants

View Source
const (
	StatusSuccess = "success"
	StatusPartial = "partial"
)

StatusSuccess and StatusPartial are the two conclusion statuses the gate moves between. They are plain strings on the wire (Conclusion.Status).

Variables

This section is empty.

Functions

func BriefInstruction

func BriefInstruction() string

BriefInstruction returns the instruction appended to a delegated subagent's prompt when delegation is enabled. It tells the subagent to close its run with a single <pando:conclusion> sentinel block listing ONLY the model-known fields. The software fills in all launch metadata (task id, engine, model, project, parent session, timestamps) from the task record it owns, so the model must NOT restate those.

The text is centralized here so it is reusable and testable, and so the orchestrator can append it as the trailing instruction after persona is applied.

func Enrich

func Enrich(task *models.Task, cfg DelegationOptions, resolver ProjectResolver) *models.Conclusion

Enrich builds the durable Conclusion for a terminal task. It parses the task's output for the sentinel block, synthesizes a fallback when configured, and always fills software-owned metadata (CapturedAt, project id/name). It returns nil when no conclusion can or should be captured.

The function is pure with respect to globals: everything it needs is passed in. It mutates task.ProjectID / task.ProjectName as a convenience for the caller (the resolved project is software-owned launch metadata) but never panics on nil inputs.

func FormatForParent

func FormatForParent(task *models.Task, res *ResolveOptions) string

FormatForParent renders a compact, pointers-not-dumps message describing a delegated task's result, suitable for injection into the parent agent loop. The header line carries only software-owned launch metadata (task id, engine, project, status, confidence) — never values the model could have hallucinated. The body carries the model-provided summary plus optional follow-up, artifacts and memory refs (each omitted when empty) so the parent can lazily fetch detail.

res controls optional enrichment of artifact paths and memory refs. When res is nil (or the individual resolver is nil), the corresponding field is rendered as a plain comma-joined list — byte-for-byte identical to the pre-resolver output. When a resolver is provided, each entry is rendered on its own line under the field header, resolved via the supplied function.

It is nil-safe: a task without a Conclusion yields a minimal single line so the parent still learns the task finished.

func Parse

func Parse(raw string) (*models.Conclusion, bool)

Parse scans raw for the sentinel block delimited by <pando:conclusion> ... </pando:conclusion>. When multiple blocks are present the LAST one is used (it is the final summary). The inner body is parsed as YAML; parsing is tolerant: missing fields default to their zero value, and an unparseable body with a present sentinel still returns a Conclusion whose Summary is the salvaged raw inner text.

Soft-schema validation accumulates human-readable warnings in Conclusion.Warnings describing what was malformed/missing/out-of-range. Data is never discarded due to warnings — the principle is warn, don't discard.

It returns (conclusion, true) when a block was found, (nil, false) otherwise.

Types

type ArtifactResolver added in v0.603.0

type ArtifactResolver func(ref string) string

ArtifactResolver enriches an artifact reference string for display. It receives the raw ref (a file path, URL, or any opaque token) and returns a richer display string. It must return the input unchanged when enrichment is not possible or the ref is unrecognized.

func NewFilesystemArtifactResolver added in v0.603.0

func NewFilesystemArtifactResolver(baseDir string) ArtifactResolver

NewFilesystemArtifactResolver returns an ArtifactResolver that stats each artifact path on the local filesystem and appends a human-readable size or "(missing)" suffix. If the ref is a relative path, it is resolved against baseDir. A blank baseDir or any stat error returns the bare ref unchanged.

type DelegationOptions

type DelegationOptions struct {
	// SynthesizeFallback enables deriving a conclusion from output/error when the
	// subagent did not emit a sentinel block. When false, a missing block means no
	// conclusion is captured.
	SynthesizeFallback bool
}

DelegationOptions carries the conclusion-relevant knobs the enricher needs. It is defined here (rather than importing internal/config) so the conclusion package stays free of import cycles; the app/orchestrator translate config into this value.

type MemoryRefResolver added in v0.603.0

type MemoryRefResolver func(ref string) string

MemoryRefResolver enriches a memory-ref identifier for display. It receives the raw ref (a KB path, memory key, or any opaque token) and returns a richer display string. It must return the input unchanged when enrichment is not possible.

type MemoryRefValidator added in v0.629.4

type MemoryRefValidator func(ref string) bool

MemoryRefValidator reports whether a memory reference (a KB path or memory key) actually resolves. A nil validator means memory refs are not checked — the gate then only verifies filesystem artifacts.

type ProjectResolver

type ProjectResolver func(canonicalPath string) (id string, name string)

ProjectResolver maps a canonical project path to its registry id and display name. It returns empty strings when the path is not a registered project.

type ResolveOptions added in v0.603.0

type ResolveOptions struct {
	// Artifacts, when non-nil, is called for each artifact entry. When nil,
	// artifacts are rendered as a plain comma-joined list (legacy behavior).
	Artifacts ArtifactResolver

	// Memory, when non-nil, is called for each memory_ref entry. When nil,
	// memory_refs are rendered as a plain comma-joined list (legacy behavior).
	Memory MemoryRefResolver
}

ResolveOptions carries optional resolvers that FormatForParent uses to enrich artifact and memory-ref entries. A nil *ResolveOptions or a nil resolver field means no enrichment is applied for that category — the output is byte-for-byte identical to the pre-resolver behavior.

type VerifyOptions added in v0.629.4

type VerifyOptions struct {
	// Disabled turns the gate off entirely: Verify becomes a no-op. Mirrors the
	// config opt-out so the gate can be switched off without unwiring it.
	Disabled bool
	// BaseDir resolves relative artifact paths (normally the task's work dir).
	// When empty, relative artifacts are considered unverifiable and ignored.
	BaseDir string
	// Memory validates memory_refs. When nil, memory refs are not checked.
	Memory MemoryRefValidator
}

VerifyOptions configures the anti-hallucination conclusion gate.

type VerifyResult added in v0.629.4

type VerifyResult struct {
	// Downgraded is true when the conclusion's status was changed.
	Downgraded bool
	// MissingArtifacts are artifact refs that were checkable and absent.
	MissingArtifacts []string
	// MissingMemoryRefs are memory refs that were checkable and unresolvable.
	MissingMemoryRefs []string
}

VerifyResult reports what the gate found.

func Verify added in v0.629.4

Verify is the anti-hallucination completion gate: it refuses to let a delegated task claim full success while citing evidence that does not exist.

Only a conclusion with status "success" is inspected. Every artifact that can be checked (a local filesystem path) is stat'ed, and every memory ref is resolved through the validator when one is wired. If any checkable reference is missing, the status is downgraded to "partial" and a warning naming the missing refs is appended. Nothing is ever discarded — the conclusion keeps its summary, artifacts and refs, exactly as the "warn, don't discard" principle of the conclusion parser requires.

Unverifiable references (URLs, git refs, glob patterns, opaque tokens, or any relative path when BaseDir is empty) are ignored rather than treated as missing: the gate is fail-open on what it cannot check and fail-closed only on what it positively disproves.

Verify is nil-safe and returns a zero VerifyResult when it does nothing.

Jump to

Keyboard shortcuts

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