YAML Authoring and Build Artifact Contract
Pharos uses YAML-first app authoring and JSON build artifacts.
Source of truth
For supported declarative app surfaces, authors edit YAML in the app source tree:
pharos.app.ymltemplates/*.page.yml- app-owned YAML contract files under
data/contracts/and related supported app directories
HTML templates, static assets, and immutable media remain app-owned files in their normal source locations. Apps that accept mutable customer uploads declare assets.runtime_media_dir for the runtime-owned external storage path. This path is separate from assets.media_dir, which remains part of the app source or immutable built artifact.
Build artifacts
The build pipeline compiles YAML source into JSON artifacts that the runtime consumes:
pharos.app.json- compiled JSON page declarations
- compiled JSON contract artifacts
Generated JSON is a build output format. It is not the preferred authored source.
Source versus artifact rule
Keep this rule straight:
- source trees are YAML-first
- artifact trees are JSON-consumption surfaces
If a document, plan, or example tells an app author to create pharos.app.json by hand as the primary manifest source, that guidance is stale.
Validation flow
Use the commands in this order:
pharos build app <app_id> --build-dir distpharos verify app <app_id> --build-dir distpharos doctor app <app_id> --build-dir dist
- compiles YAML source into artifact JSON - fails on malformed source or missing required source contract fields
- validates the built artifact contract
- reports resolved application structure and validation findings against the built app
For source changes, build is the first gate because it exercises YAML compilation. verify and doctor operate on the build output contract.
Example apps
Use these apps to prove YAML contract changes:
static_appfor the smalleststatic-pagesshapedynamic_appfor the smallest dynamic app contract setdev_docsfor docs packaging and navigationucalfor the largest shipped dynamic app and generated-surface usage
YAML validation behavior
The YAML pipeline fails closed.
Rejected inputs
Builds fail closed for:
- duplicate mapping keys
- YAML aliases
- complex or non-scalar mapping keys
- malformed YAML
- manifests or supported declarations that cannot be compiled into the required JSON contract
Expected diagnostics
Validation error families include:
yaml_duplicate_keyyaml_alias_unsupportedyaml_complex_key_unsupportedyaml_parse_error
These are source-validation failures, not runtime route failures.
Include behavior
Pharos does not treat arbitrary YAML includes as a broad authoring feature.
The supported narrow include behavior is the framework fields: include form used by app contract files where the contract allows it.
Example:
entity_id: user_account
fields: entity_fields-v1.yml#entity.user_account.fields
That form points at a sibling YAML file plus a subsection path. It is intended to reduce duplication in field-heavy contract files. Do not treat it as a general-purpose templating language.
Provenance and source mapping
When YAML is compiled into JSON artifacts, the build pipeline retains source provenance where supported so validation and generated-surface tooling can trace built output back to the authored source.
That provenance is for diagnostics and contract tracing. It does not change the rule that YAML remains the authored source and JSON remains the runtime-facing artifact.
What belongs where
Source tree:
pharos.app.yml- YAML page declarations
- YAML contract files
- app-owned HTML, CSS, JS, media, and config
Artifact tree:
pharos.app.json- compiled JSON declarations
- packaged app output under
dist/apps/<app_id>/
Do not edit generated JSON in the artifact tree and then treat it as the enduring app source.