Skip to main content

Crate whipplescript_parser

Crate whipplescript_parser 

Source
Expand description

Source parser for .whip programs.

The v0 grammar is still stabilizing, so this crate uses a small hand-written parser. It preserves source spans and keeps rule/effect bodies as source text until the typed IR is ready to lower them.

Modules§

body
Rule and flow body parsing: a real AST over body text.

Structs§

ActionDecl
action <name>(<param: type>, …) { <effect chain> } (DR-0023): a static, hygienic, inline-expanded template over rule-body effect chains. Consumed by expand_action_calls before lowering; never a runtime construct.
ActionParam
One typed parameter of an action template (DR-0023).
AgentDecl
ApplyDecl
AssertDecl
BlockSource
CampaignDecl
campaign <name> { ascend … [reach …] [guard …] [sacrifice …] } (improve design note §3): versioned, diffable objective intent at higher ceremony than a CLI invocation — the partition of the gauge vector. Unnamed gauges are guarded by default; guard widens a band, sacrifice releases a gauge, reach sets a target that becomes a hard bound.
CampaignGuard
guard <gauge> within 2 percent: an indifference-band override.
CampaignReach
reach <gauge> at least 0.9 / reach std.latency at most 800ms.
ChannelDecl
channel <name> { provider <p> [workspace <w>] [destination "<d>"] } (std.messaging): a named communication route through a provider. The bare channel construct shape is reserved by the platform for std.messaging (spec/messaging.md), so third-party packages cannot author channel-like semantics with weaker guarantees. Lowers to a metadata_only declaration (like queue); the runtime messaging provider is later-stage work.
ChannelProviderReport
std.messaging v1 provider capability report (spec/std-messaging.md “Capability reports + conditioned checks”). Reports are DATA, never code (M8): these compiled constants are mirrored by the embedded std.messaging manifest’s bindings[].config.report rows, and the conditioned static checks below admit syntax only when the selected provider’s report supports it. Report axes are messaging.md “Provider Capability Report” narrowed for v1: delivery_receipts ⊆ {accepted, failed}; identity ⊆ {anonymous, claimed_actor} (no verified_actor provider exists, so any check demanding verified identity fails closed); content ⊆ {text, markdown}.
ClassDecl
ClassField
ClockPolicy
CoerceDecl
Comment
A source comment captured by the lexer. Comments are kept out of the token stream (so the parser is unaffected) but retained here so tooling — whip fmt, the LSP — can preserve them. text is the trimmed content after the marker; span covers the marker through end of line (exclusive of the newline).
CompileOutput
CounterDecl
CredentialDecl
credential <name> { kind <kind> } (std.custody; DR-0053 §5): a bare handle naming a custodian entry — governance supplies reality via grant credential … -> credential:<addr>, and material never appears in source. kind exists so the checker can statically reject an operation the credential cannot perform (sign … with a bearer); the custodian’s registered kind is authoritative and mismatch is a check error. Kinds are spelled with underscores in source (hmac_sha256) and normalize to the protocol’s kebab-case.
DeclCanon
One declaration’s canonical identity and content hash.
DeclSymbol
One top-level declaration for an editor outline (whip lsp’s textDocument/documentSymbol): its name, a coarse kind tag, and source span.
Diagnostic
EnumDecl
EnumVariantDecl
One enum variant: bare (Accept) or data-carrying with a brace body that reuses the class field grammar (sum types, spec/sum-types.md).
EventDecl
A typed external-signal declaration (signal deploy.finished { ... }): the ingress manifest naming a dotted event and its payload schema (spec/event-ingress.md).
ExpectClause
ExprObjectField
FileStoreDecl
file store <name> { root "<dir>" } (std.files): a capability-scoped file store identity with a literal root directory. v0 is a local storage boundary.
FormatOutput
GaugeBar
An optional bar: the default decision bar for settle/campaign gates. expect P(<field>) at least 0.9 (chance-shaped) or expect p10 at least 0.7 / expect mean at most 800 (stat-shaped). Thresholds keep their exact source text (Eq-safe, format-exact); consumers parse.
GaugeDecl
gauge <name> [on <site>] { judge via ... [expect ...] [inputs ...] } (experimentation subsystem §4.2): a named quality dimension — a site, a judge, optionally a bar. The sibling of test: deterministic expectation vs. stochastic expectation, one family. Core grammar (hand-parsed): the judge via tagged union and the bar form are outside the declaration family’s shape. Bars use the word forms at least / at most because the declaration tokenizer deliberately steps over >=/<= (the same reason field presence conditions use is).
GaugeRef
A (possibly dotted) gauge reference: user gauges are bare idents, the built-in resource gauges are namespaced (std.spend / std.latency / std.tokens).
HarnessDecl
Ident
IncludeDecl
IrAccessGrant
A lowered turn-access grant: the granted operations narrow the turn’s effective authority on resource (modeled in models/maude/turn-access-grant.maude).
IrAccessGrantOp
IrAgent
IrAssertion
IrBoundedEgress
A bounded-type projection egress (record <T> from <src>): the recorded fact keeps exactly T‘s fields, copied from src, so the egress carries only the kept fields’ per-field labels — the “bounded-type” auto-redaction reading (DR-0027). The bound is the declared target type T; the labels are the SOURCE schema’s (a target field mislabelled public is still caught against the source’s label). The IFC engine governs it exactly like an explicit redact.
IrCampaign
A lowered campaign declaration (improve design note §3): the named, versioned partition of the gauge vector. metadata_only; consumed by whip improve <name>.
IrCampaignGuard
IrCampaignReach
IrChannel
A lowered channel declaration (std.messaging): the channel identity, its provider, and optional workspace/destination config. Lowering class is metadata_only; the runtime messaging provider consumes it later.
IrClass
IrClassField
IrCoerce
IrConstructUse
IrCounter
IrCredential
A lowered credential declaration (DR-0053 §5): a handle plus its declared kind, normalized to the custody protocol’s kebab-case. Metadata only — reality (material, sealing rung, grants) lives with the custodian and governance, never in the program.
IrEffectDependency
IrEffectNode
IrEnum
IrEvent
A declared external event: the typed ingress manifest (spec/event-ingress.md). Dotted name, class-shaped payload.
IrExpression
IrFileStore
A lowered file store declaration (std.files): the store identity + its literal local root directory, consumed by the runtime file provider.
IrGauge
A lowered gauge declaration (experimentation subsystem): the binding of a judge to a quality dimension, versioning with the program. Lowering class is metadata_only; the evidence engine (whip evidence / whip improve) consumes it at runtime.
IrGaugeBar
A lowered gauge bar. form is chance (P(field)) or stat (p10/mean/…); op is >= (at least) or <= (at most); threshold keeps its exact source text — consumers parse.
IrHarness
IrInclude
IrLease
Coordination resources (spec/coordination.md), lowered.
IrLedger
IrMark
A lowered mark declaration: a named cut point riding a committing site. metadata_only; the runtime stamps mark.reached events, the improve store pins scenarios at them.
IrMemoryPool
A lowered memory pool declaration (std.memory, MEM-1): the pool identity + its optional recall context-limit budget. metadata_only — provides Resource<MemoryPool>; providers read context_limit from the effect input.
IrParam
IrPatternApplication
IrPatternArgument
IrProgram
IrProjectionRead
IrRecordSource
IrRedaction
A redact <source> keep [..] as <binding> projection, surfaced for the information-flow value-flow engine (DR-0027). source is the binding being projected, keep the kept field names, binding the projected output.
IrRegion
DR-0043 Decision 5: a rule’s during/until region, pre-rendered as the three body variants the kernel lowers against. IrRule.body itself is the condition-HOLDS variant (region spliced inline), so every existing text scanner and effect-id derivation is untouched; the kernel swaps in body_removed (region gone – post-lapse suppression) or body_lapsed (region replaced by its arm) per the region’s durable state. NOT rendered into the .ir snapshot (derived, deterministic).
IrRegionEffect
DR-0043 Decision 5: one effect the region contains, with the level-1 after scope the kernel keys its effect id under.
IrRule
IrRuleCaseBranch
IrRuleDependency
IrRuleMetadata
IrSharedCoordinationUsage
IrSource
A lowered source declaration (spec/std-time.md). is_clock selects the clock_source lowering; otherwise signal_source. Both lower through the source_declaration construct family and admit a durable signal fact.
IrSourceDescription
IrSourceEmitField
IrSourceTag
IrStream
One lowered stream declaration (std.vcs): the workstream tier’s declared membership + staleness bound. Runtime homing reads this.
IrTerminalAlternative
IrTerminalCaseBranch
IrTerminalOutput
IrTest
A lowered test scenario (spec/workflow-testing.md). Tests are excluded from the executable IR (compile/run ignore them); whip check validates them and whip test runs them. The clause detail is retained for the harness.
IrTracker
IrUse
IrWhen
IrWorkflowContract
LeaseDecl
Coordination resources (spec/coordination.md): a closed family of shared, workspace-scoped resources with typed keys, atomic branchable operations, and mandatory bounds (ttl/retain/cap+reset).
LedgerDecl
MarkDecl
mark "<name>" after <site> (experimentation subsystem §4.2): a named cut point. The runtime stamps a mark.reached event when the named site commits on any run, so every run’s meaningful moments are addressable — whip pin <run> at <mark> freezes the prefix as a scenario, and regeneration replays that prefix and re-executes only the suffix. Names are stable across edits (event offsets shift, marks don’t). Deliberately a separate declaration from milestone (child→parent lifecycle signaling vs. event-log position).
MemoryPoolDecl
memory pool <name> { context limit <n> } (std.memory, MEM-1): a named durable memory place. Mirrors file store as a declaration_block / metadata_only construct providing Resource<MemoryPool>. v1 pools are provider-less; context limit <n> (optional, non-negative) is the recall packing budget. Unknown clauses are rejected (file-store precedent).
ParamDecl
ParseOutput
PatternDecl
Program
ProjQuery
A projection query: <noun> exists | count <predicate> is <N> | where <predicate>. The predicate reuses the guard expression kernel, restricted to projection fields. The noun is a dotted fact name, so a scenario can assert over runtime facts such as agent.turn.completed as well as single-identifier user facts.
RelatedInfo
A secondary span + short label attached to a Diagnostic as related information (never a top-level diagnostic of its own).
RuleDecl
RunClause
SourceDecl
A top-level source declaration: source <provider> as <name> { ... } or source clock as <name> { ... }. Lowers through the source_declaration construct family to a signal_source (generic provider) or clock_source (the clock provider) admission template (spec/std-time.md, spec/construct-grammar.md). A source admits a durable signal fact; it never fires a rule directly.
SourceEmit
SourceEmitField
SourceSpan
StreamDecl
stream <name> { members [<agent>, ...] [staleness <duration>] } (std.vcs; DR-0052 Decision 5): a declared collaboration — a named shared line whose member agents’ session lines home to it, syncing greedily in-stream and promoting to mainline through one gated boundary. Members are agent declarations (every session of that agent homes here); staleness is the §7.1 bound. Metadata-only lowering, like queue/channel; the runtime workstream tier is the enforcement seam.
StringLiteral
StubClause
stub <surface…> <outcome> [record | string]. The surface path and outcome are kept as tokens; provider-specific validation happens in the harness.
TableDecl
TableRow
TagDecl
TestDecl
A deterministic test scenario (spec/workflow-testing.md). Validated by whip check; excluded from compile/run IR; executed by whip test.
TestField
A <field> <expr> mapping inside a given record body. value is the source text of the expression (parsed via parse_expression when validated), matching how guards and assertions capture expressions.
TimeOfDay
TrackerDecl
UseDecl
WhenClause
WorkflowContractDecl
WorkflowDecl

Enums§

AgentField
BinaryOp
CalendarPattern
CommentMarker
The marker that introduced a comment, preserved so a formatter can re-emit it faithfully.
DependencyPredicate
EffectStatus
ExpectTarget
Expr
ExprLiteral
GaugeBarSubject
GaugeJudge
The generalized judge slot: judge via coerce <Name>(<args>) | prompt "<t>" | exec "<cmd>" | labels "<source>". Coerce judges carry EXPLICIT argument paths (settled 2026-07-14): each names the record value feeding the parameter (input.ticket.title, facts.Assessment.priority), or the single reserved record passes the whole judge-input record — the binding is written down and versioned, never inferred.
GivenClause
HarnessClass
The harness class (DR-0034). Managed = WhippleScript is the agent runtime (owned; hermetic context, full provenance, reproducible). Delegated = a foreign runtime WhippleScript invokes, which assembles its own context. The guarantee is two-valued, so the class is too.
IrCasePattern
IrEffectKind
IrExecTarget
The two exec source forms (spec/std-script.md): a raw command string (exec "cmd", dev-profile only) or an operator-manifest capability (exec <name> with <record>).
IrPrimitiveType
IrSchema
IrType
IrUseKind
IrWorkflowContractKind
Item
MissedPolicy
Missed-occurrence policy from spec/std-time.md. No silent default: a recurring source must declare one (enforced by the checker).
ProjQueryKind
QueryKind
Recurrence
Recurrence forms from spec/std-time.md (conservative first surface).
RuleStatus
RunKind
SourceValue
A value mapped into an emitted signal field: an observation path (tick.scheduled_at) or a literal.
StubPayload
TestClause
TypeSyntax
UnaryOp
Weekday
WorkflowContractKind

Constants§

BUILTIN_GAUGES
The built-in resource gauges: deterministic observables already in the effect ledger, present without declaration (improve design note §3). std.cache_hit is the provider prompt-cache hit rate (cache-read tokens / total input-side tokens) — present only when the provider reports cache usage (spec/inference-cache-note.md G2).
CHANNEL_PROVIDER_REPORTS
The four v1 std.messaging providers (spec/std-messaging.md “Providers”).
FILE_STORE_PROVIDERS
The v1 std.files store providers (spec/std-files.md “Providers”): local is the FileStore host-projection seam (native + DO) and the default when a file store declares no provider clause. Non-filesystem providers (S3/GitHub/Drive) are deferred with cause; an unknown identifier is a check error at the declaration.
STD_PACKAGE_IDS
The complete standard-package universe (the 13 std packages of the standard-package campaign). use std.<name> outside this list is a check error: std resolution is a built-in registry, so an unknown name can never resolve later — a typo’d use std.coercon would otherwise silently import nothing (and downstream missing-import bite is advisory only).

Functions§

canonical_declarations
Canonicalize every top-level declaration of source. None when the source does not parse or the declaration identities are ambiguous (duplicates) — callers fail closed to their pre-DR behavior. A multi-workflow program’s workflow X { … } blocks are single units (matching merge’s depth-0 split), with alpha applied to their nested rules.
canonical_program_hash
The canonical program hash: SHA-256/128 over the sorted (identity, canon_hash) pairs — insensitive to formatting, comments, declaration order, and rule-binding names. None when the source has no canonical form.
channel_provider_report
Resolve a channel’s declared provider <p> identifier against the v1 provider reports: the short name (local) or the full binding provider id (std.messaging.local) both resolve. None = unknown identifier, a check error (spec/std-messaging.md open question 2 resolved: short names resolved against contributed provider kinds, unknown = check error).
compile_program
Parses and lowers a source file into deterministic typed IR.
compile_program_with_root
Parses and lowers a source bundle into deterministic typed IR with an optional explicit root workflow selection.
document_symbols
Top-level declarations of source in source order, for an editor outline. On a parse error it returns whatever declarations parsed (best-effort outline).
format_program
Formats the syntax tree without lowering or analyzing rule bodies.
format_program_preserving_comments
Format source while preserving comments where they can be placed safely: top-level leading comments (a # … or // … line above a declaration, or a file-header block) and trailing comments on a single-line top-level declaration (workflow Demo # …, attached to that element’s line); comments inside raw-body declarations (rule/apply/coerce/table/flow, carried by the body substring); and comments inside class/agent/enum bodies, including a data-carrying enum variant’s nested field block — both own-line (interleaved by source position) and trailing comments on a field/variant line (appended to it), and signal/queue/file store bodies the same way — even though those bodies rebuild from the AST. Returns None when the program does not parse, or when a comment has nowhere to attach — e.g. one trailing a declaration’s opening-brace line, with no field on that line. The caller refuses such files rather than dropping comments.
harness_class
Classify a harness kind (DR-0034 Decision 6). Total over the supported kinds: owned and the credential-free fixture model client are Managed; every other kind (codex/claude sidecars, the native-fixture delegated adapter, command) is Delegated. An unrecognized kind — validated registry-side by the CLI (spec/std-agent.md “Open provider registry”) — defaults to Delegated, never granting the Managed guarantee to something unknown.
inline_decide_schema_name
The hygienic class name synthesized for an inline decide -> { … } as <binding>. Dots are illegal in user class names (like the flow.<name>.seg* rule convention), so decide.<rule>.<binding> can never collide with a declared schema. The lowering pass, the type checker, and the runtime fixture all derive the same name, so the anonymous result shape flows exactly like a named coerce -> Schema: after <binding> succeeds as r resolves r’s fields for case dispatch and field access.
lex_comments
Extract the comments from a source program, in source order. Comments are not part of the token stream or AST; this is the entry point tooling (whip fmt, the LSP) uses to preserve them.
parse_duration_seconds
parse_expression
Parses a deterministic expression used by guards, assertions, and branch guards.
parse_program
Parses a source file into a recoverable AST plus diagnostics.
parse_time_epoch_seconds
parser_stage
Stage marker retained for the CLI scaffold.
redact_schema_name
The hygienic synthetic class name for a redact … as <binding> projection: redact.<rule>.<binding>, holding only the kept fields of the source schema.
runtime_fact_name_for_pattern
The single lowering table for readiness sugar: maps a when pattern to the runtime fact name it matches. The general form is when fact <name> as x; the English phrases are documented abbreviations of it.
string_and_comment_spans
Byte-span regions of string literals and comments in source. A tool that edits identifier occurrences (e.g. whip lsp rename) consults these to avoid touching text inside a prompt string or a comment — only code identifiers are real references.