diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 360951c..7128b8e 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -15,8 +15,66 @@ ## Entries (newest first) -## 2026-06-22 — Three corrections to the Odoo digest framing: producer name, storage location, latent re-vendor bug +## 2026-06-22 — The "latent re-vendor bug" was a false premise; exports/ is a STAGING tier, not a permanent home (operator-decided) **Status:** FINDING +**Scope:** vocab/ tree model × verify-before-acting × correcting a prior session's claim + +Investigating the "migrate the 11 stranded Accounting files" task +(queued by the prior PR #107 entry below) caught that its founding +premise was **factually wrong** — a clean case of the +verify-before-destructive-action discipline paying off. + +The claim (PR #107, exports/PROVENANCE.md, the entry below): "11 +OGAR-produced TTLs sit in `vocab/imports/ogit/NTO/Accounting/` at +re-vendor-overwrite risk; they should migrate to `exports/`." + +What verification found: those 11 files are **committed to the +AdaWorldAPI/OGIT fork** — commit `c5dc1b8` "shrink 3-hop Odoo lookups +— promoted attrs + shortcut verbs + FiscalJurisdiction codebook", on +the fork's `master`, pushed. They were not added directly to OGAR's +`imports/`; they were promoted to the fork by a prior session, and +`imports/` faithfully mirrors the fork. The re-vendor recipe copies +*from* the fork (`cp -r /OGIT/NTO/. vocab/imports/ogit/NTO/`), so it +**preserves** them. There was never a data-loss risk. NO migration. + +The operator resolved the resulting genuine question — what is +`exports/` actually FOR — to the **staging-tier model**: + +``` +producer ──► exports/ (review, CI) ──promote──► OGIT fork ──re-vendor──► imports/ ──► consumers +``` + +- `exports/` = produced-but-not-yet-promoted content; transient; + the pre-promotion workbench. CI (round-trip + bijection + drift) + runs here before anything touches the shared fork. +- The AdaWorldAPI/OGIT fork = the enriched canonical store (upstream + arago/almato + OGAR-promoted additions like `c5dc1b8`). +- `imports/` = faithful SHA-pinned mirror of the enriched fork. +- Consumers read ONLY `imports/`. Never `exports/`. + +Under this model the 11 Accounting files are a *completed* promotion, +correctly mirrored in `imports/` — the worked example of the pipeline +run to its end, not stranded content. `exports/` stays empty until a +producer stages something that hasn't been promoted yet. + +Two lessons: +1. **Verify the target before claiming a bug about it.** "These files + are at risk" is a claim about the fork's state; one `git log` on the + OGIT clone falsified it. The CLAUDE.md discipline ("look at the + target; if what you find contradicts how it was described, surface + that instead of proceeding") caught a migration that would have + broken the imports↔fork bijection AND duplicated the 11 files. +2. **A correction can itself need correcting.** The entry below + ("Three corrections…") fixed two real things (producer name, + arm-crate role) and introduced one wrong thing (the re-vendor-bug + claim). Corrections 1 & 2 stand; correction 3 is superseded here. + +Evidence: OGIT fork commit `c5dc1b8` (11 files, `master`, pushed); +`vocab/exports/PROVENANCE.md` (rewritten to STAGING TIER v1); +`docs/ODOO-DIGEST-TO-OGIT.md §2` (staging-tier model + the correction). + +## 2026-06-22 — Three corrections to the Odoo digest framing: producer name, storage location, latent re-vendor bug +**Status:** PARTIALLY SUPERSEDED — corrections 1 & 2 stand; correction 3's "latent re-vendor bug" claim was itself wrong, see the 2026-06-22 staging-tier entry above (the 11 Accounting files are committed to the OGIT fork, NOT at risk). **Scope:** producer architecture × vocab/ tree layout × re-vendor safety × digest-to-OGIT Three corrections to the framing in `docs/ODOO-DIGEST-TO-OGIT.md` diff --git a/docs/ODOO-DIGEST-TO-OGIT.md b/docs/ODOO-DIGEST-TO-OGIT.md index 0be6c81..32040a0 100644 --- a/docs/ODOO-DIGEST-TO-OGIT.md +++ b/docs/ODOO-DIGEST-TO-OGIT.md @@ -30,11 +30,14 @@ or workflow action by rendering against the TTL via > projection that's already shipping. > > **Storage location correction (2026-06-22):** earlier drafts said -> digests land in `vocab/imports/ogit/NTO//`. That was wrong -> — it would put OGAR-produced content at re-vendor risk (the -> `imports/` re-vendor recipe is a destructive `cp -r`). Correct -> location: **`vocab/exports/ogit/NTO//`** — see -> `vocab/exports/PROVENANCE.md` for the split rationale. +> digests land in `vocab/imports/ogit/NTO//`. They actually +> STAGE in **`vocab/exports/ogit/NTO//`** — produced-but-not- +> yet-promoted content — and only land in `imports/` after being +> promoted to the AdaWorldAPI/OGIT fork and re-vendored. See §2 for the +> staging-tier model and `vocab/exports/PROVENANCE.md` for the full +> rationale. (The same draft also wrongly claimed 11 existing +> Accounting files were "at re-vendor risk"; they are committed to the +> OGIT fork and correctly mirrored — see §2.) --- @@ -60,10 +63,15 @@ or workflow action by rendering against the TTL via │ — entity-as-class for models │ — verb-as-class for workflow action signatures ▼ - OGIT-shaped TTL templates - (vocab/EXPORTS/ogit/NTO//.ttl) + OGIT-shaped TTL templates (STAGED — not yet promoted) + (vocab/exports/ogit/NTO//.ttl) — dcterms:creator = bus-compiler (digester provenance) - — distinct tree from imports/ ogit/ (re-vendor safety) + — review here (round-trip + bijection tests, drift check) + │ + │ PROMOTE: commit to the AdaWorldAPI/OGIT fork, then + │ re-vendor (cp -r /OGIT/NTO/. vocab/imports/ogit/NTO/) + ▼ + vocab/imports/ogit/NTO// (faithful mirror of the enriched fork) │ │ ogar-render-askama (entity render → views; verb render → actions) ▼ @@ -76,37 +84,44 @@ or workflow action by rendering against the TTL via The Python runtime is **only** touched at digest time. Consumers (`woa-rs`, `smb-office-rs`, `medcare-rs`, `q2`, any future renderer) -never depend on Odoo Python, only on TTL + the askama renderer. - -## §2. Why digests live in `vocab/exports/ogit/`, not `vocab/imports/ogit/` - -`imports/` is a READ-ONLY mirror of upstream OGIT (the re-vendor -recipe is a destructive `cp -r /upstream/. vocab/imports/ogit/`). -Putting OGAR-produced content in `imports/` would silently nuke -those files on the next re-vendor. **The split exists for re-vendor -safety, license/governance, and upstream-contribution path** — see -`vocab/exports/PROVENANCE.md` for the full rationale. - -The digest **mirrors the upstream layout** so consumers see one shape: - -| Concept | Upstream OGIT path (READ-only mirror) | Digest target (OGAR-produced) | -|---|---|---| -| `Accounting` | `vocab/imports/ogit/NTO/Accounting/` (23 files, Viktor Voss) | `vocab/exports/ogit/NTO/Accounting/` (Odoo-digested) | -| `SalesDistribution` | `vocab/imports/ogit/NTO/SalesDistribution/` (23 files, Marek Meyer) | `vocab/exports/ogit/NTO/SalesDistribution/` (Odoo sale.* digest) | -| `Transport` | `vocab/imports/ogit/NTO/Transport/` (27 files, chris.boos@almato.com) | `vocab/exports/ogit/NTO/Transport/` (Odoo stock.* digest) | -| … | upstream-mirrored | OGAR-produced, OGIT-shape-compatible | - -`dcterms:creator` provenance is now a SECONDARY check (the directory -split is the primary). The `OGIT-DOMAIN-LIFT-CATALOGUE.md § -Verifying domain authorship` scan still runs and still discriminates -authors, but the destructive-overwrite risk is structurally gone. - -**Migration note for the existing 11 stranded files.** A prior -session's `Claude (AdaWorldAPI/lance-graph 3-hop optim)` digest left -11 OGAR-produced files in `vocab/imports/ogit/NTO/Accounting/` -alongside Viktor Voss's 23 originals. Those 11 belong in -`vocab/exports/ogit/NTO/Accounting/`. The migration is a separate -PR; `vocab/exports/PROVENANCE.md § Migration note` carries the +never depend on Odoo Python, only on TTL + the askama renderer — and +they read `imports/`, never the `exports/` staging tier. + +## §2. The staging-tier model — `exports/` → OGIT fork → `imports/` + +(Operator-decided 2026-06-22.) `exports/` is a **staging area** for +produced-but-not-yet-promoted content; the AdaWorldAPI/OGIT fork is +the **enriched canonical store**; `imports/` faithfully mirrors the +fork; consumers read only `imports/`. See `vocab/exports/PROVENANCE.md` +for the full model. + +``` +producer ──► vocab/exports/ogit/NTO// (review/iterate, CI runs here) + │ promote (commit to OGIT fork on a branch, PR there) + ▼ + AdaWorldAPI/OGIT fork (enriched: upstream + OGAR-promoted) + │ re-vendor + ▼ + vocab/imports/ogit/ (SHA-pinned mirror — consumers read this) +``` + +Why a staging tier and not "commit straight to the fork": a digest run +produces N TTLs at once; staging lets the round-trip + bijection tests +run, the drift-vs-prior-digest diff fire, and a human review the lift — +all inside OGAR + CI — **before** anything touches the shared fork. The +promote step is the single auditable gate between OGAR-produced and +OGIT-canonical. + +**The 11 Accounting files are NOT a migration target.** An earlier +draft (commit `7d68042`) claimed 11 OGAR-produced TTLs in +`vocab/imports/ogit/NTO/Accounting/` were "at re-vendor risk" and +"belong in `exports/`." **That was wrong.** Those files are committed +to the **AdaWorldAPI/OGIT fork** (commit `c5dc1b8` "shrink 3-hop Odoo +lookups…", on `master`, pushed) — i.e. they are a *completed* +promotion. `imports/` correctly mirrors them; re-vendor preserves +them. They are the worked example of the staging-tier model run to +completion, not stranded content. `exports/` is for content that has +**not yet** made that trip. list. ## §3. The four shapes the digester produces @@ -194,7 +209,7 @@ license fee. | `ruff_rust_spo` (Rust AST frontend, for digesting medcare-rs / woa-rs / etc.) | **does not exist** — needs `syn` walker; symmetric with the other ruff frontends | | `ogar-render-askama::actions` (verb-as-class render path) | **does not exist** — ~200 LOC mirroring the existing `views/` path | | Concept mints for non-Accounting Odoo models | needs the 5+3 codebook pass per `APP-CLASS-CODEBOOK-LAYOUT.md` | -| Migration of the 11 stranded Accounting files (`imports/` → `exports/`) | **queued** — separate PR (see `vocab/exports/PROVENANCE.md § Migration note`) | +| The 11 Accounting files in `imports/` | **not a migration target** — already promoted to the OGIT fork (`c5dc1b8`); correctly mirrored. See §2. | `ruff_python_spo` and `ogar-render-askama::actions` are independent and can ship in parallel PRs. Concept mints are the slow path diff --git a/docs/OGIT-DOMAIN-LIFT-CATALOGUE.md b/docs/OGIT-DOMAIN-LIFT-CATALOGUE.md index 6066bab..c8c2235 100644 --- a/docs/OGIT-DOMAIN-LIFT-CATALOGUE.md +++ b/docs/OGIT-DOMAIN-LIFT-CATALOGUE.md @@ -78,7 +78,7 @@ arago/almato coordination." | Domain | Entities | Attributes | Verbs | Status | Notes | |---|--:|--:|--:|---|---| -| `Accounting` | 9 | 20 | 7 | Lift-tested | Mixed-authorship: `Viktor Voss` (23 files, original arago/almato) + a prior session's extension (`Claude (AdaWorldAPI/lance-graph 3-hop optim)`, 11 files). Covered conceptually via `0x02XX` commerce/ERP via Odoo lift. Structural changes to the original 23 need upstream coordination; the 11 extensions are ours. | +| `Accounting` | 9 | 20 | 7 | Lift-tested | Mixed-authorship: `Viktor Voss` / `Gibson Xavier` / `Moritz Vannahme` (25 files, original arago/almato) + a prior session's extension (`Claude (AdaWorldAPI/lance-graph 3-hop optim)`, 11 files **promoted to the OGIT fork** via commit `c5dc1b8`). The 11 are a completed promotion (fork → mirrored here), the worked example of the staging-tier model (`vocab/exports/PROVENANCE.md`), NOT stranded content. Covered conceptually via `0x02XX` commerce/ERP via Odoo lift. Structural changes to the upstream files need arago coordination; the 11 OGAR-promoted ones are ours. | | `Advertising` | 16 | 0 | 0 | Imported | | | `Audit` | 3 | 0 | 0 | Lift-tested | `Marek Meyer` (sole author) — pure upstream. Audit-as-Lance-version (ADR-013) covers the semantics. | | `Auth` | 13 | 24 | 6 | Imported | Cross-walk to `0x0BXX` auth domain (Zitadel/Zanzibar) queued | diff --git a/vocab/exports/PROVENANCE.md b/vocab/exports/PROVENANCE.md index 3b653ad..dcf574f 100644 --- a/vocab/exports/PROVENANCE.md +++ b/vocab/exports/PROVENANCE.md @@ -1,95 +1,116 @@ # PROVENANCE — `vocab/exports/` -> **OGAR-produced TTL templates, in OGIT-compatible shape.** Distinct -> from `vocab/imports/` (read-only mirror of upstream OGIT, MIT -> licensed by arago/almato). Files in this tree are AUTHORED in OGAR -> — either digested from source by a producer (`ruff_*_spo + -> ogar-from-ruff`, future `ruff_rust_spo`, etc.) or hand-authored — -> and the OGAR license applies. +> **Staging tier for OGAR-produced TTL, in OGIT-compatible shape.** +> Content here is AUTHORED in OGAR (digested from source by a producer +> — `ruff_*_spo + ogar-from-ruff`, `ogar-from-schema` — or +> hand-authored) and is **NOT YET PROMOTED** to the AdaWorldAPI/OGIT +> fork. Once reviewed, content is committed to the OGIT fork and +> re-vendored into `vocab/imports/` like any other upstream content. > -> Status: **SKELETON v0** (2026-06-22). Scaffold lands empty; content -> populates as producers digest into it. +> Status: **STAGING TIER v1** (2026-06-22). Empty until a producer +> stages content; transient by design. -## Why the split +## The model (operator-decided 2026-06-22) -`vocab/imports/` and `vocab/exports/` exist for three reasons: - -1. **Re-vendor safety.** The `imports/` re-vendor recipe is a - destructive `cp -r /upstream/. vocab/imports/...`. Putting - OGAR-produced content in `imports/` would be silently nuked on - the next re-vendor. The split makes the producer-output tree - immune. - -2. **License + governance.** `imports/` inherits MIT (Almato AI GmbH, - 2013–2024) from OGIT upstream. `exports/` inherits OGAR's own - license. Authorship discriminator (`dcterms:creator`) becomes a - secondary check rather than the primary one. +``` + OGAR producer ──► vocab/exports/ogit/NTO// (review / iterate) + (ruff_*_spo + │ + ogar-from-ruff, │ promote (commit to the OGIT fork on a branch, PR there) + ogar-from-schema) ▼ + AdaWorldAPI/OGIT fork (the enriched canonical OGIT store — + │ upstream arago/almato + OGAR-promoted) + │ re-vendor (cp -r /OGIT/NTO/. vocab/imports/ogit/NTO/) + ▼ + vocab/imports/ogit/ (faithful SHA-pinned mirror of the fork) + │ + ▼ + consumers read ONLY imports/ +``` -3. **Upstream-contribution path.** Files in `exports/` are candidates - for PR back to OGIT upstream (or onward distribution to consumers - expecting OGIT shape). Files in `imports/` are immutable mirrors. - The directory split makes the contribution flow a one-line check. +- **`exports/` is the staging area** — produced-but-not-yet-promoted + content. Review it here, then promote to the fork. +- **The AdaWorldAPI/OGIT fork is the enriched canonical store** — it + already mixes upstream arago/almato content with OGAR-promoted + additions (e.g. commit `c5dc1b8` "shrink 3-hop Odoo lookups — + promoted attrs + shortcut verbs + FiscalJurisdiction codebook" + added 11 Accounting TTLs to the fork deliberately). +- **`imports/` faithfully mirrors the enriched fork** — including any + OGAR-promoted content. Re-vendor is **safe**: it copies *from* the + fork, which has everything. +- **Consumers read only `imports/`.** `exports/` never ships to a + consumer; it is the pre-promotion workbench. + +## Why a staging tier (not "just commit to the fork directly") + +1. **Review surface.** A digest run produces N TTLs at once. Staging + them in `exports/` lets the round-trip + bijection tests run, the + diff-vs-prior-digest drift check fire, and a human review the lift, + all inside the OGAR repo and CI — before anything touches the fork. + +2. **License + governance boundary.** Until promoted, OGAR-produced + content carries OGAR's license, not the fork's MIT (Almato AI GmbH). + Promotion is the deliberate act that relicenses / blesses it into + the shared OGIT store. + +3. **The producer↔consumer split stays clean.** Producers write + `exports/`; consumers read `imports/`. Nothing reads the half-baked + tree. The promote step is the single, auditable gate between them. ## Layout ``` vocab/exports/ -└── ogit/ ← OGIT-shape (consumer-compat) +└── ogit/ ← OGIT-shape (matches the fork's layout) ├── NTO/ - │ ├── / ← mirrors upstream OGIT NTO layout + │ ├── / ← mirrors the OGIT NTO layout │ │ ├── entities/ ← entity TTLs (a rdfs:Class) │ │ ├── attributes/ ← datatype-property TTLs (a owl:DatatypeProperty) │ │ ├── verbs/ ← verb TTLs (a owl:ObjectProperty │ │ │ OR a rdfs:Class for askama-template verbs) - │ │ └── PROVENANCE.md ← per-domain source provenance (which - │ │ producer ran, which upstream input, - │ │ which Odoo/Medcare/etc. revision) + │ │ └── PROVENANCE.md ← per-domain: which producer ran, which + │ │ source input + revision, promotion status │ ├── ... └── PROVENANCE.md (this file) ``` -The layout intentionally mirrors `imports/ogit/` 1:1 so consumers -discovering both trees see one shape; the choice between -"upstream-mirrored" and "OGAR-produced" is the path prefix, nothing -else. +The layout mirrors `imports/ogit/` 1:1 so a promote step is a plain +`cp`/`git mv` into the fork at the same relative path. ## What lives here today -Empty. Producers haven't run yet; content populates as digests land: +Empty. Producers haven't staged anything yet; content populates as +digests run: -| Source | Producer (planned) | Lands at | +| Source | Producer | Stages at | |---|---|---| -| Odoo `addons/account/*` | `ruff_python_spo + ogar-from-ruff` | `exports/ogit/NTO/Accounting/` | +| Odoo `addons/account/*` | `ruff_python_spo + ogar-from-ruff` (frontend queued) | `exports/ogit/NTO/Accounting/` | | Odoo `addons/sale/*` | same | `exports/ogit/NTO/SalesDistribution/` | | Odoo `addons/stock/*` | same | `exports/ogit/NTO/Transport/` | | Odoo workflow `def action_*` | same (verb-as-class shape) | `exports/ogit/NTO//verbs/` | -| Medcare-rs domain types | `ruff_rust_spo + ogar-from-ruff` (queued) | `exports/ogit/NTO/Healthcare/` | +| Medcare-rs domain types | `ruff_rust_spo + ogar-from-ruff` (frontend queued) | `exports/ogit/NTO/Healthcare/` | | Medcare-rs MongoDB schemas | `ogar-from-schema` (XSD/JSON-Schema) | `exports/ogit/NTO/Healthcare/` | | Hand-authored OGAR Class views | direct authoring | `exports/ogit/NTO//` | -## Migration note — the 11 stranded Accounting files - -The current `vocab/imports/ogit/NTO/Accounting/` carries 11 TTLs -authored by a prior session (`dcterms:creator = "Claude -(AdaWorldAPI/lance-graph 3-hop optim)"`) sitting alongside 23 upstream -files by Viktor Voss. **Those 11 belong in `exports/ogit/NTO/Accounting/`** -— at re-vendor risk where they sit today. Migration is a separate -decision and a separate PR; the scaffold here doesn't move them yet. -The list: +## NOT a migration target — the 11 Accounting files are already promoted -``` -vocab/imports/ogit/NTO/Accounting/verbs/hasProductCategory.ttl -vocab/imports/ogit/NTO/Accounting/verbs/hasPickingType.ttl -vocab/imports/ogit/NTO/Accounting/verbs/hasFiscalCountry.ttl -vocab/imports/ogit/NTO/Accounting/attributes/productCategoryComplete.ttl -vocab/imports/ogit/NTO/Accounting/attributes/iso3166Alpha2.ttl -+ 6 more (run the dcterms:creator scan in - docs/OGIT-DOMAIN-LIFT-CATALOGUE.md § Verifying domain authorship - to list all 11) -``` - -## License + contribution - -OGAR repository license (see top-level `LICENSE`). Files here are -authored by OGAR — re-publishing back to OGIT upstream requires -explicit relicensing or arago/almato acceptance. +> **Correction (2026-06-22).** An earlier draft of this file claimed +> the 11 OGAR-produced TTLs in `vocab/imports/ogit/NTO/Accounting/` +> were "at re-vendor risk" and "belong in `exports/`". **That was +> wrong.** Those 11 files are committed to the **AdaWorldAPI/OGIT +> fork** (commit `c5dc1b8`, on `master`, pushed). `imports/` +> faithfully mirrors the fork, so re-vendor **preserves** them — there +> is no data-loss risk, and they are NOT a migration candidate. +> +> They are the worked example of a *completed* promotion: produced by +> a prior session, promoted to the fork, now correctly mirrored in +> `imports/`. Under the staging-tier model they belong exactly where +> they are. `exports/` is for content that has **not yet** made that +> trip. + +## License + promotion + +OGAR repository license (see top-level `LICENSE`) applies to content +**in this tree**. Promotion to the OGIT fork is the deliberate act +that moves a file into the fork's MIT-licensed store; it requires +committing to the fork (a separate repo, a separate PR) and is the +single auditable gate between OGAR-produced and OGIT-canonical. diff --git a/vocab/exports/ogit/README.md b/vocab/exports/ogit/README.md index 666a174..db19d6e 100644 --- a/vocab/exports/ogit/README.md +++ b/vocab/exports/ogit/README.md @@ -1,12 +1,15 @@ -# `vocab/exports/ogit/` — OGAR-produced TTL in OGIT-compatible shape +# `vocab/exports/ogit/` — OGAR's staging tier for OGIT-shaped TTL -Mirrors the upstream OGIT layout (`NTO//{entities,attributes,verbs}/`, -`SGO/sgo/verbs/`) so consumers see one shape across `imports/` and -`exports/`. The choice between "upstream-mirrored" and "OGAR-produced" -is the path prefix (`vocab/imports/ogit/` vs `vocab/exports/ogit/`), -nothing else. +Produced-but-not-yet-promoted content, in the upstream OGIT layout +(`NTO//{entities,attributes,verbs}/`, `SGO/sgo/verbs/`). A +producer stages a digest here; once reviewed (round-trip + bijection +tests, drift check, human read), it is **promoted** to the +AdaWorldAPI/OGIT fork and re-vendored into `vocab/imports/`. -See `vocab/exports/PROVENANCE.md` for the split rationale (re-vendor -safety, license/governance, upstream-contribution path) and the -migration note on the 11 stranded Accounting files currently sitting -in `imports/`. +**Consumers read `imports/`, never `exports/`.** This tree is the +pre-promotion workbench. + +See `vocab/exports/PROVENANCE.md` for the full staging-tier model, why +the fork is the enriched canonical store, and the correction on the 11 +Accounting files (already promoted via OGIT fork commit `c5dc1b8` — +NOT a migration target).