Skip to content

v5: route record and collection-metadata writes through the mdbase-next runtime (off by default) - #2386

Open
callumalpass wants to merge 6 commits into
agent/tasknotes-v5-documentationfrom
feat/v5-mdbase-next-backend
Open

callumalpass wants to merge 6 commits into
agent/tasknotes-v5-documentationfrom
feat/v5-mdbase-next-backend

Conversation

@callumalpass

@callumalpass callumalpass commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Inactive TaskNotes v5 mdbase-next backend port, targeting the v5 beta line (replaces #2385). Coordinator handles merging/release; this does not install the backend.

Records use the existing VaultMutationService funnel: field-level frontmatter updates with observed bases, document replacement with the read base, and record-path creates. Non-record backups/exports and outside-collection files retain Obsidian routing. Current24cef502 fails closed for unavailable managed records/documents before callbacks or legacy writes; resource paths require the resource API.

Collection metadata uses SafeMetadata/MetadataTransaction resource writes with exact read content as base, must_not_exist for new resources, and one mutation for a transaction. Backups remain ordinary vault writes.

Publication is required; confirmation alone is not success. The eventual adapter is SdkWriteClient (#166). Actual full-plugin/service/UI, offline, dirty-editor fencing and teardown activation remain separate qualification; no activation or release note while inactive. Existing LAB client-only backend proof is not full UI acceptance.

Checks at24cef502:4955 Jest passes/766 suites (70 suites skipped,1012 skipped tests,4 todo), typecheck, FULL lint (TS/review-types/CSS/architecture), production build:test PASS. Build copied only to this owned worktree .testbed/mdbase-next-inactive. User Obsidian CLI/profile not touched; no isolated plugin reload claimed. TMPDIR was an owned coordination scratch directory. Seven new managed-routing regressions, existing resource/CAS and mutation tests retained.

… installed

VaultMutationService is TaskNotes' single write funnel. When an
MdbaseMutationBackend is installed and claims a file (it is in the mdbase
collection and is a known record), writes become replica intents:
frontmatter callbacks -> field-level updates (set/unset keys with the read
values as merge base), content callbacks and modify -> document replace with
the read document as base, create -> record create. Each call resolves once the
write is published into the vault, so callers see the same behaviour as with
Obsidian's APIs. Without a backend, or for files outside the collection,
nothing changes. Not installed by default yet: the shared runtime wiring
lands once runtime.wasm hosts the file store.
When the backend is installed, SafeMetadata writes to mdbase.yaml, type and
contract files become resource writes through the runtime, based on the content
they read (base_revision), with null base = must_not_exist for pack-created types
(contracts #201). A MetadataTransaction's whole set is one mutation, applied
atomically by the log with no local swap journal; backups under .tasknotes/ are
still written. Setting a type aside copies it out, then deletes the resource with
its base.
@callumalpass

Copy link
Copy Markdown
Owner Author

Follow-up inactive native-profile candidate 6634483b612bb7cde09aa5a5df079c2fe8a33422: when an installed backend owns mdbase.yaml, use the existing model schemasFolder option beneath the configured types folder. Both required JSON sidecars and inline definition bytes are preserved; generated readback paths and strict pending-migration path sets follow this profile. Existing old-layout sidecars require explicit migration; all five canonical paths must be backend-owned, with no legacy fallback. Ordinary inactive/vault behavior is unchanged. Eight regressions; 125 service tests and full 4963 Jest tests/766 suites, typecheck, full lint and production build:test passed (copying only to an owned testbed). Actual isolated LAB negative initialization confirmed typed resource-path rejection of the previous profile. This candidate still requires new full-source UI/service LAB acceptance; production activation remains off.

@callumalpass

Copy link
Copy Markdown
Owner Author

Core namespace-compatibility SOURCE ACK for the exact two-file 24cef50 → 6634483 delta (not the entire eight-file PR). Actual service delta/eight new cases and resource-write context read. Native attached resource-backend profile selects existing model schemasFolder = configured typesFolder/tasknotes; both JSON sidecars remain, generated paths drive readback and strict five-path pending-set validation. Inline/schema document bytes stay identical; inactive/vault profile is unchanged. Existing physical old layout requires explicit migration, and stable native publication checks ownership of all five resources. This matches current Core namespaces (JSON files under configured types/contracts are resources, only .md files are definitions), corroborated by the independent synthetic Core five-resource admission oracle. No Core allowlist, wire or query semantics change. Author test evidence applies; no unchanged-suite rerun. Scope is path/format compatibility, not backend lifecycle/authority, real publication, positive full-UI LAB acceptance or release approval; LAB integration need not wait for consumer approval.

@callumalpass

Copy link
Copy Markdown
Owner Author

Full-source LAB exposed a product creation bypass: TaskService constructs TaskCreationService with the plugin runtime, and TaskCreationService called vault.create directly. Follow-up 01cd5c66a46d47bfc87dcc393067742dbb858199 now uses the services mutation facade and the same core backend; the helper accepts only its actual vault methods. Three real TaskService/real-backend unit regressions prove settle waiting, rejection propagation and missing-index refusal without vault fallback/success events. Full 4966 Jest tests/766 suites, typecheck, full lint and owned build:test pass. Previous LAB run published the five resource paths and rendered/saved the modal, but did not call SDK create or publish a record; not a UI pass. That fixture/evidence are retained. New positive acceptance needs a new artifact/root/fresh admission; activation remains off.

@callumalpass

Copy link
Copy Markdown
Owner Author

Actual isolated full TaskNotes UI/service LAB acceptance PASS at 06:44:52–58 on immutable 01cd5c66 + runtime tooling 94ce58e8: all five resource paths published, real rendered creation modal Save called SDK create, exact owned filename and final publication guards passed, real TaskService update completed, edit modal rendered, SDK and vault readback agreed. Two record publication receipts were observed; receipts remained state=pending/publication=published/status=absent, not relabelled confirmed. Artifact SHA 3a02633d3d73b69b27636fed952410558cd07ce879ca6067074c96fc9adcaee4; sanitized result SHA 65d5d33cb6cad9881069f3965b5ba6ffca15691c88f5a242c139aec923637d88. Owned Obsidian/Xvfb/CDP cleanup was verified and all three earlier failures retained unchanged. Scoped UI/service pass only: dirty editor, mobile/WASM/cloud, CP app-grant/SAS, lifecycle and production activation remain unqualified; backend activation stays off.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant