Health mints + ActionDef→adapter codegen back-end (furnace exam + three-axis gate)#189
Conversation
…iring Hand-authored, harvest-informed healthcare action table on the six minted 0x09XX Health concepts (patient/diagnosis/lab_value/medication/treatment/ vital_sign). Registers in capability_registry::domain_tables() through the generic entries_from_actions derive, so resolve_hotplug turns green for the Health classids that previously banged NoCapabilitiesFor. Why hand-authored, not the plan's mechanical Loop A: the 2026-07-07 harvest over the consumer C# tree falsified the auto-derive premise. The consumer is a WinForms monolith — no AR-shaped class per domain concept; the domain surface lives as verb_concept methods on one monolithic DAL class. A class-keyed lift has nothing to key on, so — exactly like ocr_actions.rs's "no ActiveRecord source" rationale — the table is declared by hand, with the capability split following the measured DAL method inventory. The concrete method-name evidence stays in the consumer repo, never committed here. visit (0x0906) deliberately excluded: zero harvest evidence (operator- confirmed). Six subjects, not the port's seven; a visit_is_minted_but_ deliberately_tableless pin keeps the exclusion visible. - healthcare_actions.rs: 20 name-only ActionDefs + HEALTHCARE_ACTION_NAMES / HEALTHCARE_SUBJECT_CLASSIDS / HEALTHCARE_EXPECTED_EXECUTORS=["medcare-rs"]; 9 module tests (subject-domain fuse, subject-const parity, visit exclusion, name-only, well-formed identity). - capability_registry.rs: healthcare_entries() DomainTable + healthcare_hotplug_resolves_vocab_and_actions probe; the each_drift_arm NoCapabilitiesFor probe moved 0x0901 -> visit 0x0906 (patient now has caps). - plan doc: P3/P4 shipped + the Loop-A-falsified correction. 131 ogar-vocab tests green; fmt + clippy -D warnings clean; PII word-boundary scan clean; no private-corpus identifiers in committed artifacts.
Guards the Boundary-4 failure mode (a green codebook-DTO check that does NOT predict nonzero registration because the check's case-folding concept_key normalization and the registration derive's exact-match canonical_concept_id disagree). codebook_dto_derive_is_bijective asserts three properties over healthcare_actions(): 1. forward total + nonzero — entries_from_actions yields a nonzero id for every row (no classid-0 sentinel escapes, the exact Boundary-4 symptom); 2. inverse round-trip — each derived id reverses via canonical_concept_name to exactly its object_class segment (concept->id->concept bijection); 3. concept_key fixed-point — every segment is already canonical snake_case (no uppercase, no ':' namespace), the condition under which the check's concept_key is the identity, so case-folding check and exact-match derive resolve this table's names identically. ogar-vocab has no ruff_spo_triplet dep, so concept_key is asserted via its fixed-point condition rather than called directly. 14 healthcare tests green.
…ine Phase 6) entries_from_actions_with_residuals: resolved rows carry their nonzero classid; an unresolvable concept lands as an UnmintedRow (capability, object_class, concept) on the slag ledger instead of degrading to the id-0 sentinel. The residual is not waste — it is the empirical boundary of the current codebook/convention; each recurring row names the next config fact (a mint, an alias row, or a convention fix). "Study the slag, teach the furnace." entries_from_actions is now the LEGACY id-0-sentinel projection of the same single-pass ordered derive (I-LEGACY-API-FEATURE-GATED: the existing name keeps byte-identical semantics — pinned by the new interleaved-order parity test; new semantics got a new name). Healthcare table through the residual derive: zero slag (mirrors the codebook_dto_derive_is_bijective pin). 135 ogar-vocab tests green; clippy -D warnings clean.
…to the lift (doctrine Phase 6 green) The production half of the CONCEPT = CLASS fix: lift_actions keys every ActionDef.object_class on the owning class — correct for AR-shaped corpora, the give-up point for God-object DALs. lift_actions_with_convention runs ruff_spo_triplet::rekey_model (ruff #72) over the model with the corpus-owner convention and re-subjects each ActionDef to its inferred concept (concept_key-fixed-point, so the codebook exact-match resolves — Boundary-4); unsplit methods keep the class subject and land on the slag ledger via entries_from_actions_with_residuals, never silent id 0. Effect/kausal enrichment delegates to lift_actions, so the two paths cannot drift. The OGAR-side furnace exam (god_object_rekey_lift_derives_nonzero_concepts_ with_slag) pins the doctrine's Phase 6 success criteria on a neutral God-object fixture: split methods nonzero, unsplittable method a NAMED residual. Run against the real corpus through the full chain (harvest -> reassemble -> rekey -> lift -> entries_with_residuals): all six healthcare concepts derived nonzero (23/4/20/11/10/11 capabilities), 2668 residuals ledgered, zero id-0 escapes. Builds against ruff_spo_triplet post-#72 main (Cargo.lock is gitignored here; the branch=main git dep re-resolves on fresh checkouts). 78 + 135 tests green; clippy -D warnings clean. Known ledgered finding: the derive is domain-blind — one real-corpus residue cross-matched an OCR-domain mint; a domain-gate convention row is the named next config fact.
Round-2 furnace-exam mints through the engineer's gate, hardened by a staged 5+3 council (5 savants -> consolidate -> 3 brutal reviewers). All four are grounded in the transcode furnace exam's slag ledger (concept-shaped unbound residues on the real corpus): anamnesis (0x0908, English synonym medical_history), investigation (0x0909), examination (0x090A, parallel grounding OGIT Healthcare:Assessment — see the assessment-drift note in ports.rs), practitioner (0x090B, the clinical actor; NOT staff/license admin, NOT HR employment). Deliberately name-level (council anti-fabrication pin): each builder carries exactly one structural attribute + the patient edge where the record lives in the patient file; clinical schemas arrive from the harvest via the production lift, never by hand. A new test pins the attribute counts. No OGIT entity yet -> no port alias; ports.rs pin stays 7 with the drift note. COUNT_FUSE 84->88 (lance-graph mirror lands paired). concepts_in_domain(Health) 7->11 across doctest + domain-loop + enumeration tests; ogar-class-view registers the 4 builders (empty-ObjectView guard extended to all 11). Pre-existing, unrelated, unchanged: ogar-adapter-csharp parity test (executor-list drift) and ogar-from-elixir unused-import warnings. Co-Authored-By: Claude <noreply@anthropic.com>
…alth concept Round-4b furnace mint, hardened by a staged 5+3 council AND an operator-directed three-axis grounding gate (method + storage + Klickwege structure): external_practice is witnessed by a DAL address-form method family, a storage projection, and — decisively — a dedicated navigation home reachable in the nav plane, so it grounds [G] rather than method-only. FHIR Organization; name-level builder, no patient edge (an org, not a patient-file record); anti-fabrication pin extended (external_practice, 0 edges). COUNT_FUSE 88->89 (lance-graph mirror paired). concepts_in_domain(Health) 11->12 across doctest + domain-loop + enumeration + tuple tests; ogar-class-view registers the builder. ports.rs alias-count note explains why 0x090C stays alias-less (mechanical sql_mirror stub, no curated OGIT entity). The round's second candidate (a permission catalog) was REFUSED a mint by the same gate: storage + method witnesses but ZERO Klickwege home (embedded combo, never a destination) => it is a lookup surface, not a concept — no codebook slot consumed. The three-axis gate is recorded in the consumer transcode doctrine. Co-Authored-By: Claude <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_4584840b-588a-4a8c-a44d-f724e3f81e17) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13e1b0fa3c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /// edge — it is an organization, not a patient-file record. | ||
| #[must_use] | ||
| pub fn external_practice() -> Class { | ||
| let mut c = Class::new("ExternalPractice"); |
There was a problem hiding this comment.
Add the ExternalPractice alias to codebook lookup
When callers resolve the new canonical class label ExternalPractice through LabelDTO::from_alias/ogar_codebook, the lookup goes through canonical_concept, which only lowercases/plural-strips unless an explicit arm exists; ExternalPractice therefore becomes externalpractice and does not resolve to the new external_practice id. Because this harvest-derived concept intentionally has no HealthcarePort alias, any consumer using the class label rather than the snake_case canonical_concept field will miss 0x090C; add the externalpractice/ExternalPractice mapping or use a resolvable label.
Useful? React with 👍 / 👎.
… Klickwege-gated The DO-arm codegen back-end of the OGAR compiler (core-first: the Core emits adapters). emit_do_adapters(classes, nav_witnessed) renders a deterministic Rust module of classid-keyed adapter scaffolds FROM harvested ActionDef signatures (writes/reads per predicate), gated on Klickwege structure-parity witnesses: a class whose canonical concept is NOT surfaced by any navigation screen is emitted with a marker so the parity gap is visible in the generated code, never silent. Fully deterministic (BTree ordering, no timestamp/id) so the emitted adapter is diffable as a golden artifact. Bodies are stubs — thinking lives in lance-graph, not in generated consumer code. Corpus-agnostic: input is typed structs, neutral Invoice/Cipher tests only (5, pinned output + shuffle-determinism + witness gate + snake/collision + stub-body). Co-Authored-By: Claude <noreply@anthropic.com>
…odebook-handover-5ulx0i # Conflicts: # crates/ogar-vocab/src/capability_registry.rs
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_a000230d-137b-4418-bca2-6912e721b817) |
…e (healthcare table fallout) The dump-parity probe for the NoCapabilitiesFor drift arm used `patient` as a 'classid with no capabilities' example. That held while the OCR table was the only DomainTable, but this branch adds the healthcare capability table — which gives `patient` capabilities, so the executor guard (tableContributes && !expected) now fires FIRST and throws UnexpectedConsumer(tesseract-ogar), uncaught by the catch(NoCapabilitiesFor) → the C# Dump() crashed and the Rust ground-truth mismatched. Switch the probe to `visit` (0x0906) — the deliberately table-less Health concept (excluded from HEALTHCARE_SUBJECT_CLASSIDS), so it has no OCR and no healthcare capabilities and reliably yields NoCapabilitiesFor. This is exactly the classid capability_registry.rs:464 already uses for the same probe. Fixed in lockstep across all three emission sites (Rust ground-truth generator + C# template + Python template) so the dumps still agree. C# dotnet parity 2/2 green. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Two arms of the OGAR compiler, both driven by the MedCare transcode furnace (nothing hand-authored):
1. Health-domain mints. Five harvest-derived concepts, each surfaced by the furnace exam's slag ledger and gated through a staged 5+3 council.
external_practiceadditionally passed an operator-directed three-axis grounding gate (method + storage + Klickwege-structure witnesses), which also refused a candidate that lacked a navigational home — so the codebook grows only where a concept is witnessed from all sides.anamnesis 0x0908,investigation 0x0909,examination 0x090A,practitioner 0x090B(round 2)external_practice 0x090C— referral-partner organization (FHIROrganization); round 4b, three-axis-witnessed → [G]ogar-vocab: CODEBOOK + consts +ALL+ five name-level builders (anti-fabrication pin blocks fabricated schemas);COUNT_FUSE84→89;concepts_in_domain(Health)7→12 across all count tests;ports.rsalias-count note.ogar-class-view: registers the five builders (empty-ObjectViewguard extended).2. Codegen back-end:
ogar-emitter::emit_do_adapters. The DO-arm of the compiler (core-first: the Core emits adapters). Renders a deterministic Rust module of classid-keyed adapter scaffolds from harvested ActionDef signatures, gated on Klickwege structure parity — a class whose canonical concept is not surfaced by any navigation screen is emitted with a// STRUCTURE-UNWITNESSEDmarker so the parity gap is visible, never silent. Bodies areunimplemented!()stubs (thinking lives in lance-graph). Corpus-agnostic, neutral tests. The private MedCare driver (PR #198) runs it on the real corpus: 162 classes, 162/162 re-keying debt — the honest measure of what the furnace still has to re-key.Merge order (cross-repo COUNT_FUSE)
Head of a three-repo train: merge this first, then lance-graph #675 (mirror), then MedCare-rs #198 (consumer). A red window on
lance-graph-ogarbetween the first two is structural.Test Plan
cargo test -p ogar-vocab(136),cargo test -p ogar-class-view,cargo test -p ogar-emitter do_adapter(5) — all green🤖 Generated with Claude Code