Editor Collaboration Model

Editor Collaboration Model

This document captures the intended collaboration model for the editor in ~/Code/quantalumin/generator.

The editor is not meant to bypass version control. It is meant to make git-backed website editing usable for staff, trusted contributors, and in some cases public contributors, while still preserving review before publish.

Core Rule

The canonical persistence boundary is the website git repository.

That means:

  • markdown, front matter, config, and structured JSON remain file-backed
  • the browser editor is an authoring interface, not the system of record
  • publish should flow from reviewed repository changes, not opaque database mutations

Collaboration Goal

The long-term goal is to allow:

  • site owners editing their own website
  • delegated editors editing only a subsection of a website
  • peer-review or administrator review on scoped portions of a site
  • public contribution flows that still land as reviewable proposed changes

The editor should therefore behave more like a patch authoring and review surface than a direct-live-CMS.

Review Scope Model

Review and edit permissions should be able to attach below whole-site level.

Useful scopes include:

  • whole site
  • page subtree
  • page
  • section
  • structured object such as a gallery, team block, FAQ, or quiz
  • shared workspace boards that define people/agent collaboration on a page

Capability decisions should come from the shared auth/policy system rather than from ad hoc logic in the generator itself.

Patch Request Workflow

The intended workflow is:

  1. A user edits a site through the generator UI.
  2. The backend writes those edits into tracked files in the site workspace.
  3. The system prepares a reviewable change set against the website repository.
  4. That change set is submitted as a patch request, branch proposal, or merge request.
  5. A reviewer inspects the diff, leaves comments, and approves or rejects it.
  6. Only approved changes are merged and published.

The key requirement is that the reviewer can see the actual file diff.

The transport may eventually speak in terms of merge requests, patch files, or forge-native pull requests, but the architectural rule is the same: edits must resolve to reviewable repository changes.

Comments

Comments should be implemented as file-backed JSON in the Hugo data/ directory for each website.

Recommended path family:

  • data/comments/

Recommended examples:

  • data/comments/_index.json
  • data/comments/about/index.json

Comments are a review layer, not authored page content. They should:

  • stay separate from markdown source
  • anchor to page/object identity rather than only screen position
  • be readable and mergeable in git
  • support administrator or peer-review workflows

The editor should overlay those threads on the live page, but comment state should still be persisted as normal tracked files.

Quizzes

Quizzes should follow the same broad model: file-backed JSON, editable through the generator, and reviewable through repository diffs.

Preferred rule:

  • authored quiz definitions should live as structured JSON in the site repo
  • for the hosted collaboration model, the canonical family should be data/quizzes/**
  • the quiz editing flow should produce reviewable file changes
  • reviewers should be able to inspect quiz changes exactly like content changes

The important constraint is that quiz definitions stay file-backed and reviewable, not hidden in an opaque runtime store.

If user submissions are later introduced, they should remain separate from the authored quiz definitions and should not be treated as normal public template data.

First Bridge Slice

The first narrow backend slice should be page-local comment persistence.

For local development, the markdown bridge should own:

  • mapping a page markdown path to data/comments/<page-path>.json
  • reading that page-local comment document
  • writing that page-local comment document back as tracked JSON

This is intentionally smaller than a full collaborative review system. It is just enough to make comments a first-class tracked file family before branch and pull-request automation is layered on top in generator-api.

Relationship To Existing Editor Rules

This collaboration model is consistent with the existing generator direction:

  • Hugo remains the render authority
  • markdown and structured files remain the source of truth
  • browser editing remains an interface layer
  • auth and review policy belong to the shared website platform

So the generator should keep moving toward:

  • file-backed editing
  • scoped permissions
  • diffable review
  • approval before publish

not toward a direct-write CMS that bypasses repository history.

Local Neovim Position Sync

Local draft workspaces can also bridge browser editor position to a running Neovim server. This is a local-authoring convenience layer; markdown files remain the source of truth and Hugo remains the renderer.

The local bridge exposes two position endpoints:

  • POST /position/update accepts a project path plus line, column, optional pageIndex, pageCount, lineCount, scrollRatio, source, and sessionId.
  • GET /position/watch?path=<project-path> streams Server-Sent Events named position for that path.

scripts/local-markdown-bridge.mjs already polls configured or discovered Neovim sockets (--nvim-server, GENERATOR_NVIM_SERVER, or default socket discovery). Loaded buffers under the site root publish their current cursor line to the position stream. Browser PDF page changes publish an approximate source line back to the bridge, and the bridge moves any visible matching Neovim buffer cursor to that line.

The first mapping is deliberately line-ratio based: browser page n maps to an approximate markdown line, and Neovim line n maps back to an approximate PDF page. A later source-span map from the Nowtype/Hugo document model can replace that approximation without changing the transport API.

Nextcloud-Managed Workspaces

When a workspace is surfaced through Nextcloud, Nextcloud should act as the filesystem shell, not the authoring authority.

The intended bridge is:

  1. Nextcloud shows a mounted author worktree under a workspace-oriented root.
  2. The user selects a file or drags one into a managed workspace.
  3. The editor resolves that selection to workspace_id + relative_path.
  4. generator-api writes into the durable author worktree.
  5. Review and publish use hidden review and execution worktrees so the mounted author tree does not jump branches or mutate under the user.

Operational rules:

  • the mount is a view onto the durable author worktree, not a separate copy
  • imports must normalize paths and reject absolute paths, .., and other escapes before writing
  • review and publish must never happen inside the mounted author tree
  • the editor should preserve tracked file bytes and existing file mode where possible
  • 0600-only source files are a bug at the runtime boundary if they block the build or contract checks from reading them
  • if a writer needs a temporary file mode, it should set that mode explicitly rather than depending on a host default

Recommended end-to-end check:

  • open a file from Nextcloud Files
  • import or edit it in the generator workspace
  • confirm the changed file appears in the mounted author worktree
  • stage a review branch from a hidden worktree
  • confirm publish runs from the hidden execution worktree
  • confirm the mounted author worktree still points at the same branch or HEAD