Phase 1 (Door A): ingest-spec v1 implementation + §11 golden fixtures, pinned to the current spec revision, with TDD order and byte-exact verification criteria. Phase 2 (Doors B/C): guard-gated inbox and external bundle import. Phase 3: configurable bundle contract via a profile object, default profile locked to the golden suite. Phase 4: zero-dep Node half, coordination-first with owner sign-offs. Each plan carries explicit key assumptions with tests and a verification section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
103 lines
6 KiB
Markdown
103 lines
6 KiB
Markdown
# Phase 4 plan — the Node half (`node/`)
|
|
|
|
Status: approved roadmap phase (see `CLAUDE.md`); details settled here before code.
|
|
Depends on: Phase 3 (the profile object must be able to express the second-brain
|
|
contract; that expressiveness is checked during Phase 3's split-table step).
|
|
Hard precondition: the coordination steps below — this phase does not start with
|
|
code, it starts with agreements.
|
|
|
|
## Goal
|
|
|
|
A zero-dependency Node/ESM package under `node/` for the second-brain world:
|
|
bundle check, index generation, inbox split/frontmatter/write, and document
|
|
conversion (docx/pdf/eml/html → md). Importable as a library AND invokable as a
|
|
CLI (`node <path> <args>`, exit code + stdout — the established plugin
|
|
invocation pattern), consumed by vendoring per plugin, not npm publishing.
|
|
The Python and Node halves share the OKF contract and the fixture suite, never
|
|
code.
|
|
|
|
## Coordination first (ordered, each with an owner sign-off)
|
|
|
|
1. **okr agreement.** The reference implementations (`okf-check.mjs`,
|
|
`okf-index.mjs`, the inbox libraries and vocabulary/link modules) are lifted
|
|
only in agreement with okr; their test suite is ported alongside the code as
|
|
the seed corpus. Known deviations between okr's current behavior and the
|
|
catalog spec are resolved WITH the convention owner before the lift — the
|
|
library implements the agreed contract, not one repo's drift.
|
|
2. **Catalog stays convention owner.** The second-brain spec remains in the
|
|
marketplace catalog; this repo implements it. After the lift, the catalog
|
|
re-pins its shared check gate to this repo's copy — acceptance is behavior
|
|
parity on the shared fixture suite, and the re-pin follows the marketplace's
|
|
release-tag pinning discipline.
|
|
3. **linkedin-studio stays plugin-local.** Its `ingest/published/`
|
|
provenance-record grammar has a different lifecycle by design and is NOT
|
|
normalized into this library. Explicit non-goal, agreed up front.
|
|
4. **Persist gate = guard-as-contract.** There is no Node guard today. The Node
|
|
half documents and enforces the guard's *contract* at its persist seam
|
|
(fail-closed hook point, no content-safety logic of its own) so a future Node
|
|
guard from the security repo can drop in. No security reimplementation in
|
|
either runtime.
|
|
5. **ms-ai-architect as greenfield consumer.** Its designed-but-unbuilt needs
|
|
(writer, index generator, checker, retrieval support) are the acceptance
|
|
sketch for the package's API surface.
|
|
|
|
## Deliverables
|
|
|
|
1. **`node/` package skeleton:** ESM, `package.json` with NO `dependencies`,
|
|
`node:` builtins only, `node:test` for tests, no build step (vendorable as
|
|
plain files).
|
|
2. **Bundle check** (`okf check`): the catalog spec's rules — `type:` required,
|
|
per-level `index.md` without frontmatter, root `okf_version`, canonical
|
|
`resource` field, preserve-unknown / tolerate-broken posture.
|
|
3. **Index generation** (`okf index`): per-level index maintenance matching the
|
|
reference behavior.
|
|
4. **Inbox primitives:** split, frontmatter emit/parse, relations, write — the
|
|
lifted library modules under this repo's test suite.
|
|
5. **Document conversion** (`okf convert`): docx/pdf/eml/html → md. Conversion
|
|
parsers cannot be zero-dep; this mirrors the Python `[extract]` pattern —
|
|
the core package stays dependency-free, the conversion module lazy-loads
|
|
optional parsers and rejects those types fail-fast when they are absent.
|
|
Which parsers, and whether they are vendored or peer-installed, is settled in
|
|
coordination step 1 (okr had concrete candidates).
|
|
6. **CLI:** one entry (`node/bin/okf.mjs check|index|inbox|convert …`),
|
|
deterministic stdout, meaningful exit codes, no interactive prompts.
|
|
7. **Shared fixture suite:** cross-runtime fixtures for the second-brain
|
|
contract, consumed by BOTH the Node tests and (via the Phase 3 profile) the
|
|
Python tests, so the halves cannot silently diverge.
|
|
|
|
## Key assumptions (each with its test)
|
|
|
|
| # | Assumption | Test |
|
|
|---|---|---|
|
|
| D1 | okr's reference code + tests transfer cleanly to this repo's layout | Ported suite green before any behavior change; parity run against okr's copy on the shared fixtures |
|
|
| D2 | The catalog spec is the single contract both halves implement | Phase 3 profile expresses it; cross-runtime fixture suite passes in both runtimes |
|
|
| D3 | Zero-dep core is compatible with doc conversion | Lazy-load pattern proven by a test run WITHOUT optional parsers installed: core commands work, `convert` fails fast with a clear message |
|
|
| D4 | Vendoring workflow works for consumers | Dry-run: copy `node/` into a scratch plugin layout, run the CLI from there, exit codes intact |
|
|
|
|
## Non-goals
|
|
|
|
- npm publishing (vendoring only), bundling/transpiling, TypeScript build chain.
|
|
- Normalizing linkedin-studio's published-record grammar.
|
|
- A Node guard, or ANY content-safety logic — guard-as-contract until the
|
|
security repo ships a Node implementation.
|
|
- Python↔Node code sharing of any kind (contract and fixtures only).
|
|
|
|
## Verification
|
|
|
|
1. `node --test node/` green; ported reference tests included.
|
|
2. Zero-dep proof: `package.json` has no `dependencies`/`optionalDependencies`;
|
|
grep for non-`node:` imports in core modules returns nothing (conversion
|
|
module exempted, lazy-load only).
|
|
3. Parity: this repo's check gate and the currently vendored reference copy
|
|
produce identical verdicts on the full shared fixture suite (scripted
|
|
comparison, part of CI until the catalog re-pins).
|
|
4. Cross-runtime agreement: Python (Phase 3 profile) and Node checkers give the
|
|
same accept/reject verdict per shared fixture (scripted matrix run).
|
|
5. CLI contract: each subcommand exercised via `node node/bin/okf.mjs …` in
|
|
tests; exit codes asserted (0 clean, non-zero on violation), stdout
|
|
deterministic (two runs diff-empty).
|
|
6. D3 test: suite run in an environment without optional parsers — core green,
|
|
`convert` on a docx fails fast naming the missing parser.
|
|
7. Coordination artifacts: each of the five steps above has a recorded sign-off
|
|
before its dependent code lands (tracked in the session state, summarized in
|
|
the commit history).
|