ORBAT — author blue/red/green assets (spec 004) + asset enrichment (spec 005)#11
Merged
Conversation
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
Contributor
|
There was a problem hiding this comment.
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 neworbatmodule (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 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 on lines
+79
to
+83
| attributes: | ||
| availability: | ||
| range: string | ||
| description: '"available | down" (own State mirror, DEC-52)' | ||
| capabilities: |
| 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. |
…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
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.Allegianceenum +Entity.allegiance+ newschema/orbat.yaml(Orbat/Asset/Blue|Red|GreenParams/Protection).app/js/orbat/orbat.js— pure deterministic add/duplicate/tune/remove/reconcile/validate/canonical/commit +assetToEntity; localStorage draft + content-addressed commit with lineage.app/js/shell/orbat-panel.js— the SME-Int role-tab (roster, tuners, duplicate/remove, commit, selection).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.
PlatformKindenum +Asset.kind/symbol→ allegiance-framed map symbols (deck.glTextLayerglyphs, no icon atlas) with per-asset override;Asset.confidence(reusingConfidenceLevel) → marker opacity.RedParams.detection_range_m/engagement_range_m(faint outer detection, bold inner engagement),engagement ≤ detectionenforced; green/blue keep the single extent.strength/notes; redthreat_type, greencategory(GreenCategoryenum), bluerole; shown in the roster + marker tooltip.normalize()migrates spec-004 red drafts (extent_m→ detection range).Verification
test/orbat.test.mjs) + 9 e2e tests (e2e/orbat.spec.ts, one+ per user story across both specs) — all green.evidence/.Project memory & blogs
ADR-0026 + ADR-0027,
key_facts/issuesentries, 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