feat(views): wire derived views onto InformationSpace + integration (WP-0010 T5)

Expose backlinks(name), recent_changes(), all_pages(), site_map() on
InformationSpace. Integration test exercises all four over two shards (BackLinks
aggregate across shards, AllPages/SiteMap span the union, RecentChanges merges an
alias decision with shard edits). SCOPE updated; WP-0010 done. 152 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 02:05:12 +02:00
parent 3a5acdcb28
commit d85d019543
4 changed files with 87 additions and 7 deletions

View File

@@ -17,7 +17,7 @@ Learnings update both SCOPE and INTENT where necessary.
| Layer | State |
|-------|-------|
| Code | Foundation slice implemented (SHARD-WP-0007): `provenance` + `policy` leaves, `model` (Identity/Placement/Span/Page/CapabilityProfile), `adapters` (contract + FolderAdapter + conformance suite), `coordination` (event-sourced DecisionLog), `union` (resolution + chorus, overlay-aware), `InformationSpace` orchestrator. Write path added (SHARD-WP-0008): writable adapter, overlay engine (draft→patch→apply-under-drift), edit() unifies write-through + overlay-before-mutation. Native engine implemented (SHARD-WP-0014): `engine` (kernel + typed-extension runtime + per-shard activation [ADR-0001] + capability-profile-from-extensions + EngineShardAdapter + the `ext.struct` built-in) — an engine shard attaches to an InformationSpace as a canonical-mode shard. Git-backed coordination log (SHARD-WP-0009): `DecisionLog` storage factored behind an `EventStore`; `GitEventStore` makes the log git-addressable (each space a ref, append = immutable CAS-guarded commit), a per-space `AppendAuthority` (lease) gives a single-writer total order with re-grantable HA hand-off, cross-process read-your-writes verified, and a verbatim one-time importer (`migrate_space`/JSONL) replays in-memory logs into git; `InformationSpace.git_backed(...)` wires it. 128 tests green, ~97% coverage |
| Code | Foundation slice implemented (SHARD-WP-0007): `provenance` + `policy` leaves, `model` (Identity/Placement/Span/Page/CapabilityProfile), `adapters` (contract + FolderAdapter + conformance suite), `coordination` (event-sourced DecisionLog), `union` (resolution + chorus, overlay-aware), `InformationSpace` orchestrator. Write path added (SHARD-WP-0008): writable adapter, overlay engine (draft→patch→apply-under-drift), edit() unifies write-through + overlay-before-mutation. Native engine implemented (SHARD-WP-0014): `engine` (kernel + typed-extension runtime + per-shard activation [ADR-0001] + capability-profile-from-extensions + EngineShardAdapter + the `ext.struct` built-in) — an engine shard attaches to an InformationSpace as a canonical-mode shard. Git-backed coordination log (SHARD-WP-0009): `DecisionLog` storage factored behind an `EventStore`; `GitEventStore` makes the log git-addressable (each space a ref, append = immutable CAS-guarded commit), a per-space `AppendAuthority` (lease) gives a single-writer total order with re-grantable HA hand-off, cross-process read-your-writes verified, and a verbatim one-time importer (`migrate_space`/JSONL) replays in-memory logs into git; `InformationSpace.git_backed(...)` wires it. Derived views (SHARD-WP-0010): `views` (wikilink + red-link model, BackLinks, RecentChanges, AllPages/SiteMap) — recomputable, provenance-carrying, presentation-free, exposed via `InformationSpace.backlinks/recent_changes/all_pages/site_map`. 152 tests green, ~97% coverage |
| Intent | `INTENT.md` established; authorization-in-core amendments drafted |
| Research | yawex prior art; c2 origins; federation concepts; wikiengines overview (`research/260608-*/`); XWiki/TWiki/Foswiki deep dives (`research/260613-*/`); Xanadu + ZigZag + Roam + Obsidian + Notion + Joplin + Logseq + local-first workspaces (Anytype/AFFiNE/AppFlowy) + Trilium + Wiki.js + Federated Wiki + Wikibase + git-forge wikis + TiddlyWiki + ikiwiki + Quip + MojoMojo + Oddmuse + UseModWiki deep dives & shard-spectrum synthesis (`research/260614-*/`) |
| Demand | NetKingdom integration asks captured, not yet negotiated |

View File

@@ -23,6 +23,16 @@ from shard_wiki.coordination import (
from shard_wiki.model import Page
from shard_wiki.policy import DEFAULT_POLICY, Policy
from shard_wiki.union import Resolution, UnionGraph
from shard_wiki.views import (
AllPagesEntry,
BackLink,
ChangeEntry,
SiteMapNode,
all_pages,
build_backlinks,
recent_changes,
site_map,
)
__all__ = ["InformationSpace"]
@@ -92,3 +102,21 @@ class InformationSpace:
draft as local truth (I-5: overlay before mutation, always)."""
overlay = self.overlay(name, body, actor=actor)
return self.apply_overlay(overlay.overlay_id)
# --- derived views (SHARD-WP-0010): recomputable, provenance-carrying, presentation-free ---
def backlinks(self, name: str, *, camelcase: bool = False) -> tuple[BackLink, ...]:
"""Pages across the union that link to ``name`` (UC-18)."""
return build_backlinks(self.union, camelcase=camelcase).to(name)
def recent_changes(self, *, limit: int | None = None) -> tuple[ChangeEntry, ...]:
"""The merged newest-first change feed: coordination journal + shard signals (UC-17)."""
return recent_changes(self.union, self.log, self.space_id, limit=limit)
def all_pages(self) -> tuple[AllPagesEntry, ...]:
"""The union's distinct pages, chorus/equivalence-collapsed with divergence noted."""
return all_pages(self.union)
def site_map(self) -> SiteMapNode:
"""The union namespace tree built from page placements."""
return site_map(self.union)

View File

@@ -0,0 +1,52 @@
"""Integration: derived views exposed on InformationSpace over two shards (SHARD-WP-0010 T5)."""
from shard_wiki.adapters import FolderAdapter
from shard_wiki.model import Identity
from shard_wiki.space import InformationSpace
def _shard(tmp_path, name, files):
root = tmp_path / name
for rel, text in files.items():
p = root / rel
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(text, encoding="utf-8")
return FolderAdapter(name, root)
def _space(tmp_path):
space = InformationSpace("space")
space.attach(
_shard(tmp_path, "wiki", {"Home.md": "welcome, see [[Guide]]", "Guide.md": "the guide"})
)
space.attach(_shard(tmp_path, "notes", {"Daily.md": "today I read [[Guide]]"}))
return space
def test_backlinks_across_two_shards(tmp_path):
space = _space(tmp_path)
sources = {bl.source for bl in space.backlinks("Guide")}
assert sources == {Identity("wiki", "Home"), Identity("notes", "Daily")}
def test_all_pages_and_site_map_over_union(tmp_path):
space = _space(tmp_path)
names = {e.name for e in space.all_pages()}
assert names == {"Home", "Guide", "Daily"}
leaves = {p.key for p in space.site_map().pages}
assert {"Home", "Guide", "Daily"} <= leaves
def test_recent_changes_includes_alias_and_edits(tmp_path):
space = _space(tmp_path)
space.alias("Start", "wiki:Home", actor="ana")
feed = space.recent_changes()
kinds = {e.kind for e in feed}
assert "alias" in kinds and "edit" in kinds
alias = next(e for e in feed if e.kind == "alias")
assert alias.source == "coordination" and alias.actor == "ana"
def test_red_link_creates_no_backlink_via_space(tmp_path):
space = _space(tmp_path)
assert space.backlinks("Nonexistent") == ()

View File

@@ -4,7 +4,7 @@ type: workplan
title: "derived views — wikilinks, BackLinks, RecentChanges, AllPages/SiteMap"
domain: whynot
repo: shard-wiki
status: active
status: done
owner: tegwick
topic_slug: whynot
created: "2026-06-15"
@@ -36,7 +36,7 @@ later by SHARD-WP-0011) and carry provenance. Presentation stays out of core (L6
```task
id: SHARD-WP-0010-T1
status: todo
status: done
priority: high
state_hub_task_id: "792660c3-9be9-4771-9f51-69d01f0c7f13"
```
@@ -51,7 +51,7 @@ red-link, CamelCase opt-in.
```task
id: SHARD-WP-0010-T2
status: todo
status: done
priority: high
state_hub_task_id: "431a54c3-82b5-4b08-b3f0-762624d4c91d"
```
@@ -65,7 +65,7 @@ chorus pages aggregate.
```task
id: SHARD-WP-0010-T3
status: todo
status: done
priority: medium
state_hub_task_id: "270c1c31-0445-42b9-9a49-92d32c298eb2"
```
@@ -79,7 +79,7 @@ alias both appear, newest-first; per-shard attribution present.
```task
id: SHARD-WP-0010-T4
status: todo
status: done
priority: low
state_hub_task_id: "898ba43e-cdef-4ce8-9fa3-4ce60ebb4fdd"
```
@@ -92,7 +92,7 @@ collapses to one entry with divergence noted; sitemap reflects paths.
```task
id: SHARD-WP-0010-T5
status: todo
status: done
priority: medium
state_hub_task_id: "7157544b-5d3b-45a2-ba5a-c32244c59323"
```