Add the Source contract, registry, and LocalSource#1042
Draft
malberts wants to merge 4 commits into
Draft
Conversation
Introduce the Source interface (by-id Subject and Schema resolution, editability, localId validation, and IRI base URI), a SourceRegistry that maps source keys to Sources with fail-fast duplicate registration and bare-id-to-local routing, and LocalSource wrapping the existing local Subject and Schema lookups as the default editable Source. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add SourceRoutingSubjectLookup, which resolves a Subject id through the
Source its key maps to and degrades an unregistered source key to
not-found plus one logged warning. Wire it into the read-side query and
resolver seams (GetSubjectQuery, GetPageSubjectsQuery, the neowiki_value
parser function, and the Lua library); write paths keep the local
repository since sourced Subjects are read-only, and revision-scoped
resolution stays local. Register the SourceRegistry on NeoWikiRegistrar
with addSource() so extensions contribute Sources through the
NeoWikiRegistration hook, with core's LocalSource seeded first.
The local lookup is wrapped in a LazySubjectLookup so building the
registry during extension registration does not require a graph backend,
keeping backend-less edit and parser-registration paths working. The
schema lookup is deferred the same way (LazySchemaLookup) because
LocalSource is built while the registry is being assembled, and a
dependency that fires the NeoWikiRegistration hook at that point would
hand handlers a still-empty registry, letting an extension claim the
local key before core registers LocalSource. SubjectResolver rethrows
GraphBackendNotConfiguredException instead of swallowing it, so a
missing graph backend stays loud for {{#neowiki_value}} and Lua rather
than degrading to silent nulls.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Record the frozen five-method Source interface, the SourceRegistry semantics, and the unresolvable-source degradation as ADR 27. Add a Sources section to the extending guide covering addSource, and a Source entry to the glossary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ADR 027 stated T4 validates relation targets via isValidLocalId; the shipped guard checks Source registration through the registry and does not call isValidLocalId, which has no consumer yet. Also drops a work-order token from the Source docblock that means nothing once merged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For #993 (work order T2). Builds on #1005 and targets
its branch, so the diff shows only this track.
This PR freezes the Source interface contract that ADR 23 left open. The contract, its whys, and the
alternatives are recorded in
docs/adr/027-source-interface-contract.md; the highlights:Sourcecontract (Domain\Source):getSubject( SubjectId ),getSchema( SchemaName ),isEditable(),isValidLocalId( string ),getBaseUri(). Sources play no part at query time:queryability is materialisation into the graph (ADR 23). Schema resolution enters the contract now
because interface additions break third-party implementers and T3 needs it.
SourceRegistry: byte-exact key comparison (two Linux MySQL/MariaDB dbnames can differ only incase, and the graph's
wiki_idstores the wiki ID verbatim, so case-folding is foreclosed),LogicExceptionon duplicate registration, bare ids map to the local source.LocalSourcewraps the existing local persistence behind lazily constructed lookups and returnsthe per-wiki RDF base (
NeoWikiConfig->rdfBaseUri, from the native RDF projection) as its base URI.subjectLookupseams (GetSubjectQuery,GetPageSubjectsQuery,both
SubjectResolversites) resolve through the registry; write paths and the revision-scopedPointInTimeSubjectLookupstay direct, since sourced Subjects are read-only per ADR 23.NeoWikiRegistrar::addSource()in theNeoWikiRegistrationhook, with coreregistering
LocalSourceunder the wiki ID before the hook fires, so colliding extensionregistrations fail fast. The lazy construction wrappers (
LazySubjectLookup,LazySchemaLookup)are load-bearing here: an eagerly built dependency chain fires the registration hook re-entrantly,
and the hook would observe an empty registry (probe-verified in both process orders).
keeps the pinned not-found contract (HTTP 200 with
{"subject":null}).{{#neowiki_value}}and Lua keepfailing loudly (
GraphBackendNotConfiguredExceptionis rethrown throughSubjectResolver'scatches); the softer degradation belongs to the Finish the graph database plugin system #895 track, not this one.
WritableSource extends Sourceextension, which is non-breaking for implementers.Production notes
Design, contract decisions, and review adjudication by
Fable 5 (max); implementation and the fixround by
Opus 4.8 (max)subagents; three parallelOpus 4.8 (max)review lenses (contractfidelity, runtime correctness, test quality) stood in for the usual pre-PR human review at
@malberts' direction. The correctness lens probe-confirmed the hook-ordering hazard and drove the
lazy-construction fix and the loud-backendless preservation described above.