Story: Investigate hand-added cross-service grants in generated iam_service_db_grants_create.sql
Table of Contents
This page documents a story in Sprint 25. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
Goal
Understand why projects/ores.sql/create/iam/iam_service_db_grants_create.sql
carries hand-added cross-service grants that the ores.codegen generator
does not emit, and close the drift so that a regeneration from the
service registry model is lossless — no load-bearing grant is ever
silently dropped by a codegen run, and the committed file matches
generator output exactly.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 25 |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-08-05 |
Acceptance
- Root cause documented: why the four hand-added grants exist (Acme provisioner logo access, party image soft-FK validation, cross-entity party membership), why the generator does not emit them, and whether they are correctly placed in the file.
- A decision on the fix: extend the registry model/template with per-service cross-domain grant lists (generation becomes lossless), or an alternative that guarantees regeneration never silently drops grants (e.g. a generator guard that fails on unexpected manual content).
- The committed file matches what the generator produces (regeneration is a no-op diff), or the drift is closed by an explicit mechanism with a test proving it.
Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Investigate and close the iam_service_db_grants_create.sql generator drift | DONE | 2026-08-05 | 2026-08-07 | iam_service_db_grants_create.sql (generated via ores.codegen ores.sql.service address from the service registry model) carries four hand-added cross-service grants the generator does not emit: iam_service select on ores_assets_ + execute on ores_assets_get_template_image_fn (Acme provisioner logo copy) + select on ores_dq_ (cross-entity party membership); refdata_service select on ores_assets_ (party image soft-FK). A regeneration silently drops them. Investigate the root cause (model/template cannot express cross-domain grants), decide the fix (per-service cross-domain grant lists in the model, or a generator guard), implement it, and prove regeneration is now lossless (regenerate = no-op diff). |
Decisions
- Cross-service grant drift was a model gap, not a template gap:
adding the missing prefixes to
service_registry.orgwas sufficient — the template already hasdml_prefixes,select_prefixes, andexecute_prefixessections that render to the right helper calls. No template change was needed. - Rationale comments for cross-service grants live in the model next to the prefix, not in the generated SQL — the generator cannot emit comments, and the model is the single source of truth.
- The nats config path mismatch (
nats-festive-dijkstra.confvs.nats-festive_dijkstra.conf) was a convention drift betweensystemd_generate.py(using rawORES_ENV_NAMEwith hyphens) andenv_init.py(usinglabel_lowerwith underscores, matchingcompass nats init'sORES_CHECKOUT_LABELconvention). Fixed in the systemd generator by mirroringenv_init'slabel_lowerconversion rather than changing the file-naming convention. - The OS sandbox was ruled out as a cause: after fixing the path mismatch, all 23 units started successfully with both global and project sandboxes active.
Out of scope
- Removing or re-justifying the controller-era grants themselves — that is the decommission task's scope (26ABA6BB).
- Any runtime grant changes beyond making generation lossless.