|
15 | 15 |
|
16 | 16 | ## Entries (newest first) |
17 | 17 |
|
| 18 | +## 2026-06-22 — extract_classes.py transcoded to Rust byte-faithfully; XSD↔TTL bijection closed; Python dependency removed from the oracle |
| 19 | +**Status:** FINDING |
| 20 | +**Scope:** XSD front-end × calibration self-containment × the queued bijection |
| 21 | + |
| 22 | +The MARS XSD classification extractor (`arago/MARS-Schema/tools/extract_classes.py`, |
| 23 | +~360 lines, ~140 logic + ~150 table formatting) is now a faithful Rust |
| 24 | +transcode at `crates/ogar-from-schema/src/xsd.rs`, behind the optional |
| 25 | +`xsd` feature (pulls `roxmltree`, a pure-Rust read-only XML DOM; the |
| 26 | +default TTL path stays zero-parser-deps). |
| 27 | + |
| 28 | +Three things this lands: |
| 29 | + |
| 30 | +1. **Byte-for-byte transcode proof.** `xsd::to_asciidoc()` reproduces |
| 31 | + the Python `-F asciidoc` output exactly — 628 lines, including the |
| 32 | + verbatim XSD-documentation whitespace and the `printAsciiDocFooter` |
| 33 | + trailing newline. Test: `xsd::tests::asciidoc_matches_python_oracle` |
| 34 | + diffs against the cached `_oracle/classifications.adoc`. |
| 35 | + |
| 36 | +2. **The XSD↔TTL bijection is closed (was "queued" in |
| 37 | + `MARS-TRANSCODING.md §2`).** `xsd::tests::xsd_classes_match_ttl_enum` |
| 38 | + asserts FULL bidirectional set-equality between the XSD-extracted |
| 39 | + Application value set and the TTL `validation-parameter` enum — not |
| 40 | + just one-directional membership. The XSD and the TTL are two |
| 41 | + independent encodings of one taxonomy and they now provably agree |
| 42 | + in both directions. |
| 43 | + |
| 44 | +3. **The Python dependency is removed from the calibration path.** |
| 45 | + `cargo test --features xsd` is the whole oracle now; no `python3` |
| 46 | + interpreter needed. `extract_classes.py` stays vendored in |
| 47 | + `_oracle/` as the provenance witness (what the transcode was proven |
| 48 | + against), not a runtime dep. |
| 49 | + |
| 50 | +Transcode discipline notes (for the next source→Rust port): |
| 51 | +- The Python `getAttribute("xml:lang")` returns `""` for absent (not |
| 52 | + `None`); the lang-filter is "absent OR en". roxmltree resolves `xml:` |
| 53 | + to the xml namespace — match on `attribute.name() == "lang"`. |
| 54 | +- `getXMLText` concatenates DIRECT text-node children only (not |
| 55 | + recursive); the documentation's internal whitespace is load-bearing |
| 56 | + for the byte-match. |
| 57 | +- The `:revdate:` is `datetime.now()` in Python (non-deterministic); |
| 58 | + the Rust `to_asciidoc(c, revdate)` takes it as a parameter so the |
| 59 | + output is reproducible and testable. |
| 60 | + |
| 61 | +Answer to "is it huge": no — ~360 lines, half output formatting; the |
| 62 | +transcode is ~350 LOC Rust including tests. And it doubles as the seed |
| 63 | +of the broader XSD→`Class` front-end (the same walk that extracts |
| 64 | +classifications is the structural-arm lift for any XSD). |
| 65 | + |
| 66 | +Evidence: `crates/ogar-from-schema/src/xsd.rs` (20/20 tests pass with |
| 67 | +`--features xsd`; 16/16 on default). `docs/MARS-TRANSCODING.md §2` |
| 68 | +updated to mark the bijection closed. |
| 69 | + |
| 70 | +## 2026-06-22 — OGIT is the canonical template store; Odoo (and any source-AST producer) digests INTO it; consumers relive agnostically via askama |
| 71 | +**Status:** FRAMING |
| 72 | +**Scope:** Foundry-parity collapse × cross-consumer architecture × digest-once-relive-N |
| 73 | + |
| 74 | +The operator's framing — *"basically digest Odoo and store it in TTL |
| 75 | +'Jinja' Templates in OGIT and relive it agnostically for any |
| 76 | +'verb/entity as a class'"* — crystallizes the four pieces shipped |
| 77 | +across this PR (TTL mirror, schema lift, verb-as-class template, |
| 78 | +author-provenance discriminator) into one coherent flow: |
| 79 | + |
| 80 | +``` |
| 81 | +Odoo source → ogar-from-python → Class IR → ttl_emit → OGIT TTL templates |
| 82 | + (stored at |
| 83 | + vocab/imports/ogit/NTO/<Domain>/, |
| 84 | + dcterms:creator = bus-compiler) |
| 85 | + │ |
| 86 | + ▼ |
| 87 | + ogar-render-askama |
| 88 | + │ |
| 89 | + ▼ |
| 90 | + any consumer (woa-rs, smb-office-rs, medcare-rs, q2, future renderers) |
| 91 | + re-instantiates any entity/verb-as-class with a fresh binding; |
| 92 | + never touches Odoo Python |
| 93 | +``` |
| 94 | + |
| 95 | +The Python runtime is **only** touched at digest time. After that, |
| 96 | +every consumer talks to TTL templates plus the askama engine. |
| 97 | + |
| 98 | +**Why store in OGIT NTO (not a parallel `vocab/imports/odoo/`):** the |
| 99 | +`dcterms:creator` author-scan finding from this same session makes |
| 100 | +provenance unambiguous without a separate namespace. The precedent |
| 101 | +exists today — `Accounting/` already has 11 Claude-digested files |
| 102 | +sitting alongside 23 Viktor Voss originals. |
| 103 | + |
| 104 | +**Foundry-parity collapse** (the punchline). Foundry's four-layer |
| 105 | +platform pitch (ingest / storage / render / IAM+audit) maps to four |
| 106 | +free open-source pieces already in this repo: |
| 107 | + |
| 108 | +| Foundry layer | Our equivalent | New code needed | |
| 109 | +|---|---|---| |
| 110 | +| Ingest | `ogar-from-python` digest | ~1500 LOC (queued) | |
| 111 | +| Storage | `vocab/imports/ogit/NTO/<Domain>/` TTL with `dcterms:creator` | zero (exists) | |
| 112 | +| Render | `ogar-render-askama::{views, actions}` | ~200 LOC for actions submodule | |
| 113 | +| IAM + audit | verb-as-class `requires-perm` slot + Lance-version-as-audit | zero (exists) | |
| 114 | +| Ontology change mgmt | `diff -r` of digest re-runs | zero | |
| 115 | + |
| 116 | +Total marginal code: <2000 LOC for what Foundry charges $$$ for. The |
| 117 | +architecture was latent the whole time; the digest→relive framing is |
| 118 | +what makes it visible as a single shape. |
| 119 | + |
| 120 | +Concrete next steps (independent, can ship in parallel PRs): |
| 121 | + |
| 122 | +1. `ogar-from-python` digester — structural-arm filter (`_name`, |
| 123 | + `_inherit`, `fields.*`, selections); behavioural-arm signatures |
| 124 | + (decorator names + action method signatures); drops method bodies |
| 125 | +2. `ogar-render-askama::actions` — verb-as-class render path, mirroring |
| 126 | + the existing `views/` submodule |
| 127 | + |
| 128 | +Doc: `docs/ODOO-DIGEST-TO-OGIT.md` (FRAMING v0) carries the full |
| 129 | +pipeline, the v0 mapping table (6 minted concepts + ~9 queued for |
| 130 | +codebook mint), the drift detector recipe, and the Foundry-parity |
| 131 | +collapse table. |
| 132 | + |
| 133 | +## 2026-06-22 — Verb-as-class is an ontological askama template — compile-time-validated action declaration, not a quirk |
| 134 | +**Status:** FINDING |
| 135 | +**Scope:** WorkOrder convention × `ogar-render-askama` integration × Foundry action-type parity |
| 136 | + |
| 137 | +WorkOrder's 12 `verbs/*.ttl` are declared as `rdfs:Class`, not |
| 138 | +`owl:ObjectProperty`. The earlier framing (commit `cce8420`) called |
| 139 | +this "an unusual convention we're free to revise toward standard |
| 140 | +`owl:ObjectProperty`" — **that framing was wrong** and is hereby |
| 141 | +corrected. |
| 142 | + |
| 143 | +The verb-as-class encoding is **load-bearing**: it makes each verb a |
| 144 | +typed template carrying its own slot list (`ogit:mandatory-attributes`), |
| 145 | +inheritance chain (`rdfs:subClassOf`), and policy metadata |
| 146 | +(`ogit:requires-perm`, `ogit:emits-audit`). That's not a flat predicate; |
| 147 | +that's a **compile-time-validated action declaration** — the ontological |
| 148 | +counterpart to askama (Rust) and jinja (Python) HTML templating. |
| 149 | + |
| 150 | +The structural correspondence is exact: |
| 151 | + |
| 152 | +- TTL file = template (`.html.j2` equivalent) |
| 153 | +- `ogit:mandatory-attributes` = struct field list (askama context shape) |
| 154 | +- Per-call binding = struct instance (askama render input) |
| 155 | +- Render = SPO triple emit + declared side effects (audit, ACL gate) |
| 156 | +- `rdfs:subClassOf` = template inheritance (`{% extends %}`) |
| 157 | +- Lift-time slot validation = askama's compile-time `{{ field }}` check |
| 158 | + |
| 159 | +This is the integration point `ogar-render-askama` was always going |
| 160 | +to need for actions. The crate currently renders `Class` *views* |
| 161 | +(noun-shaped: HTML/JSON/OpenAPI); a parallel `actions/` submodule |
| 162 | +renders `Class` *actions* (verb-shaped: SPO triple + side-effect spec). |
| 163 | +Same engine, same compile-time-validated context model, different |
| 164 | +output medium. |
| 165 | + |
| 166 | +**Foundry-parity sharpening:** Foundry's "action types" carry exactly |
| 167 | +the four properties this encoding gives — typed parameters, slot |
| 168 | +validation, declared side effects, inheritance. Foundry sells it as a |
| 169 | +paid platform feature; verb-as-class TTL + `ogar-render-askama` gives |
| 170 | +the same four from open-source schemas and Rust templates. |
| 171 | + |
| 172 | +Implications: |
| 173 | +- **WorkOrder's convention stays.** Don't normalise to `owl:ObjectProperty`. |
| 174 | +- **WorkOrder is the natural prototyping ground** (we're upstream per |
| 175 | + `dcterms:creator` = `bus-compiler` + `family-codec-smith`) for new |
| 176 | + verb-as-class predicates before pitching the pattern to OGIT upstream. |
| 177 | +- **`ogar-render-askama::actions` is the next natural module** — |
| 178 | + ~200 LOC mirroring the existing `views/` render path. |
| 179 | + |
| 180 | +Doc: `docs/VERB-AS-CLASS-TEMPLATE.md` (FRAMING v0) carries the full |
| 181 | +analogy table + worked example + render flow. |
| 182 | + |
| 183 | +## 2026-06-22 — Author provenance via `dcterms:creator` discriminates "ours to revise" from "upstream-coordinated" |
| 184 | +**Status:** FINDING |
| 185 | +**Scope:** OGIT NTO governance × multi-domain lift × who-can-change-what |
| 186 | + |
| 187 | +OGIT TTL files carry `dcterms:creator` on every subject. The field is |
| 188 | +free-form text but carries one of two semantic shapes in practice: |
| 189 | + |
| 190 | +- **Human author + email** (`chris.boos@almato.com`, `Viktor Voss`, |
| 191 | + `fotto@arago.de`, `Marek Meyer`, `Peter Larem`, `Ola Irgens Kylling`, |
| 192 | + …) — original arago/almato authors. Structural changes need upstream |
| 193 | + coordination. |
| 194 | +- **Internal agent name** (`bus-compiler`, `family-codec-smith`, |
| 195 | + `Claude (AdaWorldAPI/lance-graph 3-hop optim)`, …) — files authored |
| 196 | + by our agent fleet against this org's forks. We are upstream for |
| 197 | + these; structural changes need no external coordination. |
| 198 | + |
| 199 | +The 9-domain spot check (Transport, Accounting, SalesDistribution, |
| 200 | +Credit, Cost, ServiceManagement, WorkOrder, Compliance, Audit) revealed: |
| 201 | + |
| 202 | +- **WorkOrder is fully ours** — 100% internal-agent authorship (`bus-compiler`, |
| 203 | + `family-codec-smith`). The unusual `rdfs:Class`-as-verb convention is |
| 204 | + ours to revise toward standard `owl:ObjectProperty`-as-verb whenever |
| 205 | + the AST predicate registry needs the WorkOrder verbs. |
| 206 | +- **Accounting is mixed-authorship** — Viktor Voss (23 files, original) |
| 207 | + + a prior session's `Claude` extension (11 files). Structural changes |
| 208 | + to the original 23 require upstream coordination; the 11 are ours. |
| 209 | +- **All other 7 domains are pure-upstream** — single-or-few external |
| 210 | + human authors. |
| 211 | + |
| 212 | +This makes WorkOrder the **natural prototyping ground** for new TTL |
| 213 | +predicates OGAR wants to add: ship in WorkOrder first (no external |
| 214 | +coordination cost), validate the bijection, then pitch the pattern |
| 215 | +to OGIT upstream once it's proven. |
| 216 | + |
| 217 | +Evidence: the `dcterms:creator` provenance scan recipe lives in |
| 218 | +`docs/OGIT-DOMAIN-LIFT-CATALOGUE.md § Verifying domain authorship`; |
| 219 | +the round-trip stress test for the 9 domains is |
| 220 | +`ttl_emit::tests::nine_domains_lift_surface_round_trip` (zero failures |
| 221 | +on 210 TTLs across the nine). |
| 222 | + |
18 | 223 | ## 2026-06-22 — Schema-vs-source duality: schemas lift structure bijectively; source ASTs lift behaviour best-effort; they cross-validate at the structural boundary |
19 | 224 | **Status:** FINDING |
20 | 225 | **Scope:** producer architecture × MARS calibration × Foundry-Odoo lens × the bardioc migration |
|
0 commit comments