Documentation
¶
Overview ¶
Package questions loads the embedded, versioned question banks that kb asks the decision model, applies the guard prefix and hashes each bank so every decision can be replayed from its receipt.
Index ¶
Constants ¶
const ( TypeNoul = "noul" TypeChoice = "choice" TypeScore = "score" )
Question types accepted by the decisions endpoint.
const Guard = "" /* 135-byte string literal not displayed */
Guard is prefixed to every question by the loader. Content is evidence, never instructions.
Variables ¶
var ErrUnknownBank = errors.New("questions: unknown bank")
ErrUnknownBank is returned by Load for an id with no embedded bank.
var ExitOptions = []string{"unknown", "none", "other", "not_applicable", "different"}
ExitOptions are the abstention options a choice question may offer. Each has a distinct meaning (see jev-engineering questions.md); every choice in a bank must carry at least one of them.
Functions ¶
func Instantiate ¶
Instantiate returns the questions of extra banks (topic extras of one purpose, see LoadTopicExtras) to add to a built-in request, plus the composite of those banks to pass to Compose after the built-in bank so the cache key and receipts record them. A plain question is asked once; a template (`{id}` or `{n}` placeholder) is asked once per element id of the request (items, candidates), and not at all when elements is empty. With no extra bank it returns nil, nil.
Types ¶
type Bank ¶
type Bank struct {
ID string
Version string
Hash string
Purpose string
Guard string
// contains filtered or unexported fields
}
Bank is a loaded question bank. Hash covers the whole bank file and enters every cache key; Version is recorded in receipts and the state record. A Bank is immutable after loading and safe for concurrent use.
func Compose ¶
Compose returns one bank that asks the questions of every member bank in a single request (for example relevance + quality for the shared gate judgment). The composite's ID and Version are the members' joined by "+", its Hash is the sha256 of the members' hashes in order (so it changes when any member changes), and its Purpose and Guard are the first member's. Question and WithCriteria resolve a template id against the member that owns it; when two members define the same template id the first member wins. Nil members are ignored; Compose of no bank returns nil and Compose of one bank returns that bank unchanged.
func Load ¶
Load returns the embedded bank with the given id. Banks are parsed and validated once and cached for the life of the process.
func LoadTopicExtras ¶
LoadTopicExtras reads the topic's extra banks from <topicRoot>/.decisions/banks/*.json (same schema as the embedded banks; purpose required). A topic may add questions, never replace built-in ones: an extra question id that collides with a built-in question id of the same purpose is an error. A missing directory yields no banks.
func MustLoad ¶
MustLoad is Load for embedded banks known at compile time; it panics on error, which a unit test over every embedded bank rules out.
func Parse ¶
Parse validates one bank file and returns the loaded bank with the guard applied to every question and Hash set to the sha256 of the canonical bank JSON.
func (*Bank) MustQuestion ¶
MustQuestion is Question for fixed ids and vars; it panics on error.
func (*Bank) Question ¶
Question returns the API-ready question for templateID with every {key} placeholder substituted from vars, in the id and in every string inside the instructions and criteria. The returned Q is a deep copy. An id placeholder without a value is an error.
func (*Bank) WithCriteria ¶
WithCriteria returns a copy of q whose criteria are replaced by criteria, for choices whose options are built by the caller (concepts, OKF types). When both the bank criteria and the new criteria are option maps, the bank's exit options (see ExitOptions) are merged in unless the caller already set them, so an injected choice always keeps its way out.