V0M3

An evidence-backed document workflow where model output remains a reviewable proposal with provenance and revision history.

Personal project

Project brief

Period
2024
Status
Archived
Focus
Governed AI-assisted writing
Constraint
Generated text could never become canonical silently.
Result
Typed proposals and acceptance receipts preserved document lineage.

V0M3 was a 2024 personal project for AI-assisted long-form writing with reviewable provenance. K81R could answer questions from a bounded corpus, and every answer remained an immutable record separate from the source. V0M3 raised the difficulty: generated material would enter an authored document that changed over time, combined human and model revisions, cited evidence, and could eventually be exported as a finished artifact.

Decision record

Who could change the document?

Decision
Let models create typed proposals against exact revisions; only an explicit acceptance transition could alter canonical text.
Trade-off
The workflow added state and review work while preserving authorship and provenance.

Generated text entered a real document

The obvious interface was a chat panel beside an editor. I built it, asked for a section rewrite, copied a useful paragraph into the document, and immediately lost the most important relationships. Which sources had supported the paragraph? Which model and prompt had produced it? What had I changed after copying? Was the new paragraph a suggestion, an accepted revision, or merely text that happened to be present?

The chat transcript contained some of the history and was not the document’s state model. V0M3 replaced copy-and-paste assistance with typed proposals tied to exact document and evidence revisions.

The project operated on personal essays, project notes, and synthetic research briefs. It was not a workplace writing platform and did not claim to coordinate a professional editorial organization.

V0M3’s central rule was simple: a model could propose; it could not silently author the canonical document.

The system distinguished:

  • Source documents and their immutable revisions.
  • The current authored document revision.
  • A task describing what kind of change was requested.
  • An evidence set assembled for that task.
  • One or more generated proposals.
  • Human edits, review decisions, and accepted patches.

The canonical document changed only through an explicit revision operation. Accepting a proposal produced a patch that a person could inspect and edit. The resulting document revision recorded both the proposal lineage and the human-authored delta.

A person could write directly without involving a model. V0M3 did not wrap ordinary editing in an AI abstraction. Assistance entered only where a named task justified it.

This boundary protected ownership. Model output was material in a workflow, not a second invisible author competing with the document.

A typed workflow instead of a chat history

Each assistance task moved through explicit states:

draft → scoped → evidence-ready → generating → proposed
                                              ↘ failed
proposed → reviewing → accepted | revised | rejected | superseded

The task began with a target document revision and target range. Scoping named the requested operation: outline, summarize evidence, identify gaps, propose a rewrite, check claims, or generate alternatives.

Evidence-ready meant the selected sources had stable revisions and passed access checks. Generating recorded provider, model, prompt, tool policy, and budget. Proposed meant the output had passed schema validation and lineage checks, not that its prose was correct.

Reviewing allowed comments and edits against the immutable proposal. Acceptance created a patch onto the target document. If the document had changed since the task began, V0M3 required rebase and review rather than applying against a different revision.

Rejected and superseded proposals remained in history. Deleting them would remove evidence about how a paragraph had evolved and repeat failed directions later.

The workflow borrowed D4U7’s revision model and Z29C’s durable transitions while accounting for probabilistic output.

Evidence graphs, not citation decorations

K81R’s claim-level citations became an evidence graph in V0M3. Nodes represented source revisions, selected passages, task claims, proposal spans, document spans, and review decisions.

Edges named the relationship:

  • Passage supports claim.
  • Passage contradicts claim.
  • Proposal span derived from claim.
  • Document span accepted from proposal.
  • Human edit transformed proposal span.
  • Review decision rejected unsupported claim.

This graph allowed the document to answer practical questions. Which paragraphs depend on a source that has been superseded? Which claims in the current draft have no reviewed evidence? Which generated spans were substantially changed by the author?

The graph did not pretend to quantify authorship perfectly. A person might internalize a source and rewrite an idea independently. V0M3 recorded known workflow lineage without claiming access to intention.

Citations remained visible in the document where the genre needed them. The graph served a broader purpose: it connected evidence and decisions through revision history, even when the final prose used endnotes or no formal citation marker.

Proposals were structured patches

The first generation endpoint returned Markdown for an entire section. Reviewing a wholesale replacement made small useful changes hard to isolate.

V0M3 requested a structured proposal:

summary
operations[]
  targetAnchor
  action: insert | replace | delete | comment
  proposedText
  rationale
  evidenceIds[]
claims[]
openQuestions[]

Target anchors referred to stable document nodes and revision context rather than raw character offsets. The server validated anchors, evidence IDs, allowed operations, and output size before presenting the proposal.

The review view showed each operation beside the current text. A person could accept, edit, or reject operations independently. Accepting edited text preserved the proposal and the final authored version as separate nodes.

A summary proposal could add a comment instead of altering text when evidence remained weak. Deletion required a rationale and displayed the removed passage fully.

The structured patch increased implementation work and reduced the ambiguity of a large generated blob. It made review the normal path rather than a final glance before copy.

Provider adapters and stable product state

Models and provider APIs changed quickly. V0M3 used a provider adapter that normalized the narrow capabilities the product needed: structured generation, streaming events, usage, cancellation, and error categories.

The adapter did not erase meaningful differences. A model’s context limit, structured-output reliability, tool support, and data policy remained explicit capability fields. A workflow selected only providers satisfying its task and privacy policy.

Product state never stored opaque provider event streams as its only record. V0M3 retained the normalized request, prompt template version, evidence IDs, model identifier, provider request reference, structured output, usage, and terminal result.

Raw responses could be retained temporarily for debugging under the personal data policy and were not required to render a proposal later.

Retry followed Z29C’s distinction. A generation request with no external side effect could often be repeated, but the result would be a new proposal attempt, not a continuation pretending to be identical. If a provider supported resuming a stream, V0M3 still validated the final structured result as one attempt.

Switching providers created a comparable alternative linked to the same task and evidence set. The interface did not present one model as the hidden definition of assistance.

Streaming without granting partial authority

Raw token streaming felt responsive and created an unstable review surface. Text could imply a claim before its citation or caveat arrived. A user could start editing material that later failed schema validation.

V0M3 streamed progress and completed proposal operations. A structured operation became visible after its target, text, rationale, and evidence references validated. The proposal remained non-canonical until review.

The UI distinguished “generating,” “proposal available,” and “document changed.” A stream completing did not flash a success message that implied acceptance.

Cancellation stopped the current attempt where supported. Partial structured operations remained diagnostic data and did not become proposals. Starting again created a new attempt under the same task.

This was less theatrical than a paragraph writing itself and more consistent with the product’s authority model. Responsiveness came from clear state and incremental valid units, not from exposing every token.

Some tasks benefited from tools: search the K81R corpus, fetch a named source revision, calculate a simple transformation, or inspect document structure. V0M3 did not give the model general network or file access.

Each task received a tool policy listing allowed tool, action, scope, call limit, and result size. The model could request a tool call; the server validated it against the current policy and executed it through a typed adapter.

Tool results entered the task record with stable IDs and provenance. A retrieved passage became evidence only after the same access and lineage checks used by K81R.

Consequential tools were absent. The model could not publish, send a message, modify the canonical document, or change permissions. A proposal could recommend an action and a person could perform it through the normal interface.

The tool log separated requested, authorized, executed, failed, and denied. A denied call was useful evaluation evidence. The system did not retry with a broader tool merely because the model asked.

Budgets limited calls, tokens, wall time, and result volume. Exhaustion produced an incomplete proposal or failed attempt with a visible reason.

MCP arrived after the boundary

The Model Context Protocol was introduced publicly in November 2024. V0M3 already had typed provider and tool adapters by then, so I added an experimental MCP adapter after the initial architecture rather than rewriting the product around the protocol.

The adapter mapped approved MCP tools and resources into V0M3’s existing capability model. Server-provided descriptions remained untrusted metadata. Local policy constrained which server, resource, and action could enter a task.

MCP validated the value of an adapter-shaped boundary: tools could be discovered and invoked through a shared protocol while task state, permission, provenance, and review remained product responsibilities.

It also exposed new trust questions. A server could change its advertised tools, return instruction-like content, or expose a broader resource than its name implied. V0M3 pinned server identity, recorded tool schema digests per run, validated outputs, and required explicit enablement.

The protocol did not make tools safe or make model output authoritative. It standardized part of the connection. V0M3’s policy gate and evidence graph still determined what the result meant.

Revision-aware review

A proposal targeted one document revision. If the author changed the same region before review, V0M3 did not apply the old patch automatically.

The rebase view showed target revision, current revision, proposal operations, and intervening human changes. Operations against untouched nodes could be carried forward. Overlapping changes required a fresh decision or regeneration against the new state.

Accepted operations produced a new document revision in one transaction. The revision recorded the final text, parent revision, accepted proposal operation IDs, human edits made during acceptance, and review identity.

Undo created another document revision. It did not delete the acceptance event or proposal history. A later reader could see that generated material had been adopted and then removed.

Comments anchored to proposal operations remained on the proposal even after acceptance. Document comments reattached to the accepted span where possible and showed uncertainty when subsequent edits invalidated the anchor.

This prevented a common collaboration failure: a suggestion reviewed against one text silently landing in another.

Claim review as a separate pass

Writing quality and evidence support required different attention. V0M3 offered a claim-review task that extracted factual claims from the target revision, linked existing citations, searched for support, and proposed status labels.

The model could suggest supported, partially supported, contradicted, time-sensitive, or unsupported. The result was a review proposal, not an automatic verdict.

The interface grouped claims by document section and let the author inspect exact source passages. Accepting the review added evidence edges and optional comments; it did not rewrite prose unless a separate patch was approved.

An unsupported claim could lead to removal, qualification, a research note, or deliberate retention as opinion. The workflow preserved that human decision.

Evaluation measured passage relevance, claim-evidence agreement, and useful abstention separately. A system that labeled every subtle claim unsupported would be safe and unusable.

K81R’s fluent-wrong case remained in the suite. V0M3 added cases where a source supported one clause but not the stronger sentence produced by combining it with another.

Prompt and instruction boundaries

Task templates kept system policy, author instruction, document content, and retrieved evidence in separate structured sections. Documents and tool results were treated as data, even when they contained imperative language.

The server validated every structured output and tool request. It did not rely on the model to remember access rules. Model-visible identifiers were scoped to the task so guessing another ID could not retrieve another document.

Prompt templates were versioned and reviewed like code. A change ran against a fixture set covering long documents, conflicting evidence, injection attempts, empty retrieval, unsupported operations, and output near budget limits.

V0M3 stored the exact template version and normalized inputs with each attempt. Sensitive source text followed the personal retention policy; evaluation fixtures used synthetic or intentionally included material.

I avoided a giant universal system prompt. Product rules lived in code and validation where possible. Prompts described the bounded task and output contract.

V0M3 evaluated more than prose preference. The suite covered:

  • Correct target anchoring.
  • Evidence IDs that actually supported claims.
  • Preservation of requested meaning during rewrite.
  • Appropriate refusal when evidence was missing.
  • Tool-policy compliance.
  • Structured-output validity.
  • Human review effort by operation.
  • Rebase behavior after document changes.
  • Provenance completeness after acceptance.

For writing quality, I used paired review against a rubric: clarity, accuracy, specificity, voice preservation, and unnecessary expansion. The model could not grade its own output as the only judge.

Workflow tests interrupted generation, tool calls, acceptance transactions, and document updates. A crash could lose transient stream progress; it could not produce a canonical revision without an acceptance receipt.

Every significant defect became a scenario. A proposal that deleted a caveat while preserving its citation became a regression case tying semantics to patch review.

The benchmark did not claim general writing ability. It asked whether a configuration made V0M3’s defined workflow safer and more useful on its bounded documents.

A calm interface for probabilistic work

The document remained the visual center. Assistance tasks lived in a side index and opened into a full review view when necessary. I avoided a permanently animated chat column competing for attention.

Task states used plain labels: scoping, gathering evidence, generating, ready for review, needs attention, accepted, rejected. Token counters and model names stayed in technical details unless they affected a budget or choice.

Evidence and provenance expanded on demand from proposal operations. The default review showed enough context to decide without burying the text in metadata.

Keyboard flows covered moving among operations, accepting or editing one, opening evidence, and returning to the exact review location. Screen-reader announcements occurred on task-state transitions, not every streamed event.

Reduced-motion preferences eliminated transitional movement. Long generated text did not enter a modal. The same hierarchy used in J05N and D4U7 kept review spatially stable.

The visual restraint reinforced the authority model. Model activity was not the hero. The authored document and the person’s decisions were.

Export without losing the audit trail

The finished document could export as Markdown or a rendered package without requiring V0M3 to read it later. Portability was part of author ownership.

An optional companion manifest carried the document revision, source citations, accepted proposal operations, human edits, model and prompt identifiers, and review receipts. The readable document did not need to expose all of that metadata inline.

Export generated from one immutable revision. A changing draft could not produce a body from one moment and provenance from another. The package contained content digests so a later import could detect edits made outside V0M3.

Reimport treated an externally edited document as a new human-authored revision. It did not pretend to know which sentences had retained their earlier generated lineage. Exact unchanged spans could preserve known edges, while changed regions became ordinary authored text unless the person attached new evidence.

I tested the complete departure path: export the current document and sources, remove the local V0M3 state, and read the artifact with ordinary tools. A personal writing system should not make AI assistance the price of future access to one’s own work.

Cost and privacy as task constraints

Each assistance task estimated context size and displayed a bounded budget before generation. The default selected only the target section and approved evidence, not the entire notebook.

The provider adapter declared retention and region policy alongside capability. A task containing sensitive personal notes could be restricted to a local model or disabled when no acceptable provider existed. The interface did not silently fall back to a broader external provider.

Usage receipts recorded tokens and local cost units per attempt. Budgets applied to the whole task, including tool results and retries. An exhausted budget returned the valid proposal operations already completed only if the schema allowed a clearly partial result; otherwise the attempt failed without creating a proposal.

Caches keyed structured outputs by exact normalized inputs only for deterministic development fixtures. Personal generation was not reused across tasks merely because prompts looked similar. Privacy and authorship context outweighed speculative savings.

These constraints made provider choice part of workflow design. Capability, privacy, cost, latency, and review burden all influenced whether assistance was appropriate. “Use the best model” was not a sufficient product policy.

Places where review still looked like chat

The chat-and-copy prototype lost lineage as soon as useful text entered the editor. Typed proposals and acceptance receipts connected output to document state.

Whole-section replacement made review coarse. Structured patch operations allowed selective acceptance and preserved rationale and evidence.

Raw token streaming exposed invalid partial output and encouraged premature editing. Streaming validated operations produced a calmer boundary.

I initially treated provider normalization as hiding every difference. Explicit capability fields kept context, structured output, policy, and tool support visible.

The first tool implementation trusted names and descriptions. Server-side policy, schema digests, scoped identifiers, and output validation made tool access a product contract.

Claim review originally changed prose automatically. Separating evidence assessment from rewriting restored author control.

V0M3 transformed generative output from transient text into governed product state without making it authoritative. It combined document revisions, structured proposals, evidence graphs, provider adapters, bounded tools, human review, policy, and evaluation.

The acceptance boundary was the step that changed the project. A model proposal, a reviewed patch, and a canonical document revision were separate things connected by durable evidence. That separation made rejection, editing, rebase, undo, and provenance possible.

The project inherited K81R’s answerability and citations, Z29C’s receipts and unknown outcomes, D4U7’s revision-aware collaboration, Q2F8’s policy gates, and J05N’s accessible migration patterns.

N17Q would take the next step. V0M3’s model operated inside a predetermined document workflow with a small tool set. N17Q would let an agent choose among tools over longer runs. The challenge would shift from reviewing one proposal to evaluating and replaying an entire trajectory without repeating its external consequences.

What provenance could not decide

V0M3 used personal documents and synthetic tasks. It could not determine truth, ownership, originality, or writing quality universally. Provenance recorded known workflow lineage and did not read human intention.

MCP standardized connections without making external servers trustworthy. Structured output and claim review could fail. The system’s contribution was to bound those failures and keep canonical changes behind reviewable human action.

Technology: immutable document revisions, typed assistance workflows, structured patch proposals, evidence graphs, provider adapters, scoped tool policies, experimental MCP integration, React and Next.js server-first views, claim-level evaluation, and accessible revision-aware review.