Openworks

Content input/output

The content contracts separate Input, Processing and Output around ordered content lists. Existing research-named tables, routes, MCP tools and project lifecycles stay compatible; the contracts do not rename persisted data or imply a migration.

Module boundaries

packages/domain/src/content/ contains plain TypeScript, with no Node, browser, Convex or provider SDK dependencies:

These are capture/export-preparation contracts. They do not yet model persisted revision IDs, stale-write checks, approval state or cryptographic source versions. They must not replace a persistence layer that enforces those separate guarantees.

Lists and their nested source/processing records are copied and frozen at boundaries. Order is preserved; duplicate IDs are rejected rather than silently overwriting content. Canonical lists are validated again when processing or preparing an export, including direct JavaScript callers: malformed fields, sparse lists, unsupported source kinds and completeness flags that contradict source evidence are rejected. Completeness describes the availability of original source text, not whether a transform's resulting working text is empty. It does not verify the source's claims. Processing is synchronous; callers must supply side-effect-free transforms. The contract cannot enforce the purity of an injected callback. A caller that needs asynchronous model work, storage, retries or transport must implement that orchestration outside the shared domain package.

scripts/content-input.mts bridges existing intake jobs into these contracts. scripts/worker.mts uses that bridge before prompt construction, explicitly marking reference-only inputs so a locator is not presented as already-read content. Existing job behavior, worker ownership and storage stay compatible. The remainder of the legacy prompt builder is intentionally still in the worker; this is an incremental boundary extraction, not a claim that the entire worker has been decomposed.

Capability matrix

Boundary Implemented here Separate or not yet implemented
Screenshot input Image locator and optional caller-supplied OCR text; preserves multiple screenshots from jobs OCR execution, durable image snapshots, verification of OCR accuracy
Paper input Reference plus optional supplied text; absence remains explicit Full-text retrieval stays in the existing worker; adapter does not prove that supplied text is complete
Processing Pure injected text transform; source and operation history preserved Model quality evaluation, claim verification, asynchronous processor orchestration
Notion output Destination-specific export plan with canonical contents Direct Notion API transport, API payload conversion, authorization and live publication
Feed output Portable ordered records with plain content_text, source evidence, completeness and processing history Hosted endpoint, RSS/XML or JSON Feed standard serialization, access control and publication
Existing outputs Current digest, summaries, project artifacts and suggestions remain available Migration of every legacy output path to the new adapters
Video No video adapter Scene planning, rendering, rights review and export

Source text, URLs, titles and model results remain untrusted. A locator is not permission to read or publish. Consumers must validate transport URLs, escape text for their target format, apply their owner/access checks and obtain destination permissions before transmitting material. The feed record is internal export data, not a promise of conformance to an external feed specification.

Example

import { paperInput, textProcessor, feedOutput } from "@openworks/domain";

const input = paperInput.capture({
  id: "reading-1",
  reference: "doi:example",
  text: "Supplied source text",
});
const processed = textProcessor("local", "trim", (item) => item.text.trim()).process(input);
const exportPlan = feedOutput("My reading").prepare(processed);
// The caller reviews, serializes and publishes this plan separately.

Reproducible evidence

Run pnpm install --frozen-lockfile, pnpm typecheck and pnpm test. The dedicated content and legacy-job bridge suites exercise source preservation, missing evidence, multiple images, duplicate IDs, unknown kinds, empty lists, isolation, processing failures and output preparation. They use synthetic local fixtures; no provider, Notion account, live feed or video render is exercised.

pnpm benchmark:content runs the same capture → transform → feed preparation path for 1, 100 and 1,000 records, with warmups and repeated samples. Its JSON output includes runtime, sample sizes, p50/p95 elapsed time, record count and serialized output size. Timing is machine-dependent overhead for these pure adapters, not model latency, a reliability percentage, a baseline improvement or a SOTA comparison. The script also fails unless record count, unique IDs, stable order, unchanged source text, expected transformed text and retained processing metadata all hold.

Persisted content integrity

The runtime-readonly ContentList above is not persisted revision history. The backend separately versions memos, sections, TeX and experiments, retaining exact snapshots and rejecting stale read tokens. Agent runs pin source revisions and config at enqueue time. See Content integrity for migration, provenance and deletion semantics.