@ku0/core
v0.0.0
Published
LFCC v0.9 RC core kernel
Downloads
3
Readme
LFCC Core Kernel
Core implementation of Local-First Collaboration Contract (LFCC) v0.9 RC.
Overview
LFCC Core is a platform-agnostic, deterministic collaborative editing kernel that runs in Node.js and browser workers. All algorithms are pure functions: f(state, op) -> state.
Install
pnpm add @ku0/coreQuick Start
import {
// Canonicalization
canonicalize,
// Shadow Model
createShadowDocument,
addBlock,
applyOp,
// Annotations
createAnnotation,
transitionAnnotation,
// AI Pipeline
sanitizePayload,
runDryRun,
} from '@ku0/core';
// 1. Create a document
let doc = createShadowDocument();
const { doc: newDoc, blockId } = addBlock(doc, {
type: 'paragraph',
attrs: {},
text: 'Hello World',
parent_id: null,
children_ids: [],
}, doc.root_id);
// 2. Apply an operation
const { doc: editedDoc } = applyOp(newDoc, {
code: 'OP_TEXT_EDIT',
block_id: blockId,
offset: 5,
delete_count: 0,
insert: ' LFCC',
});
// 3. Canonicalize output
const canonical = canonicalize(editedDoc);Module Layout
packages/core/src/kernel/
├── canonicalizer/ # Recursive canonicalizer v2
├── mapping/ # Block mapping and anchoring
├── annotations/ # Annotation state machine
├── ai/ # AI dry-run pipeline
├── policy/ # Policy manifest and negotiation
├── integrity/ # Integrity verification
├── shadow/ # Shadow model and history
├── devtools/ # Developer diagnostics
├── testing/ # Consistency testing framework
└── index.ts # Unified exportsCore Modules
1. Canonicalizer (Normalization)
Converts any document structure into a deterministic canonical tree.
import { canonicalize, normalizeMarks } from '@ku0/core';
// Canonicalize a document
const canonTree = canonicalize(shadowDoc);
// Normalize marks (sort and merge)
const normalized = normalizeMarks([
{ type: 'italic' },
{ type: 'bold' },
]); // -> [{ type: 'bold' }, { type: 'italic' }]2. Shadow Model
Maintains internal document state and supports CRDT operations.
import {
createShadowDocument,
addBlock,
applyOp,
classifyOp,
} from '@ku0/core';
// Create an empty document
let doc = createShadowDocument();
// Add a block
const { doc: doc1, blockId } = addBlock(doc, {
type: 'paragraph',
attrs: {},
text: 'Hello',
parent_id: null,
children_ids: [],
}, doc.root_id);
// Apply an operation
const { doc: doc2 } = applyOp(doc1, {
code: 'OP_TEXT_EDIT',
block_id: blockId,
offset: 5,
delete_count: 0,
insert: ' World',
});
// Classify operation
const category = classifyOp({ code: 'OP_BLOCK_SPLIT', ... });
// -> 'structural'Supported operations:
OP_TEXT_EDIT- text editOP_BLOCK_SPLIT- block splitOP_BLOCK_JOIN- block joinOP_MARK_EDIT- mark editOP_BLOCK_MOVE- block moveOP_HISTORY_RESTORE- history restore
3. Annotations
Full annotation lifecycle state machine.
import {
createAnnotation,
transitionAnnotation,
AnnotationState,
} from '@ku0/core';
// Create an annotation
const anno = createAnnotation(
'anno-1',
'user-1',
['span-1', 'span-2'],
{ comment: 'Nice!' }
);
// Transition state
const resolved = transitionAnnotation(anno, 'RESOLVE', 'user-2');
console.log(resolved.state); // 'resolved'
// States: draft -> active -> resolved/rejected -> archivedState diagram:
draft ──PUBLISH──> active ──RESOLVE──> resolved ──ARCHIVE──> archived
│ │
└──REJECT──> rejected─┘4. AI Dry-Run Pipeline
Safe AI content ingestion pipeline.
import {
sanitizePayload,
runDryRun,
createEnvelope,
DEFAULT_SANITIZATION_POLICY,
} from '@ku0/core';
// 1. Create request envelope
const envelope = createEnvelope(
'frontier-abc',
'<p>AI generated content</p>',
[{ span_id: 'span-1', if_match_context_hash: 'hash-xyz' }]
);
// 2. Sanitize payload (strip unsafe tags)
const sanitized = sanitizePayload(
envelope.ops_xml,
DEFAULT_SANITIZATION_POLICY
);
// 3. Dry-run validation
const result = runDryRun(envelope, currentDoc, policy);
if (result.success) {
// Safe to apply
applyOp(currentDoc, result.operations);
} else {
console.error(result.rejection_reason);
}Security policy:
- Allowlist tags:
p,strong,em,a,code,table, etc. - Denylist tags:
script,style,iframe,onclick, etc. - Auto-normalized into the LFCC Canonical Tree
5. Policy (Negotiation)
Multi-party policy negotiation and validation.
import {
validateManifest,
negotiatePolicies,
DEFAULT_POLICY_MANIFEST,
} from '@ku0/core';
// Validate a policy manifest
const validation = validateManifest(manifest);
if (!validation.valid) {
console.error(validation.errors);
}
// Negotiate policies
const negotiated = negotiatePolicies([
clientManifest,
serverManifest,
documentManifest,
]);6. Integrity
Document integrity checks and checkpoints.
import {
computeBlockHash,
createCheckpoint,
verifyCheckpoint,
runIntegrityScan,
} from '@ku0/core';
// Compute a block hash
const hash = computeBlockHash(block);
// Create a checkpoint
const checkpoint = createCheckpoint(doc, annotations);
// Verify a checkpoint
const valid = verifyCheckpoint(checkpoint, currentDoc);
// Integrity scan
const scanResult = runIntegrityScan(doc, annotations, policy);7. Mapping and Anchors
Block mapping and anchor resolution system.
import {
createAnchor,
resolveAnchor,
expandNeighbors,
MAPPING_AXIOMS,
} from '@ku0/core';
// Create an anchor
const anchor = createAnchor('block-1', 10, 'after');
// Resolve anchor position
const position = resolveAnchor(anchor, doc);
// Neighbor expansion (for context matching)
const neighbors = expandNeighbors('block-1', doc, 2);8. DevTools
Debugging and diagnostic utilities.
import {
compareCanonTrees,
generateFullScanReport,
PerformanceTracker,
createBugReportTemplate,
} from '@ku0/core';
// Compare two canonical trees
const diff = compareCanonTrees(tree1, tree2);
if (!diff.equal) {
console.log('First diff at:', diff.first_diff_path);
}
// Performance tracking
const tracker = new PerformanceTracker();
tracker.recordScan(cpuTime);
console.log(tracker.getMetrics());
// Generate a full scan report
const report = generateFullScanReport(startTime, blocksCount, ...);
console.log(formatScanReport(report));9. Testing
Consistency and fuzz testing framework.
import {
createTestHarness,
DEFAULT_FUZZ_CONFIG,
formatSECResult,
runFuzzIteration,
runSECAssertion,
GOLDEN_FIXTURES,
runGoldenFixtureTests,
} from '@ku0/core';
// SEC (strong eventual consistency) assertion
const result = runSECAssertion({
...DEFAULT_FUZZ_CONFIG,
seed: 12345,
iterations: 100,
ops_per_iteration: 50,
replicas: 3,
});
console.log(formatSECResult(result));
// Golden fixture regression tests
const fixtureResults = runGoldenFixtureTests(applyOps);To run the core unit tests locally (no built-in 10s timeout):
pnpm -C packages/core testIf you wrap tests with a timeout in CI, prefer minute-level caps (unit tests can exceed 10s).
10. Sync Server (WebSocket)
The server must call handleConnection() (or use attachToWebSocket()) before receiving any messages, otherwise the handshake will be rejected.
import { SyncServer, attachToWebSocket } from '@ku0/core/sync/server';
const server = new SyncServer(config, persistence);
// Pseudo-code: wire to your WS library
const { onMessage, onClose } = attachToWebSocket(server, ws, docId);
ws.on('message', (data) => onMessage(data.toString(), clientId));
ws.on('close', onClose);See docs/Sync_Integration_Guide.md for full integration details and defaults.
Type Exports
All types can be imported from the root entry:
import type {
// Canonicalization
CanonNode,
CanonBlock,
CanonText,
Mark,
// Shadow Model
ShadowDocument,
ShadowBlock,
TypedOp,
// Annotations
Annotation,
AnnotationState,
AnnotationTransition,
// AI
AIEnvelope,
DryRunResult,
SanitizationPolicy,
// Policy
PolicyManifest,
NegotiationResult,
// Integrity
Checkpoint,
IntegrityScanResult,
// Testing
FuzzConfig,
SECAssertionResult,
GoldenFixture,
} from '@ku0/core';Design Principles
- Pure functions - core algorithms are
f(state, op) -> state - Determinism - same input always produces the same output
- Platform agnostic - runs in Node.js and browser workers
- Type safety - full TypeScript types, no
any - Fail-closed - any AI pipeline failure rejects the request
Testing
# Run all tests
pnpm test
# Run tests for specific modules
pnpm test canonicalizer
pnpm test shadow
pnpm test aiRelease Gate
Single command (recommended):
bash scripts/core-release-gate.shThe gate runs:
- Core tests (3x) to detect flakes
- Stress scripts (rate limit / handshake)
- Pack validation (tarball must include
dist/+README.md+ types and must not include__tests__)
Expected runtime: usually < 60s depending on machine.
CI policy: PR runs core tests + pack validation; stress scripts run nightly or manually.
Note: pnpm pack does not support --filter, so use pnpm -C packages/core pack.
See docs/Core_Release_Gate_Usage.md.
License
MIT
