row 218: C2-12 setup sheet for Melanie and the library survey run sheet (#1719)

Doc only. docs/case2/SETUP-SHEET.md and docs/case2/SURVEY-RUN.md, with claim sources and rulings in
agents/sage/work/queue-218/BUILD.md. Survey flags, output lines and exit codes from
packages/library/src/survey.mjs and scripts/mosaic:37-41.
This commit is contained in:
jason.woltje committed 2026-10-21 06:43:17 -05:00
1 parent 5c6f73ed75
commit fc0d9c26fc
3 files changed
+364

No files matched your search

+124
View File
@@ -0,0 +1,124 @@
# Your books in Mosaic: a setup sheet
This sheet is for you, Melanie. You keep writing in Obsidian the way you do now. Mosaic reads your
books repo after obsidian-git pushes it to git.mosaicstack.dev. It changes nothing on your machine and
commits nothing to your repo.
## What the agents read
The agents read your books repo as you last pushed it. A push reaches them in about a minute.
They read notes, the `.md` files, inside your book folders. They don't read:
- notes at the top of the repo, outside any book folder
- `.canvas` and `.base` files, even inside a book folder
- images and other attachments
- anything in your other repos under `~/src`
They can't write to your repo at all. That covers canon, the playground and everything else.
Which folders are book folders, and which hold characters, places, research, your tracker or chapter
summaries, is set in one place. It is the `projects` entry of your business file in Mosaic. Jason
edits it by hand, and the agents can't change it. He will ask you to confirm it before the agents start.
## Your playground
A folder named in the `playground` list of that entry is your playground. Each playground folder sits
inside one book folder, so one per book works well, for example `<book>/playground/`. You choose the
names and tell Jason. Until you have one, every note in a book folder is canon.
What the playground means for the agents:
- They search canon unless they ask for the playground on purpose.
- An agent may quote a playground note in an idea or a question. It may not use one to back a fact,
a finding or a correction. Mosaic refuses that reply before you see it.
- Only the folder decides. A tag or a property can't make a note playground or canon.
### Colour the playground in your graph
This is a setting of your own vault. It changes nothing for the agents.
1. Open the graph view and open its settings panel.
2. Under Groups, choose New group.
3. In the query box, type the playground's path with `path:`. Your vault is `~/src`, so the path
starts with your books repo folder: `path:"<books repo folder>/<book>/<playground folder>"`.
4. Pick a colour.
Add one group per playground folder.
## Two things you might not expect
### Moving a note into a book folder makes it canon
The folder decides, so a move changes what the agents may do with a note. Once you move a note out of
the playground into a book folder and push, it is canon. The agents may then cite it as fact. A note
that isn't settled yet belongs in the playground. Any note in a book folder outside the playground is
canon, rough drafts included.
### A short link can point somewhere else for the agents
Obsidian looks up a short link like `[[Mara]]` across your whole vault, `~/src`. The agents see only
your books repo. Say a note called `Mara` exists in your books repo and also in another of your repos.
Obsidian and the agents can then open different notes for the same link, and the agents can't tell.
If the name exists only in the other repo, the link leads nowhere for the agents.
A link with the full path from the top of your vault reaches the same note in both:
```
[[<books repo folder>/<book>/<characters folder>/Mara]]
```
Obsidian can write new links this way. In Settings, open Files and links and set New link format to
Absolute path in vault.
## Lists of links in properties
The agents read the links in two properties, `appears_in` and `relationships`. Put quotes around each
link in the list:
```yaml
appears_in: ["[[A]]", "[[B]]"]
```
One link per line works too:
```yaml
appears_in:
- "[[A]]"
- "[[B]]"
```
Obsidian's property editor adds the quotes for you. If you type the list by hand, don't leave them out:
```yaml
appears_in: [[[A]], [[B]]]
```
The agents' reader can't read that form. It then ignores every property of that note and lists the
note as a problem in Mosaic's status. It still finds the note by its path, its name and its text. A
value written without `[[ ]]` counts as a plain name, not a link.
## What changes for Bean and Chet
They keep their names and personalities. How they answer changes.
In Hermes they answer in free text and may write story text when you ask. In Mosaic every reply is a
short list of items. Each item is an idea, a question, a finding or a fact. Each one quotes a line
from your repo or from a web page the agent read for you.
They don't write passages. If you ask for prose, you get a question or an idea instead.
Today a reply holds at most 10 items. It has at most 5 ideas of up to 200 characters each. A question,
finding or fact runs up to 300 characters. You or Jason can ask for lower limits. When an agent can't
back an answer with a quote, you see "No cited answer" instead.
Each book world stays separate. One item can't mix quotes from two worlds.
You talk to them in the Console. Hermes keeps running until you have moved over, and stopping it is
your choice.
Five more helpers can join them: ideas, research, proofreader, fact-checker and continuity. You
choose which ones to start with, and you can add one later.
## What Jason will ask you
He will ask you to confirm your book folders and type folders, which books share a world, the name of
each playground folder, and which helpers to start with and when.
+111
View File
@@ -0,0 +1,111 @@
# Survey run sheet for the library host
This sheet is for whoever runs `mosaic library survey` on `<host>`, 10.1.1.54, under design 10 step
7. The survey reads one commit of a git repo and prints names and counts. It never prints note text,
property values, file names or link targets. Jason fills in the mapping for Melanie's books repo
from its output and her answers.
Out of scope: sending anything to Melanie. Design 10 step 7 makes that Jason's call.
## Before you start
- Jason's go for step 7. Step 4, the bot token in the `library-gitea` slot, comes first.
- You run as `mosaic` with `sudo -u mosaic -H` from `localadmin`. `mosaic` has no login shell.
- The stack copy from step 2 is in place at `/srv/mosaic/.local/share/mosaic-stack/copies/<id>`.
`<id>` is the full commit id in Jason's go. It must hold row 231, which escapes control and bidi
characters in folder names. In a canonical checkout, `git merge-base --is-ancestor 29ce1e360 <id>`
exits 0 when it does.
- `<node dir>`, the directory that holds `node`. It is the directory of the `--node` path given to
`case2-unit.sh` in step 2c. `scripts/mosaic` runs `node` from `PATH`.
- `<repo>`, an absolute path. See the next section.
## The repo to survey
The survey reads a local repo. It doesn't fetch. `<repo>` must:
- be the repo's top folder, or a bare repo's own folder. A folder inside a repo refuses, because the
survey stops git from looking above the path's parent.
- belong to `mosaic`. The survey gives git no global config, so a `safe.directory` entry can't
admit a repo another user owns.
- have a `HEAD` that names a commit. The survey reads `HEAD` and has no flag for another ref.
`<repo>` is the bus's bare mirror at `<dataRoot>/projects/<business>/<project>`, which C2-04 (row 215)
creates and C2-03a (row 222) fetches into. It is the only copy of her repo on the host (design 2.1), and
`mosaic` owns it. Survey it after the first `library.sync` succeeds. The mirror's `HEAD` points at
`refs/heads/served` (C2-03a brief), so the survey reads the commit the agents are served.
Don't survey anything else. A hand clone with the bot token would put the token where design 7.2 keeps
it out, and the mirror's refs belong to the bus. If `HEAD` names no commit, stop and report to Sage.
## Steps
1. `ssh [email protected]`.
2. Run the survey without a mapping:
```sh
cd /
sudo -u mosaic -H env PATH="<node dir>:/usr/bin:/bin" \
/srv/mosaic/.local/share/mosaic-stack/copies/<id>/scripts/mosaic library survey <repo>
echo "exit $?"
```
3. On exit 0, give the output to Jason. On any other exit, see "Refusals" below.
4. When Jason has a draft mapping, run it again with `--mapping`. The file holds the library entry
alone, `{"kind": "library", "remote": ..., "branch": ..., ...}`, without the business file or the
`"projects"` wrapper around it. `remote` and `branch` are required even though the survey doesn't
fetch. `mosaic` must be able to read the file. Set `vaultPrefix` to her books repo's folder name
in her vault. Without it, a link with the full path from the top of her vault resolves to nothing,
and the setup sheet tells her to write links that way.
```sh
sudo -u mosaic -H env PATH="<node dir>:/usr/bin:/bin" \
/srv/mosaic/.local/share/mosaic-stack/copies/<id>/scripts/mosaic library survey <repo> --mapping <file>
echo "exit $?"
```
The usage line is `mosaic library survey <repo> [--mapping <file>]`. `--mapping <file>` is the only
flag, and it may appear once. `--mapping=<file>` and every other flag refuse.
## What the output holds
Plain text on stdout, one line per item:
| Line | What it holds |
|---|---|
| `commit <id>` | the 40-hex commit `HEAD` names |
| `entries <n>` | every entry in that commit's tree |
| `folders (direct children: md canvas base other)` | then one line per folder that holds a file directly: its path as a JSON string and four counts. `(root)` is the repo's top |
| `markdown <n> files, <n> read, ...` | `.md` files, how many were read, how many have no front matter, how many have front matter the reader can't fully parse |
| `front matter key sets` | then `<count> [<keys>]` per set of property names. A name that isn't a short identifier prints as `(other key)` |
| `body links plain .., label .., heading .., embed .., self .., markdown ..; attachment ..` | link forms in note bodies, and embeds of a target with an extension other than `.md` |
| `field appears_in wikilink .., name ..` | values written as links and as plain names. A `relationships` line follows |
With `--mapping` three lines follow:
| Line | What it holds |
|---|---|
| `scopes canon .., playground .., unmapped ..; indexed ..` | tree entries per scope, and notes indexed |
| `resolved root .., vault-prefix .., relative .., shortest .., unresolved ..` | links per resolver step. `unresolved` is the R4 count |
| `problems R1 .., ..., R7 ..` | problems per rule |
Folder paths and short property names are the only words from her repo in the output. A folder name with a control or bidi
character prints it as `\uXXXX`.
## Refusals
A refusal prints nothing on stdout and one line on stderr. The survey checks the mapping before the
repo, so a bad mapping gives exit 3 even when the repo path is wrong too.
| Exit | stderr | Cause | What to do |
|---|---|---|---|
| 4 | `library survey: usage: mosaic library survey <repo> [--mapping <file>]` | no repo, two repos, an unknown flag, `--mapping` without a file or twice | Fix the command |
| 3 | `library survey: library-mapping-invalid: <file> is not a readable JSON file` | missing, unreadable by `mosaic`, or not JSON | Fix the file or its mode |
| 3 | `library survey: library-mapping-invalid: <file> <reason>` | the entry breaks the schema. The reason names the key | Give it to Jason for the draft |
| 3 | `library survey: library-playground-outside-book: <file> universes.<u>.playground "<prefix>" is not inside one of its books` | a playground prefix outside its universe's books | Give it to Jason for the draft |
| 2 | `library survey: library-git: <repo> is not a directory` | wrong path | Check `<repo>` |
| 2 | `library survey: library-git: repository has no readable HEAD commit (project-git)` | not a repo, a folder inside one, another owner, no commits, a `HEAD` with no commit, or no `git` on `PATH` | Check each. If `<repo>` is the bus mirror, stop and report to Sage |
| 2 | `library survey: library-git: <other reason>`, such as `tree listing refused (project-git)` | git failed or ran past 100 seconds | Report to Sage |
| 127 | a line ending `exec: node: not found` | `node` isn't in `<node dir>` | Fix `<node dir>` |
| other | a Node stack trace | a fault in the survey | Stop and report the exit code to Sage |
A refusal is the answer, not an obstacle. Don't run as another user, change modes on her repo or edit
its refs to get past one.