Documentation
¶
Overview ¶
Package guide mounts the Hanzo Cloud /v1/guide/* surface: the Business AI Guide, an interactive launch checklist every org completes on-site.
It is three orthogonal things composed:
- a CHECKLIST ENGINE over a machine-readable curriculum (steps with id, title, why, how-on-hanzo, done-criteria, dependencies). Per-org progress tracks a state per step (todo|in_progress|done|skipped); next-step logic honours dependencies; a step whose done-criterion maps to a real signal auto-marks done when that signal is present (auto-detect).
- a BUSINESS AI AGENT: for a step bound to an MCP tool, "do it for me" drafts the content with the embedded AI (deps.AI) and executes the tool through the per-principal MCP plane (automations.InvokeTool) AS THE CALLER — so the action can never exceed the caller's own authorization and is metered + audited like any MCP call.
- a curriculum LOADER: a minimal built-in default (embedded default.yaml) so /v1/guide works before the marketing repo's authored checklist.yaml lands; a PUT of an org-custom or platform-updated curriculum replaces it cleanly.
This file is the pure engine: the schema contract (Step / Curriculum), parsing, validation, and the dependency/next-step/auto-detect logic — all free functions over plain data, no I/O, so they are exhaustively unit-testable. Storage lives in store.go, detectors in detect.go, the agent in agent.go, and the HTTP surface in guide.go.
Index ¶
- func Mount(app *zip.App, deps cloud.Deps) error
- func Shutdown() error
- func Validate(c Curriculum) error
- type ActionRecord
- type Curriculum
- type Detector
- type Funnel
- type State
- type StateRow
- type Step
- type Store
- func (s *Store) AddAction(ctx context.Context, a ActionRecord) error
- func (s *Store) ClearCurriculum(ctx context.Context) error
- func (s *Store) Close() error
- func (s *Store) GetCurriculum(ctx context.Context) ([]byte, bool, error)
- func (s *Store) HasSuccessfulAction(ctx context.Context, tool string) (bool, error)
- func (s *Store) ListActions(ctx context.Context, limit int) ([]ActionRecord, error)
- func (s *Store) ResetState(ctx context.Context, stepID string) error
- func (s *Store) SetCurriculum(ctx context.Context, doc []byte, now int64) error
- func (s *Store) SetState(ctx context.Context, stepID string, state State, source, note string, ...) error
- func (s *Store) States(ctx context.Context) (map[string]StateRow, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Mount ¶
Mount wires /v1/guide/* onto app. Complex flavour (a package global for Shutdown + a per-org OrgStore), so it constructs the Service value directly.
func Validate ¶
func Validate(c Curriculum) error
Validate enforces the schema invariants the engine relies on: at least one step; unique non-empty ids; dependencies that reference existing ids (no self-edge); a bounded shape; and — the load-bearing one — an ACYCLIC dependency graph, so next-step selection always terminates and can never deadlock on a cycle.
Types ¶
type ActionRecord ¶
type ActionRecord struct {
ID string `json:"id"`
StepID string `json:"stepId"`
Tool string `json:"tool"`
Args string `json:"args,omitempty"`
Result string `json:"result,omitempty"`
OK bool `json:"ok"`
Err string `json:"err,omitempty"`
CreatedAt int64 `json:"createdAt"`
}
ActionRecord is one Business AI tool execution — the audit-visible ledger row.
type Curriculum ¶
type Curriculum struct {
Version string `json:"version"`
Title string `json:"title,omitempty"`
Steps []Step `json:"steps"`
}
Curriculum is an ordered set of steps plus metadata. Order is authoring order and is the tiebreak the next-step logic walks.
func Parse ¶
func Parse(raw []byte) (Curriculum, error)
Parse decodes a curriculum from YAML or JSON (sigs.k8s.io/yaml accepts both) and validates it. A parse or validation failure returns an error; the caller keeps the previous curriculum (fail-closed — a bad PUT never corrupts the active one).
func (Curriculum) Available ¶
func (c Curriculum) Available(states map[string]State, id string) bool
Available reports whether every dependency of id is satisfied.
func (Curriculum) BlockedBy ¶
func (c Curriculum) BlockedBy(states map[string]State, id string) []string
BlockedBy returns the step's dependencies that are NOT yet satisfied (not done/skipped). Empty slice means the step is available.
func (Curriculum) Counts ¶
func (c Curriculum) Counts(states map[string]State) (done, total, percent int)
Counts returns how many steps are done (skipped counts as resolved) and the total, plus an integer percent complete (0..100).
func (Curriculum) Next ¶
func (c Curriculum) Next(states map[string]State) string
Next returns the id of the step the org should tackle next: the FIRST step in authoring order that is neither done nor skipped and whose dependencies are all satisfied. It returns "" when nothing is actionable (all steps terminal, or the only remaining steps are blocked — which, on an acyclic graph, means their blockers are themselves the actionable next steps and get picked first).
type Detector ¶
Detector reports whether a step's done-criterion is satisfied by the org's real state. It is the auto-detect seam: a step names a Signal, the engine looks the detector up by that name and runs it. A detector MUST be honest — a data source it cannot reach returns an error (treated as "not present"), never a spurious true.
type Funnel ¶ added in v1.801.186
type Funnel struct {
Available bool `json:"available"`
WindowDays int `json:"windowDays"`
Pageviews int64 `json:"pageviews"`
Visitors int64 `json:"visitors"`
Signups int64 `json:"signups"`
Orders int64 `json:"orders"`
Revenue float64 `json:"revenue"`
}
Funnel is the org's top-of-funnel over the trailing window: traffic → signups → orders, with revenue. Available is false when the warehouse is unreachable or the org has emitted nothing (honest-empty), so the caller renders "turn on analytics" rather than a misleading row of zeros.
type StateRow ¶
type StateRow struct {
State State `json:"state"`
Source string `json:"source,omitempty"`
Note string `json:"note,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
}
StateRow is a step's persisted progress.
type Step ¶
type Step struct {
ID string `json:"id"`
Title string `json:"title"`
Why string `json:"why"`
How string `json:"how"` // how-on-hanzo
Done string `json:"done"` // human done-criteria
Dependencies []string `json:"dependencies,omitempty"`
// Signal, when set, names a machine detector (detect.go). When the detector
// reports the org's real state present, the step auto-marks done.
Signal string `json:"signal,omitempty"`
// Tool, when set, is the "<connector>_<action>" MCP tool the Business AI runs
// for "do it for me". Args are its default arguments; Draft is an optional AI
// prompt whose output fills the DraftInto arg (default "brief").
Tool string `json:"tool,omitempty"`
Args map[string]any `json:"args,omitempty"`
Draft string `json:"draft,omitempty"`
DraftInto string `json:"draftInto,omitempty"`
}
Step is one checklist item. The struct tags are JSON, and sigs.k8s.io/yaml decodes YAML through them — so one tag set is the ONE contract for both the embedded YAML default and a JSON PUT body (DRY: no parallel yaml tags).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is one org's guide database. Isolation is PHYSICAL: cloud.OrgStore opens a distinct file per org ({DataDir}/orgs/{org}/guide.db), so there is no org column and no cross-org query is expressible. It holds three tables:
- progress: one row per step whose state has diverged from the todo default.
- actions: the Business AI action ledger — every "do it for me" tool call, its args, and its outcome. It is both the audit-visible record and the backing state for the "acted" auto-detect signal.
- curriculum: at most one row — the org's custom curriculum override (raw doc).
The caller (guide.Mount) opens it through cloud.NewOrgStore; openStore below is the per-org open func. cloud.OrgDB has already applied the WAL/busy pragmas and single-writer bound, so openStore only migrates.
func (*Store) AddAction ¶
func (s *Store) AddAction(ctx context.Context, a ActionRecord) error
AddAction appends an action-ledger row.
func (*Store) ClearCurriculum ¶
ClearCurriculum removes the org override, reverting to the built-in default.
func (*Store) GetCurriculum ¶
GetCurriculum returns the org's custom curriculum doc, or (nil,false) when the org uses the built-in default.
func (*Store) HasSuccessfulAction ¶
HasSuccessfulAction reports whether a prior "do it for me" call on tool succeeded — the backing predicate for the "acted" auto-detect signal. A successful call means the real, audited effect (e.g. a Content draft) landed in the sibling subsystem, so the step's done-criterion is met.
func (*Store) ListActions ¶
ListActions returns the most-recent actions first, bounded by limit.
func (*Store) ResetState ¶
ResetState removes a step's row, returning it to the implicit todo default.
func (*Store) SetCurriculum ¶
SetCurriculum stores the org's custom curriculum doc (the raw validated source).