Skip to content

ORBAT — author blue/red/green assets (spec 004) + asset enrichment (spec 005)#11

Merged
IanMayo merged 10 commits into
mainfrom
claude/spec-04-implement-0u0s9y
Jun 14, 2026
Merged

ORBAT — author blue/red/green assets (spec 004) + asset enrichment (spec 005)#11
IanMayo merged 10 commits into
mainfrom
claude/spec-04-implement-0u0s9y

Conversation

@IanMayo

@IanMayo IanMayo commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Two closely-related specs delivering the ORBAT authoring surface and its enrichment, on one branch. All tasks for both specs are complete; everything is display-only (NF9 honest floor) and schema-defined + regenerated (Principle I).

Spec 004 — author & tune blue/red/green assets (specs/004-orbat-red-green-assets/)

The ORBAT authoring scaffolding: add/duplicate/tune/remove/commit allegiance-typed assets, each a first-class Entity (DEC-52) reusing the entity → map / Sync-Matrix projection.

  • Schema: Allegiance enum + Entity.allegiance + new schema/orbat.yaml (Orbat/Asset/Blue|Red|GreenParams/Protection).
  • Model app/js/orbat/orbat.js — pure deterministic add/duplicate/tune/remove/reconcile/validate/canonical/commit + assetToEntity; localStorage draft + content-addressed commit with lineage.
  • UI app/js/shell/orbat-panel.js — the SME-Int role-tab (roster, tuners, duplicate/remove, commit, selection).
  • Blue stays display-only: ROVER-1 reconciled as the single protected canonical_own_force; tuning never changes the route (e2e-asserted).

Spec 005 — asset enrichment (specs/005-orbat-asset-enrichment/)

Makes the map read like a recognised operational picture — additive to spec 004.

  • Slice A — kind + icons + confidence: PlatformKind enum + Asset.kind/symbol → allegiance-framed map symbols (deck.gl TextLayer glyphs, no icon atlas) with per-asset override; Asset.confidence (reusing ConfidenceLevel) → marker opacity.
  • Slice B — red dual range rings: RedParams.detection_range_m/engagement_range_m (faint outer detection, bold inner engagement), engagement ≤ detection enforced; green/blue keep the single extent.
  • Slice C — descriptive detail: shared strength/notes; red threat_type, green category (GreenCategory enum), blue role; shown in the roster + marker tooltip.
  • Backward compatible: idempotent normalize() migrates spec-004 red drafts (extent_m → detection range).

Verification

  • 30 unit tests (test/orbat.test.mjs) + 9 e2e tests (e2e/orbat.spec.ts, one+ per user story across both specs) — all green.
  • 0 typecheck errors; existing suites unaffected. Evidence screenshots under each spec's evidence/.

Project memory & blogs

ADR-0026 + ADR-0027, key_facts/issues entries, and a blog post per spec (specs/00{4,5}-*/blog/).

Deferred (NF9, called out in the specs)

Reactive adversary behaviour (DEC-51), capability-matched blue allocation (H2), live ROE/collateral emission (DEC-60 J3); and — for enrichment — a richer place-on-map interaction and true NATO affiliation frame shapes (a later slice).

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq

Bring all three ORBAT sides forward as display-only authoring scaffolding
(DEC-60, NF9 honest floor). Each asset is a first-class allegiance-typed
Entity (DEC-52) reusing the existing entity → map / Sync-Matrix projection.

- Schema (Principle I, regenerated): Allegiance enum + Entity.allegiance +
  new schema/orbat.yaml (Orbat/Asset/Blue|Red|GreenParams/Protection),
  reusing Waypoint/Lineage/TimeWindow.
- Model: app/js/orbat/orbat.js — pure, deterministic add/duplicate/tune/
  remove/reconcile/validate/canonical/commit + assetToEntity; localStorage
  draft + content-addressed commit with lineage.
- UI: app/js/shell/orbat-panel.js — the SME-Int role-tab authoring surface
  (roster, per-instance tuners, duplicate/remove, commit, selection).
- Projection: allegiance-coloured map markers + Sync-Matrix tracks for
  time-windowed assets.
- Blue stays display-only: ROVER-1 reconciled as the single protected
  canonical own-force; no asset tune changes the route/plan (e2e-asserted).

Tests: 11 new unit + 5 new e2e (one per user story); 0 typecheck errors.
Project memory: ADR-0026, key_facts, issues; blog post + evidence.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-14 09:48 UTC

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements spec 004 ORBAT authoring scaffolding across schema/model/UI/projection so blue/red/green assets can be authored (display-only), persisted to localStorage, committed as content-addressed objects with lineage, and projected onto map + Sync Matrix via the existing Entity pipeline.

Changes:

  • Extends the LinkML schema with Allegiance, Entity.allegiance, and a new orbat module (Orbat/Asset/params/enums) and regenerates derived artifacts.
  • Adds a pure ORBAT model (add/tune/duplicate/remove/reconcile/validate/canonical/commit) plus a new SME-Int ORBAT authoring panel wired into main projection.
  • Adds unit + e2e coverage for ORBAT workflows and updates project notes/spec docs.

Reviewed changes

Copilot reviewed 22 out of 33 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/orbat.test.mjs Unit tests covering ORBAT operations (add/tune/isolation/determinism/reconcile/duplicate/remove/commit/validate).
specs/004-orbat-red-green-assets/tasks.md Marks spec 004 task checklist complete.
specs/004-orbat-red-green-assets/blog/post.md Spec blog post documenting ORBAT feature and screenshots.
site/data-model/index.html Regenerated HTML data-model reference including ORBAT module + enums.
schema/remit.yaml Imports the new orbat LinkML module.
schema/orbat.yaml New ORBAT LinkML module defining Orbat, Asset, params classes, and Protection.
schema/gen/remit.ts Regenerated TypeScript types including ORBAT shapes and Allegiance/Protection.
schema/gen/remit.schema.json Regenerated JSON Schema including ORBAT shapes and new enums.
schema/entities.yaml Adds optional allegiance attribute to Entity.
schema/common.yaml Adds Allegiance enum to common vocabulary.
e2e/orbat.spec.ts Playwright e2e tests for ORBAT user stories (red/green/blue invariants/persistence/Sync Matrix track).
docs/project_notes/key_facts.md Records ORBAT key facts (palette, bounds, persistence key, invariants).
docs/project_notes/issues.md Adds a work-log entry for the ORBAT implementation.
docs/project_notes/decisions.md Adds ADR-0026 documenting ORBAT display-only approach + schema/model decisions.
app/styles.css Adds styling for the ORBAT authoring panel.
app/js/views/sync-matrix.js Adds support for colored “band” tracks and an optional per-row color.
app/js/views/map.js Adds rendering + e2e-visible dataset attributes for ORBAT assets on the map.
app/js/shell/roles.js Activates SME-Int role tab and mounts ORBAT panel.
app/js/shell/orbat-panel.js New ORBAT authoring panel UI (grouped by allegiance, tuners, duplicate/remove/commit, selection).
app/js/orbat/orbat.js New ORBAT model + persistence/live draft store + Asset→Entity adapter.
app/js/main.js Wires live ORBAT draft into map + Sync Matrix projection and selection highlighting.
app/js/entities/entities.js Folds ORBAT assets into projected Entities and extends Sync Matrix catalogue with asset window tracks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/js/orbat/orbat.js
Comment on lines +156 to +161
if (patch.blue && next.allegiance === 'blue') {
next.blue = { ...next.blue };
if (patch.blue.availability !== undefined) next.blue.availability = String(patch.blue.availability);
if (patch.blue.capabilities !== undefined)
next.blue.capabilities = (patch.blue.capabilities ?? []).map(String).filter(Boolean);
}
Comment thread schema/orbat.yaml
Comment on lines +79 to +83
attributes:
availability:
range: string
description: '"available | down" (own State mirror, DEC-52)'
capabilities:
Comment thread app/js/shell/orbat-panel.js
Comment thread test/orbat.test.mjs
test('canonical is stable and order-independent (NF3 determinism)', () => {
let a = addAsset(emptyOrbat('s'), { allegiance: 'red', position: pos(1) });
a = addAsset(a.orbat, { allegiance: 'green', position: pos(2) });
// Same content, assets inserted in the opposite order ⇒ identical canonical bytes.
claude added 7 commits June 13, 2026 14:53
…e render

- Schema-define BlueParams.availability_window (TimeWindow) so the blue
  availability-window the panel authors is part of the LinkML source of
  truth, not schema drift (Principle I); regenerated schema/gen + HTML ref.
- tuneAsset now persists blue availability_window (normalised start ≤ end,
  cleared when unset); previously dropped, so blue window tracks never
  projected. Renamed the field window → availability_window end-to-end
  (panel, assetToEntity). New unit test locks in persistence + hasTrack.
- orbat-panel: remove the double render — apply() relied on both setDraft's
  subscription and an explicit render(); the subscription is now the single
  render path.
- test: clarify the determinism comment (canonical sorts by id; the test
  reverses the array, not the insertion order).

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
…l-range rings

Display-only, additive follow-up to spec 004 (NF9 honest floor): a shared
platform-"kind" vocabulary driving allegiance-framed map symbols with a
per-asset override, an intel confidence attribute (reusing ConfidenceLevel),
and red dual range rings (detection vs engagement). Two independently-shippable
slices (A: kind+icons+confidence P1; B: red dual-range P2). New fields are
schema-defined + regenerated (Principle I); routing/kernel untouched.

Spec + quality checklist; all checklist items pass on first iteration.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
/speckit.plan output for spec 005: plan.md, research.md (D1–D6), data-model.md
(PlatformKind enum + Asset.kind/symbol/confidence + RedParams detection/
engagement ranges), contracts/orbat-enrichment.md, quickstart.md. Constitution
check passes (additive, display-only, schema-defined; no violations). Blog post
sketched in plan Phase 2. Agent-context marker repointed to spec 005.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
/speckit.tasks output for spec 005: 23 tasks across Setup (schema), Foundational
(normalize/migration + tune/validate + symbol lookup), US1 (kind+symbols, MVP),
US2 (confidence), US3 (red dual-range), Polish. Tests included per story; all
display-only (NF9) and backward-compatible with spec-004 drafts.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
Fold the cheap, high-value descriptive enrichments into spec 005: shared
strength + notes, and a per-allegiance descriptor (red threat_type, green
category via a new GreenCategory enum, blue role). Updated spec (US4, FR-012–015,
SC-006), plan, data-model, contract, quickstart, and tasks (new Phase 6 US4,
Polish → Phase 7; 23 → 27 tasks). All additive, schema-defined, display-only
(NF9). Place-on-map and NATO frame shapes remain out of scope for a later slice.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
…escriptors (spec 005)

Display-only, additive enrichment of the SME-Int ORBAT (NF9 honest floor) — every
new field schema-defined + regenerated (Principle I), nothing touches routing.

- Schema: PlatformKind + GreenCategory enums; Asset.kind/symbol/confidence/
  strength/notes; RedParams.detection_range_m/engagement_range_m/threat_type;
  GreenParams.category; BlueParams.role. Regenerated schema/gen + HTML ref.
- Model (orbat.js): tuneAsset handles all new fields (vocab fields ignore invalid,
  free-text trims + drops-empty); red dual-range clamp with engagement ≤ detection;
  symbolOf/confidenceOpacity (UI carve-out); idempotent normalize() migrates
  spec-004 red drafts (extent_m → detection) wired into loadDraft (FR-010).
- Panel (orbat-panel.js): per-row kind selector, icon picker + clear, confidence,
  strength, notes; red detection/engagement + threat-type; green category; blue role.
- Map (map.js): kind+allegiance symbol glyph (TextLayer, no atlas) over the marker;
  confidence → opacity; red faint detection + bold engagement rings (single extent
  for green/blue); asset hover tooltip; data-assets carries kind/confidence.

Tests: +12 unit (30 total), +4 e2e (9 total) green; 0 typecheck errors.
Memory: ADR-0027, key_facts, issues. Blog post + evidence screenshots.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
@IanMayo IanMayo changed the title ORBAT — author & tune blue/red/green assets (spec 004) ORBAT — author blue/red/green assets (spec 004) + asset enrichment (spec 005) Jun 14, 2026
claude added 2 commits June 14, 2026 09:22
Replace the free-text icon-override input (+ clear button) with a dropdown of
glyph choices (ICON_CHOICES; the "—" option reverts to the kind default), and
the comma-separated capabilities input with a multi-select listbox
(CAPABILITY_CHOICES, unioned with any existing/legacy tags so they round-trip).
Both choice lists are UI carve-outs (ADR-0012); the model keeps symbol free-text
and capabilities open string[] (NF7). e2e updated to selectOption. 30 unit + 9
e2e green; 0 typecheck errors.

https://claude.ai/code/session_012HvMXqX2tV7df5bzRcs2Nq
@IanMayo IanMayo merged commit 536e228 into main Jun 14, 2026
3 checks passed
@IanMayo IanMayo deleted the claude/spec-04-implement-0u0s9y branch June 14, 2026 09:48
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.

3 participants