Module 02
The type model
Systems, types, fields and closed enums.
Learning intent
By the end of this module you will be able to
- Read the core VSL type-model constructs as data-shape contracts.
- Explain how systems, types, fields, and closed enums make invalid structure fail.
Success criteria
- Identify the top-level system container in a VSL snippet.
- Explain why a VSL type is not a class with methods.
- Use a closed enum to rule out an invalid state.
Retrieval warm-up
Before the new material
Recall
Does the `ask` verb ever mutate state? If not, which verbs do?
Answer
No. `ask` is read-only; it retrieves authoritative truth. Only `run` (execute an action) and `create` (make a new artifact) mutate, and both under preview-by-default.
Recall
Both `show` and `ask` are read-only. What distinguishes them?
Answer
`ask` retrieves a value into the conversation; `show` renders a selection for presentation (a view or table). Same read, different intent.
Recall
What happens in a workflow when a `check` step fails?
Answer
`check` validates an artifact against its contract and emits diagnostics; it never executes. On failure the workflow fails closed, so any following `create` or `run` does not proceed.
Learner readiness
Before this reference page
Assumed terms:
Terms introduced or strengthened here:
You are ready to continue when you can:
- identify a VSL system as the top-level contract container
- explain why a type is a data shape rather than a class with methods
- explain why closed enums make invalid states fail
Concept · grounded · RICH E4
system
Top-level VSL declaration; a named governed system with mission, authority, domain, maturity.
Worked examples
system magatama.seed.year10_demonstrator {
mission "Optionally import the Year 10 reactivity-rocket project ..."
authority lane "operator:magatama-program"
domain propulsion.education-demonstrator-import
maturity draft
}
Every VSL file is rooted in a `system`. It carries identity (the dotted name), a mission string, one or more authority lanes, a domain, and a maturity rung. Everything else (types, enums, workflows) lives inside its braces.
system magatama.seed.year10_demonstrator {
context root = "helios://project/magatama/year10-demonstrator?view=detail"
compile varro-surface -> varro
}
Beyond the header, a system can bind a `context root` (its helios:// home) and declare `compile` lowering targets. These tie the abstract system to a concrete resource address and an output backend.
Try it
You are handed an empty file. Author a single, complete VSL `system` declaration for a campus room-booking surface. It must carry the full system header (mission, `authority lane`, `domain`, `maturity`, and a `context root = ...`) and a `runtime specification` block, plus at least one enum, one type, one action, one query and one workflow so the system is non-trivial. It must pass `varro check vsl` with zero errors.
system mentormind.facilities.room_booking {
mission "..."
authority lane "operator:research"
domain education
maturity draft
# context root, runtime block and at least one of each inner construct still TODO
}
Model answer (passes varro check vsl)
system mentormind.facilities.room_booking {
mission "Specify a governed room-booking surface for a campus, exposing booking state as typed contracts under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/facilities/room-booking?view=detail&tab=contract&bind=auto"
enum RoomState {
value free
value held
value booked
}
type Room {
field room_id: string required
field capacity: integer required
field state: RoomState required
}
compile booking-runtime -> varro
action hold-room {
risk low
binding required
input room_id: string required
}
query rooms.free {
output Room[]
}
workflow reserve-room {
inspect selection
resolve rooms.free
check hold-room
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Try it
Author a complete governed room-booking VSL system that composes a system header, enum, type, compile target, action, query, workflow, and runtime block, then validate it with `varro check vsl`.
system mentormind.facilities.room_booking {
mission "..."
authority lane "operator:research"
domain education
maturity draft
# full contract still TODO
}
Model answer (passes varro check vsl)
system mentormind.facilities.room_booking {
mission "Specify a governed room-booking surface for a campus, exposing booking state as typed contracts under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/facilities/room-booking?view=detail&tab=contract&bind=auto"
enum RoomState {
value free
value held
value booked
}
type Room {
field room_id: string required
field capacity: integer required
field state: RoomState required
}
compile booking-runtime -> varro
action hold-room {
risk low
binding required
input room_id: string required
}
query rooms.free {
output Room[]
}
workflow reserve-room {
inspect selection
resolve rooms.free
check hold-room
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Common trap
❌ Learners read `system` as merely a class or module wrapper.
Correction
✅ A VSL `system` is a governed unit: it must declare identity, mission, authority lanes, domain, and a maturity rung. It is a governance boundary, not just a code namespace.
Check yourself
What must a VSL `system` declaration include in its header?
Answer
Identity (the dotted name), a mission, one or more authority lanes, a domain, and a maturity rung. Types, enums, and workflows live inside its braces.
Concept · grounded · RICH E4
type
A named record of typed fields inside a system.
Worked examples
type ImportedArtefact {
field artefact_id: string required
field source_ref: uri required
field cannot_authorise: string[] required
}
A `type` names a record. Each `field` has a name, a kind (string, uri, integer, bool, a named enum, or an array like string[]), and a required/optional marker.
type RustComponentBoundary {
field component_role: string required # component-role
field permitted_output_authority: string required # output-authority
}
Fields can be constrained to a declared enum. Here the trailing comment names the enum that backs the field, moving a closed value set from prose into the type system.
Try it
Inside a complete library-catalogue `system`, declare a `Holding` record `type` whose fields capture title, an author reference, year, availability, a cover-image URI and a tag list. Use at least one enum-typed field and one reference-by-string field. Add a second `Author` type so a reference target exists. The whole system must pass `varro check vsl` with zero errors (so include the system header, a compile target and a runtime block).
type Holding {
field holding_id: string required
field title: markdown required
# author reference, year, availability, cover image, tags still TODO
}
Model answer (passes varro check vsl)
system mentormind.library.catalogue {
mission "Model a library catalogue as typed records so an agent can reason over holdings under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/library/catalogue?view=detail&tab=contract&bind=auto"
enum Availability {
value on_shelf
value on_loan
value lost
}
type Author {
field author_id: string required
field display_name: string required
field aliases: string[] required
}
type Holding {
field holding_id: string required
field title: markdown required
field author_ref: string required
field year: integer required
field availability: Availability required
field cover_image: uri required
field tags: string[] required
}
compile catalogue-runtime -> varro
action loan-holding {
risk low
binding required
input holding_id: string required
}
query holdings.available {
output Holding[]
}
workflow lend-book {
inspect selection
resolve holdings.available
check loan-holding
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Try it
Author a complete governed room-booking VSL system that composes a system header, enum, type, compile target, action, query, workflow, and runtime block, then validate it with `varro check vsl`.
system mentormind.facilities.room_booking {
mission "..."
authority lane "operator:research"
domain education
maturity draft
# full contract still TODO
}
Model answer (passes varro check vsl)
system mentormind.facilities.room_booking {
mission "Specify a governed room-booking surface for a campus, exposing booking state as typed contracts under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/facilities/room-booking?view=detail&tab=contract&bind=auto"
enum RoomState {
value free
value held
value booked
}
type Room {
field room_id: string required
field capacity: integer required
field state: RoomState required
}
compile booking-runtime -> varro
action hold-room {
risk low
binding required
input room_id: string required
}
query rooms.free {
output Room[]
}
workflow reserve-room {
inspect selection
resolve rooms.free
check hold-room
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Common trap
❌ Learners expect a VSL `type` to hold behaviour or methods like an OOP class.
Correction
✅ A VSL `type` is a pure record of typed fields. Behaviour lives in `action` and `workflow` declarations, not inside the type.
Check yourself
What does a VSL `type` contain, and can it hold methods?
Answer
A `type` is a record of typed fields (name, kind, required/optional). It holds no behaviour; methods live in `action` and `workflow` declarations.
Concept · grounded · RICH E4
field
A typed member of a type: name: type [required|optional].
Worked examples
type SourcePaper {
field paper_id: string required
field total_marks: integer required
field structure_evidence_ref: uri optional
}
A field is `field <name>: <kind> <required|optional>` inside a `type` block. The obligation is part of the type, not a downstream runtime check: `required` means the parser rejects an instance missing the member; `optional` admits absence. Kinds are the closed set string/markdown/uri/integer/number/bool, arrays (`string[]`), and named enums. Unlike a struct field default in Rust, optionality here is a declared property of the schema, not a `Default` impl — there is no inferred zero value, absence is absence.
enum Subject { physics chemistry }
type SourcePaper {
field subject: Subject required
}
Typing a field by a named enum closes its value set at the schema layer: `subject` can only be `physics` or `chemistry`, and an unlisted value fails validation before any code runs. This is the VSL idiom for lifting a prose constraint ("subject is one of...") into a checkable invariant. Evaluate it against a stringly-typed alternative (`field subject: string`): the enum form makes the illegal state unrepresentable in the spec, which is precisely the property you would otherwise have to defend with a hand-written validator and a test.
Try it
Inside a complete sensor-registry `system`, declare a `Sensor` type whose fields demonstrate every field shape you control: a required `string` id, a `bool`, a `number` reading with its `string` unit, an `optional` `uri` datasheet, and an enum-typed `health`. The point is the `field <name>: <type> [required|optional]` grammar, including making exactly one field `optional`. The full system must pass `varro check vsl` with zero errors.
type Sensor {
field sensor_id: string required
field last_reading: number required
field datasheet: uri # required or optional? pick deliberately
# unit, calibrated flag, enum-typed health still TODO
}
Model answer (passes varro check vsl)
system mentormind.devices.sensor_registry {
mission "Register field-deployed sensors with a precise typed field set so readings stay self-describing under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/devices/sensor-registry?view=detail&tab=contract&bind=auto"
enum Health {
value nominal
value degraded
value offline
}
type Sensor {
field sensor_id: string required
field label: string required
field firmware_version: string required
field calibrated: bool required
field last_reading: number required
field unit: string required
field datasheet: uri optional
field health: Health required
}
compile sensor-runtime -> varro
action mark-offline {
risk low
binding required
input sensor_id: string required
}
query sensors.nominal {
output Sensor[]
}
workflow retire-sensor {
inspect selection
resolve sensors.nominal
check mark-offline
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Common trap
❌ Coming from SQL/ORM or Rust structs, a senior engineer reads `optional` as "nullable, defaults to NULL/zero" and assumes the system fills a value when the field is absent.
Correction
✅ `optional` only declares that absence is admissible; it supplies no value and no default. There is no inferred zero. A consumer must treat an optional field as possibly-absent, not as present-with-default. Required/optional is a presence obligation in the type, distinct from any value semantics.
Check yourself
In `field source_pdf_ref: uri required`, what does the `required` keyword constrain, and at what layer is it enforced?
Answer
It constrains the schema: an instance of the enclosing type is invalid if the field is absent. Enforcement is at parse/validation of the VSL, not at runtime — `optional` would admit absence. The kind (`uri`) separately constrains the value's shape.
Concept · grounded · RICH E4
enum
A closed set of named variant values.
Worked examples
enum output-authority {
value student-analysis
value teacher-controlled-model
value vendor-only
value blocked
}
An `enum` declares a finite set of `value` variants. A field typed by this enum can only ever hold one of these names, so illegal states become unrepresentable.
# weak: field stage: string
# strong: enum demonstrator-import-stage { value source-of-truth-check ... }
# field imported_stage: string required # demonstrator-import-stage
Using a free `string` lets any typo through. Declaring an `enum` and naming it on the field documents the legal set and lets the checker reject unknown variants.
Try it
Inside a complete support-ticket triage `system`, model the three closed dimensions of a ticket as separate `enum` declarations: priority (p0..p3), lifecycle (new -> closed) and channel. Then declare a `Ticket` type that consumes all three enums as field types. The full system must pass `varro check vsl` with zero errors.
enum Priority {
value p0
# p1, p2, p3 ...
}
# Lifecycle and Channel enums, plus a Ticket type that uses all three, still TODO
Model answer (passes varro check vsl)
system mentormind.support.ticket_triage {
mission "Specify a support-ticket triage surface whose lifecycle and priority are closed enum value sets under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/support/ticket-triage?view=detail&tab=contract&bind=auto"
enum Priority {
value p0
value p1
value p2
value p3
}
enum Lifecycle {
value new
value triaged
value in_progress
value resolved
value closed
}
enum Channel {
value email
value chat
value phone
}
type Ticket {
field ticket_id: string required
field priority: Priority required
field lifecycle: Lifecycle required
field channel: Channel required
field summary: markdown required
}
compile triage-runtime -> varro
action escalate-ticket {
risk confirm_required
binding required
input ticket_id: string required
}
query tickets.open {
output Ticket[]
}
workflow triage-queue {
inspect selection
resolve tickets.open
check escalate-ticket
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Try it
Author a complete governed room-booking VSL system that composes a system header, enum, type, compile target, action, query, workflow, and runtime block, then validate it with `varro check vsl`.
system mentormind.facilities.room_booking {
mission "..."
authority lane "operator:research"
domain education
maturity draft
# full contract still TODO
}
Model answer (passes varro check vsl)
system mentormind.facilities.room_booking {
mission "Specify a governed room-booking surface for a campus, exposing booking state as typed contracts under research authority"
authority lane "operator:research"
domain education
maturity draft
context root = "helios://local/mentormind/facilities/room-booking?view=detail&tab=contract&bind=auto"
enum RoomState {
value free
value held
value booked
}
type Room {
field room_id: string required
field capacity: integer required
field state: RoomState required
}
compile booking-runtime -> varro
action hold-room {
risk low
binding required
input room_id: string required
}
query rooms.free {
output Room[]
}
workflow reserve-room {
inspect selection
resolve rooms.free
check hold-room
render center.detail
}
runtime specification {
host governed
commit-mode host-only
}
}
Common trap
❌ Learners think a field can carry an enum value that was not declared, treating the enum as a hint.
Correction
✅ An `enum` is a closed set. A field typed by it can hold only the declared `value` variants; the checker rejects anything else. That closedness is the point.
Check yourself
Can a field typed by an enum hold a value not declared in that enum?
Answer
No. An `enum` is a closed set of `value` variants; the checker rejects any undeclared value. That closedness moves constraints from prose into the type system.
Module assessment · scored