Current section
Files
Jump to
Current section
Files
priv/toolchain/platforms/ash_phoenix.md
# ash_phoenix — extraction record shapes
**Mechanical front-end available**: `../witness.py` (tree-sitter)
extracts this platform deterministically — resources, router, secrets.
Prefer it wherever python + pip are available; this guide remains the
contract (and the LLM fallback's instructions). The records it emits
are quote-verified by the instrument exactly like agent extraction.
Platform-specific half of `../extraction.md` (the generic law — quote
everything, one file per record, honesty rules — lives there and
binds here too).
## An Ash resource file
```json
{
"file": "lib/teamology/rosters/resources/guardian.ex",
"module": "Teamology.Rosters.Guardian",
"store": "guardians",
"store_quote": "table \"guardians\"",
"columns": [
{"name": "first_name", "quote": "attribute :first_name, :string"},
{"name": "email", "quote": "attribute :email, :string"}
],
"belongs_to": [
{"name": "student", "quote": "belongs_to :student, Teamology.Rosters.Student"}
],
"policies": {
"present": false,
"quote": "use Ash.Resource,",
"default_deny": null,
"admit_kinds": [],
"bypass": false
},
"actions": {
"defaults": ["read", "create", "update"],
"defaults_quote": "defaults [:read, :create, :update]",
"destroy": false,
"archive": false,
"redaction": [
{"name": "redact_message_content", "sets": ["utterance"],
"quote": "change set_attribute(:utterance, \"[redacted]\")"}
]
},
"domain_registered": false
}
```
- `store` — the `postgres do table "…"` name (or the AshPostgres
default). Non-resource `.ex` files (contexts, LiveViews, workers)
get a record with no `store` key and whatever facts apply — usually
none; `{"file": …}` alone is a valid "nothing witnessed here"
record.
- `columns` — every `attribute`/`uuid_primary_key`/timestamp column,
each quoting its declaring line. Do not classify; the instrument
derives person-signals from the platform profile's regex.
- `policies.present` — a `policies do` block exists; `default_deny`
(terminal `forbid_if always()` or equivalent), `admit_kinds`
(short strings naming what each `authorize_if` admits, each from a
quoted line), `bypass` (any `bypass` block). When absent, quote the
`use Ash.Resource` line — proof you read the file.
- `actions.redaction` — actions matching
`redact|scrub|purge|expunge|anonymi`, with the columns they set.
`destroy`/`archive` — a destroy action / an `archived_at`-style
column or archive action.
- `domain_registered` — listed in the domain module's `resources do`
block? (Read the domain file — the `.ex` directly above
`resources/`; null if you did not.)
## The router
```json
{"file": "lib/teamology_web/router.ex", "router": {"pipelines": [
{"name": "browser", "plugs": ["fetch_session", "load_from_session"],
"quote": "pipeline :browser do"}
]}}
```
## Runtime config (secrets census)
```json
{"file": "config/runtime.exs", "secrets": [
{"name": "SECRET_KEY_BASE", "quote": "System.get_env(\"SECRET_KEY_BASE\")"}
]}
```
Every `System.get_env`/`System.fetch_env!`/Hush secret read.