descriptor

package
v1.0.0-alpha.13 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 56 Imported by: 0

Documentation

Overview

Package descriptor is the internal twin of the public descriptor package: the no-execute builders (manifest, payload JSON Schema, capability declarations), predict, inspect and the request validators. It imports the public package for the result and envelope types it returns; the public package never imports it back. Predict stays header- and schema-only and must not import the execution layer (TestPredictNoExecutionImports).

Index

Constants

View Source
const (
	// ZoneCapable marks an operator whose slot accepts a per-slot `tz`
	// and resolves a zone through slot → request → options → UTC.
	ZoneCapable = "capable"

	// ZoneFollowing marks an overlay kind with no zone slot of its own
	// that inherits its host grouper's resolved zone.
	ZoneFollowing = "following"
)

Zone-capability values surfaced on the manifest `zone` key of an operator entry (descriptor.Operator.Zone) or an overlay kind entry (descriptor.OverlayCapability.Zone). An operator absent from the table is not zone-capable: the key is omitted and an explicit slot `tz` on it is refused.

View Source
const (
	ConventionCohenD    = "cohen1988_d"
	ConventionCohenEta2 = "cohen1988_eta2"
	ConventionCohenR    = "cohen1988_r"
	ConventionCohenW    = "cohen1988_w"
	ConventionCohenOR   = "cohen1988_or"
	ConventionCohenR2   = "cohen1988_r2"
	// ConventionGeorgeMalleryAlpha is George & Mallery's (2003) rule of
	// thumb for Cronbach's alpha.
	ConventionGeorgeMalleryAlpha = "georgemallery2003_alpha"
	// ConventionKaiserKMO is Kaiser's (1974) labelling of the
	// Kaiser-Meyer-Olkin measure of sampling adequacy.
	ConventionKaiserKMO = "kaiser1974_kmo"
)

Convention IDs referenced by built-in Interpretations.

View Source
const (
	ExampleReasonLayout        = "layout"
	ExampleReasonBuiltin       = "builtin"
	ExampleReasonDuplicate     = "duplicate"
	ExampleReasonMeta          = "meta"
	ExampleReasonName          = "name"
	ExampleReasonCategory      = "category"
	ExampleReasonDescription   = "description"
	ExampleReasonTags          = "tags"
	ExampleReasonIntents       = "intents"
	ExampleReasonOperators     = "operators"
	ExampleReasonCapabilities  = "capabilities"
	ExampleReasonBody          = "body"
	ExampleReasonOperatorsBody = "operators_body"
	ExampleReasonEdgeCoverage  = "edge_coverage"
)

Reasons carried in PULSE_EXTENSION_EXAMPLE_* details["reason"].

View Source
const (
	SkillReasonLayout        = "layout"
	SkillReasonBuiltin       = "builtin"
	SkillReasonDuplicate     = "duplicate"
	SkillReasonStem          = "stem"
	SkillReasonFrontmatter   = "frontmatter"
	SkillReasonName          = "name"
	SkillReasonDescription   = "description"
	SkillReasonKind          = "kind"
	SkillReasonOperator      = "operator"
	SkillReasonCategory      = "category"
	SkillReasonRequires      = "requires"
	SkillReasonSections      = "sections"
	SkillReasonBudget        = "budget"
	SkillReasonFence         = "fence"
	SkillReasonFenceCoverage = "fence_coverage"
	SkillReasonSee           = "see"
)

Reasons carried in PULSE_EXTENSION_SKILL_* details["reason"].

View Source
const (
	CoreOpen            = "open"             // Open
	CoreInspect         = "inspect"          // Inspect*, pulse_inspect
	CorePredict         = "predict"          // Predict*, pulse_predict
	CoreCountRecords    = "count_records"    // CountRecords
	CoreManifest        = "manifest"         // Manifest, pulse_manifest
	CorePayloadSchema   = "payload_schema"   // payload JSON Schema, pulse://schema
	CoreSkills          = "skills"           // skills list/get
	CoreExamples        = "examples"         // examples search/get
	CoreErrorsLookup    = "errors_lookup"    // errors lookup
	CoreCohortArtifacts = "cohort_artifacts" // CohortArtifacts
)

The always-present core surfaces.

View Source
const (
	IntentDescribe          = "describe"
	IntentCompareGroups     = "compare_groups"
	IntentRelationship      = "relationship"
	IntentDrivers           = "drivers"
	IntentChangeOverTime    = "change_over_time"
	IntentComposition       = "composition"
	IntentBenchmark         = "benchmark"
	IntentDistributionShape = "distribution_shape"
	IntentSegment           = "segment"
	IntentMeasureConstruct  = "measure_construct"
	IntentFlows             = "flows"
	IntentDataQuality       = "data_quality"
	IntentPrepare           = "prepare"
	IntentSimulate          = "simulate"
	IntentLookup            = "lookup"
)

The intent taxonomy: a small, closed set of question kinds, coarse enough that a non-statistician recognises one in their own question. Twelve are analytic (answered by operators); three route to tooling rather than operators (Analytic false). The taxonomy is static — it is not a feature, so a feature profile never prunes it.

View Source
const (
	// PurposePlainMax caps Purpose.Plain, in characters.
	PurposePlainMax = 140
	// PurposeQuestionsMin is the fewest Questions a Purpose may carry.
	PurposeQuestionsMin = 2
)

Purpose validity limits (binding for built-ins and, through the same ValidatePurpose, for extension registrations).

View Source
const (
	UseWhenSectionCap = 450
	ReadingSectionCap = 600
)

Hard caps on a generated section, in bytes (heading included).

View Source
const BuiltinFeatureSince = "1.0.0"

BuiltinFeatureSince is the Since every built-in feature carries: the v1.0.0 line is the baseline the feature table starts from.

View Source
const CrosstabFusionDisabledReason = "crosstab fusion disabled on this instance (Options.DisableCrosstabFusion)"

CrosstabFusionDisabledReason is the PredictResult.CrosstabFusionReasons entry reported when PredictOptions.DisableCrosstabFusion is set.

View Source
const DefaultDictionaryLimit = 100

DefaultDictionaryLimit is the default max entries shown for categorical dictionaries.

View Source
const FeatureForEach = "capability:for_each"

FeatureForEach is capability:for_each — the item fan-out: the `for_each` key on Window, Feature and Attribute. Exported because the MCP binder (nested for_each properties) reads it.

View Source
const FeatureModelSave = "capability:model_save"

FeatureModelSave is capability:model_save — the `save` key on a RegressionSpec and a ComposedRequest `fits` entry, which writes the fit as a model file. Exported for the MCP bound schema.

View Source
const FeatureModels = "capability:models"

FeatureModels is capability:models — the `models` key on a Request and a FacetRequest, which loads saved model files by name into the bound-model namespace. Exported for the MCP bound schema.

View Source
const FeatureMultiplicity = "capability:multiplicity"

FeatureMultiplicity is capability:multiplicity — the multiple- comparison correction surface: every `multiplicity` slot (Request, Test, OverlaySpec, ComposeOverlaySpec, ComposedRequest) and pulse.Options.DefaultMultiplicity. Exported because the root facade (DefaultMultiplicity refusal) reads it too.

View Source
const FeatureSetDigestPrefix = "fs1:"

FeatureSetDigestPrefix versions the feature_set_digest algorithm. A change to what the digest covers or how it is serialised bumps it.

View Source
const FeatureWeighting = "capability:weighting"

FeatureWeighting is capability:weighting — the row-weight surface: the request-root `weight`, every per-slot `weight`, and pulse.Options.DefaultWeight (.claude/reference/weighting.md, Feature profile). Exported because the root facade (DefaultWeight refusal) and the MCP binder (nested weight properties) read it too.

View Source
const GuidanceProseMinLen = 16

GuidanceProseMinLen is the shortest prose string (in runes) the prose ban checks. Shorter strings — intent labels such as "Describe data", band labels such as "small" — are generic phrases that legitimately collide with ordinary manifest descriptions, so banning them would flag coincidences rather than leaked guidance.

View Source
const KnownAsMax = 48

KnownAsMax caps one Purpose.KnownAs alias, in characters. An alias is a name ("anova", "chi-square test"), never a sentence.

View Source
const MatrixAuxP = "p"

MatrixAuxP is the built-in inferential matrix operators' p-value auxiliary key.

View Source
const PayloadSchemaFormatVersion = "1.1"

PayloadSchemaFormatVersion tracks the envelope format_version (see Envelope.FormatVersion / NewEnvelope). The published payload schema's $id embeds it; bump the two in lockstep. Guarded by TestPayloadSchema_VersionMatchesEnvelope.

View Source
const SharedPValue = "p-value"

SharedPValue is the shared rule-set key every p-value Interpretation cites through Interpretation.Shared.

Variables

This section is empty.

Functions

func AdvisoryCodes

func AdvisoryCodes() []string

AdvisoryCodes returns every registered PULSE_ADVISORY_* code, in rule order, as a fresh slice.

func AggregationMergeability

func AggregationMergeability(t types.AggregationType) descriptor.ComponentsMergeability

AggregationMergeability is the typed convenience that accepts a types.AggregationType directly so callers do not have to round-trip through string(...).

func AggregatorMergeability

func AggregatorMergeability(name string) descriptor.ComponentsMergeability

AggregatorMergeability returns the ComponentsMergeability declared in the built-in aggregator capability table for the operator named by name (e.g. "AGG_SUM"). Unknown names return the zero-value empty string — callers should treat that as "no streaming guarantee" and either suppress per-chunk emission or fall back to terminal-only.

This is the one-shot lookup the streaming orchestrator (pulse.ProcessStreamResult) consults to decide whether to attach a per-chunk components map (Mergeable / Partial) or suppress it until the terminal chunk (None).

Lives in the descriptor package because the capability table is the single source of truth and predict already aliases the same lookup (aggregatorComponentSchemaIndex). The descriptor package stays no-execute — this helper reads only the static capabilities slice.

func AttributeMergeability

func AttributeMergeability(t types.AttributeType) descriptor.ComponentsMergeability

AttributeMergeability returns the ComponentsMergeability declared in the built-in attribute capability table for t, or "" when t declares no ComponentSchema (it emits no Response.Components.Attributes entry) or is unknown — the streaming projection then keeps the entry as-is.

func BandOf

func BandOf(in descriptor.Interpretation, v float64) (label string, ok bool)

BandOf returns the label of the band of in that v falls in, reading v the way the bands are declared: |v| when in.Abs, and max(v, 1/v) when in.Convention is the citation of a registered SymmetricLog convention (an odds ratio of 0.1 reads like one of 10). ok is false when in has no bands or no convention, v is not finite (or a SymmetricLog ratio is not positive), or no band holds v.

func BuildManifest

func BuildManifest() *descriptor.Manifest

BuildManifest constructs the deterministic FULL-registry Manifest: the view of a profile-free instance with no extensions, carrying that instance's feature_set_digest. The unprofiled CLI serves it. The result is safe to cache and share across goroutines; callers do not mutate the returned slices.

func BuildManifestForInstance

func BuildManifestForInstance(inst *InstanceSnapshot) *descriptor.Manifest

BuildManifestForInstance constructs the Manifest of ONE instance: only what inst offers. A nil or unscoped instance yields the full registry (plus inst's extension projection), so the profile-free view is byte-identical to BuildManifest apart from the extensions it carries.

On a scoped instance:

  • components, tests / post_tests, regressions, overlays, components_schemas and cohort_types[].compatible_* list only enabled operators; extensions lists only visible registrations (pulse.New already dropped the hidden ones);
  • commands / operations are filtered through the command binding table and mcp_tools through the MCP tool binding table;
  • the facet, process_chain, join, crosstab, export and import blocks are OMITTED when their capability is hidden, and the operator / format lists inside a present block are filtered;
  • synth_distributions is empty when capability:synth is hidden;
  • every remaining prose string (descriptions, hints, rule lists) is scrubbed of sentences naming a hidden operator, MCP tool or slot token (slotTokens, e.g. p_adjusted without capability:multiplicity).

skills and the examples count / categories / tags follow the instance's Discovery prune (a skill or example for a hidden surface is absent) but are not prose-scrubbed; the error-code lists are filtered in assembleManifest.

func BuildManifestForIntent

func BuildManifestForIntent(inst *InstanceSnapshot, intent string) (*descriptor.Manifest, error)

BuildManifestForIntent constructs the instance's manifest narrowed to ONE intent — what ManifestForIntent, pulse_manifest {intent} and `pulse --json --intent` serve. The intent resolves through checkIntent (an unknown or hidden one is PULSE_RECOMMEND_INTENT_UNKNOWN, details.valid = the instance's intents). Starting from BuildManifestForInstance(inst), so it composes with a feature profile:

  • the operator-keyed sections (components.*, tests, post_tests, regressions, matrices, overlays) keep only entries whose intents name the intent;
  • skills is SkillsForIntent's ranked list;
  • crosstab stays only when a remaining aggregator can be a crosstab cell (its operator lists narrowed to the remaining aggregators), matrix only when a matrix operator remains;
  • the fixed sections (descriptor.ScopedManifestElidedKeys) are dropped, zero in the Go value and absent on the wire — components_schemas among them, since every remaining operator carries the same schema as its own component_schema;
  • version, digests, intents, return_presets and the examples counts are kept; scope carries the full intent record and elided lists, sorted, every key dropped here that the unscoped manifest carries.

func BuildManifestWithExtensions

func BuildManifestWithExtensions(snap *ExtensionsSnapshot) *descriptor.Manifest

BuildManifestWithExtensions constructs a full-registry Manifest that includes the embedder-registered extension surface (an UNSCOPED instance over snap). A nil snapshot is equivalent to BuildManifest — the Extensions block becomes the empty manifest (every category is `[]`, not `null`).

descriptor stays free of service / processing imports; the snapshot is the only way the live ExtensionRegistry reaches this layer.

func BuildPayloadSchema

func BuildPayloadSchema() json.RawMessage

BuildPayloadSchema returns the bundled JSON Schema (draft 2020-12) describing every public Pulse payload — the request envelopes (Request, ComposedRequest, ChainRequest, FacetRequest, SampleRequest) and the universal output Envelope plus every operation result it can wrap.

The schema is generated three ways, not hand-maintained:

  1. Reflection over the Go payload structs (descriptor stays free of internal/service/ and internal/processing/ imports — only types + this package). A struct field change surfaces as a golden diff, forcing a regen.
  2. Registry-injected enums: the high-cardinality discriminant enums (operator + overlay-kind + regression families) draw their value lists from types.All*Types() / AllOverlayKinds() / AllRegressionTypes(), so registering a new operator changes the schema and trips the gate.
  3. Hand-tuned strict unions for the two shapes reflection cannot express faithfully: OverlayRef (at-most-one populated arm) and OverlayPayload (shape-discriminated scalar/series/matrix, plus non-nesting named parts).

v1 boundaries (documented in docs/src/contract/payload-schema.md):

  • Operator Params (json.RawMessage) stay an open object — there is no central declarative per-operator input-param source (even the MCP binder treats params as open); the per-operator param schema lives alongside each operator's processor.
  • The small closed mode enums (OverlayScope, OverlayShape, CrosstabNormalize, etc.) are typed as plain strings: they have no All*() registry helper, so a hardcoded enum here would rot silently.

The result marshals deterministically: every object is a map (encoding /json sorts keys) and every enum / required list is sorted, so the golden is stable across runs and Go versions.

It is the profile-free view: BuildPayloadSchemaForInstance(nil).

func BuildPayloadSchemaForInstance

func BuildPayloadSchemaForInstance(inst *InstanceSnapshot) json.RawMessage

BuildPayloadSchemaForInstance returns the payload schema of ONE instance — only what inst offers:

  • the registry-backed enums (operator, overlay-kind and regression families) list only enabled names;
  • the capability-gated slots inst hides (HiddenSlotKeys: Request.crosstab / joins / overlays, the overlays slot of each other request root and of each result root) are not properties;
  • a root whose capability is hidden (compose, process_chain, facet, sample, lookup, recommend, explain) is not an entry point;

and every def reachable only through something omitted is absent, because defs are registered by walking from the surviving entries. Request, Response and Envelope are always present. $id is unchanged; the root $comment carries the instance's feature_set_digest (the same value its manifest carries). A nil / unscoped instance is the full registry view BuildPayloadSchema serves.

func BuiltinInterpretations

func BuiltinInterpretations() map[string][]descriptor.Interpretation

BuiltinInterpretations returns a copy of the built-in Interpretation registry.

func BuiltinKnownAs

func BuiltinKnownAs() map[string]string

BuiltinKnownAs returns every built-in alias, folded, mapped to the operator declaring it — the full registry, profile-blind. Extension validation reads it so an embedder alias never shadows a built-in.

func BuiltinPurposes

func BuiltinPurposes() map[string]descriptor.Purpose

BuiltinPurposes returns a copy of the built-in Purpose registry.

func ChainOverlayArrayValuedRefusal

func ChainOverlayArrayValuedRefusal(req *types.ChainRequest, inst *InstanceSnapshot, stage0 *encoding.Schema) error

ChainOverlayArrayValuedRefusal refuses a whole-chain overlay that scores an array-valued aggregation on its target or reference stage (only the last stage can carry one: an array-valued stage may not feed another) — the one params.field names on a kind seriesfield.AppliesChain accepts, else the stage's Aggregations[0] (any aggregation on a crosstab stage). A spec whose stage references do not resolve is left to the stage-reference rules. stage0 (nil: no judgement) is the schema stage 0 executes over (the cohort's, or the joined one) for the categorical-code rule; a later stage is judged against the schema synthesised from the stage before it (synthChainSchema: group key columns categorical, aggregation outputs f64) plus the code columns it inherits (vectors.AggregationKinds.ChainCodeColumns — an output column an upstream code-emitting aggregation wrote is still a code), so the stages must carry their smart defaults by then. Nil when no overlay reads one.

func ChainStageInputSchema

func ChainStageInputSchema(stages []*types.Request, idx int, stage0 *encoding.Schema, kinds vectors.AggregationKinds) *encoding.Schema

ChainStageInputSchema is the exported chainStageInputSchema: the schema chain stage idx of stages (as executed) runs over — stage0 for stage 0, else the one synthesised from the stage before it; nil when stage0 is nil. kinds is the instance's aggregation view. The runtime's whole-chain overlay barrier hands it to the series value narrowing so an expanded element column resolves against the same members predict-chain reads.

func ChainStageOverlayRefusal

func ChainStageOverlayRefusal(stages []*types.ChainStage, inst *InstanceSnapshot) error

ChainStageOverlayRefusal refuses the first ProcessChain stage whose own Request.Overlays carries a spec its stage cannot run, located by details.stage. Predict (ValidateChain) and the chain runtime (service.processChain) both run it after the stages' models, before the cohort opens, so both refuse with one code, message and details (predict-chain used to judge none of a stage's own overlays). Per spec, in order, keyed on the kind as the instance routes it:

  • a MATRIX_RESULT kind: that host reaches a process request and a Compose slot only (overlayhost.StageRefusal);
  • a kind that does not run on Request.Overlays (overlayhost.Refusal);
  • a kind over the wrong Process shape of the stage's authored request (overlayhost.ShapeRefusal);
  • a Ref or Scope its host's shared rule refuses (overlayhost.ProcessSpecRefusal: the SERIES table on a grouped stage; on a SCALAR stage every Process kind, by overlayhost.ScalarSpecRefusal). The runtime stage hooks raise the same three, unlocated.

func CollectProse

func CollectProse(v any) []string

CollectProse returns every prose string reachable from v — string fields, slice elements and map values — skipping identifier fields (proseIdentifierFields). Map keys are never prose. Order follows declaration order with map values sorted.

func ComposeOverlayArrayValuedRefusal

func ComposeOverlayArrayValuedRefusal(overlays []types.ComposeOverlaySpec, requests []*types.Request, labels []string, inst *InstanceSnapshot, slotSchema func(j int) *encoding.Schema) error

ComposeOverlayArrayValuedRefusal refuses a Compose overlay that scores (on its reference, a target, or — no targets — every slot) an array-valued aggregation: the one params.field names on a kind seriesfield.AppliesCompose accepts, else the slot's Aggregations[0] (any aggregation on a crosstab slot). labels are the slots' labels (index-aligned with requests, defaults applied). slotSchema (nil: none) returns the schema slot j executes over (its cohort's, or the joined one; nil when unreadable) for the categorical-code rule; it is called only for a slot whose scored aggregation is input-valued. Nil when no overlay reads one; a kind the instance hides is left to the kind rule.

func ComposeOverlayHiddenFloorRefusal

func ComposeOverlayHiddenFloorRefusal(overlays []types.ComposeOverlaySpec, requests []*types.Request, labels []string, defaultWeight *types.WeightSpec, inst *InstanceSnapshot, disabled func(*types.Request) bool) error

ComposeOverlayHiddenFloorRefusal is the Compose-host half of the components-disabled refusal (weighting.HiddenFloorRefusal, weighting-inferential E3-S3): a kind that scales a slot's Σw by the n_eff on its floor (OVERLAY_PROP_Z_CELL, OVERLAY_PROP_Z_PANEL, OVERLAY_CHISQ_VS_REF) over a slot whose crosstab cell is weighted under kind probability (any source: the cell's own weight, the request's, defaultWeight) and whose components are disabled — disabled(slot) is the runtime's effective setting. Without the floor the slot reads as unweighted and its Σw as the sample size. The proportion kinds test every slot they read (reference and targets); OVERLAY_CHISQ_VS_REF reads the reference only as a distribution, so only its targets count. requests and labels are parallel (labels defaulted); the runtime (Service.applyComposeOverlays) and ValidateComposeWithOptions both call it with the raw slots.

func ComposeOverlayTwoSampleInputsRefusal

func ComposeOverlayTwoSampleInputsRefusal(overlays []types.ComposeOverlaySpec, requests []*types.Request, labels []string, inst *InstanceSnapshot, disabled func(*types.Request) bool) error

ComposeOverlayTwoSampleInputsRefusal is the one rule for WHERE a Compose two-sample overlay (OVERLAY_T_VS_REF / OVERLAY_Z_VS_REF over grouped slots, OVERLAY_T_CELL / OVERLAY_Z_CELL over crosstab slots) gets each side's mean, variance and n, and the refusal of every route on which it gets none. Per slot the overlay reads (reference and targets; every slot when it names no target, for the components leg):

  • grouped slot, scored aggregation AGG_WELFORD (a payload the kind reads, overlayReadsPayload): the moments ride the slot's per-group components (processing.narrowSeriesHost). Components disabled — disabled(slot) is the runtime's effective gate (EffectiveDisableComponents; a `return` never removes them, the Compose veto keeps every sub-part of a slot an overlay names) — left the layer EMPTY with no error (U46 E4-S13): PULSE_OVERLAY_COMPONENTS_REQUIRED, reason components_disabled.
  • grouped slot, scalar scored aggregation: the row value is the side's mean; its variance and n come from params (twosample.Inputs). Absent, they were variance 1, n 2 (U46 E4-S16): PULSE_OVERLAY_PARAM_MISSING, reason params_missing, Details.side + Details.params naming the side and its keys.
  • crosstab slot under a cell kind: a cell whose components carry mean and variance (cellCarriesMoments: AGG_WELFORD, AGG_VARIANCE, AGG_STDDEV, or an extension declaring both keys) with components enabled reads them; any other cell is a scalar mean and needs the side's params, as above.
  • crosstab slot under a vs-ref kind: the handler reads grouped rows and a crosstab has none — the layer came back empty (U46 E4-S16): PULSE_OVERLAY_REF_INCOMPATIBLE_WITH_SHAPE, Details {shape: matrix, shapes: [series]}.
  • grouped slot under a cell kind: PULSE_OVERLAY_SLOT_NOT_CROSSTAB (kindRequiresMatrixCompose) owns it.

The side a slot plays is the reference for spec.Reference and the target for every label in spec.Targets. A spec with no targets is judged for the components leg only (on every slot); its params are left to the target rule. The scored aggregation resolves as ComposeOverlayArrayValuedRefusal's (params.field, else Aggregations[0]); an array-valued or other non-scalar one is that rule's.

Details carry {overlay_index, kind, slot, host, aggregation, label} plus the route's reason (and side / params). The runtime (Service.applyComposeOverlays) and ValidateComposeWithOptions (gate 2e) call it with the raw slots; the runtime re-runs it at fold time against the components each slot actually returned (an engine invariant, PROCESSING_INTERNAL). A kind the instance hides is left to the kind rule.

func ComposeOverlayWeightRefusal

func ComposeOverlayWeightRefusal(overlays []types.ComposeOverlaySpec, requests []*types.Request, labels []string, defaultWeight *types.WeightSpec, inst *InstanceSnapshot) error

ComposeOverlayWeightRefusal is the Compose-host half of the overlay weight refusal, keyed off the same per-kind class as the per-request rule (overlayWeightClass). A ComposeOverlaySpec carries no weight of its own, so a refused kind is PULSE_WEIGHT_UNSUPPORTED when a slot it reads — its reference or a target, every slot when Targets is empty — has a request-level or instance default weight applied to an aggregation or crosstab cell; a frequency-only kind is refused only when that weight is of kind probability; a kind weighted under both kinds, and a descriptive one, never. The opt-out is on the host: `weight: null` on the slot's weighted aggregations (the overlay then compares unweighted figures). requests and labels are parallel (labels already defaulted); the runtime (Service.applyComposeOverlays) and ValidateComposeWithOptions both call it with the RAW slots, so they refuse identically. Details: {slot: overlays[i], operator, field, host: requests[j].<slot>}, plus `reason` (and `alternative`) for a permanent refusal and `kind` / `supported_kinds` for a frequency-only one.

func CoreSurfaces

func CoreSurfaces() []string

CoreSurfaces returns the always-present core surface names in a stable order. They are not features.

func CrosstabCellWeightBasis

func CrosstabCellWeightBasis(req *types.Request, defaultWeight *types.WeightSpec, inst *InstanceSnapshot) weighting.Basis

CrosstabCellWeightBasis is crosstabCellWeightBasis over the engine's own inputs — the instance default weight (pulse.Options.DefaultWeight) and snapshot — for the service's compute plan, which decides with it whether a kept request overlay reads its host's weighted floor (OverlayReadsHostComponents). It resolves the cell exactly as the runtime stamps it (processing.StampWeightsWith), so it names the basis CrosstabHostView.withCellWeight records.

func CrosstabFusion

func CrosstabFusion(req *types.Request, schema *encoding.Schema, snap *ExtensionsSnapshot, inst *InstanceSnapshot) (bool, []string)

CrosstabFusion reports whether req is eligible for the engine's fused in-decode crosstab path, and every reason it is not — the no-execute twin of processing.CanFuseCrosstab. Both run the one shared rule, crosstabfuse.Decide: the runtime over its ExtensionRegistry, this over the read-only ExtensionsSnapshot plus the instance feature set, so a profile-hidden operator answers exactly as a never-registered one.

Eligibility only: Options.DisableCrosstabFusion is a dispatch-time override the engine checks outside the rule, and it does not change this answer; Predict applies it on top (PredictOptions. DisableCrosstabFusion → PredictResult.CrosstabFusable false). The one fact this arm cannot know is whether a keyable grouper's factory accepts its params; the runtime declines such a request and the buffered path then refuses it with a coded error, so the request errors on either answer.

Callers resolve smart defaults first, exactly as the engine does before it dispatches. snap, inst and schema may each be nil.

func EffectSizeKeysByTest

func EffectSizeKeysByTest() map[string][]string

EffectSizeKeysByTest returns a copy of the declared per-family effect size keys. Some keys are conditional (TEST_CHISQ phi only on a 2x2 table; TEST_T cohens_d on every variant, from different formulas), so a probe must pick fixtures that trigger each.

func EffectiveDisableComponents

func EffectiveDisableComponents(req *types.Request, engine bool) bool

EffectiveDisableComponents is the Response.Components COMPUTE gate for req on an engine whose Options.DisableComponents is engine — the one rule the runtime (Service.effectiveDisableComponents) and predict (PredictOptions.componentsDisabled) share. A request's explicit disable_components wins (an explicit `false` re-opens an engine-off gate, as before `return` existed); else the engine switch. A request `return` block never re-opens it: an engine DisableComponents sticks whatever the request shapes.

func EffectiveReturn

func EffectiveReturn(req *types.Request, inst *InstanceSnapshot) *types.Return

EffectiveReturn is the `return` block a request resolves through — the precedence both predict and the runtime apply:

  1. the request's own block, when set, REPLACES every instance layer;
  2. else the instance default (inst.DefaultReturn: Options.DefaultReturn, else the feature profile's `return`);
  3. else none (nil) — the library default `full`, identity.

The DisableComponents shorthands then merge as `exclude: ["components"]` (exclude wins over any include) exactly when the components compute gate is off for this request (EffectiveDisableComponents): a request `disable_components: true`, or the engine Options.DisableComponents unless the request sets `disable_components: false` — on whichever layer supplies the block, a request block included (it never re-opens the engine gate); an explicit `false` adds nothing and never re-includes what a block excludes or a preset omits. With no block on any layer the shorthands add nothing either — DisableComponents stays the compute gate alone, so its wire form is byte-identical to the pre-`return` baseline (no `returned` marker). The result is a fresh copy; req and inst are never mutated.

func ErrorCodeVisible

func ErrorCodeVisible(inst *InstanceSnapshot, c errors.Code) bool

ErrorCodeVisible reports whether inst lists code c.

func ErrorLookup

func ErrorLookup(inst *InstanceSnapshot, code string) (errors.LookupResult, bool)

ErrorLookup is errors.Lookup as inst sees it.

func ErrorsByDomain

func ErrorsByDomain(inst *InstanceSnapshot, domain string) []errors.LookupResult

ErrorsByDomain is errors.ByDomain as inst sees it.

func ErrorsSearch

func ErrorsSearch(inst *InstanceSnapshot, query string) []errors.LookupResult

ErrorsSearch is errors.Search as inst sees it: it scores the rendered result of every visible code, never the stripped fixups.

func EstimateCrosstabCells

func EstimateCrosstabCells(spec *types.CrosstabSpec, schema *encoding.Schema, inst *InstanceSnapshot, records int64) (int64, bool)

EstimateCrosstabCells is the schema-only upper bound on a crosstab's grid — rows x cols, the figure both runtime arms check against MaxCrosstabCells (buffered after PartitionByAxis, fused at the axis-key interners). Each axis is the product of its positions' EstimateGroups bounds, clamped by records when records >= 0 unless a position fans out (GROUP_SET_PER_ELEMENT). False when any position's cardinality is unknown. The product is a Cartesian upper bound — the runtime grid holds only the axis keys the data produces.

func EstimateFacetMemory

func EstimateFacetMemory(req *types.FacetRequest, schema *encoding.Schema, in LimitInputs) (int64, bool)

EstimateFacetMemory is the upper bound, in bytes, of a rich facet's resident state: a streaming scan (the payload, per limits.EstimateMemory) with one bucket per faceted accumulator (Fields + AdditiveFields). A field without a dictionary keeps per-value state (its distinct values; a second slot when numeric_percentiles buffers its values), bounded by the record count. False when the record count is unknown.

func EstimateGroups

func EstimateGroups(groups []*types.Group, schema *encoding.Schema, inst *InstanceSnapshot, records int64) (int64, bool)

EstimateGroups is the schema-only upper bound on the distinct group buckets a grouped request can mint — the figure the MaxGroups rule grades. Two or more groupers mint composite keys, so the bound is the PRODUCT of every grouper's own bound (the crosstab-axis rule, crosstabAxisEstimate): an upper bound, since the runtime emits only the combinations the data produces. False when the request is ungrouped or ANY grouper's keys depend on the data (GROUP_RANGE, GROUP_DATE, GROUP_ROUNDED, GROUP_SET_VALUE, extension groupers, a categorical grouper over a numeric field).

Per grouper (groupEstimate):

  • Built-in dictionary / boolean / include / quantile / k-means cases wrap vectors.EstimateBuckets, the estimator the matrix and return-size predictions share.
  • GROUP_DATE_RANGES: the range count (inline `ranges`, or the named table's range_count from the instance snapshot) plus the unmatched bucket. An unknown table yields no estimate (the runtime reports PULSE_RANGE_TABLE_UNKNOWN).

records >= 0 clamps the product (a run cannot mint more buckets than it has records) unless a grouper fans one record into several keys (GROUP_SET_PER_ELEMENT): then only the dictionary sizes bound it.

func EstimateMemory

func EstimateMemory(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, in LimitInputs) (int64, bool)

EstimateMemory is the upper bound, in bytes, of the resident state req builds over schema — limits.EstimateMemory on the arm MemoryArm picks, with the record counts from in and the request-shaped figures from the shared estimators:

  • buckets: EstimateGroups (clamped by records); a grouper of unknown cardinality is bounded by the record count; 1 ungrouped.
  • cells: EstimateCrosstabCells, else rows x cols bounded by the record count when an axis is unknown.
  • matrices: MatrixStateBytes over the merge blocks (per shard) and the matrix bucket bound — EstimatedBytes in PredictResult.Matrices — or records x accumulator bytes when the buckets are unknown (each populated block-bucket pair holds at least one record).
  • fan-out: FanOutMultiplicity over the groupers and both crosstab axes — a GROUP_SET_PER_ELEMENT record lands in one bucket per selected member, so per-value state, a buffered matrix's row store and a buffered test's values scale with it.
  • tests: testMemory — an instance per tier-1 test per bucket, the split levels / contingency cells each keys, and every value a buffered (non-streamable) test keeps.
  • a join adds its build side, and the processor is fed the left count — exact only while no right key repeats; a repeating key's joined rows are judged apart (joinFanOutFinding at predict, JoinFanOutRefusal after the build).
  • a shard archive charges its byte length in place of records x stride when larger, and one schema decode, the canonical entry's (archiveTerms; an anchor-opened shard its archive's byte length alone); on the per-shard parallel arm (ShardFanOut) every shard's partial holds its own buckets — EstimateGroups clamped by that shard's records, or its records for an unknown grouper, 1 ungrouped — and per-value state over its records.

False when the record count (or a join's right count) is unknown. The model never sees filter selectivity or field projection, so the figure is an upper bound — calibrated in internal/service TestMemoryEstimate_Calibration.

func ExpandChainItems

func ExpandChainItems(req *types.ChainRequest, l limits.Limits) (*types.ChainRequest, error)

ExpandChainItems is ExpandRequestItems over every stage of a chain: the chain itself when no stage changes, else a shallow clone whose changed stages carry their expanded Request. A refusal is located by details.stage (RefusalAt).

func ExpandRequestItems

func ExpandRequestItems(req *types.Request, l limits.Limits) (*types.Request, []sweep.FanOut, *limits.Finding, error)

ExpandRequestItems is the item for_each expansion every surface runs before validating a Request — Service.Process (and through it every Compose slot), Service.ProcessChain per stage, Service.Materialize, Predict, the Compose and chain validators — so the item lists they judge and run cannot drift: sweep.ExpandItems with the MaxDerivedColumns preflight over l (the instance's effective limits), checked BEFORE any item renders. A request without a for_each comes back as req itself, after the same limit check over its plain items. The caller runs the slot gate (SlotRefusal) first, so a hidden `for_each` is an unknown field before its contents are judged.

The returned finding is the Certain MaxDerivedColumns breach when the limit refused the request (nil otherwise), for predict's LimitFindings.

func FacetFieldRefRefusals

func FacetFieldRefRefusals(req *types.FacetRequest, schema *encoding.Schema, snap *ExtensionsSnapshot) []*errors.CodedError

FacetFieldRefRefusals is FieldRefRefusals for a FacetRequest: its filterers are judged by the Request filterer rule against the cohort schema (a facet has no features, so the schema is the whole column set). FacetSchema applies the first entry right after its zone pass; ValidateFacet reports every entry at the same point. Fields and AdditiveFields keep their own facet-specific refusals.

func FacetGroupBound

func FacetGroupBound(req *types.FacetRequest, schema *encoding.Schema, records int64) (int64, bool)

FacetGroupBound is the upper bound of the distinct values a rich facet counts against MaxGroups — the runtime counts each faceted field (Fields and AdditiveFields) separately, so the bound is the largest per-field one: a categorical field's dictionary size, two for packed_bool, clamped by records when known (>= 0). A numeric field mints no group (its accumulator is a summary), and an unknown field is refused elsewhere; false when no faceted field counts.

func FacetLimitFindings

func FacetLimitFindings(req *types.FacetRequest, schema *encoding.Schema, l limits.Limits, in LimitInputs) []limits.Finding

FacetLimitFindings is the one limit rule for a rich facet, in limit declaration order — PredictFacet reports it (FacetValidationResult.LimitFindings), the pre-flight refuses its first certain finding (FacetLimitRefusal):

  • MaxGroups (Possible): FacetGroupBound, the largest distinct-value count a faceted field's discrete accumulator can mint.
  • MaxEstimatedMemory (Certain): EstimateFacetMemory, only when the limit is set and the record count is known.

func FacetLimitRefusal

func FacetLimitRefusal(req *types.FacetRequest, schema *encoding.Schema, l limits.Limits, in LimitInputs) *errors.CodedError

FacetLimitRefusal is the facet pre-flight (Service.FacetSchema, right after the facet field-reference pass; the simple Service.Facet on its streamed path): the PULSE_LIMIT_EXCEEDED error of the first certain FacetLimitFindings finding, nil when none. MaxEstimatedMemory is the only limit a facet can breach before it scans — each field's distinct values are counted against MaxGroups as they mint.

func FacetNotMeaningfulWarnings

func FacetNotMeaningfulWarnings(req *types.FacetRequest, f *encoding.Field) []descriptor.EnvelopeEntry

facetIsNumeric is the facet-side numeric predicate. Intentionally excludes the bit-packed bool encoding (packed_bool) — a histogram or percentile profile over a binary indicator is degenerate (one or two buckets), so refusing it is more useful than producing the trivial answer. Widen only when a facet operator actually wants 0/1 numeric stats. Canonical broader predicate: encoding.FieldType.IsNumericForAnalytics. FacetNotMeaningfulWarnings are the PULSE_AGG_NOT_MEANINGFUL_FOR_CATEGORICAL warnings for one faceted field: numeric_percentiles and include_histogram compute nothing for a non-numeric field (the discrete arm has no numeric summary), so each one set says so — in that order. Predict adds them to the envelope; the runtime (service.facetSchema) appends them to FacetResult.Warnings as "CODE: message", so the two sides carry the same count and wording.

func FanOutMultiplicity

func FanOutMultiplicity(groups []*types.Group, schema *encoding.Schema) int64

FanOutMultiplicity is the most buckets one record can land in under groups: the product, over every position that fans one record into several keys (GROUP_SET_PER_ELEMENT — one bucket per selected set member), of that position's key bound (the set field's dictionary size, or its include list: vectors.EstimateBuckets), else the set type's member ceiling; 1 when no position fans out. Popcount is data, so the dictionary size is the only schema-derivable bound. An extension grouper's fan-out is its own (no schema bound), like its state. Saturating.

func FeatureCategoryOf

func FeatureCategoryOf(name string) string

FeatureCategoryOf returns the category of an operator feature — the name's leading SCREAMING_SNAKE segment (`AGG`, `GROUP`, `OVERLAY` …). Non-operator features have no category and return "".

func FeatureDependencies

func FeatureDependencies(name string) ([][]string, bool)

FeatureDependencies returns a copy of the dependency groups (AND of any-of sets) of the built-in feature spelled name.

func FeatureName

func FeatureName(k FeatureKind, bare string) string

FeatureName spells a feature of kind k whose bare name is bare: the bare name itself for an operator, `<kind>:<bare>` otherwise.

func FeatureNames

func FeatureNames() []string

FeatureNames returns every built-in feature name in table order.

func FeatureSetDigest

func FeatureSetDigest(enabled []string, b FeatureBehaviour) string

FeatureSetDigest returns "fs1:" + sha256hex over the sorted enabled names, newline-joined, followed by the effective behaviour switches. The order of enabled is irrelevant; duplicates are collapsed.

func FenceFeatureID

func FenceFeatureID(name string) string

FenceFeatureID resolves a fence name (feature-profile spelling) to the ontology node that carries it: an operator feature — or an operator that is no feature (an extension operator, a synth distribution) — is `operator:<NAME>`, every other feature its spelling verbatim.

func FieldKindOf

func FieldKindOf(ft encoding.FieldType) (kind descriptor.FieldKind, ok bool)

FieldKindOf maps a cohort field type to the coarse kind intent shapes are written in. ok is false only for an unknown type byte; every registered field type maps (TestFieldKindOf_Total walks them all).

func FieldRefRefusal

func FieldRefRefusal(req *types.Request, schema *encoding.Schema, snap *ExtensionsSnapshot) error

FieldRefRefusal is the ONE field-reference rule: the first name a Request's slots reference that the pipeline never makes available, as the coded refusal both sides return — nil when every name resolves. The runtime calls it once per Request after smart defaults and zone resolution, against the schema it executes over (the cohort's, the joined schema, or a chain stage's synthesised input), before any record is read; predict and the Compose / chain validators report every entry of FieldRefRefusals at the same point. A runtime that skipped it would treat each unknown name as an all-null column and answer with wrong numbers and no error.

func FieldRefRefusals

func FieldRefRefusals(req *types.Request, schema *encoding.Schema, snap *ExtensionsSnapshot) []*errors.CodedError

FieldRefRefusals walks every slot that names a field, in PIPELINE order, against the columns available at that point:

  1. vector fields — a native vec_f32 / vec_f64 field named in a slot that reads one value (vectorScalarRefusals): PULSE_VECTOR_FIELD_NOT_SCALAR, one per slot, reported first;
  2. features — the schema plus each earlier feature's outputs (Field; FEAT_TARGET_ENCODE params.target; FEAT_TRAIN_TEST_SPLIT params.stratify);
  3. filterers — the schema plus every feature output (attributes run after filters, so their labels are NOT visible to a filter);
  4. attributes — as filterers plus each EARLIER attribute's label (Field, or Target / Predictors for ATTR_REG_*; ATTR_FORMULA reads its expression and may omit Field);
  5. tier-1 tests, regressions, groups, aggregations and the crosstab axes / cell / margin aggregations — the record columns: schema, features and every attribute label;
  6. windows (order_by, partition_by, and Field on a value-bearing operator), sort and tier-2 post-tests — the OUTPUT row columns: the group fields and aggregation labels (or, with neither, the record columns), plus each earlier window's label (sort and post-tests see every window). A window order_by key that is a schema field is also judged for orderability (IsOrderableType — set_* is refused). A crosstab's sort and windows judge against the record columns; its post-tests run over cell rows and are not judged here. The output namespace itself is judged too: an aggregation label (explicit or "<TYPE>_<field>") equal to a group field or to an earlier aggregation's label is refused, since the row holds one value per name and the other figure was silently lost (not on a crosstab, whose output is its cell grid).
  7. vectors — Request.Vectors resolved against the schema alone (internal/vectors.Resolve): the first PULSE_VECTOR_* refusal, or the SERVICE_VALIDATION unknown-field refusal for a literal member the schema lacks; then a vector name equal to a feature output, attribute or window label of the request (PULSE_VECTOR_NAME_COLLISION — an expression would read the column, never the vector).
  8. matrices — Request.Matrices resolved by the same leaf (internal/vectors.ResolveMatrices): an unknown / hidden type, a spec setting both or neither of vector and fields, an unknown encoding, a duplicate result name or bad params (SERVICE_VALIDATION, details.reason), an undefined vector (PULSE_VECTOR_UNKNOWN), or an inline-fields vector refusal.
  9. test vector inputs — every test's vector / fields and vector2 / fields2 resolved by the same leaf (internal/vectors.ResolveTests): the exactly-one shape, a vector input on a test that reads none, an undefined vector (PULSE_VECTOR_UNKNOWN), the inline-fields vector rules, a second set of another length, and params.missing other than "listwise" (SERVICE_VALIDATION, details.reason).
  10. attribute vector inputs — every attribute's vector / fields and fitted params resolved by the same leaf (internal/vectors.ResolveAttributes): the exactly-one shape, a vector input on an attribute that reads none, an undefined vector, the inline-fields vector rules, params.fit_on's shape and params.missing other than "listwise". A vector attribute's fit_on filterers are judged at step 3 by the filterer rule.
  11. grouper vector inputs — every grouper slot's (groups and both crosstab axes) vector / fields and params resolved by the same leaf (internal/vectors.ResolveGroups): the exactly-one shape, a vector input on a grouper that reads none, an undefined vector, the inline-fields vector rules and GROUP_KMEANS's params. A vector grouper's key column (vectors.GroupKeyField) is an output column at step 5. A registered extension test, attribute or grouper that sets a vector input has its member sets judged at steps 8-10 by the same member rules (shape, undefined vector, inline-fields rules); its params and other slots stay its own.
  12. aggregation vector inputs — every aggregation slot's (aggregations, the crosstab cell and its margin aggregations) vector / fields and params resolved by the same leaf (internal/vectors.ResolveAggregations): the exactly-one shape, a vector input on an aggregator that reads a field (an extension's included), an undefined vector, the inline-fields vector rules and params.labels / params.expand. A vector aggregator's array value (its bare label) is refused at step 5 as a Sort key, a window's field / order_by / partition_by or a post-test's field; it, or under params.expand any of its per-element columns, is refused as a request overlay's host (the aggregation it scores: a series kind's params.field, else the first) — PROCESSING_CONFIG, details.reason "array_valued". An expanded per-element column <label>[<elem>] is otherwise an ordinary nullable f64 output column. Steps 6 to 11 contribute one refusal at most between them.
  13. bound vector fits — every fitted attribute's and every matrix's params.fit judged against the bound names (models: the runtime's Set, predict's FitCatalog) by internal/model.CheckVectorFit, once steps 6-11 passed: an unbound name is PULSE_MODEL_UNKNOWN (the vector fits under details.available), a regression name PULSE_MODEL_KIND_MISMATCH — located by details.attribute (the slot's label) or details.matrix (the result name), the message prefixed with the slot, exactly as the bind re-raises it. The label alignment is the bind's alone (a static catalog never resolves a battery).

Derived names follow the runtime's own naming (featureOutputLabels, attributeDefaultLabel, "<TYPE>_<field>" for an aggregation, windowLabel), so a defaulted Type is visible in a label. A feature whose outputs the rule cannot name (an extension feature) leaves the column set open: every later record- and output-level name is accepted, as the runtime may legitimately produce it. Empty names are judged where the slot requires one (aggregation, group, attribute other than ATTR_FORMULA, every built-in filterer but FILTER_EXPRESSION) and skipped where it is optional.

Names inside params are judged where an operator reads them: the two feature params above, the built-in aggregation params (aggParamFieldKeys — AGG_WEIGHTED_MEAN weight_field, AGG_RATIO numerator_field / denominator_field, AGG_DISTINCT_SUM distinct_by, on every aggregation slot, crosstab cell and margin aggregations included) and the post-test row-column params (postTestParamFieldKeys — TEST_ANOVA_F / TEST_ANOVA_WELCH n_col / variance_col, TEST_TUKEY_HSD n_column when given). An extension operator's names are the ones its registration's FieldInputs hook declares for the slot's Params (snap.DeclaredFieldInputs; a filterer's hook gets nil, as the projection extractor passes it), judged at the slot's own pipeline point; without a hook its params are not judged. A nil snap judges built-ins only. A nil request or schema yields nil — the schema-less mode of a validator that cannot read the cohort.

func FoldAlias

func FoldAlias(s string) string

FoldAlias is the comparison form of a Purpose.KnownAs alias or an intent Sound: lower-cased, surrounding whitespace trimmed and inner whitespace runs collapsed to one space. Punctuation is kept, so "chi-square" and "chi square" are distinct aliases. Uniqueness, the Sounds collision rule and the instance alias index all compare in this form.

func Glossary

func Glossary() []descriptor.Term

Glossary returns the glossary in declaration order. The result is a deep copy: callers may mutate it freely.

func GlossaryIDs

func GlossaryIDs() []string

GlossaryIDs returns the sorted glossary term IDs.

func GroupBufferBytes

func GroupBufferBytes(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, records int64) map[*types.Group]int64

GroupBufferBytes is every buffered vector grouper slot's point store (limits.KMeansBufferBytes over records), keyed by the slot — groups and both crosstab axes. Nil when no slot is a GROUP_KMEANS that resolves, or records is unknown (< 0). The memory estimate sums it; predict reports it per groups[i] slot (GroupPredict.RowBufferBytes).

func GroupMergeability

func GroupMergeability(t types.GroupType) descriptor.ComponentsMergeability

GroupMergeability is the typed convenience that accepts a types.GroupType directly so callers do not have to round-trip through string(...).

func GrouperMergeability

func GrouperMergeability(name string) descriptor.ComponentsMergeability

GrouperMergeability returns the ComponentsMergeability declared in the built-in grouper capability table for the operator named by name (e.g. "GROUP_CATEGORY"). Unknown names return the zero-value empty string with the same "no streaming guarantee" semantics as AggregatorMergeability.

GROUP_QUANTILE is the canonical None grouper — quantile cutoffs need the sorted full input, so the streaming orchestrator suppresses the per-chunk Operator emission for that slot until the terminal chunk. Every other registered grouper today (CATEGORY, DATE, RANGE, ROUNDED, SET_VALUE, SET_PER_ELEMENT) is Mergeable.

Lives alongside AggregatorMergeability in the descriptor package so the streaming projection helper has a single import path for both axes; the underlying lookup reads only the static grouperCapabilities() slice and never touches `internal/service/` or `internal/processing/`.

func HiddenSlotKeys

func HiddenSlotKeys(sample any, inst *InstanceSnapshot) []string

HiddenSlotKeys returns the top-level JSON keys of the request root sample (types.Request, ComposedRequest, ChainRequest, FacetRequest — struct or pointer) that inst hides, sorted. Nil when none is hidden, on a nil / unscoped instance, or for a root with no gated slot. The payload-schema and manifest filters drop exactly these properties.

func Inspect

func Inspect(fileData io.ReadSeeker, opts *descriptor.InspectOptions) *descriptor.Envelope

Inspect reads a .pulse file header and schema, returning structured field information. It never reads record data.

Detection is by the first four bytes at the reader's position: zip magic PK\x03\x04 routes to the shard-archive path (read by random access when the reader is an io.ReaderAt — the zip central directory at the END of the file, the canonical schema entry and each shard's header, never a record — else its remainder is buffered once); PULSE magic — or any other prefix, which then surfaces the standard ENCODING_INVALID envelope — takes the single-file path.

For archive-backed cohorts, the canonical schema and dictionaries come from the reserved _schema.pulse entry; Shards enumerates every non-reserved entry in central-directory order with per-shard RecordCount populated by peeking each shard's header; the envelope-level RecordCount is the cumulative sum across shards.

func InspectWith

func InspectWith(fileData io.ReadSeeker, opts *descriptor.InspectOptions, meta InspectMetadata) *descriptor.Envelope

InspectWith is Inspect plus the cohort's sidecar metadata: it reports InspectResult.SuggestedWeight through SuggestWeight against the schema just read (the canonical schema for an archive). Still no record is read.

func IntentIDs

func IntentIDs() []string

IntentIDs returns the sorted intent IDs — the manifest's top-level intents list.

func IntentPromptName

func IntentPromptName(intentID string) string

IntentPromptName spells the MCP prompt of an intent: `pulse-<intent-kebab>` (compare_groups → pulse-compare-groups).

func Intents

func Intents() []descriptor.Intent

Intents returns the intent taxonomy in declaration order. The result is a deep copy: callers may mutate it freely.

func InterpretationsOf

func InterpretationsOf(name string) ([]descriptor.Interpretation, bool)

InterpretationsOf returns a copy of the built-in Interpretations declared for name (a manifest entry name; tests by family).

func IsCoreSurface

func IsCoreSurface(name string) bool

IsCoreSurface reports whether name is an always-present core surface.

func IsGlossaryTerm

func IsGlossaryTerm(id string) bool

IsGlossaryTerm reports whether id names a glossary term.

func IsIntent

func IsIntent(id string) bool

IsIntent reports whether id names an intent in the taxonomy.

func IsOrderableType

func IsOrderableType(ft encoding.FieldType) bool

IsOrderableType is the ONE window ORDER BY orderability rule, applied on both sides by the shared FieldRefRefusals walk (predict reports it, every runtime execution mode refuses with it). It admits exactly the types the window comparator (internal/processing/window compareCell, shared with Request.Sort) orders by value:

  • every unsigned integer and float type, by numeric value;
  • date (signed epoch days) and datetime (signed epoch SECONDS) — pre-1970 values are negative and sort before 1970;
  • packed_bool as 0/1, false before true;
  • decimal128 by value (Decimal128.Cmp — one column shares one scale);
  • categorical_* by dictionary LABEL, byte-wise — never by dictionary index, so the order is stable across imports and shards (TestWindowOrderBy_CategoricalOrdersByLabel).

set_* is refused: a set cell decodes to a label slice the comparator cannot order, so every row would compare equal (TestWindowOrderBy_OrderabilityPredictMatchesRuntime). Nulls sort last for every admitted type. vec_f32 / vec_f64 are refused too: a vector has no single value to order by.

func IsWeightAware

func IsWeightAware(op string) bool

IsWeightAware reports whether the built-in operator op consumes a resolved row weight. The classification is internal/weighting's one table (.claude/reference/weighting.md, Aggregator classification), shared with the engine so predict never claims a weight the runtime does not apply.

func IsWeightFieldType

func IsWeightFieldType(t encoding.FieldType) bool

IsWeightFieldType reports whether a weight may live in a field of type t: the unsigned integers and the floats.

func IsZoneCapable

func IsZoneCapable(name string) bool

IsZoneCapable reports whether the named operator accepts a per-slot `tz`. A zone-following overlay kind is NOT zone-capable — it has no `tz` slot.

func JSONObjectKeys

func JSONObjectKeys(sample any) []string

JSONObjectKeys returns the top-level JSON object keys declared by the struct (or pointer to struct) sample, read from each exported field's json tag in declaration order. Fields tagged "-" are skipped; an untagged field contributes its Go name.

func JargonForms

func JargonForms() map[string]string

JargonForms maps every jargon term's surface form (lowercase) to its term ID — the vocabulary the jargon-link check scans plain-language guidance for. The map is a fresh copy.

func JoinCountRefusal

func JoinCountRefusal(req *types.Request) error

JoinCountRefusal is the v1 join-count rule — exactly one JoinSpec per Request — shared by runtime Process (internal/service, checked before the crosstab and join dispatch) and every no-execute validator (Predict, ValidateJoin, the Compose slots, chain stage 0), so both refuse with the same code, message and details: a PULSE_JOIN_TOO_MANY {count} for more than one JoinSpec, nil otherwise (including no join at all).

func JoinFanOutRefusal

func JoinFanOutRefusal(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, l limits.Limits, in LimitInputs, maxMatches int64) *errors.CodedError

JoinFanOutRefusal is the join build-side backstop (openJoinStream, after the right side is hashed and before the left side is probed): with maxMatches the most right rows one key holds, the joined rows are at most left x maxMatches, and the PULSE_LIMIT_EXCEEDED error of the memory estimate on that figure when it exceeds a set MaxEstimatedMemory — the details of the pre-flight's memory refusal plus the join location (join: 0) and the measured right_key_multiplicity / join_rows_bound. Nil when the limit is Unlimited, the count is unknown, or no key repeats (maxMatches <= 1: the pre-flight's estimate already held).

func JoinRowsBound

func JoinRowsBound(schema *encoding.Schema, in LimitInputs) (limits.JoinBound, bool)

JoinRowsBound is the joined-row bound a join's memory estimate is re-judged on when the right key may repeat (each left row then emits one joined row per matching right row, so joined rows = Σ_k L_k·R_k can exceed the left count the certain estimate assumes). Header + schema hold no uniqueness guarantee — a sidecar index's distinct-key count is not a freshness claim, Lookup's assert_unique is a per-call check — so a right side of at most one row is the only provably unique key: false there (and without a join or a known count). Else:

  • a right key field (OnPairs' right side, on the joined schema under the spec's As prefix) carrying a categorical dictionary of D entries bounds one key's matches by R - D + 1 — sound only when every entry occurs in the right cohort, which a derived, filtered, synthesised or shard-removed cohort does not guarantee, so the finding it drives is Possible. A composite key takes the smallest such bound (a tuple matches no more rows than any of its columns).
  • no key field carries a dictionary (numeric keys): left x right, every right row matching every left row — the worst case.

func LimitRefusal

func LimitRefusal(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, l limits.Limits, in LimitInputs) *errors.CodedError

LimitRefusal is the process pre-flight: the PULSE_LIMIT_EXCEEDED error of the first Certain RequestLimitFindings finding, nil when none. The runtime calls it right after the field-reference pass, so a certain breach is refused before any record is decoded — with the error predict reports for the same request.

func LimitsFor

func LimitsFor(inst *InstanceSnapshot) []descriptor.LimitMeta

LimitsFor lists the instance's EFFECTIVE resource limits as the manifest's always-present `limits` block, in declaration order. A nil snapshot (or one pulse.New never stamped) reports the built-in defaults — InstanceSnapshot.Limits' own fallback.

func MCPPromptFeatures

func MCPPromptFeatures() map[string]string

MCPPromptFeatures returns the MCP prompt name → mcp_extra feature map as a fresh copy.

func MaterializeSlotRefusal

func MaterializeSlotRefusal(req *types.Request) *errors.CodedError

MaterializeSlotRefusal is the materialize slot gate: a request slot that does not yield one value per source record is refused with PULSE_MATERIALIZE_SLOT_UNSUPPORTED, details.slot naming its JSON key, in Request field order. Accepted: cohort, label, features, filterers, attributes, windows, sort (the output row order), weight, time_zone and disable_components (which has nothing to gate). Schema-free.

func MatrixAdjustedKeys

func MatrixAdjustedKeys(key string) (adjusted, significant string)

MatrixAdjustedKeys are the auxiliary twins the multiplicity fold writes beside a p-value matrix stored under key: key+"_adjusted" (so "p" gives the built-ins' p_adjusted) and significant_adjusted.

func MatrixFitParam

func MatrixFitParam() descriptor.Param

MatrixFitParam is the engine-owned params.fit every co-moment matrix operator takes (internal/vectors resolveFit).

func MatrixMemberParams

func MatrixMemberParams() []descriptor.Param

MatrixMemberParams are the engine-owned params every matrix operator takes (internal/vectors.EngineMatrixParams): the missing-data mode and the listwise heavy-drop threshold. A co-moment (streamable) operator also takes the bound vector fit (MatrixFitParam); a buffered one refuses it, so its manifest entry does not list it.

func MatrixMemberTypes

func MatrixMemberTypes() []string

MatrixMemberTypes are the member column types every built-in matrix operator accepts — integer and float fields, plus packed_bool under the vector's coerce "binary" (internal/vectors.MemberTypeAllowed). An extension registration with no Accepts lists them in the manifest.

func MemoryArm

func MemoryArm(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, in LimitInputs) limits.MemoryArm

MemoryArm is the execution arm req runs on over schema — the arm the engine's dispatch picks: the fused crosstab when the shared fusion rule accepts (never under a join or with fusion disabled), else the buffered crosstab; otherwise streaming iff computeStreamable (the predict twin of the processor's canStream, parity-gated).

func NearestKey

func NearestKey(k string, candidates []string) string

NearestKey returns the closest candidate to k by Levenshtein distance, or "" when no candidate is close enough. The acceptance threshold is edit distance < 4, further capped at the key length, so short or unrelated keys do not yield a misleading suggestion. Ties keep the earliest candidate.

func NormalizeRequest

func NormalizeRequest(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot) *types.Request

NormalizeRequest returns a clone of req with smart defaults resolved against schema. Caller-side ergonomic for envelope.Request echo — produces the exact request the engine would execute (post-defaults) without mutating the input. Returns nil when req is nil; returns the clone unchanged when schema is nil or no defaults applied.

The clone is a shallow-deep hybrid identical to the one Predict uses internally: Aggregations and Groups are deep-cloned (the slots ResolveDefaults mutates in place); the metric fill copies Matrices itself before its first write (resolveMetricDefaults); every other slot is shared with the input. Safe to expose on read-only paths. inst is the instance feature set: a default whose target it hides is never inferred (nil hides nothing), as in ResolveDefaults.

func OntologyID

func OntologyID(kind descriptor.OntologyNodeKind, name string) string

OntologyID spells a node ID: `<kind>:<name>`, or name itself for a capability node (a feature spelling is already kind-prefixed).

func OutputLabels

func OutputLabels(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot) map[string]bool

OutputLabels is the one set of output column names a request's operators write beside the schema's own columns: every aggregation's label (types.AggregationLabelOf — its Label, else "<TYPE>_<field>"), every attribute's (attributeDefaultLabel when unlabelled), every grouper's key column (vectors.GroupKeyField), every window's (windowLabel) and every feature's outputs (featureOutputLabels, plus an explicit Label). An augment-mode label sibling "<field>_label" naming one of them is PULSE_LABEL_FIELD_COLLISION (ValidateLabels' extraFields). Predict (validateRequestBody) and the runtime (Service.validateProcessLabels, the auto-label pass) both read this set, so the two judge the same collisions. req is the defaults-resolved request, schema the one it executes over (nil: no schema-derived feature outputs); inst routes a hidden type as never registered.

func OverlayCapabilities

func OverlayCapabilities() []descriptor.OverlayCapability

OverlayCapabilities returns the canonical per-kind capability list for the manifest. Deterministic ordering: alphabetised by Kind via types.AllOverlayKinds() so the golden manifest stays stable as new kinds land. Buffered flags consult types.OverlayStreamable(kind) so the static table in types/overlay_streamability.go remains the single source of truth for streaming behaviour — a kind that flips to streamable automatically flips Buffered to false here.

OVERLAY_INDEX_VS_MARGIN is the seed entry for the catalog:

  • Shapes: [matrix] (CELL-scoped overlay layered onto a crosstab)
  • Scopes: [cell] (CELL-only today; ROW/COLUMN/TOTAL land alongside the matching payload shapes)
  • RefKinds: [Margin] (denominator is an axis-margin slot)
  • Buffered: true (margins recompute from raw rows; the host crosstab path is always buffered)

Later kinds drop in by extending the switch below. TestStreamability_OverlaysKnown (types/overlay_streamability.go) and TestManifestOperatorsComplete-style follow-ups (descriptor) enforce that every catalog entry has a row in this surface.

func OverlayHostCapabilities

func OverlayHostCapabilities(kind string) []string

OverlayHostCapabilities returns the host capabilities an overlay kind can run under, sorted. The engine-side gate compares it to handler-map membership; nil means the kind is listed under no host.

func OverlayReadsHostComponents

func OverlayReadsHostComponents(kind types.OverlayKind, cellBasis weighting.Basis) bool

OverlayReadsHostComponents reports whether a Request.Overlays kind, over a crosstab host whose cell is weighted under cellBasis (CrosstabCellWeightBasis), reads that host's Response.Components.Crosstab — the rule the service's compute plan vetoes a `return` skip with (U18), beside its refusal half validateOverlayHiddenFloor. The OVERLAY_PAIRWISE_* family always reads per-cell floors, Welford triples, margin and slab counts (PULSE_OVERLAY_COMPONENTS_REQUIRED without them). The weighting.ScalesByHostFloor kinds and OVERLAY_FISHER_EXACT_CELL read the cells' weighted floors only on a WEIGHTED host — the stamped sum_weights their summary Parameters carry (frequency), plus the Kish n_eff the χ² table is scaled by (probability); on an unweighted host CellFloor reads nothing and their layer is the MatrixPayload's alone. Their host basis comes from the stamped cell weight, never from the floor keys, so a skip cannot hide a weighted host from Fisher's frequency-only refusal. Every other host kind reads the MatrixPayload only. Components.Crosstab is the only Components sub-part any overlay reads.

func OverlayWeightKinds

func OverlayWeightKinds(kind types.OverlayKind) []types.WeightKind

OverlayWeightKinds returns the weight kinds an overlay kind honours a weight under (manifest weight_kinds), nil for a refused or descriptive kind.

func ParseSince

func ParseSince(s string) (major, minor, patch int, ok bool)

ParseSince parses a feature Since: exactly `major.minor.patch`, each a non-negative decimal integer with no sign, prefix or suffix. A pre-release or build suffix is refused (ok == false) — a Since names a release line, never a build.

func PayloadSchemaForInstance

func PayloadSchemaForInstance(inst *InstanceSnapshot) (json.RawMessage, error)

PayloadSchemaForInstance is BuildPayloadSchemaForInstance returning the (programming-error-only) marshal failure instead of panicking — the form the Pulse.PayloadSchema facade serves.

func Predict

func Predict(fileData io.ReadSeeker, req *types.Request, opts *PredictOptions) *descriptor.Envelope

Predict validates a request against a .pulse file without executing it. It reads only the header and schema, never record data. The returned Envelope contains the PredictResult in Data and any errors/warnings encountered.

Detection is by the first four bytes at the reader's position, as in Inspect: zip magic PK\x03\x04 routes to the shard-archive path, where the canonical _schema.pulse entry supplies the schema the request validates against and per-shard headers contribute the cumulative RecordCount and Shards listing (streamability is computed from the same gates the single-file path uses — an archive inherits the streamability of its request against the canonical schema, not of its shape). Any other prefix takes the single-file path, which surfaces the standard ENCODING_INVALID envelope on malformed input.

func ProfileWrittenWith

func ProfileWrittenWith(running string) string

ProfileWrittenWith returns the `written_with` stamp a generated feature profile carries when produced by the running build version: the release core (`major.minor.patch`, leading "v" and any pre-release or build suffix cut), the same reduction SinceReached applies. A running version with no usable core (`devel`, a bare SHA, a 0.0.0 pseudo-version) is stamped with the newest Since in the feature table — the newest release line the build knows — so the stamp is always a release a later `Since` can be compared against.

func PurposeOf

func PurposeOf(name string) (descriptor.Purpose, bool)

PurposeOf returns the declared Purpose of a built-in manifest entry.

func ReachedFeatureNames

func ReachedFeatureNames(running string) []string

ReachedFeatureNames returns every built-in feature name whose Since the running build version has reached, in table order: the enabled set of a profile-free instance with no extensions.

func RefusalAt

func RefusalAt(err error, key string, idx int) error

RefusalAt returns a located request-level refusal: err with its location inside a multi-request root added to its details — key "request" (0-based Compose slot) or "stage" (0-based chain stage) set to idx. A *errors.CodedError anywhere in err's chain is copied (code and message unchanged, so the code still survives errors.As); any other error is returned as is. The located refusals are the zone refusals (ResolveZones / ResolveFacetZones) and the join-count rule (JoinCountRefusal); the runtime marks them where they are raised and the validators call RefusalAt at the same points, so both sides add the same location.

func RegressionOutputKeys

func RegressionOutputKeys(name string) []string

RegressionOutputKeys returns a copy of the applicability row for regression type name: the RegressionResult JSON keys it populates on its plain fit path (nil for an unknown type). The runtime probe in internal/processing/regression holds it to what each engine emits.

func RenderGlossarySkill

func RenderGlossarySkill() string

RenderGlossarySkill renders the glossary skill's markdown: every term sorted by ID, with its definition, why it matters, the spellings that count as the term, and related terms. Deterministic.

func RenderGuidanceSection

func RenderGuidanceSection(operator, section string, ext *ExtensionsSnapshot, keepUse func(use string) bool, scrub ProseScrub) string

RenderGuidanceSection renders one generated section for operator: its Purpose (built-in, else ext's) for skills.SectionUseWhen, its Interpretation entries for skills.SectionReadingTheOutput. keepUse reports whether a not-for target (bare operator name or `<kind>:<name>` feature spelling) is visible; nil keeps every target. "" when the operator declares no metadata for the section or the section is unknown.

func RenderIntentsSkill

func RenderIntentsSkill() string

RenderIntentsSkill renders the intent taxonomy skill's markdown: the analytic intents, then those that route to tooling, each group sorted by ID, with the intent's phrasings and alternative data shapes. Deterministic.

func RenderReadingSection

func RenderReadingSection(ins []descriptor.Interpretation, scrub ProseScrub) string

RenderReadingSection renders `## Reading the output` from ins: one item per field (its meaning, or the shared rule set's summary), with the field's bands (convention named), sign and caveats as sub-items, every string through scrub. Capped at ReadingSectionCap — fields are admitted first, in declaration order, then bands, signs and caveats; "" when nothing survives.

func RenderUseWhenSection

func RenderUseWhenSection(p descriptor.Purpose, keepUse func(use string) bool, scrub ProseScrub) string

RenderUseWhenSection renders `## Use when` from p: the plain line, up to two questions, then each not-for alternative keepUse admits (nil admits all), every string through scrub. Capped at UseWhenSectionCap; "" when nothing survives.

func RequestHostCapabilities

func RequestHostCapabilities() []string

RequestHostCapabilities returns the request-executing host capabilities, in a fresh slice: the any-of group every non-overlay operator depends on. The profile validator gives extension operators the same group, so an extension operator is never enabled without a host to run it.

func RequestLimitFindings

func RequestLimitFindings(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, l limits.Limits, in LimitInputs) []limits.Finding

RequestLimitFindings is the one predict-time limit rule for a single Request against the schema it executes over: every effective limit in l (predict passes the snapshot's, the runtime the service's — the same resolved values pulse.New installs on both) a figure predict can compute from the request + schema + in exceeds, graded limits.Certain or limits.Possible, in limit-declaration order. Predict reports them (PredictResult.LimitFindings); the process pre-flight (LimitRefusal) refuses the first Certain one before any record is decoded. Reads only the schema.

  • MaxGroups (Possible): the group-bucket upper bound EstimateGroups derives — the product of every grouper's bound, clamped by in.Records when known (unless a grouper fans out) — times the tier-1 test count when the request carries tests (each runs once per group). Any unknown-cardinality grouper yields no finding.
  • MaxCrosstabCells (Possible): the crosstab grid upper bound EstimateCrosstabCells derives (rows x cols, each axis clamped by records). An axis with an unknown-cardinality grouper yields no finding.
  • MaxEstimatedMemory (Certain): EstimateMemory, the per-arm upper bound of the run's resident state. Only when the limit is set — it is Unlimited by default — and the record counts are known.
  • MaxEstimatedMemory (Possible), a join whose certain estimate fits: the estimate again on the joined-row bound JoinRowsBound derives when the right key may repeat (joinFanOutFinding) — never a refusal here; the runtime refuses the measured fan-out after the build (JoinFanOutRefusal).
  • MaxMatrixDim (Certain): each matrix's dimension p — its resolved member count, from vectors.ResolveMatrices, the resolver the runtime mints its accumulators from. A refused spec yields no finding (the field-reference pass reports the refusal).

func ResolveComposeReturn

func ResolveComposeReturn(composed *types.ComposedRequest, inst *InstanceSnapshot) (*returnplan.Plan, error)

ResolveComposeReturn resolves ComposedRequest.Return — the block that shapes the TOP-LEVEL Compose overlays — into its plan. Paths root at ComposedResponse and every include / exclude must start at `overlays` (PULSE_RETURN_INVALID otherwise: a slot is shaped by its own Requests[i].Return). `responses` is always kept whole, whatever the preset or allowlist, so a slot's own plan alone shapes it. A preset expands against the ComposedResponse root (its overlay paths survive; its Response-only paths drop). No instance default applies at this level: nil (and no error) when the block is absent. Pure; predict (ValidateComposeWithOptions) and Service.Compose / ComposeParallel call it before any slot runs.

func ResolveDefaults

func ResolveDefaults(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot) []descriptor.DefaultApplied

ResolveDefaults inspects every aggregation and grouper slot in req, fills in the Type for slots that name a field but omit the Type, fills the metric of a metric-taking matrix or comparison attribute slot reading a kind-declared vector (resolveMetricDefaults, Category "metric"), and returns one DefaultApplied entry per change made. Mutates req in place.

Rules:

  • Defaults never override an explicit Type.
  • Defaults never cross categories (a missing aggregator does not insert a grouper, and vice versa).
  • Tests (req.Tests, req.PostTests) are not defaulted; hypothesis tests are intent-bearing.
  • Field types absent from defaultRules (or with no rule for the slot's category) are left untouched and contribute no entry.
  • A rule whose target operator inst hides is treated exactly like no rule: the slot is left untouched and contributes no entry, so a default never synthesizes an operator the instance does not offer. A nil inst hides nothing.

Returns a nil slice when nothing changed.

func ResolveFacetZones

func ResolveFacetZones(req *types.FacetRequest, schema *encoding.Schema, defaultZone string, load ZoneLoader, inst *InstanceSnapshot) ([]descriptor.ResolvedZone, error)

ResolveFacetZones is ResolveZones for a FacetRequest: its filterers resolve through slot `tz` → req.TimeZone → defaultZone → "UTC" under the same rules.

func ResolveReturn

func ResolveReturn(req *types.Request, inst *InstanceSnapshot) (*returnplan.Plan, error)

ResolveReturn resolves the request's EFFECTIVE `return` block (EffectiveReturn) into the canonical selection plan. Nil (and no error) when no layer supplies a block. inst hides the paths its hidden features own and carries the instance default; nil hides nothing and has no default. It never mutates req.

func ResolveWeights

func ResolveWeights(req *types.Request, schema *encoding.Schema, defaultWeight *types.WeightSpec, inst *InstanceSnapshot) ([]descriptor.ResolvedWeight, error)

ResolveWeights is the single weight-resolution pass for a Request. The runtime (internal/service, every execution mode — Compose slots and chain stages each resolve their own Request) and predict both call it, so a request is refused or accepted identically by both.

Precedence per weight-bearing slot: slot `weight` (`null` opts the slot out) → req.Weight → defaultWeight (pulse.Options.DefaultWeight) → none. Rules, in evaluation order:

  • req.Weight and defaultWeight must pass ValidateWeightSpec (PROCESSING_CONFIG), whether or not a slot inherits them;
  • req.Weight's field, when the schema carries it, must be an unsigned-integer or float field (PROCESSING_CONFIG with details {slot, field, type});
  • a slot's own weight passes the same two checks. On AGG_WEIGHTED_MEAN, params.weight_field is the slot's own weight (kind probability); one that disagrees with an explicit slot `weight` (another field, or `null`) is PROCESSING_CONFIG, and an AGG_WEIGHTED_MEAN slot nothing resolves a weight for is PROCESSING_CONFIG;
  • the slot's operator class (internal/weighting) decides what a resolved weight does: weight-aware ⇒ applied; not weightable ⇒ skipped under the instance default but PROCESSING_CONFIG under an explicit (slot or request) weight — a WIN_* slot has no slot weight, so only the request weight is explicit there; refused (ClassRefuse — a pending inferential operator, or a permanent refusal carrying details.reason: weighting.RefusalReason, every built-in post-test, a regression with a resample or selection modifier) ⇒ PULSE_WEIGHT_UNSUPPORTED under any weight, the instance default included; frequency-only ⇒ applied under kind frequency, PULSE_WEIGHT_UNSUPPORTED naming the kind under kind probability (the default included); every operator the table does not govern ⇒ skipped;
  • an extension aggregator, attribute or test (the instance's ExtensionsSnapshot) is classed by its registration's WeightAware declaration: aware ⇒ applied (no decimal128 refusal — the extension owns its decimal reads); a non-aware aggregator ⇒ skipped under the instance default, PULSE_EXTENSION_NOT_WEIGHT_AWARE under an explicit weight; a non-aware attribute or test ⇒ PULSE_EXTENSION_NOT_WEIGHT_AWARE under any weight, the instance default included (it may read the whole population, like the built-in tests and reference attributes). A hidden extension is never-registered (skipped);
  • an overlay is classed by overlayWeightClass (the per-kind overlayWeightClasses table, else its manifest Inferential flag): a refused kind is PULSE_WEIGHT_UNSUPPORTED (a frequency-only one only under kind probability) under a weight resolved on its OWN slot (slot → request → default, so a request or instance weight that weights the host weights the overlay too); its `weight: null` opts out. A host weighted only by its own slot weight (or AGG_WEIGHTED_MEAN's params.weight_field) does not refuse an overlay nothing else weights — the shipped pairwise n_source modes read such a host on purpose;
  • a weight-aware slot whose value field is decimal128 (its Field, or AGG_RATIO's numerator_field / denominator_field) ⇒ PULSE_WEIGHT_UNSUPPORTED under ANY weight, the instance default included: the decimal path has no weighted form, and skipping it would mix an unweighted figure into a weighted table;
  • an inherited Options.DefaultWeight is judged only where it APPLIES (the slot's operator is weight-aware): there its field must exist in the schema (the field-reference refusal, SERVICE_VALIDATION) and be of a weight type. A default that applies to no slot of this request is never refused, so an instance default does not break a cohort that lacks the column for a request that would not use it.

A field the schema does not carry on a request or slot weight is the field-reference rule's refusal (FieldRefRefusals judges every explicit weight field against the schema), not this pass's. A slot with an empty operator Type is skipped (a type error, reported identically with or without a weight). A nil schema skips every field-dependent refusal. inst routes hidden operators as never-registered (not weight-aware); nil hides nothing.

The result is nil when neither the request, any slot, nor defaultWeight names a weight. It never mutates req.

func ResolveZones

func ResolveZones(req *types.Request, schema *encoding.Schema, defaultZone string, load ZoneLoader, inst *InstanceSnapshot) ([]descriptor.ResolvedZone, error)

ResolveZones is the single zone-resolution pass for a Request. The runtime (internal/service, every execution mode) and predict both call it, so a request is refused or accepted identically by both.

Precedence per zone-capable slot: slot `tz` → req.TimeZone → defaultZone (pulse.Options.DefaultTimeZone) → "UTC". Rules, in evaluation order:

  • an unknown req.TimeZone or defaultZone → PULSE_TIMEZONE_UNKNOWN, whether or not a zone-capable slot is present;
  • an explicit slot `tz` on an operator that is not zone-capable (every extension operator included) → PROCESSING_CONFIG;
  • an explicit slot `tz` whose field is in the schema and is not `datetime` (a calendar `date`, or an epoch-day count) → PROCESSING_CONFIG;
  • an unknown slot `tz` → PULSE_TIMEZONE_UNKNOWN;
  • an INHERITED zone on a non-`datetime` field is not applied: the slot echoes a null `tz`;
  • a zone that is not UTC-equivalent (temporal.Zone.IsUTC — "UTC" and the fixed-zero Etc aliases are equivalent) resolving onto a field absent from the schema (a derived or chain-synthesised column) → PROCESSING_CONFIG with details {slot, operator, tz}: the operators read an absent field as epoch days, so the zone would be silently ignored. Onto a `datetime` schema field it is accepted and applied (the runtime writes it onto the executing slot — ZonedRequest).

The slots walked are every filterer, feature, attribute, group, crosstab row and column, then each MAT_DISTANCE params.between ("matrices[i].params.between"), in that order.

A slot with an empty operator Type is skipped (it is a type error, not a zone error, and type validation reports it identically with or without a `tz`). A nil schema skips the two field-dependent refusals (explicit `tz` on a non-datetime field; a non-UTC zone onto instants): only a caller with no cohort schema in reach passes nil, and it must never refuse what the schema-holding runtime accepts.

inst is the instance feature set: an operator it hides is not zone-capable, exactly as a never-registered name. Nil hides nothing.

It never mutates req. The returned slice is never nil.

func ReturnColumnRefusal

func ReturnColumnRefusal(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot) error

ReturnColumnRefusal judges every `data[*].<column>` include / exclude path of req.Return against the columns req produces over schema (the schema the request executes over — the joined one for a join). Call it on the defaults-resolved request: a defaulted aggregation's label carries its inferred type. Nil when every named column is produced, the request has no block, or the column set is open (a join, a crosstab, an unknown feature type). A `*` glob over data columns is never refused.

func ReturnPresetsFor

func ReturnPresetsFor(inst *InstanceSnapshot) []descriptor.ReturnPresetMeta

ReturnPresetsFor lists every preset expanded against inst — the manifest's return_presets block — in types.AllReturnPresets order. Paths are the canonical spellings of the preset's selection on this instance (a hidden feature's paths are absent); nested `*.warnings` keep paths are not listed. nil inst is the full registry.

func ScopedChainStageFieldRefRefusal

func ScopedChainStageFieldRefRefusal(req *types.Request, schema *encoding.Schema, codes map[string]encoding.FieldType, inst *InstanceSnapshot, models model.Catalog) error

ScopedChainStageFieldRefRefusal is ScopedFieldRefRefusalWithModels for a chain stage >= 1, whose synthesised input schema types every forwarded aggregation column f64: codes are the input columns that carry a categorical code (vectors.AggregationKinds.ChainCodeColumns), so the stage's own overlays judge an input-valued aggregation over one as the code it is. Nil codes is ScopedFieldRefRefusalWithModels.

func ScopedFacetFieldRefRefusals

func ScopedFacetFieldRefRefusals(req *types.FacetRequest, schema *encoding.Schema, inst *InstanceSnapshot) []*errors.CodedError

ScopedFacetFieldRefRefusals is FacetFieldRefRefusals for one instance, on ScopedFieldRefRefusal's terms.

func ScopedFacetFieldRefRefusalsWithModels

func ScopedFacetFieldRefRefusalsWithModels(req *types.FacetRequest, schema *encoding.Schema, inst *InstanceSnapshot, models model.Catalog) []*errors.CodedError

ScopedFacetFieldRefRefusalsWithModels is ScopedFacetFieldRefRefusals for a FacetRequest whose filterers' coef() calls resolve against models — the runtime's loaded set, predict's static catalog of the request's `models`. Nil binds nothing.

func ScopedFieldRefRefusal

func ScopedFieldRefRefusal(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot) error

ScopedFieldRefRefusal is FieldRefRefusal for one instance: the extension projection is inst's, and an operator inst hides is walked as a never-registered name (its type-specific slots, params and output labels are not judged). The runtime's form; nil inst is FieldRefRefusal(req, schema, nil).

func ScopedFieldRefRefusalWithModels

func ScopedFieldRefRefusalWithModels(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, models model.Catalog) error

ScopedFieldRefRefusalWithModels is ScopedFieldRefRefusal for a Request whose ATTR_REG_PREDICT slots resolve against models — the runtime's bound set (a Compose slot's fits), predict's static model.FitCatalog. Nil binds nothing.

func ShardFanOut

func ShardFanOut(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, in LimitInputs) bool

ShardFanOut reports whether req runs on the per-shard parallel reducer over the archive `in` describes — the predict twin of the runtime's Service.shouldFanOut (parity: internal/service TestShardFanOut_PredictMatchesRuntime): two or more shards, a worker cap that resolves to two or more (0 = runtime.NumCPU, clamped by the shard count), and a request the shared merge gate (mergegate.MergeRefusal over the declared extension facts) admits. A crosstab or a join never reaches that dispatch.

func SharedInterpretation

func SharedInterpretation(key string) (descriptor.Interpretation, bool)

SharedInterpretation returns the shared rule set registered under key.

func SharedInterpretationKeys

func SharedInterpretationKeys() []string

SharedInterpretationKeys returns every shared rule-set key, sorted.

func SinceReached

func SinceReached(since, running string) bool

SinceReached reports whether a feature introduced in since is available in the running build version. The running version is compared on its major.minor.patch core only, so a pre-release or git-describe build of a release line offers that line's features (1.0.0-alpha.2 offers Since 1.0.0). A running version with no usable core is treated as newest. An unparseable since (a table bug TestFeaturesHaveSince refuses) is never reached.

func SlimManifest

func SlimManifest(m *descriptor.Manifest) *descriptor.Manifest

SlimManifest returns a copy of m with every prose Description field blanked. Structural metadata (names, params, types, tiers, accept-type lists, streamability flags, cross-references, fixups) is preserved.

The slim variant is intended for size-sensitive MCP/CLI clients that would rather pay a few extra discovery round-trips than transit the full ~70 kB descriptive payload at session start. The default manifest surface remains the full one; --slim is opt-in.

SlimManifest never mutates the input; it shallow-copies the top-level struct, then per-slice shallow-copies and zeroes the Description fields.

func SlotRefusal

func SlotRefusal(v any, inst *InstanceSnapshot) error

SlotRefusal is the request-slot gate. v is a *types.Request, *types.ComposedRequest, *types.ChainRequest or *types.FacetRequest (any other value — a *types.SampleRequest, nil — passes). It returns PULSE_REQUEST_UNKNOWN_FIELD when v sets a slot inst hides, reporting every hidden slot set on the first offending root:

  • the root's own slots first;
  • then the nested per-slot `weight` keys (nestedWeightRefusal) of a Request, or of a FacetRequest's overlays, then the nested `multiplicity` blocks (nestedMultiplicityRefusal) — for a ComposedRequest, its Compose-host overlays' first;
  • then, for a ComposedRequest, each Requests[i] in order with details.request = i; for a ChainRequest each Stages[i].Request with details.stage = i (the keys the service's located refusals use, descx.RefusalAt).

valid_keys and suggestions range over the offending root's VISIBLE keys only. Nil on a nil / unscoped instance. Every service funnel and Predict run it before any other request check, so a hidden slot is refused at the point an unknown JSON key would have been.

func SlotTokenCapabilities

func SlotTokenCapabilities() []string

SlotTokenCapabilities returns the capabilities with a slot-token entry, sorted.

func SlotTokenHomonymMarkers

func SlotTokenHomonymMarkers(tok string) []string

SlotTokenHomonymMarkers returns the marker tokens (a fresh slice, possibly empty) that make a sentence naming slot token tok name a different, same-spelled surface (slotTokenHomonyms).

func SlotTokensOf

func SlotTokensOf(capability string) ([]string, bool)

SlotTokensOf returns the wire tokens capability owns (a fresh slice, possibly empty) and whether it has an entry.

func SortFeatureNames

func SortFeatureNames(names []string) []string

SortFeatureNames returns names in the canonical profile order: by kind (AllFeatureKinds order), then by operator category (the table's category order; an unlisted category such as SYNTH follows, by name), then by feature-table position. Names absent from the table (extension operators, unknown spellings) follow the built-ins of their kind and category, by name. The input is not modified.

This is the order the published example profiles are written in and the order a generated profile lists its features.

func SuggestWeight

func SuggestWeight(schema *encoding.Schema, variable string, inst *InstanceSnapshot) *descriptor.SuggestedWeight

SuggestWeight is the one rule inspect and predict share for the row weight a cohort's SPSS metadata sidecar proposes. variable is the sidecar's recorded weighting variable, read by the caller.

It returns nil — silently, never a diagnostic — when variable is empty, the instance hides capability:weighting, the schema has no such column (a stale sidecar), or the column's type cannot carry a weight (IsWeightFieldType): a suggestion that would be refused if applied is not offered. Kind is always "probability", the request default; SPSS `WEIGHT BY` is frequency-like, which the documentation says wherever the suggestion appears. Nothing applies the result.

func UnknownFieldError

func UnknownFieldError(unknown, valid []string) *errors.CodedError

UnknownFieldError builds the PULSE_REQUEST_UNKNOWN_FIELD refusal for the unrecognised top-level keys unknown against the valid key set valid: details {unknown_keys (sorted), suggestions (unknown key → nearest valid key, when one is close), valid_keys (sorted)} and the message naming both lists. Nil when unknown is empty. It is THE shape of the error — the MCP strict decoder and the slot gate both build it here, so a hidden slot and an unknown key cannot drift apart.

func ValidateChain

func ValidateChain(fileData io.ReadSeeker, req *types.ChainRequest) *descriptor.Envelope

ValidateChain validates a ChainRequest against a .pulse cohort header + schema. It never reads record data — the no-execute contract holds. Errors land in the envelope as SERVICE_VALIDATION or PULSE_CHAIN_NOT_MERGEABLE / PULSE_CHAIN_EMPTY; each stage's inferred output schema is propagated forward so the next stage's field references can be checked.

The validator does not import internal/service or processing — predict's structural ban applies to the broader descriptor surface in spirit.

ValidateChain knows built-in operators only: it is ValidateChainWithExtensions with a nil snapshot, so every embedder-registered name fails the chain gate.

func ValidateChainFromBytes

func ValidateChainFromBytes(data []byte, req *types.ChainRequest) *descriptor.Envelope

ValidateChainFromBytes is a convenience wrapper that creates a reader from bytes.

func ValidateChainWithExtensions

func ValidateChainWithExtensions(fileData io.ReadSeeker, req *types.ChainRequest, snap *ExtensionsSnapshot) *descriptor.Envelope

ValidateChainWithExtensions is ValidateChain against an ExtensionsSnapshot, the predict-side twin of the runtime gate processing.CanChainRequestWithExtensions: an extension aggregator or grouper passes the chain gate on its DECLARED Mergeable flag (OperatorMeta.Mergeable), a row_local extension attribute as a row-local operator. The snapshot carries the declarations, so the no-execute ban holds (TestPredictNoExecutionImports). A nil snap is exactly ValidateChain.

func ValidateChainWithOptions

func ValidateChainWithOptions(fileData io.ReadSeeker, req *types.ChainRequest, opts *PredictOptions) *descriptor.Envelope

ValidateChainWithOptions is ValidateChain with the predict options in reach: opts.Extensions is the chain-gate snapshot, and opts.DefaultTimeZone / ZoneLoader / DisableDefaults / SchemaLoader drive the per-stage zone resolution — the runtime's order: defaults, zones, the chain gate, then the field-reference rule (FieldRefRefusals), weights, then the Process-predict request body (validateRequestBodyAt — operators, accepted types, the stage's own overlays and labels), each zone, field and body refusal tagged details.stage (a joined stage 0: gate, the join-count rule, the join-key rule, zones, then field references against the joined schema). The gate, the field checks and stage-schema propagation run on the defaulted stage, as the runtime does. A nil opts is ValidateChain.

opts.Strict promotes every warning the chain collected (stage 0's PULSE_VECTOR_METRIC_UNSUITED, a whole-chain overlay's PULSE_OVERLAY_CHAIN_STAGE_SHAPE_DIVERGENT) into an error at the chain envelope (finishPredictRoot); opts.EchoRequest echoes the normalized chain on env.Request (chainEcho).

func ValidateCompose

func ValidateCompose(req *types.ComposedRequest) *descriptor.Envelope

ValidateCompose runs the no-execute COMPOSE-host overlay walk over a *types.ComposedRequest. Returns an envelope whose Data carries a *ComposeValidationResult and whose Errors carry one entry per spec failure. The validator never reads record data; per-slot schema shape inference (MATRIX / SERIES / SCALAR) is derived from each slot's *types.Request alone via inferComposeSlotShape.

Under PredictOptions.EchoRequest the envelope's Request is the batch's normalized form (composeEcho); without it, nil.

func ValidateComposeExpanded

func ValidateComposeExpanded(req *types.ComposedRequest, opts *PredictOptions) (*descriptor.Envelope, *types.ComposedRequest)

ValidateComposeExpanded is ValidateComposeWithOptions also returning the effective request it judged — the sweep expanded into slots after the explicit ones (sweep.Expand) — so the facade can reach every slot cohort (the managed-import TTL) without expanding twice. The effective request is the input itself when it carries no sweep, and the input too when the sweep was refused before it expanded.

Options.Strict promotes every warning the batch collected (a slot's PULSE_VECTOR_METRIC_UNSUITED, located details.request) into an error at the batch envelope (finishPredictRoot); Options.EchoRequest echoes the normalized batch on env.Request (composeEcho).

func ValidateComposeWithOptions

func ValidateComposeWithOptions(req *types.ComposedRequest, opts *PredictOptions) *descriptor.Envelope

ValidateComposeWithOptions is ValidateCompose with the predict options in reach — today that means PredictOptions.Extensions, the read-only snapshot through which an embedder-registered grouper's fan-out declaration reaches the panel's within-prefix slab gate. descriptor/ may not import internal/processing/, so the snapshot is the only route; the runtime twin reads the live registry instead and both hand their resolver to the same types-side predicate.

Additive rather than a signature change on ValidateCompose: the no-options entry point shipped, and a host with no extensions gets the identical answer either way (a nil snapshot yields a nil resolver, which the gate reads as "no extension groupers").

func ValidateDefaultReturn

func ValidateDefaultReturn(r *types.Return, inst *InstanceSnapshot) error

ValidateDefaultReturn checks an instance `return` default (from Options.DefaultReturn or a feature profile) against inst: the same preset / precision / path-syntax / path-existence rules a request block meets, returning the resolver's own coded error. Nil r is valid. A `data[*].<column>` path is not judged here (no request, no schema): an instance default names columns openly and the runtime warns PULSE_RETURN_PATH_UNMATCHED when one matches nothing.

func ValidateFacet

func ValidateFacet(fileData io.ReadSeeker, req *types.FacetRequest) *descriptor.Envelope

ValidateFacet validates a FacetRequest against a .pulse cohort header + schema. It never reads record data — predict's "no execution" contract applies here too. Errors land in the envelope as SERVICE_VALIDATION; advisory issues (percentiles on a non-numeric field, a low DiscreteTopK, IncludeHistogram on a discrete-only request) become warnings.

Callers can use this to gate a UI before issuing the (potentially expensive) FacetSchema call.

func ValidateFacetFromBytes

func ValidateFacetFromBytes(data []byte, req *types.FacetRequest) *descriptor.Envelope

ValidateFacetFromBytes is a convenience wrapper that creates a reader from bytes.

func ValidateFacetOverlays

func ValidateFacetOverlays(env *descriptor.Envelope, req *types.FacetRequest, schema *encoding.Schema)

ValidateFacetOverlays walks every spec in req.Overlays and appends structural errors to the envelope. Sibling to ValidateOverlays — the Request-host validator — but enforces the FACET-host contract: the host is a FacetSchema FacetResult, the population reference is resolved against an alternate cohort, and the host-field the spec decorates is selected from FacetRequest.Fields.

No-op when req is nil or req.Overlays is empty. The schema is used for the per-kind host-arm gates (CHISQ rejects numeric; KS rejects categorical); when schema is nil those gates short-circuit.

func ValidateFacetOverlaysWithOptions

func ValidateFacetOverlaysWithOptions(env *descriptor.Envelope, req *types.FacetRequest, schema *encoding.Schema, opts *PredictOptions)

ValidateFacetOverlaysWithOptions is ValidateFacetOverlays with the predict options in reach: opts.Instance makes a kind the instance feature set hides fail the catalog probe like an unknown kind.

func ValidateFacetWithExtensions

func ValidateFacetWithExtensions(fileData io.ReadSeeker, req *types.FacetRequest, snap *ExtensionsSnapshot) *descriptor.Envelope

ValidateFacetWithExtensions extends ValidateFacet with the embedder-registered extension snapshot so label-table references can be resolved. Pass nil to opt out (same behavior as ValidateFacet).

func ValidateFacetWithOptions

func ValidateFacetWithOptions(fileData io.ReadSeeker, req *types.FacetRequest, opts *PredictOptions) *descriptor.Envelope

ValidateFacetWithOptions is ValidateFacet with the predict options in reach: opts.Extensions resolves label tables, and opts.DefaultTimeZone / ZoneLoader drive the filterer zone resolution (ResolveFacetZones — the pass FacetSchema runs). A nil opts is ValidateFacet.

opts.Strict promotes every warning the facet collected into an error (finishPredictRoot); opts.EchoRequest echoes the request on env.Request as passed — the form the runtime facet echoes.

func ValidateJoin

func ValidateJoin(leftData, rightData io.ReadSeeker, req *types.Request) *descriptor.Envelope

ValidateJoin validates a Request whose Joins slot carries one JoinSpec against the headers + schemas of the left and right cohorts. It never reads record data — descriptor's no-execute contract applies. Errors land as SERVICE_VALIDATION or PULSE_JOIN_*; emits JoinedFields when the join would succeed at runtime.

func ValidateJoinFromBytes

func ValidateJoinFromBytes(left, right []byte, req *types.Request) *descriptor.Envelope

ValidateJoinFromBytes is a convenience wrapper around byte buffers.

func ValidateLabels

func ValidateLabels(
	env *descriptor.Envelope, bindings []*types.LabelBinding,
	schema *encoding.Schema,
	snap *ExtensionsSnapshot,
	inst *InstanceSnapshot,
	extraFields map[string]bool,
) (augmentNames map[string]bool)

ValidateLabels walks a slice of LabelBindings against the resolved schema and the extension snapshot, surfacing per-binding failures as envelope errors. ValidateLabels never reads record data — it is safe to call from any no-execute predict path.

Validation order is deterministic: bindings are inspected in input order; the first failure per binding is recorded but later bindings are still examined so callers see every problem in one pass.

`extraFields` lists output-only field names that count as occupying the schema namespace for augment-mode collision detection (e.g. aggregation output labels, attribute labels). Pass nil when only raw schema fields matter.

Returns the set of (output) field names occupied by augment-mode sibling columns so callers can fold them into downstream collision checks (group keys, sort keys against the augmented schema).

func ValidateMultiplicitySpec

func ValidateMultiplicitySpec(m *types.Multiplicity, where string) error

ValidateMultiplicitySpec checks a block's own values — a known method and family and an alpha inside (0, 1) — with where naming it in the refusal ("Options.DefaultMultiplicity", "tests[0].multiplicity"). A nil block is valid. pulse.New applies it to Options.DefaultMultiplicity; the resolver runs it on every block before the per-surface rules.

func ValidateOverlays

func ValidateOverlays(env *descriptor.Envelope, req *types.Request, schema *encoding.Schema, opts *PredictOptions)

ValidateOverlays walks every spec in req.Overlays and appends structural errors to the envelope. Exported so engines and tests can run the validator standalone; Predict wires it inline so overlay issues surface alongside crosstab / aggregator / test ones.

No-op when req is nil or req.Overlays is empty. Schema is currently unused — every rule is structural — but the signature accepts it so later kinds can validate against schema-derived state (e.g. referenced field types on sibling / baseline-index families) without re-opening every call site.

Level / Within out-of-range gate: runs alongside the per- kind ref/scope checks via validateOverlayLevelWithinPredict. Mirrors the PULSE_CROSSTAB_NORMALIZE_LEVEL_OUT_OF_RANGE shape on the crosstab path — out-of-range slots surface PULSE_OVERLAY_LEVEL_OUT_OF_RANGE on the envelope with Details carrying the spec index, kind, level / within, and the axis depth. The runtime mirror lives at processing.validateOverlayLevelWithinRuntime so a programmatic Process caller that skipped predict still gets the same failure shape.

func ValidateSkillFences

func ValidateSkillFences(body string, g *OntologyGraph) error

ValidateSkillFences checks body's fences against g (nil = the base graph): each must parse, and each name must be a node of g — a built-in feature, or an operator g carries. The error is a *skills.FenceError (Line = the opener's line).

func ValidateSuppressAdvisories

func ValidateSuppressAdvisories(codes []string) error

ValidateSuppressAdvisories refuses an Options.SuppressAdvisories entry that is not a registered advisory code with PULSE_SUPPRESS_ADVISORY_UNKNOWN (details: code, valid). Validated against the whole registry, not the instance view: suppressing a code a feature profile can never fire is harmless.

func ValidateWeightSpec

func ValidateWeightSpec(spec *types.WeightSpec, where string) error

ValidateWeightSpec is the shape rule every weight passes before any schema is consulted: a non-empty field and a known kind (empty means probability). where names the weight in the refusal ("weight", "aggregations[0].weight", "Options.DefaultWeight"). A nil spec is valid (no weight). pulse.New applies it to Options.DefaultWeight; the resolver applies it to every request and slot weight.

func VisibleSlotKeys

func VisibleSlotKeys(sample any, inst *InstanceSnapshot) []string

VisibleSlotKeys returns JSONObjectKeys(sample) minus HiddenSlotKeys, in declaration order — the instance's valid top-level keys.

func WeightFloorKeys

func WeightFloorKeys() []descriptor.ComponentKey

WeightFloorKeys returns the optional weighted floor keys (sum_weights, n_eff, n_weight_invalid) a weighted aggregator or matrix slot adds beside its floor.

func WeightedMeanParamField

func WeightedMeanParamField(a *types.Aggregation) string

WeightedMeanParamField returns AGG_WEIGHTED_MEAN's `params.weight_field` (the slot-weight sugar), or "" when the aggregation is another type, carries no such key, or its params do not decode (the factory owns that refusal).

func WindowFrameRequired

func WindowFrameRequired(t types.WindowType) bool

WindowFrameRequired reports whether predict refuses a window of type t that carries no frame — the rule Recommend's drafts ask the caller to satisfy.

func ZoneCapabilityOf

func ZoneCapabilityOf(name string) string

ZoneCapabilityOf returns the declared zone participation for a built-in operator or overlay kind name: ZoneCapable, ZoneFollowing, or "" when the name is not zone-capable (including every extension operator and every unknown name).

func ZonedFacetRequest

func ZonedFacetRequest(req *types.FacetRequest, zones []descriptor.ResolvedZone, load ZoneLoader) *types.FacetRequest

ZonedFacetRequest is ZonedRequest for a FacetRequest's filterers; zones is ResolveFacetZones' result for req.

func ZonedRequest

func ZonedRequest(req *types.Request, zones []descriptor.ResolvedZone, load ZoneLoader) *types.Request

ZonedRequest returns the Request an execution arm runs: req itself when no INHERITED zone (request `time_zone` or the options default) that is not UTC-equivalent resolved onto a slot, otherwise a shallow copy whose affected slots are copies carrying that zone in their `tz`. zones is ResolveZones' result for req; load resolves a name (nil: temporal.LoadZone).

The operator factories see only the slot and the schema, so the zone rides on the slot: every arm (buffered, streaming, fused crosstab, parallel decode, shard reduce, chain stages) builds its operators from the returned request and sees the zone with no further plumbing. An explicit slot `tz` is already on the slot, an inherited zone on a non-`datetime` field resolved to a null TZ and is never written, and a UTC-equivalent zone is never written — so the zone-free request executes the unchanged object. req is never mutated: the caller's request (request echo, request hashing, the Compose echo) stays exactly as the caller wrote it plus smart defaults.

Types

type ChainOverlaySchemaDivergence

type ChainOverlaySchemaDivergence struct {
	// Index is the position of the offending spec in
	// ChainRequest.Overlays.
	Index int `json:"index"`

	// Kind echoes the spec's whole-chain overlay kind.
	Kind types.OverlayKind `json:"kind"`

	// RefIndex is the resolved stage index of the spec's Ref.
	RefIndex int `json:"ref_index"`

	// RefShape is the inferred OverlayShape of the Ref stage's
	// Request slot.
	RefShape types.OverlayShape `json:"ref_shape"`

	// TargetIndex is the resolved stage index of the spec's Target
	// (defaulting to the latest stage when both Target slots were
	// empty per the runtime resolver contract).
	TargetIndex int `json:"target_index"`

	// TargetShape is the inferred OverlayShape of the Target stage's
	// Request slot.
	TargetShape types.OverlayShape `json:"target_shape"`
}

ChainOverlaySchemaDivergence carries one shape-divergent (Ref, Target) chain-overlay pair from ValidateChain's overlay walk. Mirrors the per-spec envelope-warning Details shape so wire consumers can read the list directly instead of stitching envelope entries together.

type ChainValidationResult

type ChainValidationResult struct {
	// Valid mirrors envelope.Errors emptiness.
	Valid bool `json:"valid"`

	// Request echoes the input chain request unchanged.
	Request *types.ChainRequest `json:"request"`

	// SchemaInfo summarises the source cohort schema used for stage 0.
	SchemaInfo *descriptor.PredictSchemaInfo `json:"schema_info,omitempty"`

	// StageSchemas exposes the inferred output schema per stage as a
	// list of field names. Index i carries the columns produced by
	// stage i (input to stage i+1). Useful for debugging chain breaks
	// when stage N+1 cannot find a field stage N was expected to emit.
	StageSchemas [][]string `json:"stage_schemas,omitempty"`

	// OverlaysSchemaDivergence lists every shape-divergent (Ref, Target)
	// chain-overlay pair from the ValidateChain overlay walk per
	// kind-catalog-v1 PRD §I-FR-I3. Populated alongside the matching
	// PULSE_OVERLAY_CHAIN_STAGE_SHAPE_DIVERGENT envelope WARNING (the
	// runtime answers that pair with an empty layer) so LLM
	// planners can budget reshapes without re-parsing envelope details.
	// Empty (and omitted on the wire) when every chain-overlay spec
	// passes the shape-match gate.
	OverlaysSchemaDivergence []ChainOverlaySchemaDivergence `json:"overlays_schema_divergence,omitempty"`

	// LimitFindings lists every instance resource limit the chain's
	// predicted figures exceed, graded like PredictResult.LimitFindings:
	// the stage count (MaxChainStages, certain, unlocated), then each
	// stage's Request findings located by details.stage. Stage 0 is
	// judged on the cohort's header count, exactly as its Process
	// pre-flight; a later stage's input rows exist only at runtime, so
	// it carries no memory estimate and its group bounds are unclamped.
	// A certain finding is also a PULSE_LIMIT_EXCEEDED error. Omitted
	// when none fires.
	LimitFindings []descriptor.LimitFinding `json:"limit_findings,omitempty"`
}

ChainValidationResult is the structured output of ValidateChain. Mirrors FacetValidationResult: the resolved request echoes back so callers can forward it after inspection, and per-stage schemas expose the inferred lineage for debugging.

type CohortCounts

type CohortCounts struct {
	Records      int64
	ShardRecords []int64
	ArchiveBytes int64
}

CohortCounts are the header facts of one cohort the limit rules read (LimitInputs.Records / ShardRecords / ArchiveBytes): the record count (-1 unknown), an archive's per-shard counts and its byte length, an anchor-opened shard's archive length. PredictOptions. CohortCounter returns them for a Compose slot's (or fit's) cohort — the facade passes the runtime pre-flight's own reader, so a slot's certain finding carries the figure the slot's Process refuses with.

type CommandBinding

type CommandBinding struct {
	Command string
	Feature string
	Core    string
	Ungated bool
}

CommandBinding records which feature (or core surface) owns one manifest command (a CLI leaf, Manifest.Commands) or library-only operation (Manifest.Operations). Exactly one of Feature, Core and Ungated is set. Ungated marks a process-level leaf that describes the binary rather than the instance (the MCP server, the build version): it is neither a feature nor a core surface and is always listed.

func CommandBindingOf

func CommandBindingOf(command string) (CommandBinding, bool)

CommandBindingOf returns the binding for one manifest command or operation name.

func CommandBindings

func CommandBindings() []CommandBinding

CommandBindings returns the manifest command / operation → feature table in a stable order.

type ComponentFloor

type ComponentFloor struct {
	// Slot is the Response.Components field the floor belongs to
	// ("aggregations", "groupers", "filterers", "matrices",
	// "attributes"), which is
	// also the Manifest.ComponentsSchemas sub-map of its operators.
	Slot string
	// Keys are the floor keys, in emission order.
	Keys []descriptor.ComponentKey
}

ComponentFloor is one Response.Components slot's floor: the keys the orchestrator fills on every entry of the slot, ahead of the operator's own keys. Every built-in ComponentSchema of the slot opens with them (TestComponentFloors_PrefixEverySchema).

func ComponentFloors

func ComponentFloors() []ComponentFloor

ComponentFloors returns the floor of every Response.Components slot that carries per-operator schemas, in Response.Components order. The generated reference (internal/docgen) reads it so the floor it documents is the floor the capability tables declare.

type ComposeMultiplicityPlan

type ComposeMultiplicityPlan struct {
	Requests []*MultiplicityPlan
	Overlays []ResolvedMultiplicity
}

ComposeMultiplicityPlan is the resolved correction of one ComposedRequest: one plan per slot request (index-aligned; nil when nothing applies to that slot) plus one entry per Compose-host overlay.

func ResolveComposeMultiplicity

func ResolveComposeMultiplicity(req *types.ComposedRequest, def *types.Multiplicity, inst *InstanceSnapshot) (*ComposeMultiplicityPlan, error)

ResolveComposeMultiplicity is ResolveMultiplicity for a whole ComposedRequest: each slot request resolves with the Compose request's block between its own and def (and may use the `compose` family), a refusal located with details.request; then each Compose-host overlay resolves (own → Compose request → def; families `layer`, `row` / `column` for a MATRIX kind, `compose` — never `request`); then every `compose`-family member, across slots and Compose-host overlays, must agree on one method (PULSE_MULTIPLICITY_CONFLICT, member slots prefixed "requests[i]."). Nil when nothing names a block.

type ComposeValidationResult

type ComposeValidationResult struct {
	// Valid mirrors envelope.Errors emptiness.
	Valid bool `json:"valid"`

	// Request echoes the input composed request unchanged.
	Request *types.ComposedRequest `json:"request"`

	// OverlaysSchemaDivergence lists every (reference, target)
	// pair the overlay walk rejected per PRD §I-FR-I3. Populated
	// alongside the matching envelope error so MCP planners can
	// budget reshapes without re-parsing envelope details. Empty
	// (but non-nil) when every spec passes; never nil so JSON
	// renderers see an empty array, matching PredictResult's
	// contract.
	OverlaysSchemaDivergence []descriptor.SlotPair `json:"overlays_schema_divergence"`

	// OverlayCost maps each COMPOSE-host overlay-spec Name to a coarse
	// cost score the routing layer can consult before execution. Sibling
	// to PredictResult.OverlayCost / FacetValidationResult.OverlayCost —
	// streamable kinds carry overlayCostStreamable (~5% extra work) and
	// buffered kinds carry overlayCostBuffered (~one extra payload
	// traversal). The two multi-ref kinds (OVERLAY_PROP_Z_PANEL,
	// OVERLAY_PANEL_INDEX_VS_REF) scale the base cost by
	// `min(len(spec.Targets), MaxPanelTargets)` so renderers can budget
	// per-panel fan-out without re-deriving the cap. Single-target kinds
	// ignore the Targets slice and surface the raw kind cost. Per
	// kind-catalog-v1 PRD §I-FR-I3 the value is intentionally coarse —
	// callers budgeting cost across slots sum the map values. Empty (but
	// non-nil) when req.Overlays is empty; never nil in JSON output.
	OverlayCost map[string]float64 `json:"overlay_cost"`

	// PValues counts the inferential p-values the Compose-host overlays
	// emit and how many no multiplicity block corrects. Their extent
	// depends on slot results predict never sees, so each inferential
	// spec counts as one and the basis is always lower_bound. Omitted
	// when no host overlay is inferential, when the batch multiplicity is
	// refused, and when the instance hides capability:multiplicity.
	PValues *descriptor.PValueCount `json:"p_values,omitempty"`

	// Advisories carries the coded, non-blocking PULSE_ADVISORY_* notes:
	// each slot's Request advisories in slot order (details.request = the
	// slot index, every slot path prefixed "requests[i]."), then
	// PULSE_ADVISORY_MANY_TESTS over PValues. Never a warning; omitted
	// when none fires.
	Advisories []descriptor.Advisory `json:"advisories,omitempty"`

	// Sweep summarises what the request's `sweep` block expands to —
	// axes, resolved mode, expanded slot count and (once expanded) the
	// sweep slots' labels. Set whenever the sweep is structurally
	// valid, also on a refused batch; omitted without a sweep.
	Sweep *descriptor.SweepSummary `json:"sweep,omitempty"`

	// Fits lists the request's `fits` entries in declaration order —
	// name, regression type, target, the predictors as written and the
	// cohort — read statically, never fitted. Set once the fits pass
	// their structural rules (model.CheckFits); omitted without fits.
	Fits []descriptor.FitSummary `json:"fits,omitempty"`

	// LimitFindings lists every instance resource limit the batch's
	// predicted figures exceed, graded like PredictResult.LimitFindings:
	// the slot count (MaxComposeSlots — explicit plus sweep-expanded —
	// certain, unlocated), then each slot's Request findings located by
	// details.request, then each fit request's by details.fit. A slot is
	// judged on its cohort's header counts (PredictOptions.
	// CohortCounter), the figures its Process pre-flight reads. A
	// certain finding is also a PULSE_LIMIT_EXCEEDED error. Omitted when
	// none fires.
	LimitFindings []descriptor.LimitFinding `json:"limit_findings,omitempty"`
}

ComposeValidationResult is the structured output of ValidateCompose. Mirrors ChainValidationResult / FacetValidationResult: the input request echoes back so callers can forward it after inspection, and the per-spec divergence slice is populated alongside the envelope errors so renderers can read the rejected (reference, target) pairs without re-parsing envelope details.

type Discovery

type Discovery struct {
	// contains filtered or unexported fields
}

Discovery is one instance's view of the embedded skill pack and request example library, read off the instance's PRUNED ontology graph (ontology_instance.go): a skill or example is visible iff its node survived the prune. It keeps a feature-profiled instance from advertising a skill or example for a surface it does not offer.

Every discovery path reads through it — pulse_skills_list / pulse_skills_get, pulse_examples_search / pulse_examples_get (via the facade's ExamplesSearch / ExampleGet), the pulse-skill:// enumeration and template read, and the manifest's skills list and examples count / categories / tags — so they agree. A pruned skill or example is absent from every listing and an exact-name read of it takes the same not-found path as a name that never existed (parity principle).

Visibility is the graph prune (pruneOntology): an atomic skill follows the operator or MCP tool it documents, a topical skill goes when any `requires:` feature is hidden, an example goes when an operator it exemplifies, a capability it requires or an operator its description routes to is hidden. Type skills and the virtual intents / glossary skills always stay; the virtual bodies render from the pruned graph (an intent no enabled operator serves, a term every user of which is hidden, is absent). Rendering on top of visibility:

  • every surviving skill's listed metadata (description, applies_to, covers, examples_tags) is rendered through the instance's ProseScrub, so it names no hidden operator or tool (a frontmatter description cannot hold a feature fence);
  • every surviving embedded BODY — atomic and topical — is rendered by its feature fences against the pruned graph, and an atomic body's `## See` section by edge (skill_render.go). Fence markers are always stripped. Prose outside a fence is served as written: a body names a hidden feature only where it is not fenced yet.

Embedder skills and examples (Extensions.Skills / .Examples) are nodes of the same graph and are served next to the built-ins: skills merged by name, examples through one merged, name-sorted library.

A Discovery with nothing hidden (no feature profile, or a profile that hides nothing) passes every call straight through to the embedded packages, so profile-free output is byte-identical.

func (*Discovery) Example

func (d *Discovery) Example(name string) (*examples.Example, bool)

Example returns a visible example; a pruned name answers exactly as a nonexistent one (nil, false).

func (*Discovery) ExampleStats

func (d *Discovery) ExampleStats() (count int, categories, tags []string)

ExampleStats returns the manifest's examples count, categories and tags over the visible examples. A category or tag carried only by pruned examples is absent. Slices are sorted and never nil.

func (*Discovery) ExampleVisible

func (d *Discovery) ExampleVisible(name string) bool

ExampleVisible reports whether the instance exposes the named example.

func (*Discovery) ExamplesSearch

func (d *Discovery) ExamplesSearch(query string, tags []string, category string) []examples.ExampleSummary

ExamplesSearch is examples.Search minus the pruned examples; ranking and order of the survivors are unchanged. Visible embedder examples are searched with them, ranked by the same rules. Never nil.

func (*Discovery) SearchExamples

func (d *Discovery) SearchExamples(q examples.Query, opts examples.Options) []examples.ExampleSummary

SearchExamples is examples.SearchQuery over the instance's visible library (the embedded examples minus the pruned ones, plus the visible embedder examples). A pruned example is dropped before any match tier runs, so it never decides which tier answers. opts carries the synonym tables; its KeepExample is set here. Never nil.

func (*Discovery) Skill

func (d *Discovery) Skill(name string) (string, bool)

Skill returns the markdown body of a visible skill; a pruned name answers exactly as a nonexistent one ("", false). An embedded body is rendered for the instance (renderBody, skill_render.go): its feature fences against the pruned graph and, atomic only, its `## See` section by edge — so a table row, list item or code block survives whole or goes whole. The virtual intents / glossary bodies render from the pruned graph. The pass-through view serves skills.Get (the full render: every fence kept, markers stripped).

func (*Discovery) SkillVisible

func (d *Discovery) SkillVisible(name string) bool

SkillVisible reports whether the instance exposes the named skill.

func (*Discovery) Skills

func (d *Discovery) Skills() []skills.Metadata

Skills is skills.List() minus the pruned skills, in the same order, each survivor's metadata rendered for the instance: the description prose-scrubbed and every applies_to / covers / examples_tags entry naming a hidden token dropped (topical metadata included; bodies render by feature fence in Skill).

Visible embedder skills (Extensions.Skills) are merged in by name.

type ExtensionExample

type ExtensionExample struct {
	// Example is the served record: Body is the request with `_meta`
	// stripped, re-marshaled deterministically.
	Example      examples.Example
	Intents      []string
	Capabilities []string
	// ExtOperators are the registered extension operators the example
	// names anywhere (body, description, `_meta.operators`); the example
	// is no node of an instance that hides any of them.
	ExtOperators []string
}

ExtensionExample is one validated embedder example.

func LoadExtensionExamples

func LoadExtensionExamples(fsys fs.FS, ext *ExtensionsSnapshot) ([]ExtensionExample, error)

LoadExtensionExamples reads and validates every example in fsys against ext (the snapshot of EVERY registration — not the profile-filtered one). Nil fsys loads nothing. The examples come back sorted by name.

type ExtensionMatrixOp

type ExtensionMatrixOp struct {
	Accepts    []encoding.FieldType
	OutputKeys descriptor.MatrixOutputKeys
	PValues    string
	// Params are the operator's own params in the manifest's Param
	// shape; the engine-owned missing / max_drop_share are prepended by
	// the manifest projection (MatrixMemberParams).
	Params []descriptor.Param
}

ExtensionMatrixOp is one extension MAT_* operator's facts beyond its OperatorMeta projection (ExtensionsSnapshot.MatrixOps): the typed member types it accepts (empty: the built-in member types), its declared OutputKeys and the auxiliary key holding its p-values ("": it opts out of multiplicity correction).

type ExtensionSkill

type ExtensionSkill struct {
	Metadata skills.Metadata
	Raw      string
}

ExtensionSkill is one validated embedder skill: its parsed frontmatter and its file verbatim (fences and all).

func LoadExtensionSkills

func LoadExtensionSkills(fsys fs.FS, ext *ExtensionsSnapshot, deps map[string][]string) ([]ExtensionSkill, error)

LoadExtensionSkills reads and validates every skill in fsys against ext (the snapshot of EVERY registration — not the profile-filtered one) and deps (each extension operator's DependsOn). Nil fsys loads nothing. The skills come back sorted by name.

type ExtensionsSnapshot

type ExtensionsSnapshot struct {
	Aggregators        []descriptor.OperatorMeta
	Attributes         []descriptor.OperatorMeta
	Filterers          []descriptor.OperatorMeta
	Groupers           []descriptor.OperatorMeta
	Windows            []descriptor.OperatorMeta
	Features           []descriptor.OperatorMeta
	Tests              []descriptor.OperatorMeta
	SynthDistributions []descriptor.OperatorMeta
	// MatrixOps are the extension MAT_* operators
	// (pulse.MatrixOpRegistration): Name, Namespace, Description,
	// Streamable (the declared tier; Mergeable follows it), WeightAware,
	// Accepts and Params, so every per-category walk (MCP enums, the
	// ontology, the merge gate, the weight resolver) reads them like any
	// other category. MatrixDetails carries the matrix-only facts.
	MatrixOps        []descriptor.OperatorMeta
	ExprFunctions    []descriptor.ExprFunctionMeta
	LookupTables     []descriptor.LookupTableMeta
	ReferenceVectors []descriptor.ReferenceVectorMeta
	LabelTables      []descriptor.LabelTableMeta
	RangeTables      []descriptor.RangeTableMeta
	// Populations are the instance's registered populations: the names
	// and member labels predict binds beneath every request (the
	// runtime's registered set, statically — PopulationCatalog).
	Populations []descriptor.PopulationMeta

	// ComponentSchemas projects per-extension ComponentSchema
	// declarations keyed by registered operator name. The map carries
	// aggregator / grouper / filterer schemas declared via
	// pulse.AggregatorRegistration.ComponentSchema (and the matching
	// grouper / filterer variants) so manifest + predict surface
	// extension operators on the same shape as built-ins. Missing
	// entries are equivalent to floor-only registrations — the
	// orchestrator emits the universal floor without operator-
	// specific extras.
	//
	// Wired by buildExtensionsSnapshot in pulse.New; manifest assembly
	// merges this map into ComponentsSchemas alongside the built-in
	// capability tables, and predict's per-slot ComponentSchema
	// lookups fall through to this map when the built-in capability
	// table does not carry an entry for the slot's operator name.
	ComponentSchemas map[string]descriptor.ComponentSchema

	// MatrixDetails carries each extension MAT_* operator's matrix-only
	// facts (typed Accepts, OutputKeys, the p-value key, manifest
	// params), keyed by name; its own ComponentSchema keys ride
	// ComponentSchemas. Never serialised.
	MatrixDetails map[string]ExtensionMatrixOp `json:"-"`

	// OverlayKinds is the forward-compat reservation slot for
	// embedder-registered overlay catalog entries. The runtime
	// pulse.Options.Extensions.OverlayKinds registration surface
	// (referenced in types/overlay.go) is not yet implemented; this
	// snapshot slot exists so the MCP per-facade schema binders
	// (mcp/gosdk/bind.go) can merge custom kind names
	// into the per-facade overlay_kind enum the moment the
	// registration surface lands — no churn on the binder when the
	// runtime catches up. Today the slot is populated by tests
	// only; production code paths leave it nil and the per-facade
	// enums fall back to the built-in catalog drawn from
	// types.AllOverlayKinds() via descriptor.OverlayCapabilities().
	// Each entry carries Name (SCREAMING_SNAKE OVERLAY_* constant)
	// alongside the standard OperatorMeta knobs so the per-facade
	// classifier can route an extension kind onto the right tool's
	// enum once the registration surface declares which facade(s)
	// the custom kind targets. v1 lacks the per-kind facade tag —
	// the binder treats every snapshot entry as Request-facade
	// only (the lowest-risk fallback) until the registration
	// surface lands the tag.
	OverlayKinds []descriptor.OperatorMeta

	// FieldInputs carries each registration's optional FieldInputs hook
	// (pulse.FieldInputsFunc — the callback the runtime's buffered
	// projection already consults), keyed "<category>|<name>" with the
	// category spelled as processing.StreamabilityKey spells it
	// (aggregator, attribute, filterer, grouper, window, feature, test).
	// FieldRefRefusals calls it with the slot's Params so the
	// no-execute layer judges the names an extension declares it reads,
	// exactly as the runtime does; a registration without the hook is
	// absent and its params are not judged. Never serialised.
	FieldInputs map[string]func(raw json.RawMessage) []string `json:"-"`

	// Purposes carries each registration's optional Purpose, keyed by
	// registered operator name, already validated at pulse.New. The
	// manifest projects only its intent IDs (OperatorMeta.Intents); the
	// prose stays on demand. A registration without a Purpose is absent.
	// Never serialised.
	Purposes map[string]descriptor.Purpose `json:"-"`

	// Interpretations carries each test registration's optional
	// Interpretation entries, keyed by registered test name, already
	// structure-checked at pulse.New. Never serialised.
	Interpretations map[string][]descriptor.Interpretation `json:"-"`

	// Skills carries every embedder skill (Extensions.Skills), already
	// validated at pulse.New against EVERY registration
	// (LoadExtensionSkills). The instance graph keeps the ones whose
	// operator / requires survive the profile (extendOntology).
	// Never serialised.
	Skills []ExtensionSkill `json:"-"`

	// Examples carries every embedder example (Extensions.Examples),
	// already validated at pulse.New against EVERY registration
	// (LoadExtensionExamples). The instance graph keeps the ones whose
	// extension operators survive the profile (extendOntology), then
	// prunes them like built-ins. Never serialised.
	Examples []ExtensionExample `json:"-"`
}

ExtensionsSnapshot is the immutable read-only view that the service hands to descriptor.BuildManifestWithExtensions and predict. It carries everything the manifest + predict surfaces need without importing the live processing registry — keeping TestPredictNoExecutionImports satisfied.

func (*ExtensionsSnapshot) AggregatorMarginReducibility

func (s *ExtensionsSnapshot) AggregatorMarginReducibility(t types.AggregationType) types.MarginReducibility

AggregatorMarginReducibility reports the crosstab margin class of aggregator t: an extension's DECLARED class from the snapshot (empty reads as types.MarginRecompute, the not-fusable default), else the built-in per-type MarginReducibility(). The no-execute twin of processing.ExtensionRegistry.AggregatorMarginReducibility. Nil-safe.

func (*ExtensionsSnapshot) DeclaredFieldInputs

func (s *ExtensionsSnapshot) DeclaredFieldInputs(category, name string, raw json.RawMessage) (names []string, ok bool)

DeclaredFieldInputs returns the field names the extension operator (category, name) declares it reads for params raw, and whether it declares any hook at all. A hook that panics is treated as no declaration (ok=false) rather than crashing predict or the runtime check — the same input the projection extractor would then widen for. Nil-safe.

func (*ExtensionsSnapshot) GrouperFanOut

func (s *ExtensionsSnapshot) GrouperFanOut(name string) (fansOut bool, ok bool)

GrouperFanOut reports the fan-out fact an embedder declared for the grouper registered under name, and whether the snapshot carries such a grouper at all. Nil-snapshot-safe: ok=false.

This is the descriptor half of the bridge that keeps predict free of internal/service/ and internal/processing/ imports (TestPredictNoExecutionImports). The runtime half is processing.ExtensionRegistry.GrouperFanOut; both feed types.CheckPairwiseSlabPartitionWith, which owns the built-in- first resolution order so the two arms cannot drift.

Takes a plain string rather than types.GroupType so the accessor stays usable from the manifest side, where names are untyped.

func (*ExtensionsSnapshot) HasAggregator

func (s *ExtensionsSnapshot) HasAggregator(name string) bool

HasAggregator reports whether name is an embedder-registered aggregator in the snapshot. Nil-safe.

func (*ExtensionsSnapshot) PopulationCatalog

func (s *ExtensionsSnapshot) PopulationCatalog() model.Catalog

PopulationCatalog is predict's view of the registered populations: each a vector fit bound under its name with its member labels (model.RegisteredSignature — the runtime's registered set, statically). Nil (not a typed nil) when none are registered, so a rule judging against it is exactly the one judging against nothing.

func (*ExtensionsSnapshot) PurposeOf

func (s *ExtensionsSnapshot) PurposeOf(name string) (descriptor.Purpose, bool)

PurposeOf returns the Purpose the extension operator name declares. Nil-safe.

func (*ExtensionsSnapshot) ReferenceTables

func (s *ExtensionsSnapshot) ReferenceTables() vectors.ReferenceTables

ReferenceTables is the predict view of the snapshot's reference-vector tables: labels and keys, no profile values (vectors.ReferenceTable).

func (*ExtensionsSnapshot) WeightAwareness

func (s *ExtensionsSnapshot) WeightAwareness(category, name string) (registered, aware bool)

WeightAwareness reports whether name is an embedder-registered operator of category ("aggregator", "attribute", "test" — tier-1 and tier-2 tests alike — or "matrix") and, if so, whether its registration declared WeightAware. Nil-safe: a nil snapshot registers nothing.

type FacetValidationResult

type FacetValidationResult struct {
	// Valid mirrors envelope.Errors emptiness.
	Valid bool `json:"valid"`

	// Request echoes the input request unchanged.
	Request *types.FacetRequest `json:"request"`

	// SchemaInfo summarises the cohort schema used for validation.
	SchemaInfo *descriptor.PredictSchemaInfo `json:"schema_info,omitempty"`

	// OverlaysApplied lists every FACET-host overlay spec the validator
	// accepted, in req.Overlays order. Each entry echoes the catalog
	// identity (Name, Kind, Scope) plus the streamability flag harvested
	// from types.OverlayStreamable(kind) so the caller can reason about
	// the buffered/streaming routing decision without re-parsing the
	// spec. Empty when req.Overlays is empty; never nil in JSON output.
	//
	// Per kind-catalog-v1 PRD §I-FR-I3 the FACET-host predict surface
	// mirrors the Request-host predict surface so LLM callers see the
	// same per-spec descriptor shape regardless of host. The four
	// FACET-host kinds (OVERLAY_INDEX_VS_POP / OVERLAY_ZSCORE_VS_POP /
	// OVERLAY_CHISQ_VS_POP / OVERLAY_KS_VS_POP) route onto this
	// surface; sibling to PredictResult.OverlaysApplied.
	OverlaysApplied []descriptor.OverlayAppliedDescriptor `json:"overlays_applied"`

	// OverlayCost maps each FACET-host overlay-spec Name to a coarse
	// cost score the routing layer can consult before execution. Sibling
	// to PredictResult.OverlayCost — streamable kinds carry
	// overlayCostStreamable (~5% extra work) and buffered kinds carry
	// overlayCostBuffered (~one extra payload traversal). Per kind-
	// catalog-v1 PRD §I-FR-I3 the value is intentionally coarse — callers
	// budgeting cost across slots sum the map values. Empty when
	// req.Overlays is empty; never nil in JSON output.
	OverlayCost map[string]float64 `json:"overlay_cost"`

	// PValues counts the inferential p-values the facet overlays emit
	// (one per OVERLAY_CHISQ_VS_POP / OVERLAY_KS_VS_POP spec) and how
	// many no multiplicity block corrects — PredictResult.PValues for the
	// FACET host. Omitted when no p-value is emitted, when the overlays'
	// multiplicity is refused, and when the instance hides
	// capability:multiplicity.
	PValues *descriptor.PValueCount `json:"p_values,omitempty"`

	// Advisories carries the coded, non-blocking PULSE_ADVISORY_* notes
	// predict raises on the facet request — PredictResult.Advisories for
	// the FACET host; never a warning. A FacetRequest has no test,
	// aggregator or weight slot, so only PULSE_ADVISORY_MANY_TESTS can
	// fire. Omitted when none does.
	Advisories []descriptor.Advisory `json:"advisories,omitempty"`

	// LimitFindings lists every instance resource limit the facet's
	// predicted figures exceed — PredictResult.LimitFindings for the
	// FACET host (FacetLimitFindings: a possible MaxGroups bound from the
	// faceted fields' dictionary sizes, the certain MaxEstimatedMemory
	// estimate the pre-flight refuses with). A certain finding is also a
	// PULSE_LIMIT_EXCEEDED error. Omitted when none fires.
	LimitFindings []descriptor.LimitFinding `json:"limit_findings,omitempty"`
}

FacetValidationResult is the structured ValidateFacet output. Mirrors the predict surface: the resolved request is echoed back verbatim (callers may want to forward it to FacetSchema after inspection) and Warnings carry advisory issues that do not block execution.

type Feature

type Feature struct {
	// Name is the one spelling a profile uses: bare for operators,
	// `<kind>:<name>` for every other kind. There are no aliases.
	Name string
	// Kind classifies the row.
	Kind FeatureKind
	// Since is the Pulse release (major.minor.patch) that introduced the
	// feature.
	Since string
	// DependsOn is the feature's dependency expression: the AND of its
	// groups, each group an any-of set of feature names. A feature is
	// usable only when, for EVERY group, at least one named feature is
	// also present. nil means no dependency. Rows never spell this by
	// hand — withDependencies derives it from the host rules and the
	// hard-edge table below.
	DependsOn [][]string
}

Feature is one row of the internal feature table. It is deliberately NOT a field on any public struct (descriptor.Operator and friends stay untouched), so the manifest and public API goldens do not move.

func Features

func Features() []Feature

Features returns every built-in feature row in table order. The slice is a fresh copy; duplicates (a table bug the gate refuses) are kept so the gate can see them.

func LookupFeature

func LookupFeature(name string) (Feature, bool)

LookupFeature returns the built-in row spelled exactly name.

type FeatureBehaviour

type FeatureBehaviour struct {
	DisableDefaults   bool
	DisableComponents bool
	DisableProjection bool
	DisableCohortScan bool
}

FeatureBehaviour is the EFFECTIVE set of engine switches an instance runs with: a feature profile's behaviour ORed with pulse.Options. It feeds the feature_set_digest so two instances that differ only in a switch are told apart.

type FeatureKind

type FeatureKind string

FeatureKind classifies one row of the feature table. It is the vocabulary feature profiles are written in: a profile lists feature NAMES, and the kind decides how a name is spelled and which surface it gates.

const (
	// FeatureKindCapability is an engine capability: a facade method
	// family, its CLI leaves and MCP tools, or a request slot.
	FeatureKindCapability FeatureKind = "capability"
	// FeatureKindOperator is a registered operator — every
	// types.All*Types() entry (AGG/ATTR/FILTER/GROUP/WIN/FEAT/TEST/REG/
	// OVERLAY). Extension operators are operators too, but they are not
	// rows of this table: they carry no Since.
	FeatureKindOperator FeatureKind = "operator"
	// FeatureKindIOFormat is one tabular I/O format, gating BOTH its
	// import and its export direction.
	FeatureKindIOFormat FeatureKind = "io_format"
	// FeatureKindMCPExtra is an MCP surface that is neither a tool nor
	// core: a prompt or the cohort-resource enumeration.
	FeatureKindMCPExtra FeatureKind = "mcp_extra"
)

The four feature kinds. Operators are spelled bare (their registered SCREAMING_SNAKE name); every other kind is spelled `<kind>:<name>`.

func AllFeatureKinds

func AllFeatureKinds() []FeatureKind

AllFeatureKinds returns the four kinds in a stable order.

func FeatureKindOf

func FeatureKindOf(name string) (FeatureKind, bool)

FeatureKindOf returns the kind of the built-in feature spelled name.

func FeatureKindOfName

func FeatureKindOfName(name string) FeatureKind

FeatureKindOfName classifies any feature spelling, built-in or not: the table row's kind when name is a built-in, otherwise the kind its prefix names (`capability:`, `io_format:`, `mcp_extra:`), and an operator for a bare name (an extension operator).

type FeatureSet

type FeatureSet struct {
	Enabled   []string
	Hidden    []string
	Behaviour FeatureBehaviour
}

FeatureSet is the resolved feature set of one instance, computed once at pulse.New. Enabled is every feature the instance offers (no feature profile: every built-in whose Since is reached plus every registered extension operator; with one: exactly the profile's list). Hidden is the rest of the resolvable universe — names that WOULD resolve on a default instance but this one does not offer.

type FieldCheck

type FieldCheck int

FieldCheck is the static verdict on one Interpretation.Field.

const (
	// FieldUnknown: the path names nothing the operator emits.
	FieldUnknown FieldCheck = iota
	// FieldStatic: the path is anchored to a declared output — a result
	// struct tag, a ComponentSchema key, a declared overlay shape, a
	// descriptive operator's value / value.* primary result.
	FieldStatic
	// FieldDeferred: the path descends into a map-valued slot
	// (details.*, summary.parameters.*) whose keys exist only at run
	// time. It passes the static check; the runtime probe in
	// internal/processing / internal/service proves the key is emitted.
	FieldDeferred
)

The static verdicts.

type GuidanceLintHit

type GuidanceLintHit struct {
	Rule string
	Span string
}

GuidanceLintHit is one text-rule hit: the rule ID and the offending span.

func LintGuidanceText

func LintGuidanceText(text string) []GuidanceLintHit

LintGuidanceText runs the guidance lint's text rules (ASA-*, MULTI-COMP-MANUAL, SLOT-TOKEN) over text — a prose string or rendered guidance — and returns every hit in rule order. The registry rules need the declared guidance, not text, and run only in TestGuidanceProseLint.

type InspectMetadata

type InspectMetadata struct {
	// WeightVariable is the weighting variable the cohort's SPSS
	// metadata sidecar records ("" when there is no sidecar, the
	// sidecar is unreadable or stale, or it names no weight).
	WeightVariable string
	// Instance is the instance feature set. With capability:weighting
	// hidden no suggestion is reported. Nil hides nothing.
	Instance *InstanceSnapshot
}

InspectMetadata carries the facts about a cohort that sit BESIDE its bytes rather than in them — read by the caller (the facade, from the cohort's sidecars through its afero.Fs) and judged here against the schema. Inspect itself never opens a file: it is handed a stream.

type InstanceSnapshot

type InstanceSnapshot struct {
	// contains filtered or unexported fields
}

InstanceSnapshot is the immutable, no-execute view of ONE instance's feature scoping: the extension projection it was built with plus its resolved feature set and feature_set_digest. pulse.New builds it once and installs it on the service; manifest, predict, payload schema and the runtime lookup sites read it to decide what this instance offers.

A nil *InstanceSnapshot is UNSCOPED: every name is enabled, nothing is hidden, there are no extensions and the digest is empty. Engine code constructed outside pulse.New (tests, internal tools) therefore keeps its pre-feature-profile behaviour.

func NewInstanceSnapshot

func NewInstanceSnapshot(ext *ExtensionsSnapshot, set FeatureSet) *InstanceSnapshot

NewInstanceSnapshot builds the scoped snapshot pulse.New installs. ext may be nil (no extension registrations survive).

func UnscopedInstanceSnapshot

func UnscopedInstanceSnapshot(ext *ExtensionsSnapshot) *InstanceSnapshot

UnscopedInstanceSnapshot wraps an extension projection with no feature scoping: Enabled is true for every name, Hidden is always false and the digest is empty. For callers that install extensions on a service directly, outside pulse.New.

func (*InstanceSnapshot) AdvisorySuppressed

func (s *InstanceSnapshot) AdvisorySuppressed(code string) bool

AdvisorySuppressed reports whether the instance suppresses the advisory code. Nil-safe: a nil snapshot suppresses nothing.

func (*InstanceSnapshot) Behaviour

func (s *InstanceSnapshot) Behaviour() FeatureBehaviour

Behaviour returns the effective behaviour switches the digest covers.

func (*InstanceSnapshot) DefaultReturn

func (s *InstanceSnapshot) DefaultReturn() *types.Return

DefaultReturn returns a copy of the instance `return` default, nil when the instance has none (the library default `full`). Nil-safe.

func (*InstanceSnapshot) Digest

func (s *InstanceSnapshot) Digest() string

Digest returns the instance's feature_set_digest ("fs1:<sha256hex>"), or "" on a nil / unscoped snapshot.

func (*InstanceSnapshot) Discovery

func (s *InstanceSnapshot) Discovery() *Discovery

Discovery returns the instance's skill / example view, built with the snapshot (NewInstanceSnapshot). Nil-safe: a nil, unscoped or hide-nothing snapshot returns the shared pass-through view.

func (*InstanceSnapshot) Enabled

func (s *InstanceSnapshot) Enabled(name string) bool

Enabled reports whether the instance offers the feature spelled name (operators bare, other kinds `<kind>:<name>`). O(1). On a scoped snapshot a name outside the resolved set — hidden, unregistered, or a core surface (core surfaces are not features) — is false. A nil or unscoped snapshot answers true for every name.

func (*InstanceSnapshot) EnabledNames

func (s *InstanceSnapshot) EnabledNames() []string

EnabledNames returns the resolved enabled set, sorted, as a fresh copy. Nil on an unscoped snapshot.

func (*InstanceSnapshot) ExamplesSearch

func (s *InstanceSnapshot) ExamplesSearch(q examples.Query) ([]examples.ExampleSummary, error)

ExamplesSearch runs one example search for the instance: the visible library, the synonym tier fed by the instance's alias index (KnownAs) and the Sounds of the intents its ontology keeps, and the optional intent filter. An intent outside the taxonomy, or one the instance hides, is PULSE_RECOMMEND_INTENT_UNKNOWN — the code pulse_recommend raises — whose details.valid lists the instance's intents. A hidden operator's aliases and a hidden intent's Sounds never expand a query, and a hidden intent is dropped from every summary. Never nil on success.

func (*InstanceSnapshot) Extensions

func (s *InstanceSnapshot) Extensions() *ExtensionsSnapshot

Extensions returns the extension projection, or nil when the instance has no (visible) extension registrations. Nil-safe.

func (*InstanceSnapshot) Hidden

func (s *InstanceSnapshot) Hidden(name string) bool

Hidden reports whether name is a feature this build resolves (a built-in whose Since is reached, or a registered extension operator) that the instance's feature profile does not offer. O(1). A hidden name must behave exactly like a never-registered one; this is the predicate native lookup sites consult. A name that is merely unknown is NOT hidden — it already fails on its own. Always false without a feature profile.

func (*InstanceSnapshot) HiddenNames

func (s *InstanceSnapshot) HiddenNames() []string

HiddenNames returns the hidden set, sorted, as a fresh copy.

func (*InstanceSnapshot) KnownAs

func (s *InstanceSnapshot) KnownAs() map[string]string

KnownAs returns the instance's alias index: every Purpose.KnownAs alias (folded with FoldAlias) mapped to the operator declaring it, over the built-in Purposes plus the instance's extension Purposes. An operator the instance ontology prunes — hidden by the feature profile — contributes nothing, so its aliases act never-declared. A fresh map; nil-safe (a nil snapshot answers the full built-in index).

func (*InstanceSnapshot) Limits

func (s *InstanceSnapshot) Limits() limits.Limits

Limits returns the instance's effective resource limits — the built-in defaults when none were installed. Nil-safe; the result is a copy.

func (*InstanceSnapshot) Ontology

func (s *InstanceSnapshot) Ontology() *OntologyGraph

Ontology returns the instance's pruned ontology graph (read-only; the base graph itself when the instance neither extends nor hides anything). A nil snapshot answers the base graph.

func (*InstanceSnapshot) Scoped

func (s *InstanceSnapshot) Scoped() bool

Scoped reports whether the snapshot carries a resolved feature set (built by pulse.New). An unscoped or nil snapshot enables everything.

func (*InstanceSnapshot) SkillsForIntent

func (s *InstanceSnapshot) SkillsForIntent(intent string) ([]skills.Metadata, error)

SkillsForIntent returns the instance's skills relevant to one intent, ranked — the list pulse_skills_list {intent} serves. The intent is resolved by checkIntent (an unknown or hidden one is PULSE_RECOMMEND_INTENT_UNKNOWN, details.valid = the instance's intents), and every edge is read off the instance's PRUNED ontology, so a hidden operator contributes nothing:

  1. the skills the intent node is documented_by (the virtual `intents` skill);
  2. design skills whose (rendered) covers names an operator serving the intent, or that operator's category prefix (`TEST` covers TEST_T), by name;
  3. the atomic skills those serving operators are documented_by, ranked by the operator's Purpose.Level (basic → intermediate → advanced; no Level last) — the Level is joined through the skill's operator, never stored on it — then by name.

Each entry is the instance's rendered metadata, exactly as Skills lists it. An intent no operator serves answers its reference skill only. Never nil on success.

func (*InstanceSnapshot) WithDefaultReturn

func (s *InstanceSnapshot) WithDefaultReturn(r *types.Return) *InstanceSnapshot

WithDefaultReturn returns a copy of the snapshot carrying r as the instance `return` default (nil clears it). r is cloned. pulse.New installs the validated default (Options.DefaultReturn, else the feature profile's `return`) so predict and the runtime resolve a request through the same layer. A nil receiver yields an unscoped snapshot carrying only the default.

func (*InstanceSnapshot) WithLimits

func (s *InstanceSnapshot) WithLimits(l limits.Limits) *InstanceSnapshot

WithLimits returns a copy of the snapshot carrying l as the instance's effective resource limits. pulse.New installs the resolved limits so predict, the runtime and the manifest read the same values. A nil receiver yields an unscoped snapshot carrying only the limits.

func (*InstanceSnapshot) WithSuppressedAdvisories

func (s *InstanceSnapshot) WithSuppressedAdvisories(codes []string) *InstanceSnapshot

WithSuppressedAdvisories returns a copy of s whose predict omits every advisory whose code is in codes (Options.SuppressAdvisories, validated by ValidateSuppressAdvisories first). An empty list suppresses nothing. Nil-safe like WithLimits.

type InterpretationField

type InterpretationField struct {
	// Name is the registry key (TEST_* family, REG_*, OVERLAY_*, ...).
	Name string
	// Category is the PurposeSurfaces category Name belongs to.
	Category string
	// Field is the declared normalised path.
	Field string
	// Deferred is true for a map-valued path (details.*,
	// summary.parameters.*) only a runtime probe can confirm.
	Deferred bool
}

InterpretationField is one declared (operator, field) pair of the built-in Interpretation registry.

func DeclaredInterpretationFields

func DeclaredInterpretationFields() []InterpretationField

DeclaredInterpretationFields returns every declared (operator, field) pair of the built-in registry, sorted by name then field. It is the seam the runtime probes (internal/processing for tests and regressions, internal/service for overlays) hold two-way complete: every Deferred pair must be probed against the real emitted value.

type InterpretationRule

type InterpretationRule string

InterpretationRule names one validity rule ValidateInterpretations enforces (binding for built-ins via TestInterpretationCoversOutputs, and for extension registrations through the same function).

const (
	// InterpretationRuleField: Field is a well-formed normalised path
	// (dot-separated lowercase snake_case segments, "*" only as the last
	// segment) and is declared once per operator.
	InterpretationRuleField InterpretationRule = "field"
	// InterpretationRuleFieldUnknown: Field names an output the operator
	// emits (struct tag, ComponentSchema key, declared overlay shape or
	// per-regression-type applicability).
	InterpretationRuleFieldUnknown InterpretationRule = "field_unknown"
	// InterpretationRuleMeans: an Interpretation says what the value
	// means — a non-empty Means, or a Shared rule set.
	InterpretationRuleMeans InterpretationRule = "means"
	// InterpretationRuleConvention: Bands and Convention come together —
	// bands are a labelled convention, never authoritative.
	InterpretationRuleConvention InterpretationRule = "convention"
	// InterpretationRuleBands: every band has a label and Min < Max; the
	// bands are ordered ascending and do not overlap (only the first may
	// be open below, only the last open above).
	InterpretationRuleBands InterpretationRule = "bands"
	// InterpretationRuleShared: Shared names a registered shared rule set.
	InterpretationRuleShared InterpretationRule = "shared"
	// InterpretationRuleSign: Sign keys are "+" / "-" with non-empty
	// meanings.
	InterpretationRuleSign InterpretationRule = "sign"
)

The validity rules.

type InterpretationViolation

type InterpretationViolation struct {
	// Name is the operator (or registry key) the Interpretation belongs to.
	Name string
	// Field is the Interpretation's Field as declared.
	Field string
	// Rule is the broken rule.
	Rule InterpretationRule
	// Detail says what is wrong, in a sentence.
	Detail string
}

InterpretationViolation is one broken validity rule on one Interpretation.

func ValidateInterpretations

func ValidateInterpretations(name string, ins []descriptor.Interpretation, outputs OutputResolver) []InterpretationViolation

ValidateInterpretations checks ins, declared for name, against every validity rule and returns the violations (nil when valid). outputs judges each Field; a nil resolver is STRUCTURE-ONLY mode — path syntax is checked but existence is not (the extension registration path, where no emitted-key declaration exists).

func (InterpretationViolation) String

func (v InterpretationViolation) String() string

type JoinValidationResult

type JoinValidationResult struct {
	Valid        bool                          `json:"valid"`
	Request      *types.Request                `json:"request"`
	LeftSchema   *descriptor.PredictSchemaInfo `json:"left_schema,omitempty"`
	RightSchema  *descriptor.PredictSchemaInfo `json:"right_schema,omitempty"`
	JoinedFields []string                      `json:"joined_fields,omitempty"`
}

JoinValidationResult is the structured output of ValidateJoin. Echoes the request unchanged and exposes the inferred output schema as a list of field names.

type LimitInputs

type LimitInputs struct {
	// Records is the header record count of the cohort the request
	// scans (a join's left side; a chain stage's input rows); -1 when
	// unknown. It clamps the group and crosstab bounds and drives the
	// memory estimate (unknown: no MaxEstimatedMemory finding).
	Records int64
	// ShardRecords are an archive's per-shard counts (merge blocks
	// restart per shard); nil for a single file, whose blocks derive
	// from Records.
	ShardRecords []int64
	// ArchiveBytes is a shard archive's byte length (predict: the bytes
	// it was handed; the runtime: what Open read), 0 for a single file.
	// Open and the scan read every byte onto the heap. An anchor-opened
	// shard (`archive.pulse#shard.pulse`) carries its archive's length
	// too, with no ShardRecords: Open reads the whole archive to extract
	// the one shard (predict: PredictOptions.AnchorArchiveBytes).
	ArchiveBytes int64
	// ShardWorkers is the instance's per-shard worker cap
	// (Options.ShardWorkers: 0 = runtime.NumCPU, 1 = serial) — with the
	// shard count and the merge gate it decides whether an archive run
	// takes the per-shard parallel arm (ShardFanOut).
	ShardWorkers int
	// Join reports a request carrying its one JoinSpec; JoinRightRows
	// is that build side's header count (-1 unknown: no memory
	// finding). A join never runs the fused crosstab.
	Join          bool
	JoinRightRows int64
	// JoinSpec is that join (nil without one) — its right key fields,
	// read on the joined schema under the spec's As prefix, bound the
	// joined rows a repeating right key fans the left side out to
	// (JoinRowsBound). The runtime pre-flight judges a Joins-stripped
	// clone, so the spec rides here rather than on the request.
	JoinSpec *types.JoinSpec
	// Extensions and FusionDisabled feed the arm decision (streamable,
	// fused) exactly as predict's computeStreamable / CrosstabFusion
	// and the engine's dispatch read them.
	Extensions     *ExtensionsSnapshot
	FusionDisabled bool
}

LimitInputs are the run facts the limit rules read beyond the request and schema. Predict fills them from the header (and the facade's header-only right-side counter); the process pre-flight from the same header counts (Service.CountRecords, an archive's shard manifest) — so a certain finding carries the same figure on both sides.

type MCPIntentPrompt

type MCPIntentPrompt struct {
	Prompt  string
	Intent  string
	Feature string
}

MCPIntentPrompt is one generated per-intent MCP prompt: its prompt name, the analytic intent it scripts, and its mcp_extra feature.

func MCPIntentPrompts

func MCPIntentPrompts() []MCPIntentPrompt

MCPIntentPrompts returns one generated prompt per ANALYTIC intent, in intent-registry order. The tooling intents (prepare, simulate, lookup) route to tools, never to a prompt. A prompt mounts iff its feature is enabled AND its intent node survives the instance's ontology prune (mcp/gosdk scope.go).

type MCPToolBinding

type MCPToolBinding struct {
	Tool    string
	Feature string
	Core    string
}

MCPToolBinding records which feature (or core surface) owns one MCP tool. Exactly one of Feature and Core is set. Data only today; the MCP registration filter consumes it in a later unit.

func MCPToolBindingOf

func MCPToolBindingOf(tool string) (MCPToolBinding, bool)

MCPToolBindingOf returns the binding for one MCP tool name.

func MCPToolBindings

func MCPToolBindings() []MCPToolBinding

MCPToolBindings returns the MCP tool → feature/core table in a stable order.

type MaterializeColumn

type MaterializeColumn struct {
	Name        string
	Description string
	Window      bool
}

MaterializeColumn is one derived column a materialize run appends to the source schema: the column name the pipeline writes (the same label Process emits), its generated field description, and where the value is read — off the record (a feature or attribute output) or off the windowed row set (a window output).

func MaterializeColumns

func MaterializeColumns(req *types.Request, schema *encoding.Schema, inst *InstanceSnapshot, source string) ([]MaterializeColumn, *errors.CodedError)

MaterializeColumns names the derived columns a materialize run of req appends, in pipeline order — features, then attributes, then windows, declaration order within each, a multi-output feature contributing every output (featureOutputLabels) — each with a generated description naming the operator, its source, its params and source (the cohort path the run reads; only its base name is used). An operator whose capability declares ReadsExpression is named by its Expression verbatim ("ATTR_FORMULA = a * 0.9") instead of its unread Field; a regression attribute adds its slot-level penalty.

Refusals: PULSE_MATERIALIZE_NO_DERIVED when req carries no feature, attribute or window; PULSE_MATERIALIZE_OUTPUT_UNDECLARED for an embedder-registered feature (its outputs are known only after it runs) or a built-in one whose outputs cannot be named from its params and schema. A feature type that is neither built-in nor registered contributes nothing here: the run refuses it as an unknown operator, exactly as Process does. Reads only the schema.

type ModelFileReader

type ModelFileReader interface {
	ReadModelFile(path string) ([]byte, error)
}

ModelFileReader reads a model file's bytes at a path relative to the instance filesystem root (PredictOptions.ModelLoader; the runtime's Service satisfies it).

type MultiplicityPlan

type MultiplicityPlan struct {
	Tests     []ResolvedMultiplicity
	PostTests []ResolvedMultiplicity
	Overlays  []ResolvedMultiplicity
	// Matrices is index-aligned with Request.Matrices.
	Matrices []ResolvedMultiplicity
}

MultiplicityPlan is the resolved correction of one Request, each list index-aligned with the request slot it resolves.

func ResolveMultiplicity

func ResolveMultiplicity(req *types.Request, def *types.Multiplicity, inst *InstanceSnapshot) (*MultiplicityPlan, error)

ResolveMultiplicity is the single multiplicity-resolution pass for a standalone Request (Process, ProcessStream, every ProcessChain stage). The runtime and predict both call it, so a request is refused or accepted identically by both.

Precedence per slot and per field (method, family and alpha fall through independently): the slot's own block → req.Multiplicity → def (pulse.Options.DefaultMultiplicity) → none. Rules, in evaluation order (PULSE_MULTIPLICITY_INVALID unless noted):

  • def, the request's block and every slot block must name a known method and family, and an alpha inside (0, 1);
  • the request's block may not name the `compose` family (Compose only);
  • a test's or post-test's own family must be `request`; its own block may not set alpha (the test's own Test.Alpha governs);
  • an explicit non-none method on the Tukey HSD post-test is refused; an inherited method skips it (Member false);
  • an overlay's own family must be `layer`, `request`, or — for a kind whose payload is MATRIX — `row` / `column`;
  • a matrix spec's own block is refused on a matrix operator that emits no p-values (outside vectors.InferenceTypes); its own family must be `matrix` or `request`; it becomes a member only under params.inference (set, or implied by its own block);
  • an inherited family the slot's surface does not offer falls back to the surface default (`request` for tests, `layer` for overlays, `matrix` for matrix specs), never refused;
  • members of the `request` family (tests, post-tests, inferential overlays and inferential matrix specs whose method is not none) must agree on one method, else PULSE_MULTIPLICITY_CONFLICT.

The plan is nil when nothing — the request, any slot, or def — names a block. inst routes hidden test types and overlay kinds as never-registered; nil hides nothing. It never mutates req.

func (*MultiplicityPlan) Active

func (p *MultiplicityPlan) Active() bool

Active reports whether any slot of the plan is a family member.

type OntologyGraph

type OntologyGraph struct {
	// contains filtered or unexported fields
}

OntologyGraph is a built ontology plus its lookup indexes. Treat it as read-only; Ontology() hands out a copy.

func BaseOntology

func BaseOntology() *OntologyGraph

BaseOntology returns the process-wide, profile-independent base graph, built on first use. Shared: never mutate it.

func (*OntologyGraph) Has

func (g *OntologyGraph) Has(id string) bool

Has reports whether the graph carries the node id.

func (*OntologyGraph) In

In returns the edges entering id, of the given kind ("" = every kind), in graph order.

func (*OntologyGraph) Node

Node returns the node with the given ID.

func (*OntologyGraph) Ontology

func (g *OntologyGraph) Ontology() descriptor.Ontology

Ontology returns a deep copy of the graph's sorted nodes and edges.

func (*OntologyGraph) OperatorsServing

func (g *OntologyGraph) OperatorsServing(intentID string) []string

OperatorsServing is the intent → operator reverse index: the sorted names of the operators whose Purpose declares intentID.

func (*OntologyGraph) Out

Out returns the edges leaving id, of the given kind ("" = every kind), in graph order.

func (*OntologyGraph) Problems

func (g *OntologyGraph) Problems() []string

Problems returns the references the build could not resolve to a node, sorted. Empty on a healthy base graph.

type OutputResolver

type OutputResolver func(field string) (FieldCheck, string)

OutputResolver judges a normalised Field path for one operator, returning the verdict and, for FieldUnknown, why.

func BuiltinOutputResolver

func BuiltinOutputResolver(name string) OutputResolver

BuiltinOutputResolver returns the static OutputResolver for the built-in manifest entry name (tests by family). Tests resolve against types.TestResult; regressions against types.RegressionResult filtered by the per-type applicability table; overlays against the kind's declared shapes plus types.OverlaySummary; aggregators, groupers and filterers against components.<key> from their ComponentSchema plus the universal floor; aggregators, attributes, windows and features also against their primary result as `value` / `value.*` (interpretation_reading.go); matrices against their MatrixResult as primary.values and scalars.<key> from the manifest output_keys. Every other category (and an unknown name) emits nothing an Interpretation can read.

type PredictOptions

type PredictOptions struct {
	// Strict upgrades warnings to errors.
	Strict bool

	// Extensions is the read-only snapshot of embedder-registered
	// operators + expression-side state. Nil takes the built-in-only
	// path. The snapshot adds every custom operator name to the
	// validator's known-types set so predict does not flag
	// embedder-registered ops as unknown, and feeds streamability
	// overrides into computeStreamable.
	Extensions *ExtensionsSnapshot

	// EchoRequest causes Predict to populate envelope.Request with the
	// normalized (post-defaults) request. PredictResult.Request stays
	// the raw input request — the envelope field is the new uniform
	// surface across all envelope-producing endpoints. Off by default.
	EchoRequest bool

	// DefaultTimeZone is pulse.Options.DefaultTimeZone — the zone a
	// zone-capable slot inherits when neither its own `tz` nor the
	// request's `time_zone` names one. Empty means UTC.
	DefaultTimeZone string

	// DefaultWeight is pulse.Options.DefaultWeight — the row weight a
	// weight-bearing slot inherits when neither its own `weight` nor
	// the request's `weight` names one. Nil means none.
	DefaultWeight *types.WeightSpec

	// DefaultMultiplicity is pulse.Options.DefaultMultiplicity — the
	// multiple-comparison block every test, post-test and overlay
	// inherits field by field after its own block and its request's.
	// Nil means none.
	DefaultMultiplicity *types.Multiplicity

	// ZoneLoader resolves zone names (nil: temporal.LoadZone). The
	// facade passes its per-instance cache so predict and the runtime
	// resolve through the same loader.
	ZoneLoader ZoneLoader

	// DisableComponents is pulse.Options.DisableComponents — the engine
	// default a request's disable_components overrides. Predict reads it
	// where a components-disabled host changes the answer (an overlay
	// that needs the host's weighted floor is refused).
	DisableComponents bool

	// DisableDefaults is pulse.Options.DisableDefaults. When set,
	// predict validates the request WITHOUT smart defaults — exactly
	// what the runtime executes — so a slot left with an empty Type is
	// reported the way the runtime reports it. DefaultsApplied is still
	// computed: it then lists the defaults that WOULD apply.
	DisableDefaults bool

	// SchemaLoader reads the header + schema of the cohort at a path
	// (no record data). The facade passes the runtime's own cohort
	// opener. Predict uses it for Request.Joins: the request is
	// validated against the joined schema (internal/encoding.
	// JoinedSchema, the rule the runtime builds its join over), so a
	// right-side field is resolved by its real type. Nil leaves a join
	// unresolved and validation runs against the left schema alone.
	SchemaLoader func(path string) (*encoding.Schema, error)

	// RecordCounter returns the record count of the cohort at a path
	// from its header + schema alone (no record data) — the facade
	// passes the runtime's own header-only counter (Service.
	// CountRecords). Predict uses it for the build (right) side of a
	// Request.Joins entry, whose count is exactly the number of records
	// the runtime's join build decodes, so a MaxJoinBuildRows breach is
	// a certain finding. Nil (or a count error) yields no join-build
	// finding.
	RecordCounter func(path string) (int64, error)

	// CohortCounter returns the header facts the limit rules read for
	// the cohort at a path (CohortCounts: the record count, an
	// archive's per-shard counts and byte length) — the facade passes
	// the runtime pre-flight's own reader (Service.CohortCounts). The
	// Compose root reads it per slot and fit, so a slot's limit
	// findings carry the figures its Process refuses with. Nil falls
	// back to RecordCounter's count (no archive terms).
	CohortCounter func(path string) (CohortCounts, error)

	// ModelLoader reads a model file's bytes at a path relative to the
	// instance filesystem root — the facade passes the runtime's own
	// read (Service.ReadModelFile). Predict uses it for every `models`
	// entry (Request, FacetRequest, Compose slots and fits, chain
	// stages): the file is decoded and version-checked by the runtime's
	// rule and its terms judged against the scoring frame. Nil refuses
	// every entry as PULSE_MODEL_FILE_UNREADABLE (reason unreadable).
	ModelLoader ModelFileReader

	// Instance is the instance feature set. The request-time overlay
	// kind gates (Request, Compose and Facet hosts) report a kind it
	// hides exactly as a kind not in the catalog. Nil hides nothing.
	Instance *InstanceSnapshot

	// SuggestedWeightVariable is the weighting variable the cohort's SPSS
	// metadata sidecar records; the facade reads the sidecar (Predict
	// itself never opens a file) and leaves it "" when there is none.
	// Predict echoes it as PredictResult.SuggestedWeight when no slot
	// resolves a weight — it is never applied.
	SuggestedWeightVariable string

	// SidecarMeasureLevels maps a field name to the SPSS measure level
	// ("nominal", "ordinal", "scale", "unset") the cohort's SPSS metadata
	// sidecar records; the facade reads it (nil when there is no usable
	// sidecar). It feeds the measure-level advisories and nothing else.
	SidecarMeasureLevels map[string]string

	// SidecarLoader reads the SPSS metadata sidecar facts beside the
	// cohort at a path — the weighting variable ("" when there is none or
	// capability:weighting is hidden) and the measure levels (nil when
	// there is no usable sidecar). Compose predict calls it once per slot
	// cohort, because each slot names its own cohort; the single-cohort
	// roots take SuggestedWeightVariable / SidecarMeasureLevels instead.
	// Nil reads nothing: no sidecar advisory fires on a Compose slot.
	SidecarLoader func(path string) (weightVariable string, measureLevels map[string]string)

	// DisableCrosstabFusion is pulse.Options.DisableCrosstabFusion. When
	// set, PredictResult.CrosstabFusable answers false with
	// CrosstabFusionDisabledReason for every crosstab request, as the
	// engine then never dispatches the fused arm.
	DisableCrosstabFusion bool

	// ShardWorkers is pulse.Options.ShardWorkers (0 = runtime.NumCPU,
	// 1 = serial). Over a shard archive it decides whether the memory
	// estimate counts the per-shard parallel arm's partials
	// (ShardFanOut), as the engine's dispatch decides the arm.
	ShardWorkers int

	// AnchorArchiveBytes is, when the predicted bytes are ONE shard the
	// caller extracted from an `archive.pulse#shard.pulse` anchor, that
	// archive's byte length (0 otherwise). The runtime's OpenAnchor reads
	// the whole archive to reach the shard, so the memory estimate
	// charges the archive's bytes in place of the shard's payload when
	// larger (LimitInputs.ArchiveBytes), exactly as the run's pre-flight
	// does. Ignored when the bytes are themselves an archive.
	AnchorArchiveBytes int64
}

PredictOptions controls predict behavior.

type ProseScrub

type ProseScrub struct {
	// contains filtered or unexported fields
}

ProseScrub is one instance's prose scrub, exported for the surfaces outside the manifest that carry hand-written prose naming features — the MCP tool descriptions, the reflected and bound tool input schemas, and the prompt bodies. It is the manifest scrub (hiddenProseNames + redactProse), not a second implementation: the same hidden-token set, the same whole-token match and the same sentence drop. Build it once per registration with NewProseScrub; the zero value (and a scrub over a nil / unscoped instance) returns every input unchanged.

func NewProseScrub

func NewProseScrub(inst *InstanceSnapshot) ProseScrub

NewProseScrub captures inst's hidden-token set: every hidden operator name, every MCP tool whose owning feature the instance does not offer, and the wire tokens of every hidden slot-owning capability (slotTokens in features.go).

func (ProseScrub) Active

func (p ProseScrub) Active() bool

Active reports whether the scrub can change anything (the instance hides at least one prose token).

func (ProseScrub) SchemaDescriptions

func (p ProseScrub) SchemaDescriptions(raw json.RawMessage) (json.RawMessage, error)

SchemaDescriptions returns raw (a JSON Schema document) with Text applied to every string-valued "description" keyword at any depth. A schema none of whose descriptions changes is returned as is (same bytes); otherwise the document is re-encoded with encoding/json.

func (ProseScrub) Text

func (p ProseScrub) Text(s string) string

Text returns s without the sentences that mention a hidden token. It is line-aware so multi-paragraph descriptions and markdown prompt bodies keep their layout: each line is redacted on its own, a line left empty (or holding only a list / heading marker) is dropped, the rest of an ordered list a dropped item belonged to is renumbered, and the blank-line runs a drop leaves behind collapse to one. A string that mentions no hidden token is returned unchanged.

type ProseString

type ProseString struct {
	Source string
	Text   string
}

ProseString is one declared guidance prose string and where it came from (e.g. "purpose:AGG_AVERAGE", "glossary:p-value").

func GuidanceProse

func GuidanceProse() []ProseString

GuidanceProse returns every declared guidance prose string of at least GuidanceProseMinLen runes, sorted by source then text.

func LeakedGuidanceProse

func LeakedGuidanceProse(payload []byte) []ProseString

LeakedGuidanceProse returns every GuidanceProse string that appears in payload, either verbatim or in its JSON-escaped spelling (so a string carrying an apostrophe, '<' or '&' is still caught after encoding/json escaped it).

type PurposeResolver

type PurposeResolver func(use string) bool

PurposeResolver reports whether a NotFor.Use or FollowUps.Use target names something that exists: a bare registered operator, or a "<kind>:<name>" feature.

func BuiltinPurposeResolver

func BuiltinPurposeResolver() PurposeResolver

BuiltinPurposeResolver resolves a NotFor.Use against the full built-in registry: a bare name must be a registered built-in surface (any PurposeSurfaces member), a prefixed name a row of the feature table.

type PurposeRule

type PurposeRule string

PurposeRule names one validity rule ValidatePurpose enforces. The rules fall into four families, one per named gate: the limits (TestSkillsCoverAllPurposes), alternatives and follow-ups (TestPurposeAlternativesResolve), intents (TestPurposeQuestionsResolve) and glossary links (TestGlossaryTermsResolve).

const (
	// PurposeRulePlain: Plain is non-empty and at most PurposePlainMax
	// characters.
	PurposeRulePlain PurposeRule = "plain"
	// PurposeRuleIntents: at least one intent is declared.
	PurposeRuleIntents PurposeRule = "intents"
	// PurposeRuleQuestions: at least PurposeQuestionsMin non-empty
	// Questions.
	PurposeRuleQuestions PurposeRule = "questions"
	// PurposeRuleNotFor: at least one NotFor entry.
	PurposeRuleNotFor PurposeRule = "not_for"
	// PurposeRuleUseCases: at least one UseCase, every key a known
	// Domain, every value non-empty.
	PurposeRuleUseCases PurposeRule = "use_cases"
	// PurposeRuleLevel: Level is one of the declared levels.
	PurposeRuleLevel PurposeRule = "level"
	// PurposeRuleAlternative: every NotFor entry has a When and a Use
	// that resolves (and is not the operator itself).
	PurposeRuleAlternative PurposeRule = "alternative"
	// PurposeRuleFollowUp: every FollowUps entry has a When and a Use
	// that resolves (and is not the operator itself). FollowUps is
	// optional: an empty list breaks nothing.
	PurposeRuleFollowUp PurposeRule = "follow_up"
	// PurposeRuleIntentUnknown: every intent ID is in the taxonomy and
	// listed once.
	PurposeRuleIntentUnknown PurposeRule = "intent_unknown"
	// PurposeRuleGlossaryUnknown: every Glossary ID is a glossary term
	// and listed once.
	PurposeRuleGlossaryUnknown PurposeRule = "glossary_unknown"
	// PurposeRuleJargonUnlinked: every jargon term whose Form appears in
	// Plain is listed in Glossary.
	PurposeRuleJargonUnlinked PurposeRule = "jargon_unlinked"
	// PurposeRuleKnownAs: every KnownAs alias is non-empty, at most
	// KnownAsMax characters, listed once and distinct from every intent
	// Sound (folded with FoldAlias). Across operators each alias is
	// unique too (KnownAsCollisions; at pulse.New for extensions).
	PurposeRuleKnownAs PurposeRule = "known_as"
)

The validity rules.

type PurposeSurface

type PurposeSurface struct {
	// Category is the coverage-report grouping (e.g. "aggregator").
	Category string
	// Names lists the category's registry keys, sorted.
	Names []string
}

PurposeSurface is one category of built-in manifest entries a Purpose may be declared for, with its registry keys.

func PurposeSurfaces

func PurposeSurfaces() []PurposeSurface

PurposeSurfaces returns every built-in name a Purpose may be keyed by, grouped into the eleven categories in a stable order. Tests are keyed by family (one Purpose covers both tiers), so post-test variants contribute their family.

type PurposeViolation

type PurposeViolation struct {
	// Name is the operator (or registry key) the Purpose belongs to.
	Name string
	// Rule is the broken rule.
	Rule PurposeRule
	// Detail says what is wrong, in a sentence.
	Detail string
}

PurposeViolation is one broken validity rule on one Purpose.

func KnownAsCollisions

func KnownAsCollisions(reg map[string]descriptor.Purpose) []PurposeViolation

KnownAsCollisions returns a violation for every alias two operators of reg both declare (folded), in sorted alias order, naming the alphabetically later operator. TestPurposeKnownAsUnique runs it over builtinPurposes.

func ValidatePurpose

func ValidatePurpose(name string, p descriptor.Purpose, resolve PurposeResolver) []PurposeViolation

ValidatePurpose checks p, declared for name, against every validity rule and returns the violations (nil when valid). resolve judges NotFor.Use targets; a nil resolver rejects every target. The built-in gates and the extension registration path share this one function.

func (PurposeViolation) String

func (v PurposeViolation) String() string

type ResolvedMultiplicity

type ResolvedMultiplicity struct {
	// Slot is the slot path inside its request ("tests[0]",
	// "post_tests[1]", "overlays[2]", "matrices[3]"); a Compose-host
	// overlay is "overlays[i]" of the ComposedRequest.
	Slot string
	// Operator is the slot's test type, overlay kind or matrix type as
	// authored.
	Operator string
	// Name is a matrix spec's result name (MatrixSpec.EffectiveName):
	// the fold pairs every Response.Matrices entry (one per group
	// bucket) with its slot by it. Empty on every other slot.
	Name string
	// Method is the resolved method; MultiplicityMethodNone when
	// nothing names one.
	Method types.MultiplicityMethod
	// Family is the resolved family; the surface default when nothing
	// names one, or when an inherited family is not one the slot's
	// surface offers.
	Family types.MultiplicityFamily
	// Alpha is the resolved overlay significance level
	// (types.DefaultMultiplicityAlpha when nothing sets one). Zero on a
	// test: a test's adjusted flag reads its own Test.Alpha.
	Alpha float64
	// Member reports whether the slot's p-values join Family under
	// Method: Method is not none, the slot emits p-values (a test, an
	// inferential overlay kind the instance offers, or a matrix spec
	// under params.inference — set, or implied by its own block), and
	// it is not skipped (an inherited correction never reaches the
	// Tukey HSD post-test, which is already corrected).
	Member bool
	// PValueKey is a matrix spec's auxiliary key holding its p-values:
	// "p" on a built-in inferential operator, an extension operator's
	// declared MatrixOpRegistration.PValues; "" on every other slot.
	// The fold writes the adjusted twins beside it (MatrixAdjustedKeys).
	PValueKey string
}

ResolvedMultiplicity is one slot's resolved correction: the method, family and alpha in force after the field-by-field fall-through (slot → request → Compose request → pulse.Options.DefaultMultiplicity → none / surface default).

func ResolveFacetMultiplicity

func ResolveFacetMultiplicity(req *types.FacetRequest, def *types.Multiplicity, inst *InstanceSnapshot) ([]ResolvedMultiplicity, error)

ResolveFacetMultiplicity resolves a FacetRequest's overlays: own block → def → none, families `layer` (default) and `row` / `column` for a MATRIX kind. A FacetRequest has no block of its own. Index- aligned with req.Overlays; nil when nothing names a block.

type ZoneLoader

type ZoneLoader func(name string) (*temporal.Zone, error)

ZoneLoader resolves a zone name to a *temporal.Zone. A nil loader means temporal.LoadZone; long-lived owners pass a temporal.Cache's Load so a request does not rebuild a transition table per call.

Source Files

Jump to

Keyboard shortcuts

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