OpenWriterControle/novel/PACK-NOTES.md
cclohmar 4b9a535d6c
Some checks are pending
Create Release / Check if Version Bump PR Merged (push) Waiting to run
Create Release / Create Git Tag and GitHub Release (push) Blocked by required conditions
Post-Merge Version Bump / Check if Version Bump Needed (push) Waiting to run
Post-Merge Version Bump / Create Version Bump PR (push) Blocked by required conditions
docs(novel): switch the pack to the container-vault layout
One Obsidian vault holds every book; each book is a subfolder and is the opencode
workspace. The pack is shared at the vault root and inherited by walking up, so a
book no longer gets its own .opencode copy:

- SCHEMA §1 rewritten: container vault -> book folders, shared .opencode + docs
- init.md: scaffolds only the book (AGENTS.md, DATA/, 01/), checks that a shared
  pack is reachable, and no longer copies agent/command files into the project
- PACK-NOTES: layout diagram + a headless section documenting the deny-based
  permission model
2026-10-16 23:36:04 +01:00

105 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenNovelWriter agent pack — provenance
Committed 2026-10-16 by Hermes. Before this, the pack existed **only** as three byte-identical copies inside Obsidian vaults, with no version control.
## Lineage (verified from filesystem mtimes)
The three vaults are not redundant copies of one thing — they have distinct roles:
| when (8–9 Sept 2026) | where | what |
|---|---|---|
| 17:10 → 21:33 | `OpenNovelWriter` vault | the pack was **authored/rebuilt here** (AI-assisted OAC → OWC conversion); `docs/SCHEMA.md` last revised 21:30 |
| 21:34:47 | `Scruffy-der-Weltenhund` + `Die-Kessler-Zwillinge` | the pack was **deployed** to both — hence identical md5s |
| 21:46 → 22:00 | `Scruffy-der-Weltenhund` | **real writing and data**: `DATA/style.md` 21:46, `glossary` 21:52, `wiki`+`timeline` 21:54, `01/DE/Kapitel 002` 22:00 |
| 9 Sept 13:44 | `Scruffy-der-Weltenhund` | `01/DE/Kapitel 001.md` — the newest file in the whole set |
**Consequences for anyone reading this later:**
- **Scruffy is the live project and the best instance** — it holds the only book content (`DATA/`, `01/DE/`, a filled-in `AGENTS.md`) and the newest timestamps. It is the reference for how the pack behaves in real use.
- **`OpenNovelWriter` is the pack's source** — it is where the framework was authored and revised, and it carries the distribution extras (`LICENSE`, `templates/`, product `README.md`).
- **`Die-Kessler-Zwillinge` was an import test, not the final project.** It contains only the pack plus Obsidian's stock `Welcome.md`; no manuscript was ever imported into it. Treat it as disposable — create a fresh vault for the real Kessler import.
- The pack was deployed *before* Scruffy's writing began, so Scruffy's instance files are **newer than the pack** — never "restore" a vault from the pack wholesale; sync only the pack-managed paths.
## Sources
| file | md5 | source |
|---|---|---|
| `.opencode/agent/ContinuityEditor.md` | `5083c6929bd2` | agent |
| `.opencode/agent/CopyrightWatchdog.md` | `0457635edecc` | agent |
| `.opencode/agent/Illustrator.md` | `e8dc9e1c5fd8` | agent |
| `.opencode/agent/Importer.md` | `67d2434b980e` | agent |
| `.opencode/agent/LineEditor.md` | `cdb3f8b1e69c` | agent |
| `.opencode/agent/OpenNovelAgent.md` | `15b891682a34` | agent |
| `.opencode/agent/Proofreader.md` | `7572ea57ef75` | agent |
| `.opencode/agent/StoryReviewer.md` | `a4a9249b1401` | agent |
| `.opencode/agent/StyleAnalyst.md` | `b19f9cba3eff` | agent |
| `.opencode/agent/Translator.md` | `8efac4a757f7` | agent |
| `.opencode/command/import.md` | `edfd797b99ce` | command |
| `.opencode/command/init.md` | `19f0c1670b64` | command |
| `.opencode/languages.yaml` | `0a33e641d04c` | language map |
| `.opencode/opencode.json` | `65438515bec8` | pristine config (default_agent) |
| `LICENSE` | `538dbda71eed` | pack doc |
| `README.md` | `805f1d95a2f3` | pack doc |
| `docs/SCHEMA.md` | `e28c37ae2ada` | canonical schema (revision of 21:30) |
| `start.sh` | `841b0997a053` | launcher |
| `templates/AGENTS.md` | `ba5da851f769` | template |
| `templates/DATA/glossary.yaml.md` | `af92947f7799` | template |
| `templates/DATA/style.md` | `61dd239ac643` | template |
| `templates/DATA/timeline.yaml.md` | `06fa5d2c0fc6` | template |
| `templates/DATA/wiki.yaml.md` | `ffbb023a0a18` | template |
| `templates/README.md` | `937b06aaa694` | template |
## What was verified before committing
- All **10 agents**, both **commands** (`import.md`, `init.md`), `languages.yaml` and `start.sh` are **md5-identical** in all three vaults — there was no divergence to reconcile for them.
- `docs/SCHEMA.md` is the only real divergence: the pack version (9477 B, 257 lines, **21:30**) supersedes Scruffy's copy (5812 B, 182 lines, **17:45**). Scruffy's seven unique lines are **structural only** — the old section numbers (`## 7. The Co-Authoring Cycle`, `## 9. Versioning`) and the old ASCII tree — so nothing was lost in the revision. The committed version adds *workspace = book*, `images/prompts` + `images/generated`, multiple-books-in-parallel, a **Temperature Policy** section, and renumbers Co-Authoring Cycle to §8 / Versioning to §10. Scruffy's copy is simply the *pre-revision* one — not damaged, just older.
- `AGENTS.md` in the Scruffy vault is a *filled-in instance* (real series title/author/genre), not the template — the placeholder version is committed as `templates/AGENTS.md`; instances stay in their vault.
- `opencode.json` is committed pristine (`$schema` + `default_agent`). The permission block added to the Kessler vault (external_directory allow for `/Users/Shared/Novels/**`) is machine-local and deliberately **not** in the pack.
## Layout this pack is built for
One container vault, one folder per book, **one** `.opencode` shared at the vault root:
```
/Users/Shared/Vaults/Novels/ # the vault (human interface: Obsidian)
├── .opencode -> /Users/Shared/NovelPack/.opencode # this pack, symlinked
├── docs -> /Users/Shared/NovelPack/docs # this SCHEMA
├── AGENTS.md # house rules
├── Scruffy/ # a book = a workspace
└── Kessler/ # another book
```
opencode walks up from the book folder to find `.opencode`, so books carry no copies.
(`/Users/Shared/NovelPack` exists because opencode writes `node_modules/` and a
`package.json` next to the agents it loads — pointing that at a plain pack directory
keeps both the vault and this repo clean.)
## Headless operation
The pack runs headless: `bash` is allowed by default in `OpenNovelAgent` and
`Importer` (it was `"ask"`, which opencode cannot prompt for in `opencode run`, so
every tool call was auto-rejected). Safety now comes from **explicit denies** of
irreversible commands — `rm -rf *`, `rm -rf /*`, `sudo *`, `mkfs*`, `diskutil *`,
`shutdown *`, `reboot*` — plus the existing `.env`/`.key`/`.secret`/`.git` edit denies.
`--dangerously-skip-permissions` is therefore no longer needed.
The other eight agents keep `bash: "deny"` on purpose: they are note-editing
subagents that use opencode's file tools and never need a shell.
## Sync direction
The repo is the source of truth **for the pack**. Vaults pull pack-managed files from here:
```sh
novel/sync-to-vault.sh /Users/Shared/Vaults/Scruffy-der-Weltenhund # dry run
novel/sync-to-vault.sh /Users/Shared/Vaults/Scruffy-der-Weltenhund --apply # write (backs up what it replaces)
```
`sync-to-vault.sh` overwrites only agent/command files, `docs/SCHEMA.md`, `languages.yaml` and `start.sh`. It never touches `DATA/`, `AGENTS.md`, `01/`, `Notizen/`, `Welt/` or the vault's own `opencode.json` — the newest content in the set (Scruffy's) is exactly what it leaves alone.
## Known open items
- Scruffy's `docs/SCHEMA.md` predates the pack revision — running the sync refreshes just that file and loses nothing of the writing.
- No book-specific content is committed here by design: `DATA/`, chapters and `AGENTS.md` instances stay in their vaults (or get their own repo).
- `Die-Kessler-Zwillinge` is a spent import test; pick a fresh vault target before running the real import.
- `Importer` is a subagent: invoke via the primary agent or `/import`, not `opencode run --agent Importer`.