Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 67 additions & 17 deletions crates/ogar-class-view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,74 @@ use lance_graph_contract::{
ontology::{DisplayTemplate, FieldRef, ObjectView},
};
use ogar_vocab::{
Class,
accounting_account,
// 0x0CXX — automation (HIRO MARS CMDB + DO-arm actuators)
action_applicability, Class,
accounting_account, action_handler, anatomical_structure, auth_ory_keto, auth_store,
auth_zanzibar, auth_zitadel, automation_trigger, billable_work_entry, billing_party, bone,
canonical_concept_id, commercial_document, commercial_line_item, currency_policy, diagnosis,
hr_department, hr_employee, hr_employment_contract, hr_job, joint, knowledge_item, lab_value,
mars_application, mars_machine, mars_node_template, mars_resource, mars_software, medication,
osint_person, osint_system, patient, payment_record, pricelist, pricelist_rule, priority,
product, project, project_actor,
project_attachment, project_changeset, project_comment, project_custom_field,
project_custom_value, project_enabled_module, project_forum, project_journal,
project_member_role, project_membership, project_message, project_news, project_query,
project_relation, project_repository, project_role, project_status, project_type,
project_version, project_watcher, project_wiki_page, project_work_item, skeleton, tax_policy,
treatment, unit_of_measure, visit, vital_sign,
action_applicability,
action_handler,
anatomical_structure,
auth_ory_keto,
auth_store,
auth_zanzibar,
auth_zitadel,
automation_trigger,
billable_work_entry,
billing_party,
bone,
canonical_concept_id,
commercial_document,
commercial_line_item,
currency_policy,
diagnosis,
hr_department,
hr_employee,
hr_employment_contract,
hr_job,
joint,
knowledge_item,
lab_value,
mars_application,
mars_machine,
mars_node_template,
mars_resource,
mars_software,
medication,
patient,
payment_record,
pricelist,
pricelist_rule,
priority,
product,
project,
project_actor,
project_attachment,
project_changeset,
project_comment,
project_custom_field,
project_custom_value,
project_enabled_module,
project_forum,
project_journal,
project_member_role,
project_membership,
project_message,
project_news,
project_query,
project_relation,
project_repository,
project_role,
project_status,
project_type,
project_version,
project_watcher,
project_wiki_page,
project_work_item,
skeleton,
tax_policy,
treatment,
unit_of_measure,
visit,
vital_sign,
};

/// All promoted canonical concepts: `(canonical_concept_name, Class)`.
Expand Down Expand Up @@ -128,9 +181,6 @@ fn all_canonical_classes() -> Vec<(&'static str, Class)> {
("pricelist", pricelist()),
("pricelist_rule", pricelist_rule()),
("unit_of_measure", unit_of_measure()),
// ── 0x07XX — OSINT (AIRO/AIwar dual-use intelligence) ──
("osint_system", osint_system()),
("osint_person", osint_person()),
// ── 0x09XX — health (OGIT Healthcare) ──
("patient", patient()),
("diagnosis", diagnosis()),
Expand Down
152 changes: 16 additions & 136 deletions crates/ogar-vocab/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,16 +1122,15 @@ const CODEBOOK: &[(&str, u16)] = &[
("pricelist", 0x0209),
("pricelist_rule", 0x020A),
("unit_of_measure", 0x020B),
// ── 0x07XX — OSINT domain (AIRO/AIwar dual-use intelligence) ──
// Minted from the q2 cockpit V3 SoA bake (`data/osint-v3/`, harvested from
// `AdaWorldAPI/aiwar-neo4j-harvest`). The low u16 is the FROZEN canonical
// concept (07xx is operator-ratified canonical; the slot is the owner's);
// the render-skin APP_PREFIX (`0x1000`, the V3 format signal) is the
// consumer's half (`classid = (APP_PREFIX << 16) | concept`). Two concepts:
// the AI-system card (GUID1, 12 AIRO dims) and the person card (GUID2, 5
// McClelland/Rubicon dims — the Epstein-archetype implicit-motive lens).
("osint_system", 0x0700),
("osint_person", 0x0701),
// ── 0x07XX — OSINT domain: ZERO vocabulary rows BY DESIGN (operator
// ruling 2026-07-02, corrects PR #145's two hallucinated concept mints
// `osint_system@0x0700` / `osint_person@0x0701`). Within the OSINT domain
// the low byte is NOT a concept slot — it is allocated domain-wise as an
// APPID: `0x0700` = the OSINT domain itself (low byte 00 = domain-wide),
// `0x0701` = OSINT-for-q2 (q2 is appid 0x01, the consumer); V3 form
// `0x1000_0701`. Class content (AIRO/VAIR system card, McClelland/Rubicon
// person lens) lives consumer-side in q2's `osint_classview.rs` — OGAR
// vocabulary carries no OSINT concept names. Do NOT re-mint rows here.
// ── 0x09XX — Health domain (clinical / patient / care) ──
// medcare-rs Healthcare-namespace promotion (Northstar T9). The 7
// entities the OGIT `NTO/Healthcare/entities/` TTL ships, projected
Expand Down Expand Up @@ -1652,14 +1651,9 @@ pub mod class_ids {
/// (`ogit.Automation:Trigger`).
pub const AUTOMATION_TRIGGER: u16 = 0x0C09;

// ── 0x07XX — OSINT domain (AIRO/AIwar dual-use intelligence) ──

/// `osint_system` (`0x0700`) — AI system profiled on the 12 AIRO/VAIR
/// dual-use dims (V3 SoA GUID1 `6×(8:8)` tier cascade).
pub const OSINT_SYSTEM: u16 = 0x0700;
/// `osint_person` (`0x0701`) — person profiled on McClelland motive +
/// Rubicon stage (V3 SoA GUID2; the Epstein-archetype implicit-motive lens).
pub const OSINT_PERSON: u16 = 0x0701;
// ── 0x07XX — OSINT domain: no concept constants (low byte = APPID,
// domain-wise; q2 = 0x01 → `0x0701` is OSINT-for-q2, not a concept —
// operator ruling 2026-07-02; see the CODEBOOK section note). ──

/// Every `(canonical_concept_name, id)` pair the constants vouch for.
/// Drift-guarded against [`super::CODEBOOK`] by tests in this module.
Expand Down Expand Up @@ -1704,8 +1698,6 @@ pub mod class_ids {
("pricelist_rule", PRICELIST_RULE),
("unit_of_measure", UNIT_OF_MEASURE),
// 0x07XX — OSINT (AIRO/AIwar dual-use intelligence)
("osint_system", OSINT_SYSTEM),
("osint_person", OSINT_PERSON),
// 0x09XX — health
("patient", PATIENT),
("diagnosis", DIAGNOSIS),
Expand Down Expand Up @@ -2465,18 +2457,6 @@ pub fn canonical_concept(name: &str) -> String {
) {
return "priority".to_string();
}
// OSINT domain (0x07XX) — the canonical class-name spellings must
// round-trip so ordinary PascalCase model-name inputs (`OsintSystem` /
// `OsintPerson`, the builders' `Class::new(...)` names) recover their
// codebook ids; without this arm they lexically land on `osintsystem` /
// `osintperson`, which are NOT in the codebook (`osint_system` /
// `osint_person` are). Codex P2 on PR #145, mirrors the PR #60 pattern.
if matches!(lower.as_str(), "osintsystem" | "osint_system") {
return "osint_system".to_string();
}
if matches!(lower.as_str(), "osintperson" | "osint_person") {
return "osint_person".to_string();
}
// ── Layer 2: lexical fallback ──
lexical_concept(name)
}
Expand Down Expand Up @@ -2611,8 +2591,6 @@ pub fn all_promoted_classes() -> Vec<Class> {
unit_of_measure(),
// 0x07XX — OSINT arm (AIRO/AIwar dual-use: system + person cards),
// in class_ids::ALL order.
osint_system(),
osint_person(),
// 0x09XX — health arm (7 OGIT Healthcare concepts), in
// class_ids::ALL order.
patient(),
Expand Down Expand Up @@ -3722,88 +3700,6 @@ pub fn treatment() -> Class {
c
}

// ─────────────────────────────────────────────────────────────────────
// 0x07XX — OSINT domain (AIRO/AIwar dual-use intelligence)
//
// Minted from the q2 cockpit V3 SoA bake (`data/osint-v3/`, harvested from
// `AdaWorldAPI/aiwar-neo4j-harvest`). Two concepts mirror the two GUIDs of a
// baked node: GUID1 (the AI system, 12 AIRO/VAIR dims) and GUID2 (the person,
// 5 McClelland/Rubicon dims). Field order IS the SoA tier order — the FieldMask
// bit basis. The low u16 is the frozen canonical concept; the render-skin
// APP_PREFIX (`0x1000`, a V3 format signal) is the consumer's half.
// ─────────────────────────────────────────────────────────────────────

/// OSINT **AI system** — the AIRO/AIwar dual-use system card (`osint_system`,
/// `0x0700`). The 12 dims the V3 SoA bake packs into GUID1's `6×(8:8)` tier
/// cascade: HEEL `current_status:type`, HIP `military_use:civic_use`,
/// TWIG `ml_task:ml_type`, LEAF `purpose:capacity`, family `output:impact`,
/// identity `stakeholder:airo_role`. Attribute declaration order IS the tier
/// order, so the lifted `ObjectView` FieldMask bit `i` == tier byte `i`. The
/// reasoning roles (Demand `offer⟷need`, Causality `intent⟷impact`) are a
/// consumer-side overlay on these names (see q2 `osint_classview.rs`).
#[must_use]
pub fn osint_system() -> Class {
let mut c = Class::new("OsintSystem");
c.language = Language::Unknown;
c.canonical_concept = Some("osint_system".to_string());
c.description =
Some("An AI system profiled on the AIRO/AIwar dual-use dimensions".to_string());
c.source_domain = Some("osint".to_string());
c.source_curator = Some("aiwar".to_string());
let mut attrs = Vec::with_capacity(12);
for name in [
"current_status", // HEEL.hi — state
"type", // HEEL.lo — identity
"military_use", // HIP.hi — dual-use need
"civic_use", // HIP.lo — dual-use need
"ml_task", // TWIG.hi — the task (need)
"ml_type", // TWIG.lo — the technique (offer)
"purpose", // LEAF.hi — intent (explicit)
"capacity", // LEAF.lo — offer
"output", // family.hi — offer
"impact", // family.lo — causality (implicit)
"stakeholder", // identity.hi — relation
"airo_role", // identity.lo — actor role (person)
] {
let mut a = Attribute::new(name);
a.type_name = Some("string".to_string());
attrs.push(a);
}
c.attributes = attrs;
c
}

/// OSINT **person** — the McClelland / Rubicon actor card (`osint_person`,
/// `0x0701`). The 5 dims the V3 SoA bake packs into GUID2: HEEL `stage:need`,
/// HIP `receptor:rubicon`, TWIG `motive`. This is the Epstein-archetype lens —
/// implicit motive (`nPow`/`nAch`/`nAff`) × Rubicon crossing × power receptor —
/// the Person side of the Person×Situation split (the system card carries the
/// Situation). Attribute order IS the GUID2 tier order (the FieldMask bit basis).
#[must_use]
pub fn osint_person() -> Class {
let mut c = Class::new("OsintPerson");
c.language = Language::Unknown;
c.canonical_concept = Some("osint_person".to_string());
c.description =
Some("A person profiled on McClelland motives and the Rubicon action stage".to_string());
c.source_domain = Some("osint".to_string());
c.source_curator = Some("aiwar".to_string());
let mut attrs = Vec::with_capacity(5);
for name in [
"stage", // HEEL.hi — Rubicon stage I..IV
"need", // HEEL.lo — McClelland nPow/nAch/nAff
"receptor", // HIP.hi — power receptor
"rubicon", // HIP.lo — Rubicon crossing
"motive", // TWIG.hi — dominant motive
] {
let mut a = Attribute::new(name);
a.type_name = Some("string".to_string());
attrs.push(a);
}
c.attributes = attrs;
c
}

/// Visit — a clinical encounter (OGIT `Visit`, `0x0906`). The temporal
/// container diagnoses / labs / treatments / vitals are recorded within.
#[must_use]
Expand Down Expand Up @@ -4258,24 +4154,6 @@ mod tests {
assert!(wire_synergies(&[a, b, c]).is_empty());
}

#[test]
fn canonical_concept_promotes_osint_classes_deterministically() {
// OSINT domain (0x07XX): the builders' PascalCase class names must
// round-trip to their codebook ids, like every other promoted class
// (codex P2 on PR #145). Without the resolver arm, `OsintSystem`
// lexically lands on `osintsystem`, which is NOT in the codebook.
assert_eq!(canonical_concept("OsintSystem"), "osint_system");
assert_eq!(canonical_concept("OsintPerson"), "osint_person");
assert_eq!(canonical_concept("osint_system"), "osint_system");
assert_eq!(canonical_concept("osint_person"), "osint_person");
// Full round-trip through the codebook resolver.
assert_eq!(ogar_codebook("OsintSystem"), Some(0x0700));
assert_eq!(ogar_codebook("OsintPerson"), Some(0x0701));
// The class builder's own `.name` resolves to its codebook id.
assert_eq!(ogar_codebook(&osint_system().name), Some(0x0700));
assert_eq!(ogar_codebook(&osint_person().name), Some(0x0701));
}

#[test]
fn canonical_concept_promotes_billable_work_entry_deterministically() {
// Promoted cross-domain invariant — OpenProject `TimeEntry` and
Expand Down Expand Up @@ -4967,8 +4845,10 @@ mod tests {
],
"Automation domain set drift — re-sync the consumer coverage gate",
);
// The OSINT domain carries the two AIRO/AIwar cards (system + person).
assert_eq!(concepts_in_domain(ConceptDomain::Osint).count(), 2);
// The OSINT domain carries ZERO vocabulary rows BY DESIGN (operator
// ruling 2026-07-02): its low byte is appid space (q2 = 0x01), not a
// concept slot — see the CODEBOOK 0x07XX section note.
assert_eq!(concepts_in_domain(ConceptDomain::Osint).count(), 0);
}

#[test]
Expand Down
23 changes: 23 additions & 0 deletions docs/DISCOVERY-MAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,3 +587,26 @@ isolation. The map's job is to keep them visible.
the ClassView from a manifest is fine ("compile types", not hot-path
serde). Detail: `docs/APP-CLASS-CODEBOOK-LAYOUT.md` §3.5–3.7. `[H]`
pending a hot-path no-serde probe across one render + one RAG path.

- **D-OSINT-APPID-NOT-CONCEPT (the OSINT low byte is appid space,
domain-wise; 2026-07-02; [G], operator ruling):** PR #145's two OSINT
codebook mints were hallucinations — "OSINT Person was a
hallucination" (operator, verbatim). The corrected semantics: `0x07`
is the OSINT **domain**; its low byte is allocated **domain-wise as
an APPID**, not as concept vocabulary. `0x0700` = the domain itself
(low byte `00` = domain-wide); `0x0701` = **OSINT-for-q2** (q2 is
appid `0x01`, the consumer); V3 form `0x1000_0701`. Consequently the
OSINT domain contributes **zero vocabulary rows** — `osint_system` /
`osint_person` removed from `CODEBOOK` / `class_ids::ALL` / the
resolver / `all_promoted_classes` / the Class builders (this pass).
Class *content* (AIRO/VAIR system card, McClelland/Rubicon person
lens) is consumer-side — q2 `osint_classview.rs` — never OGAR
vocabulary. Side effect: codebook count returns 67 → 65, balancing
the lance-graph mirror COUNT_FUSE with zero mirror changes, and
dissolving lance-graph `ISS-OSINT-SYSTEM-ROOT-SLOT-VIOLATION`
(neither of its Options A/B — the ruling is sharper: no concept rows
at all). Adjacent confirmations in the same ruling: FMA anatomy = own
domain (`0x0A`), adjacent to but separate from Health (`0x09`),
consumed by q2; CPIC likewise its own Genetics domain (`0x0E`) under
q2. Do NOT re-mint OSINT concept rows; the codebook section carries
the guard note.
Loading