walkthrough

package
v0.84.0 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 11 Imported by: 0

README

pkg/walkthrough — declaration, pin and checkpoint contracts

Pure Go implementation of the walkthrough contracts owned by spec/features/project-walkthroughs/declaration-format.md in datatug/backstage:

  • the ordinary datatug-walkthrough/1 declaration;
  • the opt-in datatug-walkthrough/2 training declaration additions;
  • immutable asset/package references and source pins;
  • the public story registry entry shape and owner-context alias admission;
  • the external checkpoint envelope shape, its owner-resolved admission and pure match decisions.

It validates bytes supplied by a caller and returns typed projections or structured recoverable issues. It never reads a project, navigates, publishes or consumes activity, stores progress, runs SQL or checks, mutates Work or renders UI. This package is a contract, not the walkthrough runtime.

/1 API

result := walkthrough.ParseDeclaration(directoryID, declarationBytes)
if result.NewerClient {
    // the declaration names a schema major this client cannot parse
}
if !result.Accepted {
    // result.Definition is nil; result.Issues is a stable {Code, Path, Message}
}
definition := result.Definition // typed, fully validated, defensively owned
revision := result.Digest       // SHA-256 of the exact input bytes

Declaration.Projection() is the stable, language-neutral normalized view shared with the TypeScript contract and the conformance corpus. It exposes defaults, capture references, support status, entry steps and the digest; it does not expose presentation prose.

A /2 declaration passed to ParseDeclaration is still reported as Result.NewerClient, exactly as before the /2 entry point existed.

/2 training API

parsed := walkthrough.ParseTrainingDeclaration(directoryID, declarationBytes)
if !parsed.Accepted {
    // parsed.Definition is nil; the /2-only fields were refused
}
declaration := parsed.Definition // structurally valid only

resolution := walkthrough.ResolveTraining(
    declaration,
    walkthrough.SourceContext{Project: identity, ContentPin: pin, DeclarationSHA256: digest},
    projectAuthority, // trusted opaque owner adapter
    trainingOwners,   // trusted validated package/asset/challenge lookup
)
if !resolution.Admitted {
    // structured refusal; no admitted executable bundle is exposed
}
bundle := resolution.Bundle

ParseTrainingDeclaration is a distinct explicit entry point. It shares the JSON/variant machinery without widening ordinary /1 admission: an unknown target or condition kind stays step-local needs-newer, while an unknown step kind, a wrong variant pairing, a malformed checkpoint mapping or an unsafe pin refuses the package. A structurally valid parse is never called "render-ready": package, Case, asset and challenge authority come only from ResolveTraining.

TrainingDeclaration.Projection() extends the ordinary normalized view with the package and narrative references, the step kind/segmentId and the checkpoint mapping. TrainingDeclaration.WalkthroughIdentity() returns the declared walkthrough identity used by registry admission.

Source pins and owner contexts

  • AssetReference is exactly path, sha256 (64 lowercase hex) and bytes (positive canonical lexeme). PackageReference adds id and revision. VerifyBytes checks the exact length and SHA-256 before any parse.
  • ContentPin is exactly one {kind: git, commit: <40 hex>} (normalized lowercase) or {kind: digest, sha256: <64 lowercase hex>}. A digest pin identifies the exact declaration bytes, so it must equal the parsed declaration digest at every binding point: ResolveTraining, registry admission, envelope admission and an active wait refuse a shape-valid record whose digest pin and declaration digest disagree.
  • ProjectIdentity is opaque. This package never interprets it, never builds a canonical project serialization and never compares identities itself: ProjectAuthority supplies BindProject/AdmitProject/EqualProject. Production adapters reuse the owning project-context normalization; test doubles prove wiring only. Snapshotting the opaque identity value stays the owner adapter's responsibility.
  • Admission takes an independent snapshot of every contract-owned input. A parsed declaration remains caller-owned and mutable, but an admitted bundle never aliases it, and the envelope owns a copy of the exact project byte span it was parsed from.
  • TrainingOwnerContext supplies the admitted package inventory, asset admission and the exact owner-validated challenge manifest. There is no fallback to an ordinary service, no invented package document and no trusted "passed" boolean.

Story registry and checkpoint envelope

ParseStoryRegistryEntry reads the closed shape storyId/revision/projectUrl/walkthroughId/contentPin/declarationSha256. AdmitStoryChapter then requires an owner-established canonical immutable URL, an owner-established public scope, exact pin agreement and a declared chapter; it returns a RouteDescriptor and never invents a walkthrough URL. Private/unknown scope refuses, and a historical pin mismatch never falls back to latest.

ParseCheckpointEnvelope reads exactly the owner fields, including the opaque project value (copied at parse and handed to the adapter as the exact input bytes). Inconsistent outcome/complete summaries refuse. AdmitCheckpointEnvelope resolves the project through the owner adapter and retains an independent copy of the project span; an inconsistent digest pin refuses. MatchCheckpointEnvelope and MatchRetainedCompletion return only a consume/revisit/no-match decision: consuming once, pause/scheduling, retained completion storage and authority lifecycle remain runtime owner work. There is no namespace field on the validation envelope, so a reference/Test-labelled payload is an unknown-field refusal, never a match.

Boundaries

  • Only /1 through ParseDeclaration, /2 through ParseTrainingDeclaration. Later majors are NewerClient for both explicit entry points; /1 rejects every /2-only field and /2 refuses a /1 document rather than down-converting it.
  • An unknown target or condition kind is step-local: the step is kept with SupportNeedsNewer, its opaque body is discarded rather than exposed or executed, and unrelated steps remain usable. Unknown target/condition kinds inside a /2 dialogue/challenge step keep that policy instead of becoming a fatal variant-pairing error.
  • Captures may be produced only by parameter-value, record-selected and incident-open, and never by a /2 dialogue or challenge step.
  • A finish/exit { "walkthrough": "<id>" } is checked against the ID grammar. Whether that walkthrough exists, and whether any target asset exists or is readable, is caller-owned external context.
  • Unknown fields reject at every object level. Field names are matched exactly; JSON decoding is hand-written because standard Go decoding is case-folding, replaces malformed UTF-8 and cannot enforce field presence or nested unions.
  • Escaped surrogates use the repository's established Go-compatible treatment: valid pairs become one code point, unpaired surrogates become U+FFFD in both values and keys. Character budgets count code points after normalization; byte budgets count exact input bytes.
  • Positive integers keep their canonical decimal lexeme with no machine-integer cap, so 2^53, the uint64 boundary and larger values survive exactly. Fractions, exponents, signs, zero and null refuse where a positive integer is required.

Shared locale profile

AdmitAuthoredLocale and NormalizeVisitorLocale are separate pure entry points for the /2 locale contract. Authored fields (sidecar defaults, catalogue references and catalogue documents) must use values registered in the pinned IANA snapshots, including the registered private-use ranges; an unknown but well-formed value is a recoverable unsupported_registry_version naming the snapshot. Visitor requests keep syntactically well-formed unknown values for the later exact / primary-language / fallback selector, while malformed syntax is a structured refusal rather than an ambient language.

Both paths enforce the 64-character input and canonical-output bound, ASCII hyphen-separated grammar, duplicate-variant and duplicate-singleton rejection, grandfathered/private-use recognition, registered whole-tag and subtag Preferred-Value mappings, contextual extlang replacement, explicit script and private-tail preservation, and extension-block ordering by singleton. Extension payloads stay opaque. The returned Tag is the canonical comparison key, so aliases that collide (for example iw-IL/he-IL) can be rejected as duplicate catalogue tags. PrimaryLanguage is the genuine regular primary language, or empty for private-use-only and unreplaced irregular grandfathered tags; this package does not implement the later catalogue selector.

The data lives in testdata/locale/: the exact official registry bytes, the checked-in table generator, locale-tables.json, its provenance and the independently authored expected-value corpus. Tests assert complete runtime inventory equality with the committed table and every registered grandfathered and redundant record. Regenerate only after an intentional pinned-snapshot change:

python3 pkg/walkthrough/testdata/locale/generate_locale_tables.py
go test ./pkg/walkthrough

Corpus

testdata/corpus.json is the canonical, language-neutral /1 conformance corpus (119 vectors, unchanged). testdata/corpus-v2.json is the separately versioned training corpus; each vector's operation selects the explicit entry point (training-declaration, checkpoint-envelope, story-registry-entry). Raw bytes live in testdata/declarations/ and testdata/declarations-v2/. Expected normalized projections are authored from the owner tables by the independent normalizer in testdata/generate_corpus.py; they are never produced by this package.

provenance-v2.json records every file hash, the training corpus hash and the hash of the unchanged base /1 corpus. Regenerate fixtures after an intentional corpus change:

python3 pkg/walkthrough/testdata/generate_corpus.py
go test ./pkg/walkthrough

The TypeScript mirror copies these bytes identically and records the Core commit and per-file SHA-256 in its fixture provenance.

Documentation

Overview

Package walkthrough owns the pure walkthrough contracts: the ordinary `datatug-walkthrough/1` declaration, the opt-in `datatug-walkthrough/2` training declaration additions, immutable asset/package references and source pins, the public story registry shape and the external checkpoint envelope with its pure match decisions.

The package is deliberately passive. It reads bytes supplied by a caller, validates them against the normative owner tables in `datatug/backstage` `spec/features/project-walkthroughs/declaration-format.md` and returns either typed definitions or structured recoverable issues. It never reads a project, opens a route, publishes or consumes activity signals, records progress, runs SQL or checks, mutates Work, or renders UI. Owner authority (project identity, package inventory, Case and challenge admission) enters only through the explicit trusted ports in ProjectAuthority and TrainingOwnerContext.

Admission boundaries

  • A declaration is a UTF-8 JSON object of at most MaxDeclarationBytes.
  • The declaration ID must equal the directory ID in `walkthroughs/<id>/walkthrough.json` (DeclarationPath).
  • The revision is the SHA-256 of the exact bytes supplied. It is never a hash of a reserialized object.
  • ParseDeclaration admits ordinary /1 only; a /2 document is reported as Result.NewerClient exactly as before the explicit /2 entry point existed. ParseTrainingDeclaration admits exactly /2 and reports a later major as TrainingResult.NewerClient.
  • A structurally valid /2 parse is not a resolved admission. Package, Case, asset, challenge, project and source-pin authority require ResolveTraining; a refused resolution never exposes a bundle.
  • An unknown target or condition `kind` is a step-local newer-client boundary: the step is retained as SupportNeedsNewer, its opaque body is neither exposed nor executed, and unrelated steps remain usable.
  • Unknown fields on known variants are fatal. `/1` rejects every /2-only top-level or step field. Unknown step kinds and wrong /2 variant pairings reject the training package.
  • A refused declaration never yields a partially admitted executable definition.

Source pins

An asset reference is a safe project-root-relative path, a lowercase 64-hex digest and a positive byte count; a package reference adds its ID and revision. Supplied bytes are verified against the pin before any parse. A content pin is one immutable Git commit (normalized lowercase) or one exact content digest. A digest pin identifies the exact declaration bytes, so wherever it binds (resolution, registry admission, envelope admission and an active wait) it must equal the parsed declaration digest itself; a shape-valid record whose two digest fields disagree is never admitted. No canonical project serialization is invented here: project identity is an opaque value owned by the injected adapter, which also owns its snapshot.

Defensive snapshots

A parsed declaration, registry entry or envelope draft stays caller-owned and mutable. Admission takes an independent deep snapshot of every contract-owned input (chapters, steps, target/condition mappings, references, pins and the envelope's exact project byte span) and returns projections that never alias the caller's structures. Only the opaque project identity value itself remains the trusted owner adapter's snapshot responsibility.

Escaped surrogates

JSON permits unpaired UTF-16 surrogate escapes. Both this package and the TypeScript contract deliberately follow the repository's existing Go-compatible treatment: a valid high/low pair is one code point, and an unpaired surrogate becomes U+FFFD. The same treatment applies to object keys and to every string value, so a lone surrogate and a literal U+FFFD compare equal in both languages. Character budgets count Unicode code points after that normalization; byte budgets always count the exact input bytes.

Not in this package

Narrative/catalogue JSON schemas, events, presentation and branches, segment/chapter/event/reference closure, catalogue selection and localisation catalogues, aggregate text accounting, `/2` generation, seek and adapter handoffs, navigation, progress storage, activity delivery, target existence checks and Walkthrough UI are owned by later slices and other packages. The pure locale admission/canonicalization profile in AdmitAuthoredLocale and NormalizeVisitorLocale returns canonical data only; the exact/primary/fallback catalogue selector remains later work. The ordinary /1 user journey and the training runtime do not exist merely because these contracts do.

Index

Constants

View Source
const (
	MaxDeclarationBytes = 64 << 10
	MaxChapters         = 20
	MaxStepsPerChapter  = 30
	MaxSteps            = 200
	MaxTitleChars       = 120
	MaxTextChars        = 400
)

Ordinary /1 bounds from the normative owner declaration table.

View Source
const (
	ReasonMatched             = "matched"
	ReasonMissingContext      = "missing_context"
	ReasonWaitInvalid         = "wait_invalid"
	ReasonBindingUnvalidated  = "binding_not_validated"
	ReasonProjectMismatch     = "project_mismatch"
	ReasonAuthorityStale      = "authority_stale"
	ReasonPinMismatch         = "pin_mismatch"
	ReasonDeclarationMismatch = "declaration_mismatch"
	ReasonNarrativeMismatch   = "narrative_mismatch"
	ReasonPackageMismatch     = "package_mismatch"
	ReasonWalkthroughMismatch = "walkthrough_mismatch"
	ReasonChapterMismatch     = "chapter_mismatch"
	ReasonStepMismatch        = "step_mismatch"
	ReasonChallengeMismatch   = "challenge_mismatch"
	ReasonRevisionMismatch    = "revision_mismatch"
	ReasonCheckpointMismatch  = "checkpoint_mismatch"
	ReasonAttemptMismatch     = "attempt_mismatch"
	ReasonSubmissionStale     = "submission_stale"
	ReasonOutcomeNotPassed    = "outcome_not_passed"
	ReasonAttemptIncomplete   = "attempt_incomplete"
)

Stable matching reasons. They are decisions, not refusal issues.

View Source
const (
	// LocaleRegistryFileDate is the pinned IANA Language Subtag Registry File-Date.
	LocaleRegistryFileDate = "2026-09-17"
	// LocaleRegistrySHA256 is the SHA-256 of the exact retained registry bytes.
	LocaleRegistrySHA256 = "755fad43283be7b41ebe3c89ad054b6eaf928f404f9c0edb74799e0eab74beb1"
	// LocaleRegistryURL is the official source of LocaleRegistrySHA256.
	LocaleRegistryURL = "https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry"
	// LocaleExtensionsRegistryFileDate is the pinned extension registry File-Date.
	LocaleExtensionsRegistryFileDate = "2014-04-02"
	// LocaleExtensionsRegistrySHA256 is the SHA-256 of the retained extension bytes.
	LocaleExtensionsRegistrySHA256 = "fdf7764455c493c245a9b3b5b9cd3938391f0637302c3e943fde86aee652e376"
	// LocaleExtensionsRegistryURL is the official source of that snapshot.
	LocaleExtensionsRegistryURL = "https://www.iana.org/assignments/language-tag-extensions-registry/language-tag-extensions-registry"
	// LocaleTablesSHA256 is the SHA-256 of testdata/locale/locale-tables.json.
	LocaleTablesSHA256 = "7328cbddaa0f4450eeb730ebca222cedf9bd9c7a16a8037f3d3ad22a4e5ccad6"
)
View Source
const (
	// PinGit is an immutable Git commit pin.
	PinGit = "git"
	// PinDigest is an immutable content-digest pin for cloud/local sources.
	PinDigest = "digest"
)
View Source
const CompletionWholeChallenge = "whole-challenge"

CompletionWholeChallenge is the only checkpoint completion kind this version admits. Part-level, multiple or alternative mappings require a separately reviewed owning contract.

View Source
const LocaleProfile = "datatug-bcp47-profile/1"

LocaleProfile identifies the deterministic BCP-47 profile implemented by AdmitAuthoredLocale and NormalizeVisitorLocale.

View Source
const MaxAttemptIDLen = 128

MaxAttemptIDLen is the owner limit for the external checkpoint envelope's opaque execution-owned attempt id: 1..128 printable ASCII characters.

View Source
const MaxLocaleCharacters = 64

MaxLocaleCharacters is the inclusive bound on both an input tag and the canonical tag produced from it. Locale tags are US-ASCII, so this is also the byte bound.

View Source
const SchemaV1 = "datatug-walkthrough/1"

SchemaV1 is the ordinary schema this package admits through ParseDeclaration. Any other major is reported as needing a newer DataTug rather than parsed.

View Source
const SchemaV2 = "datatug-walkthrough/2"

SchemaV2 is the opt-in training extension admitted only through ParseTrainingDeclaration. The ordinary entry point keeps reporting it as a newer-client declaration.

Variables

View Source
var ErrNewerClient = errors.New("walkthrough: declaration needs a newer DataTug")

ErrNewerClient is returned by Result.Err and TrainingResult.Err when the declaration bytes name a schema this entry point cannot parse. It is a recoverable newer-client boundary, not a malformed declaration.

View Source
var Outcomes = []string{"passed", "failed", "cancelled", "timed-out", "error"}

Outcomes is the closed checkpoint-result outcome set. Assistance is orthogonal and never a replacement outcome.

Functions

func DeclarationPath

func DeclarationPath(id string) string

DeclarationPath returns the exact project-relative location of a walkthrough declaration.

func KnownConditionKind

func KnownConditionKind(kind string) bool

KnownConditionKind reports whether kind is in the ordinary /1 condition registry.

func KnownTargetKind

func KnownTargetKind(kind string) bool

KnownTargetKind reports whether kind is in the ordinary /1 target registry.

Types

type ActiveWait added in v0.83.0

type ActiveWait struct {
	Project               ProjectIdentity
	AuthorityGeneration   Integer
	ContentPin            ContentPin
	DeclarationSHA256     string
	NarrativeSHA256       string
	TrainingPackageSHA256 string
	WalkthroughID         string
	ChapterID             string
	ChallengeStepID       string
	ChallengeID           string
	ChallengeRevision     Integer
	CheckpointID          string
	AttemptID             string
	SubmissionGeneration  Integer
	Dialogue              DialogueChallengeBinding
}

ActiveWait is the explicit runtime wait a result must match field for field.

type AdmittedChallengeStep added in v0.83.0

type AdmittedChallengeStep struct {
	ChapterID    string
	StepID       string
	ChallengeID  string
	Revision     Integer
	CheckpointID string
}

AdmittedChallengeStep is one structurally valid challenge step whose target and checkpoint the owner context has admitted.

type AdmittedTraining added in v0.83.0

type AdmittedTraining struct {
	Declaration           *TrainingDeclaration
	Project               ProjectIdentity
	ContentPin            ContentPin
	DeclarationSHA256     string
	Narrative             AssetReference
	NarrativeSHA256       string
	Package               PackageReference
	TrainingPackageSHA256 string
	WalkthroughID         string
	Chapters              []string
	ChallengeSteps        []AdmittedChallengeStep
	Cases                 []string
}

AdmittedTraining is the resolved, immutable training identity: no file has been read, but every pin, package, Case, challenge and checkpoint identity is bound together and admitted by its owner.

type AssetExistsCondition

type AssetExistsCondition struct {
	Asset string
	ID    string
}

AssetExistsCondition observes that an asset is readable in the resolved project.

type AssetReference added in v0.83.0

type AssetReference struct {
	Path   string
	SHA256 string
	Bytes  Integer
}

AssetReference pins one immutable UTF-8 JSON asset of the declaring project: a safe project-root-relative path, the lowercase SHA-256 of its exact bytes and its positive byte length.

func (AssetReference) Equal added in v0.83.0

func (r AssetReference) Equal(other AssetReference) bool

Equal reports field-for-field equality of two asset references.

func (AssetReference) VerifyBytes added in v0.83.0

func (r AssetReference) VerifyBytes(data []byte) error

VerifyBytes checks supplied bytes against this reference before any parse: the byte length must match exactly and the SHA-256 must equal the pinned digest. A mismatch is a recoverable refusal with no partially admitted asset.

type BoardTarget

type BoardTarget struct {
	BoardID    string
	Parameters []NamedValue
	Tutorial   bool
}

BoardTarget is a saved board; Tutorial adds the board-action tutorial mode.

type BoardTutorialCondition

type BoardTutorialCondition struct {
	UntilCard string
}

BoardTutorialCondition observes board tutorial progress.

type CardTarget

type CardTarget struct {
	CardID     string
	Parameters []NamedValue
}

CardTarget is a saved card with optional parameter values.

type ChallengeBinding added in v0.83.0

type ChallengeBinding struct {
	ChallengeID string
	Revision    Integer
}

ChallengeBinding is one owner-validated immutable challenge revision.

type ChallengePassedCondition added in v0.83.0

type ChallengePassedCondition struct {
	Checkpoints []CheckpointMapping
}

ChallengePassedCondition observes whole-attempt completion of the step's exact challenge target. It carries exactly one walkthrough-owned checkpoint mapping.

type ChallengeTarget added in v0.83.0

type ChallengeTarget struct {
	ChallengeID string
	Revision    Integer
}

ChallengeTarget is the exact published challenge revision this step targets. The id/revision follow the challenge-execution owner contract, not the shorter walkthrough ID grammar.

type Chapter

type Chapter struct {
	ID             string
	FormerIDs      []string
	Title          string
	Why            string
	Requires       string
	RequiresReason string
	ContinuesFrom  string
	Readiness      *Condition
	Steps          []Step
	EntryStepID    string
}

Chapter is one ordered chapter. EntryStepID is the first Explore step whose target is not none (an unknown target kind still declares the entry).

type CheckRunCondition

type CheckRunCondition struct {
	Outcome string
}

CheckRunCondition observes a Check completion with an optional outcome.

type CheckTarget

type CheckTarget struct {
	CheckID string
}

CheckTarget is a Check and its runs.

type CheckpointEnvelope added in v0.83.0

type CheckpointEnvelope struct {
	Project ProjectIdentity
	EnvelopeDraft
}

CheckpointEnvelope is an admitted envelope: the owner-resolved project identity plus every verified field.

type CheckpointMapping added in v0.83.0

type CheckpointMapping struct {
	ID         string
	Completion string
}

CheckpointMapping is the walkthrough-owned whole-challenge checkpoint mapping. Completion is always "whole-challenge"; part-level or narrative-defined mappings are not representable.

type Code

type Code string

Code is a stable refusal code for a declaration problem. Callers may switch on it; human wording is not part of the contract.

const (
	// CodeTooLarge means the input exceeds MaxDeclarationBytes.
	CodeTooLarge Code = "too_large"
	// CodeInvalidUTF8 means the input bytes are not valid UTF-8.
	CodeInvalidUTF8 Code = "invalid_utf8"
	// CodeInvalidJSON means the bytes are not one JSON value with JSON syntax.
	CodeInvalidJSON Code = "invalid_json"
	// CodeDuplicateKey means a JSON object repeats a key (including an escaped
	// spelling of the same key).
	CodeDuplicateKey Code = "duplicate_key"
	// CodeTrailingData means non-whitespace bytes follow the JSON value.
	CodeTrailingData Code = "trailing_data"
	// CodeNotObject means the root JSON value is not an object.
	CodeNotObject Code = "not_object"
	// CodeMissingField means a required field is absent.
	CodeMissingField Code = "missing_field"
	// CodeUnknownField means an object carries a field outside its closed set.
	CodeUnknownField Code = "unknown_field"
	// CodeInvalidType means a value has the wrong JSON type (including explicit
	// null where a value is required).
	CodeInvalidType Code = "invalid_type"
	// CodeInvalidValue means a string, enum, integer lexeme or identity does
	// not satisfy its declared rule.
	CodeInvalidValue Code = "invalid_value"
	// CodeTooLong means a text value exceeds its character limit.
	CodeTooLong Code = "too_long"
	// CodeTooMany means an array or total count exceeds its limit.
	CodeTooMany Code = "too_many"
	// CodeDuplicateID means a chapter, former, step or captured identity is
	// repeated in a scope that requires uniqueness.
	CodeDuplicateID Code = "duplicate_id"
	// CodeInvalidReference means a static reference (continuesFrom, chapter
	// exit, readiness/needs pairing) does not resolve.
	CodeInvalidReference Code = "invalid_reference"
	// CodeMissingDefault means a captured value object omits its mandatory
	// literal default.
	CodeMissingDefault Code = "missing_default"
	// CodeUnknownCapture means a captured value names no declared producer.
	CodeUnknownCapture Code = "unknown_capture"
	// CodeCaptureNotEarlier means a captured value references a producer that
	// is not earlier in document order.
	CodeCaptureNotEarlier Code = "capture_not_earlier"
	// CodeCaptureNotAllowed means a capture is attached to a known condition
	// kind that cannot produce a value.
	CodeCaptureNotAllowed Code = "capture_not_allowed"
	// CodeMissingExploreEntry means a chapter has no step available in Explore.
	CodeMissingExploreEntry Code = "missing_explore_entry"
	// CodeInvalidEntryTarget means a chapter's first Explore step targets none.
	CodeInvalidEntryTarget Code = "invalid_entry_target"
	// CodeInvalidPath means an asset path is not a safe project-relative path.
	CodeInvalidPath Code = "invalid_path"
	// CodeMissingContext means a required owner adapter or resolved source
	// context is absent. Nothing may be admitted from a refused context.
	CodeMissingContext Code = "missing_context"
	// CodeNotAdmitted means the trusted owner context does not admit the named
	// package, asset, Case or challenge manifest.
	CodeNotAdmitted Code = "not_admitted"
	// CodeMismatch means two bound identities or references must be equal field
	// for field and are not.
	CodeMismatch Code = "mismatch"
	// CodePinMismatch means a source pin is not the one exact immutable pin its
	// source requires (for example a branch or HEAD where a commit is required).
	CodePinMismatch Code = "pin_mismatch"
	// CodeDigestMismatch means supplied bytes or a repeated digest disagree with
	// the pinned SHA-256.
	CodeDigestMismatch Code = "digest_mismatch"
	// CodeByteCountMismatch means supplied bytes disagree with the pinned byte
	// length.
	CodeByteCountMismatch Code = "byte_count_mismatch"
	// CodeInconsistentSummary means a checkpoint envelope's outcome and
	// whole-attempt completion contradict each other.
	CodeInconsistentSummary Code = "inconsistent_summary"
	// CodeIneligible means a registry entry or namespace may not be used here:
	// a non-public scope or a reference/Test-only result.
	CodeIneligible Code = "ineligible"
)

func ErrorCode

func ErrorCode(err error) Code

ErrorCode returns the first stable issue code, or "" when err is not a walkthrough refusal.

type CompletionRecord added in v0.83.0

type CompletionRecord struct {
	Project               ProjectIdentity
	AuthorityGeneration   Integer
	ContentPin            ContentPin
	DeclarationSHA256     string
	NarrativeSHA256       string
	TrainingPackageSHA256 string
	WalkthroughID         string
	ChapterID             string
	ChallengeStepID       string
	ChallengeID           string
	ChallengeRevision     Integer
	CheckpointID          string
	Outcome               string
	Complete              bool
}

CompletionRecord is one runtime-retained execution completion. Revisit never creates an envelope or replays an external effect.

type Condition

type Condition struct {
	Kind             string
	Supported        bool
	ParameterValue   *ParameterValueCondition
	RecordSelected   *RecordSelectedCondition
	QueryRun         *QueryRunCondition
	PanelOpen        *PanelOpenCondition
	FilterApplied    *FilterAppliedCondition
	CheckRun         *CheckRunCondition
	AssetExists      *AssetExistsCondition
	BoardTutorial    *BoardTutorialCondition
	DialogueFinished *DialogueFinishedCondition
	ChallengePassed  *ChallengePassedCondition
}

Condition is one closed-registry completion condition. Exactly the pointer matching Kind is populated for a supported kind; an unknown kind has Supported false and no variant data.

type ContentPin added in v0.83.0

type ContentPin struct {
	Kind   string
	Commit string
	SHA256 string
}

ContentPin is the resolved source pin. Exactly one variant is populated: KindGit pins a 40-hex commit (normalized lowercase); KindDigest pins the lowercase SHA-256 of the exact declaration bytes.

func (ContentPin) Equal added in v0.83.0

func (p ContentPin) Equal(other ContentPin) bool

Equal compares two pins after their parsers normalized hex spelling.

func (ContentPin) Valid added in v0.83.0

func (p ContentPin) Valid() bool

Valid reports whether the pin is one exact, immutable variant.

type Declaration

type Declaration struct {
	Schema   string
	ID       string
	Version  Integer
	Title    string
	Summary  string
	Chapters []Chapter
	Finish   Exit
	Revision string
}

Declaration is a fully validated ordinary /1 walkthrough. Revision is the lowercase SHA-256 of the exact input bytes.

func (*Declaration) Projection

func (d *Declaration) Projection() map[string]any

Projection renders the stable, language-neutral normalized view used by the shared conformance corpus. It exposes defaults, references, support status and the exact digest-related identity, but no presentation prose.

type DeclaredWalkthrough added in v0.83.0

type DeclaredWalkthrough struct {
	ID       string
	Revision string
	Chapters []string
}

DeclaredWalkthrough is the admitted walkthrough identity a registry entry must resolve to: exact ID, exact revision and ordered declared chapters.

type DialogueChallengeBinding added in v0.83.0

type DialogueChallengeBinding struct {
	Validated       bool
	SegmentID       string
	ChapterID       string
	DialogueStepID  string
	ChallengeStepID string
}

DialogueChallengeBinding is the a3 narrative validator's verdict that the pinned dialogue segment bound to this chapter/step waits for this exact challenge step. This slice cannot validate a sidecar, so an unvalidated binding never matches.

type DialogueFinishedCondition added in v0.83.0

type DialogueFinishedCondition struct{}

DialogueFinishedCondition is presentation-step completion of the pinned Play segment. It never awards a challenge pass.

type EnvelopeAdmission added in v0.83.0

type EnvelopeAdmission struct {
	Envelope *CheckpointEnvelope
	Issues   []Issue
}

EnvelopeAdmission is the outcome of owner resolution.

func AdmitCheckpointEnvelope added in v0.83.0

func AdmitCheckpointEnvelope(draft EnvelopeDraft, authority ProjectAuthority) EnvelopeAdmission

AdmitCheckpointEnvelope resolves the envelope's opaque project reference through the trusted owner authority. A missing or refusing adapter admits nothing.

func (EnvelopeAdmission) Err added in v0.83.0

func (r EnvelopeAdmission) Err() error

Err returns nil for an admitted envelope or the aggregate recoverable refusal.

type EnvelopeDraft added in v0.83.0

type EnvelopeDraft struct {
	ProjectRaw            []byte
	AuthorityGeneration   Integer
	ContentPin            ContentPin
	DeclarationSHA256     string
	NarrativeSHA256       string
	TrainingPackageSHA256 string
	WalkthroughID         string
	ChapterID             string
	StepID                string
	ChallengeID           string
	ChallengeRevision     Integer
	CheckpointID          string
	AttemptID             string
	SubmissionGeneration  Integer
	Outcome               string
	Complete              bool
	Assisted              bool
}

EnvelopeDraft is the strictly parsed shape of one external checkpoint envelope, before the owner resolves the opaque project reference. No SQL, rows, evidence, transcript, token or any other extra field is representable.

func (EnvelopeDraft) Projection added in v0.83.0

func (d EnvelopeDraft) Projection() map[string]any

Projection is the stable normalized view used by the shared corpus.

type EnvelopeResult added in v0.83.0

type EnvelopeResult struct {
	Draft  *EnvelopeDraft
	Issues []Issue
}

EnvelopeResult is the outcome of the strict envelope shape parse.

func ParseCheckpointEnvelope added in v0.83.0

func ParseCheckpointEnvelope(data []byte) EnvelopeResult

ParseCheckpointEnvelope parses exactly one closed envelope shape. An inconsistent outcome/complete summary refuses here: the adapter must never hand an inconsistent summary to matching.

func (EnvelopeResult) Err added in v0.83.0

func (r EnvelopeResult) Err() error

Err returns nil for a parsed draft or the aggregate recoverable refusal.

type Error

type Error struct {
	Issues []Issue `json:"issues"`
}

Error is the aggregate refusal returned by Result.Err. It is recoverable: reloading a supported schema or fixing the named declaration fields can succeed, and no completion may be recorded from a refused parse.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Recoverable

func (e *Error) Recoverable() bool

Recoverable reports whether retrying with a supported schema or corrected bytes can succeed. Every refusal produced by this package is recoverable.

type Exit

type Exit struct {
	Kind        string
	Chapter     string
	Walkthrough string
	Target      *Target
}

Exit is the walkthrough finish (or a chapter's next exit). Exactly one variant is set.

type FilterAppliedCondition

type FilterAppliedCondition struct {
	Field  string
	Equals *Scalar
}

FilterAppliedCondition observes a log or table filter.

type IncidentTarget

type IncidentTarget struct {
	Incident *Value
}

IncidentTarget is an incident in the resolved project, or its incident list when Incident is absent or null.

type Integer

type Integer string

Integer is a canonical, non-negative decimal integer lexeme. Keeping the lexeme rather than a machine integer preserves versions and row thresholds exactly in both Go and TypeScript without inventing a representability cap.

func (Integer) String

func (i Integer) String() string

type Issue

type Issue struct {
	Code    Code   `json:"code"`
	Path    string `json:"path"`
	Message string `json:"message"`
}

Issue is one structured, recoverable declaration problem. Path is a JSON Pointer into the input ("" is the root).

func ValidateActiveWait added in v0.83.0

func ValidateActiveWait(wait ActiveWait) []Issue

ValidateActiveWait reports every structural problem that would make a wait unable to consume or revisit a result.

func (Issue) Error

func (i Issue) Error() string

type LocaleCode added in v0.84.0

type LocaleCode string

LocaleCode is a stable refusal code for locale admission or normalization. Callers may switch on it; human wording is not part of the contract.

const (
	// LocaleCodeEmpty means the explicit locale string is empty. Caller
	// absence is not an empty string; default selection belongs to the later
	// catalogue resolver.
	LocaleCodeEmpty LocaleCode = "empty_locale"
	// LocaleCodeTooLong means the input or its canonical form exceeds
	// [MaxLocaleCharacters].
	LocaleCodeTooLong LocaleCode = "too_long"
	// LocaleCodeNonASCII means the input contains a non-ASCII byte.
	LocaleCodeNonASCII LocaleCode = "non_ascii"
	// LocaleCodeMalformed means the input does not match the profile's
	// hyphen-separated ASCII BCP-47 grammar.
	LocaleCodeMalformed LocaleCode = "malformed_locale"
	// LocaleCodeDuplicateVariant means one variant subtag appears twice.
	LocaleCodeDuplicateVariant LocaleCode = "duplicate_variant"
	// LocaleCodeDuplicateSingleton means one extension singleton appears twice.
	LocaleCodeDuplicateSingleton LocaleCode = "duplicate_singleton"
	// LocaleCodeReservedExtlangPosition means a second or third extlang
	// position was used; RFC 5646 permanently reserves those positions.
	LocaleCodeReservedExtlangPosition LocaleCode = "reserved_extlang_position"
	// LocaleCodeExtlangPrefixMismatch means a registered extlang does not
	// follow its registered Prefix primary language.
	LocaleCodeExtlangPrefixMismatch LocaleCode = "extlang_prefix_mismatch"
	// LocaleCodeUnsupportedRegistryVersion means an authored value is not
	// recognized in the pinned registry snapshot. It is recoverable and says
	// nothing about validity in a later registry.
	LocaleCodeUnsupportedRegistryVersion LocaleCode = "unsupported_registry_version"
)

func LocaleErrorCode added in v0.84.0

func LocaleErrorCode(err error) LocaleCode

LocaleErrorCode returns the first stable locale issue code, or "" when err is not a locale refusal.

type LocaleError added in v0.84.0

type LocaleError struct {
	Issues []LocaleIssue `json:"issues"`
}

LocaleError is the aggregate, recoverable refusal returned by LocaleResult.Err.

func (*LocaleError) Error added in v0.84.0

func (e *LocaleError) Error() string

func (*LocaleError) Recoverable added in v0.84.0

func (e *LocaleError) Recoverable() bool

Recoverable reports whether retrying with corrected input or a later registry snapshot can succeed. Every refusal produced by this profile is recoverable.

type LocaleIssue added in v0.84.0

type LocaleIssue struct {
	Code     LocaleCode `json:"code"`
	Subtag   string     `json:"subtag,omitempty"`
	Snapshot string     `json:"snapshot,omitempty"`
	Message  string     `json:"message"`
}

LocaleIssue is one structured locale refusal. Subtag is the offending subtag when there is one; Snapshot names the pinned registry File-Date for LocaleCodeUnsupportedRegistryVersion.

func (LocaleIssue) Error added in v0.84.0

func (i LocaleIssue) Error() string

type LocaleResult added in v0.84.0

type LocaleResult struct {
	Accepted        bool          `json:"accepted"`
	Tag             string        `json:"tag,omitempty"`
	PrimaryLanguage string        `json:"primaryLanguage,omitempty"`
	Issues          []LocaleIssue `json:"issues,omitempty"`
}

LocaleResult is the outcome of one locale operation. Accepted is true only when Tag is canonical. PrimaryLanguage is the genuine regular primary language of the canonical tag, or "" for a private-use-only tag and for an irregular grandfathered tag without a replacement. Tag is also the canonical comparison key: equivalent spellings collide on it, so catalogue admission can reject duplicate tags before selection.

func AdmitAuthoredLocale added in v0.84.0

func AdmitAuthoredLocale(input string) LocaleResult

AdmitAuthoredLocale admits and canonicalizes one authored `/2` locale field (a sidecar default, a catalogue reference or a catalogue document locale). Every language, script, region, variant, registered extlang and extension singleton must exist in the pinned registry snapshots; recognized private-use ranges are admitted too. An unknown but well-formed value is a recoverable LocaleCodeUnsupportedRegistryVersion naming the snapshot, never a silent rewrite and never a claim about a future registry.

func NormalizeVisitorLocale added in v0.84.0

func NormalizeVisitorLocale(input string) LocaleResult

NormalizeVisitorLocale normalizes one visitor request. Syntactically well-formed unknown values are preserved for the later exact / primary / fallback selection instead of being rejected merely because the pinned snapshot lacks them. Malformed syntax is a structured refusal, never an ambient browser language. A registered extlang still has to match its registered Prefix, and reserved extlang positions stay invalid.

func (LocaleResult) Err added in v0.84.0

func (r LocaleResult) Err() error

Err returns nil for an admitted tag or an aggregate recoverable LocaleError.

type LogSourceTarget

type LogSourceTarget struct {
	Source string
	Stream string
	Filter []NamedValue
}

LogSourceTarget is the generic log reader grid.

type MatchDecision added in v0.83.0

type MatchDecision struct {
	Verdict MatchVerdict
	Reason  string
}

MatchDecision is the result of one pure match. Reason is stable and machine-readable; human wording is the runtime's.

func MatchCheckpointEnvelope added in v0.83.0

func MatchCheckpointEnvelope(
	wait ActiveWait,
	envelope CheckpointEnvelope,
	authority ProjectAuthority,
) MatchDecision

MatchCheckpointEnvelope compares every envelope field with the explicit active wait. Only a validated, fully consistent, fully matching pass may be consumed. The validation envelope type has no reference/Test namespace field, so such a payload is an unknown-field refusal rather than a match.

func MatchRetainedCompletion added in v0.83.0

func MatchRetainedCompletion(
	record CompletionRecord,
	wait ActiveWait,
	authority ProjectAuthority,
) MatchDecision

MatchRetainedCompletion decides whether a stored completion may satisfy a revisit with identical pins, checkpoint and live authority.

type MatchVerdict added in v0.83.0

type MatchVerdict string

MatchVerdict is a pure matching decision. Consuming, retaining for revisit, pausing/scheduling and authority lifecycle remain runtime owner work.

const (
	// MatchConsume means the envelope satisfies the active wait and may be
	// consumed once by the runtime.
	MatchConsume MatchVerdict = "consume"
	// MatchRevisit means a retained execution completion satisfies the same
	// wait without a new envelope, resubmission or replayed external effect.
	MatchRevisit MatchVerdict = "revisit"
	// MatchNoMatch means wrong, stale, duplicate, non-passing or unvalidated
	// input: do nothing and keep waiting.
	MatchNoMatch MatchVerdict = "no-match"
)

type NamedValue

type NamedValue struct {
	Name  string
	Value Value
}

NamedValue is one entry of a parameters, key or filter object. Entries are kept sorted by name so normalized projections are deterministic.

type PackageInventory added in v0.83.0

type PackageInventory struct {
	Ref    PackageReference
	Assets []AssetReference
	Cases  []string
}

PackageInventory is the owner-established inventory of one admitted package.

type PackageReference added in v0.83.0

type PackageReference struct {
	ID       string
	Revision Integer
	Path     string
	SHA256   string
	Bytes    Integer
}

PackageReference pins the immutable fictional training package. It carries the same three asset fields plus the package's own ID and revision.

func (PackageReference) Asset added in v0.83.0

func (p PackageReference) Asset() AssetReference

Asset returns the package's asset-reference view.

func (PackageReference) Equal added in v0.83.0

func (p PackageReference) Equal(other PackageReference) bool

Equal reports field-for-field equality of two package references.

func (PackageReference) VerifyBytes added in v0.83.0

func (p PackageReference) VerifyBytes(data []byte) error

VerifyBytes checks supplied package bytes against the package reference.

type PanelOpenCondition

type PanelOpenCondition struct {
	Panel string
}

PanelOpenCondition observes a panel belonging to the target asset.

type ParameterValueCondition

type ParameterValueCondition struct {
	Name   string
	Equals *Scalar
}

ParameterValueCondition observes a query, board or card parameter.

type ProjectAuthority added in v0.83.0

type ProjectAuthority interface {
	// BindProject admits a canonical project URL or reference spelling and
	// reports the owner's verdicts.
	BindProject(raw string) (ProjectBinding, error)
	// AdmitProject admits an opaque project-reference JSON value, as carried by
	// an external checkpoint envelope, and returns only its snapshot.
	AdmitProject(raw []byte) (ProjectIdentity, error)
	// EqualProject is the owner's full identity equality; this package never
	// compares opaque identities by itself.
	EqualProject(a, b ProjectIdentity) bool
}

ProjectAuthority is the trusted opaque project-identity adapter port. The production Apps adapter reuses the owning project-context normalization; a test double only proves wiring, never authority.

type ProjectBinding added in v0.83.0

type ProjectBinding struct {
	Identity ProjectIdentity
	// CanonicalURL is the owner's one canonical address of the project.
	CanonicalURL string
	// Public is the owner-established public-scope verdict. A URL spelling never
	// implies it.
	Public bool
	// Commit is the exact lowercase 40-hex commit the reference pins, or "" when
	// the reference does not name an immutable Git commit (a branch, HEAD, the
	// default branch or a non-Git source).
	Commit string
	// DigestAddressed reports whether the source serves exact bytes by content
	// digest (cloud/local), which is the only valid content pin for it.
	DigestAddressed bool
}

ProjectBinding is the owner's admission verdict for one project URL or reference. Only the owner adapter may populate it; this package only reads the verdicts the training contracts need.

type ProjectIdentity added in v0.83.0

type ProjectIdentity struct {
	Value any
}

ProjectIdentity is an opaque snapshot owned by the injected ProjectAuthority. This package never interprets Value, never builds a canonical project serialization and never compares identities itself.

type PublicDataProviderTarget

type PublicDataProviderTarget struct {
	Provider string
}

PublicDataProviderTarget is a provider's OVDB Directory entry.

type QueryRunCondition

type QueryRunCondition struct {
	MinRows *Integer
}

QueryRunCondition observes a completed saved-query run.

type QueryTarget

type QueryTarget struct {
	QueryID    string
	Parameters []NamedValue
}

QueryTarget is a saved query with optional parameter values. It never runs the query.

type RecordSelectedCondition

type RecordSelectedCondition struct {
	Field  string
	Equals *Scalar
}

RecordSelectedCondition observes a selected record or query result row.

type RegistryAdmission added in v0.83.0

type RegistryAdmission struct {
	Route  *RouteDescriptor
	Issues []Issue
}

RegistryAdmission is the owner-context admission outcome. Route is non-nil only when the alias may resolve.

func AdmitStoryChapter added in v0.83.0

func AdmitStoryChapter(
	entry StoryRegistryEntry,
	chapterID string,
	declared DeclaredWalkthrough,
	authority ProjectAuthority,
) RegistryAdmission

AdmitStoryChapter admits one public alias for one declared chapter. It requires an owner-established canonical immutable project address, an owner-established public scope, exact pin agreement and a declared chapter. A private or unknown scope, a branch/HEAD/default address, a historical pin mismatch or an undeclared chapter refuses; nothing falls back to latest.

func (RegistryAdmission) Err added in v0.83.0

func (r RegistryAdmission) Err() error

Err returns nil for an admitted alias or the aggregate recoverable refusal.

type RelatedTarget

type RelatedTarget struct {
	Source  string
	Table   string
	Key     []NamedValue
	Meaning string
}

RelatedTarget is a record with its Related panel open.

type Resolution added in v0.83.0

type Resolution struct {
	Admitted bool
	Bundle   *AdmittedTraining
	Issues   []Issue
}

Resolution is the outcome of owner-context admission. Admitted is true only when Bundle is non-nil; a partially resolved bundle is never exposed.

func ResolveTraining added in v0.83.0

func ResolveTraining(
	declaration *TrainingDeclaration,
	source SourceContext,
	authority ProjectAuthority,
	owners TrainingOwnerContext,
) Resolution

ResolveTraining binds a structurally valid /2 declaration to the resolved declaring-project context and to its owner-admitted package, asset, Case and challenge identities. Missing authority or context refuses; nothing is read.

func (Resolution) Err added in v0.83.0

func (r Resolution) Err() error

Err returns nil for an admitted bundle or the aggregate recoverable refusal.

type Result

type Result struct {
	Accepted    bool         `json:"accepted"`
	NewerClient bool         `json:"newerClient"`
	Digest      string       `json:"digest"`
	Definition  *Declaration `json:"definition,omitempty"`
	Issues      []Issue      `json:"issues,omitempty"`
}

Result is the outcome of one ordinary declaration parse. Definition is non-nil only when Accepted is true. Digest is always the SHA-256 of the exact bytes supplied.

func ParseDeclaration

func ParseDeclaration(directoryID string, data []byte) Result

ParseDeclaration validates one ordinary /1 declaration. directoryID is the `<id>` in `walkthroughs/<id>/walkthrough.json`; it must equal the declaration ID. The input slice is never retained or mutated. A /2 declaration is reported as Result.NewerClient exactly as before the explicit /2 entry point existed.

func (Result) Err

func (r Result) Err() error

Err returns nil for an admitted declaration, ErrNewerClient for a newer schema major, or an aggregate recoverable Error.

type RouteDescriptor added in v0.83.0

type RouteDescriptor struct {
	StoryID           string
	Revision          Integer
	ProjectURL        string
	WalkthroughID     string
	ChapterID         string
	ContentPin        ContentPin
	DeclarationSHA256 string
}

RouteDescriptor is the resolved public alias target. It names the declared project, walkthrough and chapter and retains the pins; it deliberately does not invent another walkthrough URL or router.

type Scalar

type Scalar struct {
	Kind   ScalarKind
	Bool   bool
	Number string
	Text   string
}

Scalar is one JSON scalar. Number retains the exact input lexeme.

type ScalarKind

type ScalarKind string

ScalarKind is the closed JSON scalar kind of a literal value.

const (
	ScalarNull    ScalarKind = "null"
	ScalarBoolean ScalarKind = "boolean"
	ScalarNumber  ScalarKind = "number"
	ScalarString  ScalarKind = "string"
)

type SourceContext added in v0.83.0

type SourceContext struct {
	Project           ProjectIdentity
	ContentPin        ContentPin
	DeclarationSHA256 string
}

SourceContext is the resolved declaring-project context. It is deliberately not a declaration field: the caller's owner adapter establishes the project identity, the exact content pin and the verified declaration digest.

type Step

type Step struct {
	ID        string
	Kind      string
	SegmentID string
	Title     string
	Why       string
	Hint      string
	Modes     []string
	Target    Target
	Done      Condition
	Capture   string
	Needs     string
	Support   Support
}

Step is one ordered walkthrough step. Kind and SegmentID exist only in the /2 training profile; ordinary /1 steps leave Kind empty.

type StoryRegistryEntry added in v0.83.0

type StoryRegistryEntry struct {
	StoryID           string
	Revision          Integer
	ProjectURL        string
	WalkthroughID     string
	ContentPin        ContentPin
	DeclarationSHA256 string
}

StoryRegistryEntry is the strict structural shape of one public story registry entry. Shape admission only: canonical immutable URL, public scope and chapter lookup are owner-established by AdmitStoryChapter.

func (StoryRegistryEntry) Projection added in v0.83.0

func (e StoryRegistryEntry) Projection() map[string]any

Projection is the stable normalized view used by the shared corpus.

type StoryRegistryResult added in v0.83.0

type StoryRegistryResult struct {
	Entry  *StoryRegistryEntry
	Issues []Issue
}

StoryRegistryResult is the outcome of the strict shape parse.

func ParseStoryRegistryEntry added in v0.83.0

func ParseStoryRegistryEntry(data []byte) StoryRegistryResult

ParseStoryRegistryEntry parses exactly one closed registry entry shape.

func (StoryRegistryResult) Err added in v0.83.0

func (r StoryRegistryResult) Err() error

Err returns nil for a parsed entry or the aggregate recoverable refusal.

type Support

type Support string

Support is the admission status of a target, condition or step.

const (
	// SupportSupported is a fully validated /1 variant.
	SupportSupported Support = "supported"
	// SupportNeedsNewer is an unknown target/condition kind retained only so
	// the rest of the walkthrough stays usable. Its opaque body is not exposed
	// or executed.
	SupportNeedsNewer Support = "needs-newer"
)

type TableRecordTarget

type TableRecordTarget struct {
	Source string
	Table  string
	Key    []NamedValue
}

TableRecordTarget is a table of a project source, optionally with a record open.

type Target

type Target struct {
	Kind               string
	Supported          bool
	TableRecord        *TableRecordTarget
	Query              *QueryTarget
	Board              *BoardTarget
	Card               *CardTarget
	Related            *RelatedTarget
	LogSource          *LogSourceTarget
	PublicDataProvider *PublicDataProviderTarget
	Incident           *IncidentTarget
	Check              *CheckTarget
	None               *struct{}
	Challenge          *ChallengeTarget
	TrainingCase       *TrainingCaseTarget
}

Target is one closed-registry target variant. Exactly the pointer matching Kind is populated for a supported kind; an unknown kind has Supported false and no variant data.

type TrainingCaseTarget added in v0.83.0

type TrainingCaseTarget struct {
	ManifestCaseID  string
	TrainingPackage PackageReference
}

TrainingCaseTarget is existing generic Case presentation through a training adapter. TrainingPackage must equal the declaration's top-level package reference field for field.

type TrainingDeclaration added in v0.83.0

type TrainingDeclaration struct {
	Schema          string
	ID              string
	Version         Integer
	Title           string
	Summary         string
	TrainingPackage PackageReference
	Narrative       AssetReference
	Chapters        []Chapter
	Finish          Exit
	Revision        string
}

TrainingDeclaration is a structurally valid datatug-walkthrough/2 declaration. It is not a resolved admission: package, Case, challenge and source-context authority are established by ResolveTraining.

func (*TrainingDeclaration) Projection added in v0.83.0

func (d *TrainingDeclaration) Projection() map[string]any

Projection renders the stable, language-neutral normalized view of a /2 declaration used by the shared conformance corpus. It extends the ordinary projection with the package and narrative references, the step kind, the dialogue segment id and the checkpoint mapping.

func (*TrainingDeclaration) WalkthroughIdentity added in v0.83.0

func (d *TrainingDeclaration) WalkthroughIdentity() DeclaredWalkthrough

WalkthroughIdentity is the declared walkthrough identity used by registry admission: the ID, the exact revision and the ordered chapter IDs.

type TrainingOwnerContext added in v0.83.0

type TrainingOwnerContext interface {
	// AdmitPackage returns the exact admitted package and its declared asset and
	// Case inventory.
	AdmitPackage(ref PackageReference) (PackageInventory, error)
	// AdmitAsset admits one exact project-relative asset reference.
	AdmitAsset(ref AssetReference) error
	// AdmitChallenge resolves the exact challenge manifest through the challenge
	// owner. A manifest that has not passed the owning validator is not admitted.
	AdmitChallenge(challengeID string, revision Integer) (ChallengeBinding, error)
}

TrainingOwnerContext is the trusted validated-owner lookup port. It never reads files, loads a package document this package would have to invent, or falls back to an ordinary (non-training) service.

type TrainingResult added in v0.83.0

type TrainingResult struct {
	Accepted    bool                 `json:"accepted"`
	NewerClient bool                 `json:"newerClient"`
	Digest      string               `json:"digest"`
	Definition  *TrainingDeclaration `json:"definition,omitempty"`
	Issues      []Issue              `json:"issues,omitempty"`
}

TrainingResult is the outcome of one explicit /2 declaration parse. It is a structural admission only; owner-context admission is ResolveTraining.

func ParseTrainingDeclaration added in v0.83.0

func ParseTrainingDeclaration(directoryID string, data []byte) TrainingResult

ParseTrainingDeclaration validates one explicit datatug-walkthrough/2 declaration. It shares the ordinary JSON and variant machinery without widening ordinary /1 admission. The returned definition is structurally valid only: a parsed declaration is never claimed render-ready, and package, Case, challenge and source-context authority still require ResolveTraining.

func (TrainingResult) Err added in v0.83.0

func (r TrainingResult) Err() error

Err returns nil for an admitted declaration, ErrNewerClient for a later schema major, or an aggregate recoverable Error.

type Value

type Value struct {
	Captured string
	Literal  *Scalar
	Default  *Scalar
}

Value is either a literal scalar or a captured reference with its mandatory literal default.

func (Value) IsCaptured

func (v Value) IsCaptured() bool

IsCaptured reports whether the value references an earlier capture.

Jump to

Keyboard shortcuts

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