Documentation
¶
Overview ¶
Package wfhook parses a workflow's LIFECYCLE HOOK declarations — the operations that fire OUTSIDE the status graph (story creation today) and so cannot be expressed as a DOT node or edge (sty_ede16f51).
Before this package, create review resolved a skill from `create_review:` frontmatter and then ran it against an EMPTY agent selector, which the engine silently resolved to `[reviewer]`. Nothing in the substrate could inspect or change that allocation and nothing validated it. A hook now declares BOTH the skill and the logical agent, so the choice is readable in the workflow file and checkable before it runs.
The grammar is ONE generic declaration, not a per-operation shape:
hooks:
- operation: create_review
skill: satelle-story-create-review
agent: strict-reviewer # optional; defaults to reviewer
The pre-existing scalar shorthand stays a first-class, documented form:
create_review: satelle-story-create-review
Go's ONLY per-operation knowledge is the operations table below — which operations exist and which yield a verdict. No provider, model, effort, command, or tool grant is named here or anywhere on the hook path: execution configuration comes from the agents.toml section the hook names, resolved by the existing binding path. Adding a future lifecycle operation is a name in that table plus its call site — not a new parser, resolver, or validator.
Near-leaf so agentstep, agentvalidate, structure and cli can all import it without a cycle. Its ONE dependency is docindex, itself a leaf, for reading frontmatter — and that is deliberate, not a slip. A workflow's frontmatter is now either a markdown `---` block or a TOML `[meta]` table (sty_81bb0dde), and a private scan here that only understood `---` would find no `create_review` in a TOML route source: the story-CREATE gate would stop firing, silently, on the engine path. One reader for one question, or the two drift apart.
Index ¶
Constants ¶
const ( // SourceHooks is an explicit entry in the `hooks:` block. SourceHooks = "hooks" // SourceShorthand is the scalar `<operation>: <skill>` form. SourceShorthand = "shorthand" )
Hook sources — how the declaration was written, so a display surface can say where an allocation came from rather than presenting a default as a choice.
const DefaultAgent = "reviewer"
DefaultAgent is the logical agent a hook resolves to when it declares none: the repo's `[reviewer]` binding. It is a DOCUMENTED default with provenance, not the invisible empty-selector fallback it replaces.
const OpCreateReview = "create_review"
OpCreateReview is the content/alignment review that runs when a work item is CREATED — the one lifecycle hook that exists today.
Variables ¶
This section is empty.
Functions ¶
func IsVerdict ¶
IsVerdict reports whether op yields an accept/reject verdict. False for an unknown operation — an unrecognised declaration never silently acquires gate authority.
func Operations ¶
func Operations() []string
Operations returns every known lifecycle operation, sorted.
Types ¶
type Hook ¶
type Hook struct {
// Operation is the lifecycle operation (OpCreateReview, …). An unrecognised
// value is CARRIED, not dropped, so validation can report it by name.
Operation string
// Skill is the rubric the operation runs. Resolution against the substrate
// is the caller's job — this package does no doc lookup.
Skill string
// Agent is the agents.toml section that runs the skill. Never empty after
// Parse: an omitted agent is filled with DefaultAgent, with Source recording
// that it was defaulted rather than chosen.
Agent string
// AgentDeclared reports whether the workflow named the agent explicitly.
// False means Agent is DefaultAgent by default, which a display surface
// should say out loud.
AgentDeclared bool
// Verdict reports whether this operation yields an accept/reject verdict.
Verdict bool
// Source is SourceHooks or SourceShorthand.
Source string
}
Hook is one declared lifecycle-adjacent operation: which operation, which skill judges it, and which logical agent runs that skill.
func Parse ¶
Parse returns every lifecycle hook a workflow body declares, in operation order, along with any declaration problems. Problems are reported rather than returned as an error: a malformed hook is a substrate defect for a validator to surface, and dropping the whole set would hide the rest of the file.
When an operation is declared BOTH ways, the explicit `hooks:` entry wins and the duplicate is reported — an ambiguous declaration must not resolve silently.