Foundry. Manifest
(foundry v0.1.4)
Copy Markdown
The project manifest resource. Validates and provides typed access to the
.foundry/manifest.exs configuration file for a target project.
Storage
The manifest lives as a plain Elixir keyword list at .foundry/manifest.exs
in the target project's repository (ADR-015). This Ash resource is the
schema + validation layer — it does not persist to a database.
Ash.DataLayer.Simple is used here solely to leverage Ash's changeset
validation, attribute type coercion, and embedded resource support. The
manifest is always a single instance — it is loaded once at Studio
startup and held in-process. It is never queried by ID, never paginated,
and never written to a database. Ash.DataLayer.Simple is the lightest
data layer that gives us Ash validations without any storage infrastructure.
Do not add :read actions that imply collection semantics (list, filter,
sort). The only meaningful action is :load — construct from a keyword list.
Loading
Use Foundry.Manifest.Reader.load!/1 to read and validate the manifest file.
That function parses the .exs file, constructs a Foundry.Manifest record
via Ash.Changeset.for_create/3 with the :load action, and raises if
validation fails. The returned record is cached in ETS for the session
(ADR-015 Tier 2 — keyed on {:manifest, mix_exs_mtime}).
Validation
All fields declared in docs/manifest-schema-draft.md are validated here.
Invalid manifests raise at Studio startup — Foundry will not run against a
project with a broken manifest.
Calculations
Calculations on this resource use Elixir-native expr/1 forms only.
SQL fragment/1 expressions are not valid with Ash.DataLayer.Simple —
it evaluates expressions in Elixir, not Postgres. Any calculation that
appears to need a fragment should be implemented as a module-based
calculation instead.
ADR
ADR-011 (deferred — write after this resource is stable in production).
Pre-ADR schema: docs/manifest-schema-draft.md.
Summary
Types
@type t() :: %Foundry.Manifest{ __lateral_join_source__: term(), __meta__: term(), __metadata__: term(), __order__: term(), aggregates: term(), approval_sla: term(), approvers: term(), ash_money_enabled: term(), auto_apply_structural: term(), calculations: term(), change_generation_enabled: term(), conditional_libraries: term(), context_exclusions: term(), copilot_model: term(), coverage_gate: term(), coverage_weights: term(), data_retention: term(), domain_type: term(), fun_with_flags_enabled: term(), has_notification_config: term(), id: term(), inserted_at: term(), mcp_enabled: term(), notifications: term(), project_name: term(), sensitive_resource_exemptions: term(), sensitive_resources: term(), tidewave_scaffold: term(), updated_at: term() }
Functions
Validates that the keys in the provided input are valid for at least one action on the resource.
Raises a KeyError error at compile time if not. This exists because generally a struct should only ever
be created by Ash as a result of a successful action. You should not be creating records manually in code,
e.g %MyResource{value: 1, value: 2}. Generally that is fine, but often with embedded resources it is nice
to be able to validate the keys that are being provided, e.g
Resource
|> Ash.Changeset.for_create(:create, %{embedded: EmbeddedResource.input(foo: 1, bar: 2)})
|> Ash.create()
Same as input/1, except restricts the keys to values accepted by the action provided.