Skip to content

Commit 5d29a22

Browse files
authored
Merge pull request #152 from AdaWorldAPI/claude/medcare-bridge-lance-graph-wmx76z
OSM Rails → OGAR transpile: THINK structs, Geo codebook, DO-arm action rail, map mapping
2 parents 4037e88 + 58a64d4 commit 5d29a22

71 files changed

Lines changed: 5729 additions & 18 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
**/*.rs.bk
3+
Cargo.lock
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[workspace]
2+
resolver = "2"
3+
members = ["crates/osm-domain"]
4+
5+
[workspace.package]
6+
edition = "2021"
7+
license = "GPL-2.0-or-later"
8+
repository = "https://github.com/AdaWorldAPI/openstreetmap-website-rs"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# OSM transpile — status of the three autoattended next-steps (2026-07-04)
2+
3+
## ✅ 1. classid mint — DONE (OGAR side)
4+
5+
Allocated **`ConceptDomain::Geo` (`0x0FXX`)** in `ogar-vocab` and minted the 10
6+
OSM geodata concepts: `osm_node` `0x0F01`, `osm_way` `0x0F02`, `osm_relation`
7+
`0x0F03`, `osm_changeset` `0x0F04`, `osm_element_tag` `0x0F05`,
8+
`osm_relation_member` `0x0F06`, `osm_way_node` `0x0F07`, `osm_note` `0x0F08`,
9+
`osm_gpx_trace` `0x0F09`, `osm_user` `0x0F0A`.
10+
11+
Full codebook contract satisfied (all `ogar-vocab` tests green, 96):
12+
`CODEBOOK` + `class_ids::{consts,ALL}` + `all_promoted_classes()` constructors +
13+
`ConceptDomain::Geo` + `canonical_concept_domain(0x0F)` + `COUNT_FUSE` pin
14+
`68→78`.
15+
16+
The render now emits `CLASS_ID` for the 20 grounded geodata files
17+
(`Node → 0x0F01`, …) via the Rails-name→concept grounding map in
18+
`render_osm.rs`.
19+
20+
### ⏳ Sequenced follow-up (post-merge, NOT doable now)
21+
22+
The **lance-graph mirror** (`lance-graph-contract::ogar_codebook::CODEBOOK`) +
23+
`lance-graph-ogar::parity::COUNT_FUSE` must be bumped `68→78` **after** this
24+
OGAR `ogar-vocab` change merges to OGAR `main` — because `lance-graph-ogar`'s
25+
`COUNT_FUSE` is a compile-time assert `contract::CODEBOOK.len() ==
26+
ogar_vocab::class_ids::ALL.len()`, and lance-graph pulls `ogar_vocab` via **git
27+
main** (still 68). Bumping the mirror first would break that assert against the
28+
unmerged ogar-vocab. This is the E-CODEBOOK-MINT-IS-A-CROSS-REPO-ARC lockstep.
29+
30+
**Operator:** confirm the `0x0F` / Geo domain allocation before merge.
31+
32+
## ✅ 2. lance-graph wiring — DONE (manifest)
33+
34+
`harvest/osm_graph.spo` — the OSM association graph as **154 classid-keyed SPO
35+
edges**. node/way/relation is a graph; each grounded subject carries its
36+
`CLASS_ID` and every association is an edge to a target concept (classid where
37+
the target grounds), e.g.:
38+
39+
```
40+
osm_node[0x0F01] --BelongsTo:changeset--> changeset[0x0F04]
41+
osm_node[0x0F01] --HasMany:element_tags--> NodeTag[0x0F05]
42+
osm_node[0x0F01] --HasMany:containing_relations--> Relation[0x0F03]
43+
osm_changeset[0x0F04] --BelongsTo:user--> user[0x0F0A]
44+
```
45+
46+
Targets shown `[----]` are ungrounded (plural relation names that don't
47+
normalise to a minted concept, or non-geodata app entities) — an honest gap in
48+
the simple grounding, not a lift error. This manifest is the feed a
49+
`lance-graph` graph loader consumes.
50+
51+
## ⛔ 3. DO-arm methods — CAPABILITY GAP (honestly scoped, not faked)
52+
53+
The render *supports* behaviour methods — `render_class_with_methods(class,
54+
mask, actions: &[ActionDef])` lifts each `ActionDef` into a struct method. But
55+
**there are no `ActionDef`s to pass**:
56+
57+
- `ruff_ruby_spo::extract` walks **`app/models` only**; `app/controllers` (where
58+
Rails request behaviour lives) is never parsed.
59+
- The `Class` IR carries `associations` / `enums` / `mixins` / `attributes`
60+
**no methods / callbacks / actions field**.
61+
62+
So the DO-arm is empty by construction today. Closing it needs a **new
63+
capability**: a Ruby controller/action harvester (`ruff_ruby_spo` extended to
64+
`app/controllers`, or a `ruff_ruby_action_spo`) that lifts controller actions →
65+
`ActionDef { predicate, object_class, body_source, on_enter }`. That is a ruff
66+
feature, filed as the honest next brick — not something to synthesise from the
67+
model tree.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# PARKED — belongs in `AdaWorldAPI/openstreetmap-website-rs`
2+
3+
This tree is the ruff → OGAR transcode of `openstreetmap/openstreetmap-website`
4+
(Rails). Its real home is the empty repo **`AdaWorldAPI/openstreetmap-website-rs`**.
5+
6+
It is parked here **only** because that repo is not in this session's write
7+
allowlist: `git clone`/`fetch` of it succeed, but `git push` returns `403`
8+
(the GUI "add repository to current session" did not update the proxy
9+
allowlist — a backend bug). Pushing to an in-scope repo (OGAR) is the durable
10+
save until the target repo becomes writable.
11+
12+
## Relocation (when `openstreetmap-website-rs` is in scope)
13+
14+
```sh
15+
git clone <proxy>/AdaWorldAPI/openstreetmap-website-rs /tmp/osm-rs
16+
cp -r harvest/osm-website-rs/. /tmp/osm-rs/ # (excluding this PARKED.md)
17+
cd /tmp/osm-rs && git add -A && git commit && git push
18+
```
19+
20+
## Provenance
21+
22+
| Input | Pin |
23+
|---|---|
24+
| OSM source (`openstreetmap/openstreetmap-website`) | `173885c17d91c4a2ceb70f7a4e911f2b250628ef` |
25+
| ruff (`AdaWorldAPI/ruff`) | `61ce2b490fc3c432d36c44eceed08125f838b405` |
26+
| OGAR | `4037e88` |
27+
28+
Regenerate the IR with the harvest driver committed alongside:
29+
`cargo run -p ogar-from-rails --example harvest_osm -- <osm-website-root> --ir`.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# openstreetmap-website-rs
2+
3+
A Rust transcode of [`openstreetmap/openstreetmap-website`](https://github.com/openstreetmap/openstreetmap-website)
4+
(Ruby on Rails) produced through the **ruff → OGAR** transpile pipeline.
5+
6+
The Ruby source is canonical; this repo is the target. The domain model is
7+
harvested mechanically from the Rails `app/models` tree — not hand-ported — so
8+
the Rust structure tracks the Ruby structure by construction.
9+
10+
## Pipeline
11+
12+
```
13+
openstreetmap-website/app/models/*.rb (Ruby, canonical)
14+
│ ruff_ruby_spo::extract
15+
16+
ruff_spo_triplet::ModelGraph (language-agnostic IR)
17+
│ ogar_from_ruff::lift_model_graph
18+
19+
Vec<ogar_vocab::Class> (OGAR canonical vocab — the transpile)
20+
│ render (ogar-render-askama → Rust struct + methods) [next]
21+
22+
crates/osm-domain/ (Rust domain types)
23+
```
24+
25+
The node / way / relation / changeset / tag model is a graph, so the harvested
26+
`Class` set drops directly onto `lance-graph`.
27+
28+
## Status
29+
30+
-**Harvest** — 50 classes lifted from real OSM source. Full IR in
31+
[`harvest/osm_ir.txt`](harvest/osm_ir.txt) (associations, mixins, STI parents).
32+
-**Render** — all 50 `Class`es rendered to Rust in
33+
[`crates/osm-domain/src/generated/`](crates/osm-domain/src/generated/) via
34+
`ogar-render-askama` (`render_class_with_methods`): associations become typed
35+
edge fields (`belongs_to → Option<u64>`, `has_many → Vec<u64>`) + a `new(..)`
36+
constructor. **Compiles + tests green** (`cargo build` / `cargo test`).
37+
Regenerate: `cargo run -p ogar-render-askama --example render_osm -- <osm-root> <out>`.
38+
-**Next** — classid mint (OSM concepts into the codebook so `CLASS_ID`
39+
emits), `ActionDef` DO-arm (behaviour methods) once controller/model actions
40+
are harvested, and lance-graph wiring (node/way/relation as a graph).
41+
42+
## Provenance (regenerate deterministically)
43+
44+
| Input | Pin |
45+
|---|---|
46+
| OSM source (`openstreetmap/openstreetmap-website`) | `173885c17d91c4a2ceb70f7a4e911f2b250628ef` |
47+
| ruff (`AdaWorldAPI/ruff`) | `61ce2b490fc3c432d36c44eceed08125f838b405` |
48+
| OGAR (`AdaWorldAPI/OGAR`) | `4037e88` |
49+
50+
Harvest driver: `ogar-from-rails/examples/harvest_osm.rs`
51+
`cargo run -p ogar-from-rails --example harvest_osm -- <osm-website-root> --ir`.
52+
53+
## The 50 harvested classes
54+
55+
Core geodata: `Node` `Way` `Relation` `Changeset` + `*Tag` / `RelationMember` /
56+
`WayNode` + the `Old*` versioned mirrors. Plus `User` (the 32-association hub),
57+
`Note` / `Trace` / `DiaryEntry` / `Message` / `Issue` and their comment /
58+
subscription satellites. See `harvest/osm_ir.txt` for the complete graph.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "osm-domain"
3+
version = "0.0.0"
4+
edition.workspace = true
5+
license.workspace = true
6+
repository.workspace = true
7+
description = "OSM domain types, transcoded from openstreetmap-website Rails app/models via the ruff → OGAR pipeline."
8+
9+
[dependencies]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @generated by ogar-render-askama — ruff → OGAR transpile
2+
// source class: Acl (openstreetmap-website app/models)
3+
4+
5+
6+
7+
8+
//! `Acl` — canonical class generated from `ogar_vocab::acl()`.
9+
//! Fields are the ClassView × FieldMask projection; methods are the OGAR
10+
//! `ActionDef` DO-arm (behaviour is Rust, never SurrealQL DDL).
11+
//! DO NOT EDIT BY HAND. Re-render via `ogar-render-askama`.
12+
13+
/// Canonical concept name as in the OGAR codebook.
14+
pub const CANONICAL_CONCEPT: &str = "acl";
15+
16+
#[derive(Debug, Clone, Default, PartialEq)]
17+
pub struct Acl {
18+
}
19+
20+
impl Acl {
21+
22+
/// Struct-of-methods constructor over the ClassView × FieldMask field set.
23+
pub fn new() -> Self {
24+
Self { }
25+
}
26+
}

0 commit comments

Comments
 (0)