Skip to content
Open
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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ jobs:
env:
RUSTDOCFLAGS: "-D warnings"

package:
name: cargo package --list
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: install stable toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_STABLE_VER }}

- name: cargo package --list
run: |
cargo package -p addressable --locked --list >/dev/null
cargo package -p addressable_tree --locked --list >/dev/null

typos:
name: typos
runs-on: ubuntu-latest
Expand Down
91 changes: 62 additions & 29 deletions PLANS.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,73 @@
# Addressable tree runtime consumer slice
# Addressable 0.1 release evidence

## Goal

Turn the first real Exedra consumer into subtraction by moving reusable rooted
tree resolution and query execution into a small `no_std + alloc`
`addressable_tree` crate. Exedra should retain its storage and domain policies
while deleting its custom path type, recursive path lookup, and consumer-local
assembly-query executor. Preserve the revision clock across extraction, and
make in-place commits the normal mutation path.
Prepare `addressable` and `addressable_tree` for a first `0.1.0` release only
after their public contracts have survived independent consumer use. Bring
forward API corrections that concrete consumers expose, then package the two
reusable crates without publishing, tagging, or landing consumer branches.

## Fence

Addressable owns durable addressing and shared interaction semantics; it
explicitly does not own consumer storage, UI state, presence reduction,
collaboration algorithms, or composition policy.

## Non-goals

- A compulsory storage engine or index.
- Generic endpoint value or mutation traits before a second domain proves them.
- Async execution, persistence, or a textual query language.
- Publishing crates, creating a release, or merging consumer work.
- Generalizing the reference-specific tooling adapter without a second real
schema-backed adapter.
- Adding a textual query language, universal evaluator, collaboration model,
or speculative revision branches.
- Counting an adapter as evidence merely because its types compile.

## Evidence sequence

1. Audit the two proposed release crates for public invariants, documentation,
package contents, and commitments that known near-term work would overturn.
2. Adapt Overstory's retained inspection tree to `addressable_tree`. Require the
integration to replace traversal or selection glue and demonstrate rich
resolution, pins, or budgeted queries against real snapshots.
3. Adapt a Layerstack composed stage without moving interned path, storage, or
composition ownership. Require it to expose a genuine tree-host seam and to
preserve Layerstack's path semantics.
4. Explore a Ruthere presence facet that carries current Addressable focus. Keep
presence and collaboration separate, and retain this consumer only if it
exercises locator or pin semantics rather than adding decorative wrapping.
5. Fold only consumer-earned corrections into Addressable. Record meaningful
public semantic changes in an ADR and migration note.
6. Prepare release notes and package metadata for `addressable` and
`addressable_tree`; keep the reference, tooling, and tour packages
unpublished.
7. Run package inspection plus the full workspace gates, review the resulting
API and consumer diffs, and open draft or review-ready PRs without merging.

## Steps
## Evidence so far

1. Define a host-owned node projection trait and reusable tree runtime.
2. Prove exact, relative, pinned, cardinality, budget, deduplication, handle,
suspend/resume, and in-place commit behavior in tests and rustdoc.
3. Make the Basilica assembly projection a second `TreeHost`; retain its
dependency-specific evaluator only for graph and cross-view axes.
4. Replace Exedra's `InstancePath` machinery with structured Addressable exact
addresses and a host-owned index.
5. Implement the small tree projection in `exedra_assembly`, retain its material
explanation/edit policy, and remove Basilica-specific resolution/selection
helpers.
6. Validate and submit the Addressable and Exedra changes as separate PRs.
- Overstory can borrow a retained inspection snapshot at its existing revision
and resolve, query, budget, pin, and recover generational handles. The adapter
is additive and does not replace Overstory's topology-aware live outline
patch, so it is evidence for the core API rather than a consumer PR yet.
- Layerstack can borrow a composed `Stage` without leaking `PathId` into durable
identity. It exposed the need for host-reported predicate work: composed
field matching now charges one unit to find the field stack plus one per
opinion.
- Ruthere can carry a typed pin as an application-owned presence facet through
its real visibility, replacement, cursor, and expiry behavior. It exposed
unsafe manual pin construction and the need to state that current `SpaceId`
text is runtime-scoped. Addressable does not absorb Ruthere presence or any
collaboration algorithm.

## Risks

- A trait shaped too narrowly around Exedra. Prove the assembly seam against
both Exedra and the Basilica reference domain while leaving Basilica's graph
axes domain-owned.
- Runtime mutation bypassing revisions. Expose immutable host access, preserve
the clock on extraction, and provide an in-place commit that advances once.
- Treating exact address text as domain storage. Hosts store structured
`AbsoluteAddress` values; string forms remain serialization only.
- A UI-tree or USD-tree adapter may accidentally make Addressable own labels,
storage, or domain traversal policy. Keep those decisions in the host.
- Runtime `SpaceId` values may be mistaken for durable cross-process space
names when locators enter presence or tooling payloads. Either make that
lifetime explicit or add a consumer-earned durable envelope before release.
- Existing reference and tooling crates demonstrate breadth but are not yet
reusable production boundaries. Do not publish them or describe their
reference-specific schemas as a stable generic protocol.
- Consumer branches can become dependency tangles. Use adapters and examples,
preserve one-way dependencies, and avoid cross-consumer coupling.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,13 @@ on the workflow types use the same call paths and run as doctests.
traversal budgets are explicit.
- Pinned resolution reports stale, moved, or rebound outcomes instead of
silently accepting a different referent.
- `Pinned::from_location` captures exact address, referent, and revision from
one observation. `SpaceId` and textual locator/pin forms are runtime-scoped,
not durable cross-process names.
- Guarded transactions validate every operation before applying any operation.
- Replaying a query delta produces the same snapshot as full recomputation;
another space or live-query stream is rejected atomically.
another space, live-query stream, regressing revision, or unclocked change is
rejected atomically.
- Correspondence preserves one-to-many mappings and provenance, and composed
mapping legs cannot disagree about their connecting source.
- Dynamic tooling recovers a declared schema and uses the same typed guarded
Expand Down
57 changes: 35 additions & 22 deletions STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
## Current state

The complete initial vertical slice landed on `main` on 2026-08-24. No crate
has been tagged or published.
has been tagged or published. `addressable` and `addressable_tree` are now the
proposed first `0.1.0` release crates; the reference, tooling, and tour packages
remain internal proofs.

The workspace contains five packages:

Expand All @@ -29,8 +31,10 @@ The reference slice exercises every lifecycle item required by the initial
architecture:

1. One arch referent has distinct north and south assembly occurrences.
2. Exact, relative, and pinned locators have canonical round-trip documents and
resolve with rich outcomes; pinned rebinding has a regression test.
2. Exact and relative locators have delimiter-safe runtime-scoped textual
round trips. Pins are constructed from one resolved location, reject
cross-space text, and resolve with rich outcomes; pinned rebinding has a
regression test.
3. Typed queries cross explicitly between assembly and dependency views. Query
cardinality is restricted to the sealed `One`, `Optional`, and `Many`
markers. Ordering, deduplication, cycle policy, and four work budgets are
Expand All @@ -44,7 +48,8 @@ architecture:
revision, value, and capability preconditions, and return undo information.
7. Query deltas are replayed and compared with full recomputation. Replay
rejects another space, live-query stream, or cross-space transition without
partial effect.
partial effect. Revisions cannot move backward or carry changes without
advancing; an empty same-revision poll remains valid.
8. One arch referent maps to two independently addressable catalog results while
retaining correspondence evidence.
9. The dynamic adapter declares its view/facet/value schema, reconstructs typed
Expand Down Expand Up @@ -81,8 +86,9 @@ The contracts are real; the first execution is intentionally modest:
- `addressable_tree` deliberately covers rooted canonical-address trees only;
other relationship views keep specialized evaluators;
- tree hosts yield projected nodes lazily, can index referent occurrences, and
use ordered sets for cycle detection and deduplication;
- runtime extraction preserves the revision needed by `resume`, while
use ordered sets for cycle detection and deduplication; predicate matching
reports host-defined work charged against the query budget;
- runtime extraction preserves the revision needed by `from_revision`, while
validated in-place commits advance the clock without cloning a whole host.

These are replaceable host choices, not placeholders in the core semantic
Expand All @@ -106,22 +112,29 @@ cargo +1.88 check -p addressable -p addressable_tree --locked --target x86_64-un
cargo run -p addressable_tour --locked
```

Results: 26 unit tests and 16 doctests pass; strict Clippy and warning-denied
rustdoc pass; native stable, Rust 1.88, bare-metal `no_std`, and WebAssembly
core checks pass; repository formatting, typo, SPDX-header, and whitespace
checks pass.

## Repository decisions retained by the owner

All packages remain `publish = false`. No merge, release, publication, or
sibling-repository edit was performed. The repository includes the standard
forest-rs Apache-2.0 and MIT license texts matching its workspace metadata.
Results: 37 unit tests and 18 doctests or compile-fail laws pass; strict Clippy
and warning-denied rustdoc pass; native stable, Rust 1.88, bare-metal `no_std`,
and WebAssembly core checks pass; repository formatting, typo, SPDX-header, and
whitespace checks pass. `addressable` verifies from its packaged archive; both
proposed release crates produce registry-normalized archives containing their
README, changelog, and Apache-2.0/MIT license texts.

## Next architectural evidence

The Exedra consumer exposed a genuine shared host seam, and the Basilica
assembly view now proves it against a second storage model. An outline/tree UI
is a credible next consumer: occurrence-aware rows, stable addresses, ordering,
budgets, and multiple views already fit. Pull live row deltas, lazy ranges, or
other execution machinery forward only when that consumer supplies concrete
behavior and deletion.
The Exedra consumer exposed a genuine shared host seam, and Basilica proves it
against a second storage model. Three isolated consumer experiments sharpened
the release boundary further:

- an Overstory inspection snapshot borrows into the tree runtime at its own
revision, but its topology-aware live outline patch should not be replaced by
the flat generic delta;
- a Layerstack composed stage keeps storage, path interning, and composition
policy while reporting real opinion-resolution work to query budgets;
- a Ruthere presence facet carries a typed focus pin through visibility,
replacement, cursors, and expiry without making Addressable own presence or
collaboration.

These are evidence branches, not automatic integration candidates: the
Overstory and Layerstack adapters currently add inspection capability without
deleting consumer code. Durable cross-process space naming remains deliberately
unclaimed until a transport consumer can prove its envelope.
15 changes: 15 additions & 0 deletions crates/addressable/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Changelog

## 0.1.0 - 2026-08-27

Initial release of the typed `no_std + alloc` vocabulary:

- structured absolute and relative addresses, locators, locations, pins, and
runtime-scoped revisions;
- explicit query cardinality, ordering, deduplication, cycle policy, and
traversal budgets;
- exhaustive rich resolution outcomes and revision-scoped resolved handles;
- typed endpoints, explanations, guards, transactions, replayable live-query
deltas, and evidence-preserving correspondence;
- atomic delta replay rejects cross-space transitions, revision regression, and
unclocked changes while preserving empty same-revision polls.
7 changes: 6 additions & 1 deletion crates/addressable/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "Typed no_std vocabulary for addressable structured object spaces"
readme = "README.md"
keywords = ["address", "graph", "no-std", "query"]
categories = ["data-structures", "no-std"]
publish = false

[lints]
workspace = true

[package.metadata.docs.rs]
all-features = true
default-target = "x86_64-unknown-linux-gnu"
targets = []
Loading