Appearance
Quickstart: compile an English pilot package
This walkthrough is for implementation collaborators who already have approved repository access. It proves the current English path, shows the recommended authoring order, and compiles a new package without treating compilation as publication or runtime installation.
Prerequisites
Run commands from the repository root. The compiler requires Python 3.11+ and uv; the playable local application also requires Node.js 20.19+ and Docker. Use npm run setup if the repository dependencies have not yet been prepared.
1. Prove the compiler with the English canary
The repository's Orbital Garden Relay canary is deliberately synthetic and lives under test fixtures. Compile it with its fixture content root:
bash
uv run --project apps/api meet-u-compile-pilot \
--content-root apps/api/tests/fixtures \
--output-root /tmp/meet-u-orbital-bundles \
--package-id orbital-garden-relay \
--version 1A successful result is JSON with "status":"succeeded", paths to the canonical IR and runtime-bundle content, and a content digest. It also says "activatable":false; that is expected.
Verify that the existing content-addressed output exactly matches a fresh compile:
bash
uv run --project apps/api meet-u-compile-pilot \
--content-root apps/api/tests/fixtures \
--output-root /tmp/meet-u-orbital-bundles \
--package-id orbital-garden-relay \
--version 1 \
--check--check does not create the expected output for the first time. Run the ordinary compile first, keep the same output root, and then run --check.
2. Create the package directory
Production-tree source packages use this path:
text
content/creator-sources/my-pilot/v1/Use a package ID made from lowercase letters, digits, and hyphens, beginning with a letter or digit. The path, compiler argument, and source-package.yaml identity must agree exactly:
yaml
package:
id: my-pilot
version: 1Create all seven fixed YAML filenames listed in the technical package overview. The manifest's six module references are closed literals; the compiler does not accept alternate names or omit a module.
Use the v1 field reference for every field and nested type. The source models reject unknown fields, so do not infer field names from the broader proposal specification.
3. Author meaning before wiring IDs
Write a short Creator brief before filling YAML. Settle these questions:
- Who is the character, and what makes their choice recognizably theirs?
- Why can the remote user communicate with them without entering the world?
- What can the user ask, challenge, comfort, or influence—and what can they never directly do?
- What is the bounded dilemma, and which decisions remain faithful?
- What objective outcome follows each allowed decision?
- What does the character observe, choose to disclose, and later tell the user?
- What exact visual and Journal evidence makes the causal chain legible?
This brief is the human-created dramatic foundation. The compiler checks its typed expression; it does not invent missing drama.
4. Fill the seven files in dependency order
A. source-package.yaml
Declare the schema version, package identity, six fixed module references, at least one external provenance reference, and non-empty semantic_parity.preserves and semantic_parity.excludes lists.
This is the manifest shape for the example package:
yaml
schema_version: meet_u.creator_source_package.v1
package:
id: my-pilot
version: 1
display_name: My Pilot
ip_title: My Original IP
default_locale: en-US
primary_character_id: my_character
arc_id: first_dilemma
modules:
character: character.yaml
relationship: relationship.yaml
arc: arc.yaml
dialogue: dialogue.yaml
visual: visual.yaml
acceptance: acceptance.yaml
provenance:
- role: semantic_normalization_authority
ref: creator-private://my-pilot/reviewed-brief-v1
semantic_parity:
preserves:
- "REPLACE: specific meaning retained from Creator material or an accepted decision"
excludes:
- "REPLACE: mechanics or historical behavior intentionally outside this source"The manifest also names the primary character and arc IDs. Reuse those exact IDs in character.yaml, relationship.yaml, and arc.yaml.
Every REPLACE value above must be replaced before review. The example creator-private reference is only a placeholder for a durable, access-controlled source record; it does not define an intake storage scheme. Provenance must truthfully identify the source of the normalized meaning; it is not a box to check. The current role vocabulary is unusually narrow. If a new IP's source cannot honestly use one of the allowed roles, do not invent a reference or mislabel the source just to compile—record the contract gap first. See the provenance role boundary for the complete current list and limitation.
B. character.yaml
Define identity, values, goals, contradiction, boundaries, prohibited portrayals, decision tendencies, knowledge limits, disclosure posture, voice, and constructive refusal. Write these as portrayal constraints and dramatic meaning, not as instructions to obey the user.
The constructive_refusal.style_anchor is also the exact text referenced by the current CHAT_ONLY recovery surface. Keep it truthful and useful even when no user-requested effect is permitted.
C. relationship.yaml
Describe the user as a remote confidant and keep the fixed v1 channel flags false: the user has no physical presence; NPCs cannot receive, verify, or answer user messages; and the character cannot forward the raw message.
Choose a small, semantic influence_vocabulary, such as support, challenge, or respected boundary meanings appropriate to this character. These IDs are evidence categories, not keywords and not commands that select a decision.
Add the optional reciprocal promise or invented shared context only when the story genuinely needs it. Every extra semantic mechanism adds cross-file obligations.
D. arc.yaml
Author in this order:
- narrative time, world facts, locations, NPCs, and one narrative deadline;
- the current Arc Progression V1 phase and its initial character beliefs;
- character decisions, each with typed eligibility, qualitative influence fit, one typed action, and one outcome ID;
- one deterministic outcome for every decision; and
- at least one character-owned follow-up option for every outcome.
Although arc.progression is optional in the base source model, it is required by the only current CLI build target, local_owner_synthetic_preview. Its decision phase must cover every decision exactly once and use the declared world deadline as its single horizon.
Write narrative_time.anchor_local_time and the deadline's narrative_local_time as ISO local times such as "05:20". Quote them so the YAML parser preserves text. If a reciprocal promise has a narrative due time, quote its ends_local_time the same way.
The terminal no_eligible_guidance.public_projection.text must include en-US for an English package. It may also contain zh-CN, but the rest of the package is not translated automatically.
E. dialogue.yaml
Write the exact Creator opening, guided ordinary-dialogue obligations, recovery declarations, one semantic-lock dialogue entry per arc follow-up, and exact Journal copy.
Keep opening.generated_reply_suggestions: false for the current pilot work. The schema can carry a boolean, but accepted product decisions leave broader suggested-reply enablement open; a compilable true value is not authorization to ship that interaction.
For an English package, both recovery.degraded_chat.locale and every recovery.chat_only[].locale must be en-US. Every fact ID in a must_not_disclose_fact_ids list must exist in the arc fact graph.
Across the CHAT_ONLY surfaces, cover the three required immediate recovery contexts exactly once: ordinary_no_effect, capability_boundary, and their combined set. The same exact constructive-refusal anchor may serve all three, as both current example packages do.
The Journal is exhaustive: provide exactly one statement for every influence kind, decision ID, and outcome ID. Statements describe the validated causal record; they must not credit the user with the character's action or the world result.
F. visual.yaml
Declare visual identity, one portrait asset, and exactly one depiction per outcome. Assets must already exist. Package-local paths begin with assets/; the only allowed external alternative is the same package/version's historical pilots/<package-id>/v<version>/assets/ namespace, written relative to the selected content root. For --content-root content, for example, write source_path: pilots/my-pilot/v1/assets/portrait.png; the corresponding repository file is under content/pilots/..., but content/ is not part of the YAML value.
visible_fact_ids may include only externally visible facts committed by that outcome. Put private or visually misleading facts in forbidden_fact_ids. Asset provenance is required authorial traceability; it is not asset approval.
The current compiler accepts .avif, .gif, .jpeg, .jpg, .png, .svg, and .webp assets. The suffix comparison is case-insensitive, and the emitted bundle path is derived from the asset ID and normalized suffix.
G. acceptance.yaml
Write meaning-level cases that distinguish useful user positions, expected influence kinds, allowed decision space, and forbidden effects. Add paraphrase ranges that should preserve meaning across different wording.
Never write quoted phrases as routes. Acceptance cases are evaluation evidence; they cannot directly choose stance, action, outcome, or reply.
5. Compile the package
For the example identity above:
bash
uv run --project apps/api meet-u-compile-pilot \
--content-root content \
--output-root /tmp/meet-u-my-pilot-bundles \
--package-id my-pilot \
--version 1After it succeeds, rerun the same command with --check:
bash
uv run --project apps/api meet-u-compile-pilot \
--content-root content \
--output-root /tmp/meet-u-my-pilot-bundles \
--package-id my-pilot \
--version 1 \
--checkThe compiler reads the whole source and asset closure, validates cross-file meaning, lowers deterministic canonical IR, and emits content-addressed runtime bundle files. It does not call an LLM.
6. Read failures from the outside inward
| Error family | What to check first |
|---|---|
| Invalid or duplicate YAML | Indentation, quoting, unique mapping keys, UTF-8 text, and whether the document root is a mapping |
| Semantic contract violation | The field path in the Pydantic error and the exact type/closed value in the field reference; unknown fields are rejected |
| Forbidden Creator source field | Remove runtime, provider, prompt, approval, lifecycle, or raw-text routing configuration from Creator YAML |
| Package identity mismatch | Directory ID/version, CLI arguments, manifest package identity, primary character references, and arc ID |
| Unknown or inconsistent reference | Trace the ID across relationship, arc, dialogue, visual, and acceptance modules; do not fix it by inventing a second near-duplicate ID |
| Missing Arc Progression V1 | Add arc.progression, a world deadline, full decision coverage, and the default-locale no-eligible projection |
| Locale catalog or recovery mismatch | Use exactly en-US or zh-CN; make every recovery locale equal package.default_locale |
Incomplete or ambiguous CHAT_ONLY recovery | Cover the immediate ordinary-no-effect, capability-boundary, and combined obligation sets exactly once across all chat_only surfaces |
| Missing or unsafe asset | Check file existence, case, package-local assets/ path, absence of symlinks or .., and outcome coverage |
| Unsupported media suffix | Use .avif, .gif, .jpeg, .jpg, .png, .svg, or .webp |
| Journal coverage mismatch | Provide one and only one statement for every influence kind, decision, and outcome |
--check bundle mismatch | Compile once to that output root, keep the same source/compiler/policy inputs, and check that the expected digest directory still exists |
Source values must be canonical: mapping keys are strings, floating-point numbers are forbidden, integers must be JavaScript-safe, and booleans should be YAML booleans rather than quoted strings. Declared paths cannot be absolute, escape their allowed root, contain symlinks, or collide after Unicode/case normalization.
7. Stop at the correct boundary
A green compile proves that one frozen source graph can be lowered under the current compiler and platform policy. It does not prove rights, Creator approval, asset approval, behavioral qualification, release eligibility, or activation. Continue with compilation and lifecycle before making any broader claim.