OpenLoreDocumentationGitHub ↗
Browse documentation
GovernanceOpenLore / Manual

Writing and Publishing

On this page

OpenLore is read-only by default. Set readonly: false to enable its writable substrate; identity and docset policy still determine which paths each session can change. Embedded-docs binaries cannot be made writable.

Write operations

echo "# Notes" > /mydocset/notes.md
echo "- point" >> /mydocset/notes.md
cat input.md | tee /mydocset/copy.md
cat change.diff | patch /mydocset/x.md
sed -i 's/old/new/g' /mydocset/x.md
mkdir -p /mydocset/a/b/c
mv /mydocset/draft.md /mydocset/final.md
rm /mydocset/old.md
rm -r /mydocset/section

Every operation is a whole-object atomic swap. Directory moves are not supported because the filesystem has no atomic tree-move operation; create the destination and move files explicitly.

Publish to an inbox

publish lets a contributor read a whole docset while creating or editing only inside its inbox:

echo "# API Notes" | publish backend api-notes.md
echo "# Research" | ssh -p 2222 server publish backend research/findings.md
ssh -p 2222 server publish  # list available inboxes

Configure an inbox and grant publish:

{
  "docsets": {
    "backend": {
      "paths": ["/docs/backend"],
      "inbox": "inbox",
      "access": { "allow": { "contributor": "publish" } }
    }
  },
  "roles": {
    "contributor": {}
  },
  "identities": [
    { "name": "research-agent", "roles": ["contributor"] }
  ]
}

The write lands under /docs/backend/inbox. A publish grant never permits deletion; use rw for unrestricted writes within the docset.

Conflict handling

Overwrites use compare-and-swap by default. If a file changed since the session read it, OpenLore rejects the stale write rather than silently clobbering newer content. Append and patch operations always use compare-and-swap.

readonly: false
write_conflict_policy: hash  # hash (default) or last_write_wins

Override the policy for a specific docset in lore.json:

{
  "docsets": {
    "ops": {
      "paths": ["/ops"],
      "write_conflict_policy": "hash"
    }
  }
}

Human approval

Selected paths can route writes and deletes into pending changesets instead of committing immediately:

{
  "docsets": {
    "ops": {
      "paths": ["/ops"],
      "requires_approval": [
        { "path": "/ops/policy.md", "capability": "approve@oncall" }
      ]
    }
  }
}

Pending changes appear under /requests. An identity with the required capability reviews and commits them with approve. A pending delete preserves an exact subtree snapshot for review.

Asynchronous jobs

The optional spawn command lets explicitly trusted identities run configured external work and write its output back later. Grant the spawn capability on a role and bound concurrency:

readonly: false
max_jobs: 8

Jobs appear under /jobs. Their write-back goes through the same path scope, compare-and-swap checks, validation, and approval policy as an interactive write. A normal session without this explicit capability cannot execute host processes.

Validation and hooks

All write verbs converge on one write seam. Plugins can reject content before commit, require knowledge-format conformance, enrich metadata, or react after a successful commit without creating alternate mutation paths.

See Plugins and knowledge formats for policy extensions and Write system internals for the filesystem and commit model.

Edit this page on GitHub ↗Source: docs/writing.md

Search the manual

Search the project documentation. No external service.