Skip to content

rm-core 0.1.2: airm-placement document normative (PROTOCOL §5.4) - #3

Merged
gspark-etri merged 1 commit into
mainfrom
placement-document
Oct 19, 2026
Merged

gspark-etri merged 1 commit into
mainfrom
placement-document

Conversation

@gspark-etri

Copy link
Copy Markdown
Contributor

HUB-12 / roadmap W6: the airm-placement ConfigMap format becomes part of the protocol.

Derived from the three existing users

Role Format
ai-rm rm-controller/document.py writer {protocol, generation, updatedAt, placement, decisions[{pool, workload{kind,model,slo,labels}, acceleratorIds, kvTransport, reason}]}; generation bumps only on change; label airm.ai-computing.io/accelerator: <vendor>.<model> per role
hetero-llm-d deploy/airm/ documents it, ships the empty default same fields; empty doc {"protocol":"0.1","generation":0,"updatedAt":null,"decisions":[]}
lmd-top src/airm.rs reader reads decisions.json, keys decisions by pool/kind, tolerant of missing fields

§5.4 states what they all agree on. No field changed, protocol stays 0.1, so this is a patch release (0.1.2) like 0.1.1, and components pinned rm-core>=0.1,<0.2 pick it up.

How the requested items map onto the existing format (no new fields were needed):

  • roles prefill/decode/any → workload.kind: one prefill + one decode decision per PD pool; an aggregated (any-role) pool uses serve (any is not a WORKLOAD_KINDS value and is rejected).
  • card refs by node + accelerator id → acceleratorIds = <node>/<vendor>:<index> (= AcceleratorProfile.spec.id); node is the part before / (Decision.nodes).
  • vendor.model label → optional workload.labels["airm.ai-computing.io/accelerator"], as in the node labels; cards must match its vendor.
  • generation → MUST go up on any change of placement/decisions, never down; an unchanged rewrite keeps it. Readers apply only a greater generation (is_newer).
  • timestamps → updatedAt RFC 3339 UTC, null only at generation 0. policy name → placement, required once generation > 0.
  • compatibility → unknown fields ignored at every level; newer minor of the same major accepted; at most one decision per (pool, kind).

Changes

  • PROTOCOL.md §5.4 (MUST/SHOULD), §5.2/§8 pointers, change log 0.1.2
  • src/rm_core/placement.py: PlacementDocument/Decision (to/from dict), stdlib validate(doc) -> list[str], parse, build, configmap, is_newer
  • k8s/airm-placement.schema.json (draft 2020-12) for the structure; cross-field rules are documented as validator-only
  • python -m rm_core.conformance: airm.placements check also builds the document from the policy's decisions (incl. the empty-pool decision) and validates + round-trips it
  • tests/test_placement.py (14 tests): the real documents from all three users, 23 violation cases, unknown-field tolerance, generation rule, ConfigMap parse, schema enums == code enums, schema agreement via jsonschema when installed
  • version 0.1.2 in pyproject.toml/__version__, README EN/KO layout + roadmap. Not tagged/released; install pins and badge stay at v0.1.1 until the tag.

Verified

  • python -m unittest discover -s tests → 27 tests OK (Python 3.11, clean venv with pip install -e . + jsonschema)
  • python -m rm_core.conformance → PASS sim, loopback, greedy; with ai-rm's rm-controller installed also PASS airm.placements:topology
  • ai-rm rm-controller tests (12) pass against this rm-core
  • rm-controller's real output for examples/spec.yaml and examples/hetero-p2p.yaml (placed and unplaceable) validates, and PlacementDocument.from_dict(doc).to_dict() == doc, so switching writers does not bump generation on the live ConfigMap
  • tools/check_sensitive.py . clean

Follow-ups after release (not in this PR)

  • rm-controller should switch to rm_core.placement (replace rm_controller/document.py with Decision.from_placement, build, parse, configmap) and pin rm-core>=0.1.2,<0.2.
  • hetero-llm-d deploy/airm/README.md: says generation is "incremented on every write"; should read "on every change" and link §5.4 instead of restating the format.
  • lmd-top may drop its legacy one-key-per-workload layout once nothing writes it (§5.4: writers MUST use decisions.json only).

🤖 Generated with Claude Code

The airm-placement ConfigMap was defined by usage: rm-controller writes it, hetero-llm-d documents
and ships its empty default, lmd-top reads it. 5.4 states the format they already agree on (no field
changes, protocol stays 0.1): location, fields, roles via workload.kind, card refs by accelerator id,
the vendor.model label, the generation rule and forward compatibility.

- rm_core.placement: PlacementDocument/Decision model, stdlib validate(doc) -> list[str], parse,
  build (generation bumps only on change), configmap, is_newer (reader rule)
- k8s/airm-placement.schema.json, tested against the code's enumerations and examples
- airm.placements conformance also validates the document made from a policy's decisions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gspark-etri
gspark-etri merged commit c208c53 into main Oct 19, 2026
8 checks passed
@gspark-etri
gspark-etri deleted the placement-document branch October 19, 2026 09:31
gspark-etri added a commit that referenced this pull request Oct 20, 2026
rm-core 0.1.2: airm-placement document normative (PROTOCOL §5.4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant