guide

package
v1.801.150 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mount

func Mount(app *zip.App, deps cloud.Deps) error

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 Shutdown

func Shutdown() error

Shutdown closes every cached per-org store. Idempotent.

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

type Detector func(ctx context.Context, org string, step Step) (bool, error)

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 State

type State string

State is a step's per-org lifecycle state.

const (
	StateTodo       State = "todo"
	StateInProgress State = "in_progress"
	StateDone       State = "done"
	StateSkipped    State = "skipped"
)

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

func (s *Store) ClearCurriculum(ctx context.Context) error

ClearCurriculum removes the org override, reverting to the built-in default.

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying database. Idempotent-safe via sql.DB.

func (*Store) GetCurriculum

func (s *Store) GetCurriculum(ctx context.Context) ([]byte, bool, error)

GetCurriculum returns the org's custom curriculum doc, or (nil,false) when the org uses the built-in default.

func (*Store) HasSuccessfulAction

func (s *Store) HasSuccessfulAction(ctx context.Context, tool string) (bool, error)

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

func (s *Store) ListActions(ctx context.Context, limit int) ([]ActionRecord, error)

ListActions returns the most-recent actions first, bounded by limit.

func (*Store) ResetState

func (s *Store) ResetState(ctx context.Context, stepID string) error

ResetState removes a step's row, returning it to the implicit todo default.

func (*Store) SetCurriculum

func (s *Store) SetCurriculum(ctx context.Context, doc []byte, now int64) error

SetCurriculum stores the org's custom curriculum doc (the raw validated source).

func (*Store) SetState

func (s *Store) SetState(ctx context.Context, stepID string, state State, source, note string, now int64) error

SetState upserts a step's state with its source ("manual"|"agent"|"auto") and an optional note.

func (*Store) States

func (s *Store) States(ctx context.Context) (map[string]StateRow, error)

States returns every recorded progress row keyed by step id. Steps with no row are implicitly todo (the engine's stateOf default) — absence is the todo state, so a fresh org needs no seeding.

Jump to

Keyboard shortcuts

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