Story: Attach pictures at runtime through one seam

Table of Contents

This page documents a story in Sprint 27. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

1. Goal

Pictures are attached at runtime through one seam: an assets operation ensures a template image exists in a tenant, and an IAM operation reconciles accounts' pictures from a scope. Staff photos, party logos, counterparty logos and the service accounts' pictures all use it, and both ores.shell and ores.web can run it.

2. Status

Field Value
State DONE
Parent sprint Sprint 27
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-06

3. Acceptance

  • assets.v1.images.ensure copies a system-tenant template image into a tenant and returns its id, idempotently, with no workflow context.
  • iam.v1.accounts.attach-pictures reconciles the accounts a scope names: each account that wants a picture and has no image_id gets one.
  • The three places that copy templates today use the assets operation; no copy logic is duplicated.
  • The wanted picture code rides the account API, so the handler stops reading ores_dq_accounts_artefact_tbl.
  • The service accounts' pictures attach from the service registry at installation bring-up and on demand, and iam_service_account_pictures_populate.sql plus its validation_ignore.txt entry are gone.
  • Both clients reach the same subjects; no behaviour is client-specific.

4. Tasks

Task State Start End Description
Scaffold story: Attach pictures at runtime through one seam DONE 2026-10-06 2026-10-06 Story scaffolding rides this task: documents, sprint wiring, and the scaffold PR. Close it before merging that PR.
Add the ensure-image operation DONE 2026-10-06 2026-10-06 One assets operation copies a system-tenant template image into a tenant and returns its id, idempotently; the three existing copiers use it.
Reconcile account pictures DONE 2026-10-06 2026-10-06 One IAM operation reconciles each account's picture from a scope; attach_photos delegates to it.
Model the picture code on the account DONE 2026-10-06 2026-10-06 The wanted picture code rides the account API, so the handler stops reading the DQ artefact table.
Attach the service account pictures DONE 2026-10-06 2026-10-06 Reconcile the service accounts from the service registry at installation bring-up, expose it to both clients, and delete the build-time script.

5. Decisions

  • One seam per concern. Copying a template into a tenant is the assets service's job, exposed as assets.v1.images.ensure. Deciding which account gets which picture is IAM's job, exposed as iam.v1.accounts.attach-pictures. Neither knows about the other's tables.
  • Runtime and server-side, so both clients are equal. The operations are ordinary NATS subjects, so ores.shell and ores.web reach them through the same generated protocol. No behaviour lives in a client.
  • Reconcile, do not orchestrate. Each operation is idempotent and safe to re-run; the caller supplies a scope, not a step-by-step plan. This is what lets the installation bring-up and an operator's re-run use the same call.
  • The provisioning step keeps its place. attach_photos stays the place a tenant's staff photos are attached; it becomes a caller of the two operations rather than an owner of the copy logic.

6. Out of scope

  • Re-picturing an account when its template image changes. The reconcile fills a missing picture and leaves an existing one alone. Whether a changed icon should overwrite every account that carries the old one is a product decision, and it changes the idempotence rule.
  • The dead attach_staff_photos_best_effort wrapper. It has no callers and retires with the legacy synchronous handler, not here.

7. Result

One seam per concern, both at runtime, both reachable from either client.

assets.v1.images.ensure copies a system-tenant template image into a tenant and returns its id, idempotently, with no workflow context. The three places that copied templates now call it; no copy logic is duplicated.

iam.v1.accounts.attach-pictures reconciles the accounts a scope names, and the wanted picture code rides the account API, so the handler no longer reads ores_dq_accounts_artefact_tbl. attach_photos stays the place a tenant's pictures are attached and became a caller of those operations rather than an owner of the copy logic.

The service accounts name their pictures from the service registry: the upsert function gained p_picture_code and the accounts archetype passes the derived image code. attach_photos reconciles the system tenant's accounts where it attaches the administrators' pictures. A recreate writes 20 picture codes, the same 20 the deleted script covered, and every one of those codes has a matching system avatar. iam_service_account_pictures_populate.sql, its archetype, its tangled mustache, its facet row and its validation_ignore.txt entry are gone.

The suite passes 94 of 94 after a full recreate.

8. Not verified

The pictures could not be watched appear end to end. The ACME provisioning run aborts before attach_photos at fpml.supervisory_body: the publish asks for coding scheme FPML_SUPERVISORY_BODY, which does not exist for the target tenant, because fpml.coding_schemes is deliberately not a bundle member. That failure belongs outside this story, whose files do not touch it. Until it is fixed, the reconcile is proven by the seed, the avatar join and the suite, not by a live bring-up.

Emacs 29.3 (Org mode 9.6.15)