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
3 changes: 3 additions & 0 deletions .claude/harvest/osm-website-rs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock
8 changes: 8 additions & 0 deletions .claude/harvest/osm-website-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[workspace]
resolver = "2"
members = ["crates/osm-domain"]

[workspace.package]
edition = "2021"
license = "GPL-2.0-or-later"
repository = "https://github.com/AdaWorldAPI/openstreetmap-website-rs"
67 changes: 67 additions & 0 deletions .claude/harvest/osm-website-rs/NEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# OSM transpile — status of the three autoattended next-steps (2026-07-04)

## ✅ 1. classid mint — DONE (OGAR side)

Allocated **`ConceptDomain::Geo` (`0x0FXX`)** in `ogar-vocab` and minted the 10
OSM geodata concepts: `osm_node` `0x0F01`, `osm_way` `0x0F02`, `osm_relation`
`0x0F03`, `osm_changeset` `0x0F04`, `osm_element_tag` `0x0F05`,
`osm_relation_member` `0x0F06`, `osm_way_node` `0x0F07`, `osm_note` `0x0F08`,
`osm_gpx_trace` `0x0F09`, `osm_user` `0x0F0A`.

Full codebook contract satisfied (all `ogar-vocab` tests green, 96):
`CODEBOOK` + `class_ids::{consts,ALL}` + `all_promoted_classes()` constructors +
`ConceptDomain::Geo` + `canonical_concept_domain(0x0F)` + `COUNT_FUSE` pin
`68→78`.

The render now emits `CLASS_ID` for the 20 grounded geodata files
(`Node → 0x0F01`, …) via the Rails-name→concept grounding map in
`render_osm.rs`.

### ⏳ Sequenced follow-up (post-merge, NOT doable now)

The **lance-graph mirror** (`lance-graph-contract::ogar_codebook::CODEBOOK`) +
`lance-graph-ogar::parity::COUNT_FUSE` must be bumped `68→78` **after** this
OGAR `ogar-vocab` change merges to OGAR `main` — because `lance-graph-ogar`'s
`COUNT_FUSE` is a compile-time assert `contract::CODEBOOK.len() ==
ogar_vocab::class_ids::ALL.len()`, and lance-graph pulls `ogar_vocab` via **git
main** (still 68). Bumping the mirror first would break that assert against the
unmerged ogar-vocab. This is the E-CODEBOOK-MINT-IS-A-CROSS-REPO-ARC lockstep.

**Operator:** confirm the `0x0F` / Geo domain allocation before merge.

## ✅ 2. lance-graph wiring — DONE (manifest)

`harvest/osm_graph.spo` — the OSM association graph as **154 classid-keyed SPO
edges**. node/way/relation is a graph; each grounded subject carries its
`CLASS_ID` and every association is an edge to a target concept (classid where
the target grounds), e.g.:

```
osm_node[0x0F01] --BelongsTo:changeset--> changeset[0x0F04]
osm_node[0x0F01] --HasMany:element_tags--> NodeTag[0x0F05]
osm_node[0x0F01] --HasMany:containing_relations--> Relation[0x0F03]
osm_changeset[0x0F04] --BelongsTo:user--> user[0x0F0A]
```

Targets shown `[----]` are ungrounded (plural relation names that don't
normalise to a minted concept, or non-geodata app entities) — an honest gap in
the simple grounding, not a lift error. This manifest is the feed a
`lance-graph` graph loader consumes.

## ⛔ 3. DO-arm methods — CAPABILITY GAP (honestly scoped, not faked)

The render *supports* behaviour methods — `render_class_with_methods(class,
mask, actions: &[ActionDef])` lifts each `ActionDef` into a struct method. But
**there are no `ActionDef`s to pass**:

- `ruff_ruby_spo::extract` walks **`app/models` only**; `app/controllers` (where
Rails request behaviour lives) is never parsed.
- The `Class` IR carries `associations` / `enums` / `mixins` / `attributes` —
**no methods / callbacks / actions field**.

So the DO-arm is empty by construction today. Closing it needs a **new
capability**: a Ruby controller/action harvester (`ruff_ruby_spo` extended to
`app/controllers`, or a `ruff_ruby_action_spo`) that lifts controller actions →
`ActionDef { predicate, object_class, body_source, on_enter }`. That is a ruff
feature, filed as the honest next brick — not something to synthesise from the
model tree.
29 changes: 29 additions & 0 deletions .claude/harvest/osm-website-rs/PARKED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# PARKED — belongs in `AdaWorldAPI/openstreetmap-website-rs`

This tree is the ruff → OGAR transcode of `openstreetmap/openstreetmap-website`
(Rails). Its real home is the empty repo **`AdaWorldAPI/openstreetmap-website-rs`**.

It is parked here **only** because that repo is not in this session's write
allowlist: `git clone`/`fetch` of it succeed, but `git push` returns `403`
(the GUI "add repository to current session" did not update the proxy
allowlist — a backend bug). Pushing to an in-scope repo (OGAR) is the durable
save until the target repo becomes writable.

## Relocation (when `openstreetmap-website-rs` is in scope)

```sh
git clone <proxy>/AdaWorldAPI/openstreetmap-website-rs /tmp/osm-rs
cp -r harvest/osm-website-rs/. /tmp/osm-rs/ # (excluding this PARKED.md)
cd /tmp/osm-rs && git add -A && git commit && git push
```

## Provenance

| Input | Pin |
|---|---|
| OSM source (`openstreetmap/openstreetmap-website`) | `173885c17d91c4a2ceb70f7a4e911f2b250628ef` |
| ruff (`AdaWorldAPI/ruff`) | `61ce2b490fc3c432d36c44eceed08125f838b405` |
| OGAR | `4037e88` |

Regenerate the IR with the harvest driver committed alongside:
`cargo run -p ogar-from-rails --example harvest_osm -- <osm-website-root> --ir`.
58 changes: 58 additions & 0 deletions .claude/harvest/osm-website-rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# openstreetmap-website-rs

A Rust transcode of [`openstreetmap/openstreetmap-website`](https://github.com/openstreetmap/openstreetmap-website)
(Ruby on Rails) produced through the **ruff → OGAR** transpile pipeline.

The Ruby source is canonical; this repo is the target. The domain model is
harvested mechanically from the Rails `app/models` tree — not hand-ported — so
the Rust structure tracks the Ruby structure by construction.

## Pipeline

```
openstreetmap-website/app/models/*.rb (Ruby, canonical)
│ ruff_ruby_spo::extract
ruff_spo_triplet::ModelGraph (language-agnostic IR)
│ ogar_from_ruff::lift_model_graph
Vec<ogar_vocab::Class> (OGAR canonical vocab — the transpile)
│ render (ogar-render-askama → Rust struct + methods) [next]
crates/osm-domain/ (Rust domain types)
```

The node / way / relation / changeset / tag model is a graph, so the harvested
`Class` set drops directly onto `lance-graph`.

## Status

- ✅ **Harvest** — 50 classes lifted from real OSM source. Full IR in
[`harvest/osm_ir.txt`](harvest/osm_ir.txt) (associations, mixins, STI parents).
- ✅ **Render** — all 50 `Class`es rendered to Rust in
[`crates/osm-domain/src/generated/`](crates/osm-domain/src/generated/) via
`ogar-render-askama` (`render_class_with_methods`): associations become typed
edge fields (`belongs_to → Option<u64>`, `has_many → Vec<u64>`) + a `new(..)`
constructor. **Compiles + tests green** (`cargo build` / `cargo test`).
Regenerate: `cargo run -p ogar-render-askama --example render_osm -- <osm-root> <out>`.
- ⏳ **Next** — classid mint (OSM concepts into the codebook so `CLASS_ID`
emits), `ActionDef` DO-arm (behaviour methods) once controller/model actions
are harvested, and lance-graph wiring (node/way/relation as a graph).

## Provenance (regenerate deterministically)

| Input | Pin |
|---|---|
| OSM source (`openstreetmap/openstreetmap-website`) | `173885c17d91c4a2ceb70f7a4e911f2b250628ef` |
| ruff (`AdaWorldAPI/ruff`) | `61ce2b490fc3c432d36c44eceed08125f838b405` |
| OGAR (`AdaWorldAPI/OGAR`) | `4037e88` |

Harvest driver: `ogar-from-rails/examples/harvest_osm.rs` —
`cargo run -p ogar-from-rails --example harvest_osm -- <osm-website-root> --ir`.

## The 50 harvested classes

Core geodata: `Node` `Way` `Relation` `Changeset` + `*Tag` / `RelationMember` /
`WayNode` + the `Old*` versioned mirrors. Plus `User` (the 32-association hub),
`Note` / `Trace` / `DiaryEntry` / `Message` / `Issue` and their comment /
subscription satellites. See `harvest/osm_ir.txt` for the complete graph.
9 changes: 9 additions & 0 deletions .claude/harvest/osm-website-rs/crates/osm-domain/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "osm-domain"
version = "0.0.0"
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "OSM domain types, transcoded from openstreetmap-website Rails app/models via the ruff → OGAR pipeline."

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @generated by ogar-render-askama — ruff → OGAR transpile
// source class: Acl (openstreetmap-website app/models)





//! `Acl` — canonical class generated from `ogar_vocab::acl()`.
//! Fields are the ClassView × FieldMask projection; methods are the OGAR
//! `ActionDef` DO-arm (behaviour is Rust, never SurrealQL DDL).
//! DO NOT EDIT BY HAND. Re-render via `ogar-render-askama`.

/// Canonical concept name as in the OGAR codebook.
pub const CANONICAL_CONCEPT: &str = "acl";

#[derive(Debug, Clone, Default, PartialEq)]
pub struct Acl {
}

impl Acl {

/// Struct-of-methods constructor over the ClassView × FieldMask field set.
pub fn new() -> Self {
Self { }
}
}
Loading
Loading