ref:main

Standards structured payloads, dictionary and attachments are unreachable from the CLI (anvil#405 / #258) #49

open Opened by cole.christensen@gmail.com

Links

No links yet.

Problem

fangorn/anvil#405 landed server-side in anvil PR #258: standards now carry a typed, validated structured payload, backed by an ISO 13584 / IEC 61360 property dictionary and class registry, plus an attachment substrate for the source documents (#398).

None of it is reachable from the CLI. That PR touched zero files in this repo. Every operation is raw HTTP today, one request per property and per class, with no bulk path — so seeding a class hierarchy and its properties is dozens of hand-built requests.

That is a poor fit for the data in question, whose entire value depends on careful transcription from a source document. The tool used to enter it should not itself be an error source.

What the server exposes

All under /api/v1, org-scoped. Existing auth and --json conventions apply.

Attachments (the source document)

POST /:org/standards/:id/attachments AttachmentController :create_for_standard
GET /attachments/:id AttachmentController :show

The content hash is computed server-side and must never be sent by the client.

Standard payload

PUT /:org/standards/:id/payload StandardController :put_payload
GET /:org/standards/:id StandardController :show (payload included)
GET /:org/standards/strict StandardController :strict (coverage gate)

put_payload returns every validation problem, not first-fail. The CLI must render the whole list — a payload with four transcription errors should cost one round trip, not four.

Dictionary

GET /:org/dictionary/properties :list_properties
POST /:org/dictionary/properties :create_property
GET /:org/dictionary/classes :list_classes
POST /:org/dictionary/classes :create_class
GET /:org/dictionary/classes/:code :show_class
POST /:org/dictionary/classes/:code/properties :put_class_property
POST /:org/dictionary/classes/:code/case-of :put_case_of
POST /:org/dictionary/classes/:code/constraints :put_constraint
POST /:org/dictionary/classes/:code/constants :put_constant

Wanted

  1. anvil standard attach / download — upload a source document to a standard, fetch one back. Never compute or send a hash from the client.

  2. anvil standard payload get / put — read and set the typed payload. put takes a file or stdin. On rejection, print every problem, one per line, in a form a human can act on.

  3. anvil dictionary property list|create and anvil dictionary class list|show|create, plus put-property, put-case-of, put-constraint, put-constant on a class.

  4. Bulk import for the dictionary. anvil requirement import already does YAML/JSON bulk with an export that round-trips; mirror that shape, so a whole class hierarchy plus its properties is one file and one command. Round-tripping matters: an org will want its dictionary in version control.

  5. --json on every read, per the existing convention.

Hard constraint: no codegen. Ever.

The CLI must never gain a command that generates source code, types, structs or schemas from a payload or the dictionary.

The payload’s entire value is that it is an independent reading of a source document, written separately from the implementation it exists to verify. A consumer’s CI compares its own implementation against the payload and fails on divergence. If the implementation is generated from the payload, that comparison compares a copy with itself — it will pass while faithfully reproducing every transcription error, with a green test beside it.

This is not a style preference. It is the property the whole feature exists to provide, and it is destroyed silently rather than loudly: everything looks fine, forever.

anvil ships test/anvil/requirements/standards/no_codegen_guard_test.exs, which scans the server modules and API surface for any payload-to-source affordance. This repo wants the equivalent guard, so a future contributor adding anvil dictionary generate-types as a helpful convenience is stopped by a test rather than by luck.

Notes

  • strict is a coverage gate that returns 422 with the offending (standard, repo) pairs. Worth a CLI surface, but secondary to the above.
  • Follow this repo’s existing command structure, error shapes ({"ok":false,"error":…}), and test conventions rather than inventing new ones.