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
14 changes: 14 additions & 0 deletions .claude/draft/ruff-csharp-do-arm-handover.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# DRAFT / HANDOVER — close out the C# (Roslyn) DO-arm harvest for MedCare

> **RESOLVED — 2026-07-07.** The ready-to-apply patch this handover
> pointed at landed as [AdaWorldAPI/ruff#59](https://github.com/AdaWorldAPI/ruff/pull/59)
> and merged (`5c6c0fcf9ca4a7ac3a7efb924b00285456b5cf51`). The ruff-write
> 403 was proxy-specific, not an org/token permission gate — direct
> `git`/REST against `github.com` with the proxy env unset worked (see
> `tesseract-rs/CLAUDE.md` § GitHub access matrix). Loader fixture +
> codebook-DTO check are in on `main` now. Still open: the `dotnet` run
> against a real C# corpus to de-draft `EmitBodyArm` (no `dotnet` in the
> sandbox that closed this out). Full record:
> `MedCare-rs/.claude/handovers/ruff-csharp-arm/RESOLVED.md`.

---


> **Why this lives in OGAR, not ruff:** ruff writes are currently
> **403-blocked** for this session (org-level — the Claude GitHub App needs
> (re)connecting for `AdaWorldAPI`, and/or `ruff` re-added to its scope;
Expand Down
5 changes: 4 additions & 1 deletion crates/ogar-adapter-csharp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,10 @@ public static class OgarCapabilitySurface

try
{
ResolveHotplug("tesseract-ogar", new[] { ClassIds["patient"] }, Array.Empty<string>());
// `visit` (0x0906): the table-less Health concept — the stable
// "no capabilities" probe now that `patient` carries the
// healthcare table (whose executor guard would fire first).
ResolveHotplug("tesseract-ogar", new[] { ClassIds["visit"] }, Array.Empty<string>());
throw new Exception("expected NoCapabilitiesFor");
}
catch (NoCapabilitiesFor e) { lines.Add($"NoCapabilitiesFor={e.ClassId:X4}"); }
Expand Down
13 changes: 11 additions & 2 deletions crates/ogar-adapter-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,10 @@ def dump() -> str:
lines.append(f"UnknownClassid={e.classid:04X}")

try:
resolve_hotplug("tesseract-ogar", [CLASS_IDS["patient"]], [])
# `visit` (0x0906): the table-less Health concept — the stable
# "no capabilities" probe now that `patient` carries the healthcare
# table (whose executor guard would fire first).
resolve_hotplug("tesseract-ogar", [CLASS_IDS["visit"]], [])
raise AssertionError("expected NoCapabilitiesFor")
except NoCapabilitiesFor as e:
lines.append(f"NoCapabilitiesFor={e.classid:04X}")
Expand Down Expand Up @@ -625,7 +628,13 @@ pub mod ground_truth {
"UnknownClassid={}\n",
expect_drift_hex(r1, "UnknownClassid")
));
let r2 = resolve_hotplug("tesseract-ogar", &[class_ids::PATIENT], &[]);
// `visit` (0x0906) is the deliberately table-less Health concept
// (excluded from HEALTHCARE_SUBJECT_CLASSIDS) — no OCR and no
// healthcare capabilities, so it is the stable "no capabilities"
// probe. `patient` USED to work here but now carries the
// healthcare table, so its executor guard fires before the
// NoCapabilitiesFor check (matches capability_registry's own probe).
let r2 = resolve_hotplug("tesseract-ogar", &[class_ids::VISIT], &[]);
out.push_str(&format!(
"NoCapabilitiesFor={}\n",
expect_drift_hex(r2, "NoCapabilitiesFor")
Expand Down
26 changes: 22 additions & 4 deletions crates/ogar-class-view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ use ogar_vocab::{
// 0x0CXX — automation (HIRO MARS CMDB + DO-arm actuators)
action_applicability,
action_handler,
anamnesis,
anatomical_structure,
auth_ory_keto,
auth_store,
Expand All @@ -85,10 +86,13 @@ use ogar_vocab::{
commercial_line_item,
currency_policy,
diagnosis,
examination,
external_practice,
hr_department,
hr_employee,
hr_employment_contract,
hr_job,
investigation,
joint,
knowledge_item,
lab_value,
Expand All @@ -114,6 +118,7 @@ use ogar_vocab::{
page_layout,
patient,
payment_record,
practitioner,
pricelist,
pricelist_rule,
priority,
Expand Down Expand Up @@ -210,14 +215,19 @@ fn all_canonical_classes() -> Vec<(&'static str, Class)> {
("page_layout", page_layout()),
("page_image", page_image()),
("ocr_renderer", ocr_renderer()),
// ── 0x09XX — health (OGIT Healthcare) ──
// ── 0x09XX — health (7 OGIT Healthcare + 4 harvest-derived mints) ──
("patient", patient()),
("diagnosis", diagnosis()),
("lab_value", lab_value()),
("medication", medication()),
("treatment", treatment()),
("visit", visit()),
("vital_sign", vital_sign()),
("anamnesis", anamnesis()),
("investigation", investigation()),
("examination", examination()),
("practitioner", practitioner()),
("external_practice", external_practice()),
// ── 0x0AXX — anatomy (FMA reference kinds) ──
("anatomical_structure", anatomical_structure()),
("skeleton", skeleton()),
Expand Down Expand Up @@ -596,9 +606,12 @@ mod tests {

#[test]
fn health_concepts_are_registered_with_their_fields() {
// The 7 OGIT Healthcare concepts resolve to registry entries —
// this is what makes `every_codebook_id_appears_in_class_ids_all`
// green for the 0x09XX block.
// All 12 Health concepts (7 OGIT + 5 harvest-derived mints)
// resolve to registry entries — this is what makes
// `every_codebook_id_appears_in_class_ids_all` green for the
// 0x09XX block. The `!fields.is_empty()` assertion is the
// empty-ObjectView guard: even the name-level mints must carry
// at least one field.
let v = OgarClassView::new();
for concept in [
"patient",
Expand All @@ -608,6 +621,11 @@ mod tests {
"treatment",
"visit",
"vital_sign",
"anamnesis",
"investigation",
"examination",
"practitioner",
"external_practice",
] {
let id = canonical_concept_id(concept).unwrap();
let view = v
Expand Down
Loading
Loading