| permalink | /02-tutorial.html |
|---|---|
| title | Tutorial |
This tutorial is intentionally strict: every valid snippet below follows FACET v2.1.3 normative syntax.
@context
budget: 32000
@vars
prompt: "Explain deterministic compilation in one paragraph."
@system
content: "You are a technical assistant."
@user
content: $prompt
Run:
facet-fct build --input tutorial-01.facet
facet-fct run --input tutorial-01.facet --format prettyForward references are allowed; unknown references are not.
@vars
final_prompt: "$prefix: $query"
prefix: "Question"
query: @input(type="string") |> trim()
@system
content: "Answer clearly."
@user
content: $final_prompt
querycomes from runtime input.final_promptdepends onprefixandquery.- Evaluation order is resolved by dependency graph (Phase 3), with tie-break by ordered-map insertion rules.
Valid:
@vars
q: @input(type="string")
clean_q: @input(type="string") |> trim() |> lowercase()
Invalid (must raise F452):
@vars
bad: { q: @input(type="string") }
@var_types
age: "int"
name: "string"
status: "string | null"
@vars
age: 30
name: "Alice"
status: null
Constraint examples:
@var_types
score: "float"
@vars
score: 98.5
Type mismatch must raise F451; constraint/placement violations must raise F452.
Valid message fields are limited to content, layout fields (id|priority|min|grow|shrink|strategy), and when.
@vars
include_note: true
@system
content: "You are concise."
@assistant(when=$include_note)
content: "Acknowledged."
@user
content: "Summarize FACET in 3 bullets."
Non-boolean when must raise F451.
base.facet:
@vars
a: "base"
@system
content: "Base system message."
main.facet:
@import "base.facet"
@vars
a: "override"
b: "new"
@user
content: "$a / $b"
Rules:
- Imports are expanded in source order.
- Singleton facets are deep-merged with stable first-insertion key positions.
- Repeatable facets (
@system,@user, etc.) are concatenated in encounter order.
@interface WeatherAPI
fn get_current(city: string) -> struct {
temp: float
condition: string
} (effect="read")
@system
tools: [$WeatherAPI]
content: "Use weather tools when needed."
@user
content: "Weather in Minsk?"
Missing function effect must raise F456.
@policy
deny:
- id: "deny-write-tools"
op: "tool_call"
effect: "write"
allow:
- id: "allow-weather-read"
op: "tool_call"
name: "WeatherAPI.get_current"
effect: "read"
@system
tools: [$WeatherAPI]
content: "You can read weather only."
Key properties:
- Rule fields are conjunctive (AND).
denyis evaluated beforeallow.- Deterministic deny is
F454; undecidable guard state isF455.
@vars
query: @input(type="string")
@system
content: "You are helpful."
@user
content: $query
@test "basic"
input:
query: "hello"
assert:
- canonical.messages[0].role == "system"
- canonical contains "hello"
Run tests:
facet-fct test --input tutorial-test.facetThese are legacy/non-spec and should not be used as valid FACET syntax:
@systemfields likerole,model,instructions,temperature@context.documentsor using@contextas data storage- non-standard directives such as
@if(...)in expressions