Skip to main content

20  Knowledge across domains

This chapter is about Reflection pages that draw on more than one domain: who reads such a page, why a section carries only what all of its readers may read, how an agent running on its own is kept from passing a secret along and how a person shares a line on purpose anyway. It picks up where Chapter 12, Chapter 14 and the access that follows GitHub (Chapter 19) left off.

20.1 A page is a noticeboard

In Chapter 12 a page could draw on the engrams of other domains too (handy when one page should sum up several). Picture the noticeboard in the clubroom. A note pinned there reaches everyone who walks by, key to the room it came from or not, and a page reaches everyone who may read it the same way. Hence the one rule every section follows: it may draw on another domain only when everyone who reads the page may also read that domain’s engrams.

On the page’s side of that rule you count everyone who reads the domain’s Reflection (its Reflection collaborators too), on the other side only the people who read the engrams. A Reflection grant there opens that domain’s pages and never its engrams, so it doesn’t help. Drawing on the page’s own domain is always fine, and the admins and the machine owner read everything anyway, so they never decide anything here.

On the club’s server access follows GitHub (Chapter 19): club is shared, so every signed-in account at viewer or above reads it, and committee is private and lives in a repository of its own, dallas/club-committee, where only Dallas and you are collaborators. Set the two directions side by side (Figure 20.1): a committee page may draw on club, because the people who read it (Dallas and you) both read club anyway. A club page may not draw on committee, since every member reads the page and most of them can’t open committee.

Two panels side by side. Left, titled A committee page draws on club: a large box, club's engram readers, every member, holds a smaller box, page readers, Dallas and you, entirely inside it. Below it the verdict: allowed. Right, titled A club page draws on committee: a large box, page readers, every member and Lambert, holds a smaller box, committee's engram readers, Dallas and you, so the page's readers spill far beyond the smaller box. Below it the verdict: refused, unless shared on purpose. A strip across the bottom says that on a team domain the page's readers also include everyone who can read its repository.
Figure 20.1: The readers of a page compared with the readers of the domain a section draws on. The page may carry the text when its readers fit inside.

Say Dallas switches Reflection on for committee one day and wants a page on what the club spent on books this year, built from the receipts in committee and the reading list in club: the agent writes it and nobody hears a thing. Ask for the same receipts on a club page and the write is refused, with nothing written.

TipUnder the hood

The rule holds for every writer: a person’s agent, the machine owner and a scheduled run, on the daemon, the embedded stdio server and a one-shot command alike. A refused write gets “this source is in a domain fewer people may read than this page’s domain; leave out the source and every sentence drawn from it, since the check sees only named sources, or write that text on a page in that domain instead”. The check sees only the sources a write names and never reads the text. An agent that drops a refused source and keeps its sentences isn’t caught, so a curator reads a page built from several domains with that in mind. Name a domain the writer may not open and the refusal looks like the one for a domain that doesn’t exist. When the accounts store can’t be opened, every source outside the page’s own domain is refused. (With a GitHub App, a private domain is read by the instance admins plus the linked accounts its repository lists as collaborators with read or more, never an account with the instance role none.)

20.2 Guests at the board

Lambert follows the club on her phone: her account has the instance role none and she holds a Reflection grant on club as a contributor, so she reads and edits every club page and has never seen an engram. As long as she holds that grant, no club page may draw on any other shared domain, sci-fi included (it lives in the same repository, and every member reads it). The other way round is fine, though: Lambert has no grant on sci-fi, so whoever reads a sci-fi page reads club too.

Visitors without an account are the other kind of guest. On the club’s server a visitor reads a shared domain only when its repository is public on GitHub, and dallas/book-club is private, so they don’t come into it. If Dallas ever makes it public, every visitor reads every club page, and a club page then draws only on domains a visitor may read as well.

You’ll most likely find out about Lambert like this:

You:    On the Dune page, add what the sci-fi shelf says about
        the sequels, with sci-fi as the source.
Agent:  Refused, nothing written: this source is in a domain
        fewer people may read than club's. I can leave out the
        source and every sentence from it, or write the text on
        a page in sci-fi instead.
You:    Lambert. She reads every club page and no engrams.
        Leave it out, then.
Agent:  Left out. The Dune page is as it was.

The refusal names nobody, so working out why is up to you, and on the club’s server the answer is nearly always Lambert.

TipUnder the hood

A Reflection grant counts on the page’s side and never on the other side. On a domain that follows GitHub, an account with the instance role none gets nothing from its instance Reflection level, so Lambert reads the club’s pages through her grant on club alone. (A grant on sci-fi as well wouldn’t help club pages and would also stop sci-fi pages from drawing on club.) An account that gets such a grant later is caught by the queue, which checks again on every scan. A page an anonymous visitor reads may only draw on domains an anonymous visitor reads too.

20.3 The repository reads along

A page in a team domain also goes to the crystalline/reflections branch of its repository as a backup, and anyone who can read the repository can read that branch, with an account on the server or without one. That gives the rule a second half, and a section needs both: the domain it draws on has to be on GitHub too, and everyone who reads the page’s repository has to be able to read the other repository. A domain from the page’s own repository always passes, and one from a public repository does too. When the page’s repository is private, another repository passes if each collaborator of the page’s repository is a collaborator there too. A local or virtual domain never passes without a person’s yes, which is why personal knowledge can’t end up in a team’s repository this way.

In the club the second half mostly agrees with the first. club and sci-fi share dallas/book-club, so only Lambert stops a club page from drawing on sci-fi. A committee page drawing on club passes again (Dallas and you are the only collaborators on dallas/club-committee, and you’re both on dallas/book-club). A club page drawing on committee fails here as well: Kane reads dallas/book-club, so does the GitHub user the club’s scheduled run acts as, and neither of them is on dallas/club-committee. Your own books and shops stay on your laptop and never get near the club’s pages.

TipUnder the hood

A source in a domain that isn’t on GitHub is refused with “this source is in a domain that is not shared through GitHub, and this page is backed up to a GitHub repository; leave out the source and every sentence drawn from it, or cite it from a page in that domain instead”. The repository half is answered from the App’s list of collaborators, which is fetched once per repository, kept for five minutes and refreshed at once by a webhook, and while it isn’t known the source is refused. An internal repository of a GitHub Enterprise is read by the whole enterprise, so a page there draws only on its own repository’s domains and on public ones. Without the App, Crystalline doesn’t know a repository’s readers and treats any two connected domains alike. One honest caveat: the branch keeps each page as it is on disk, so whoever reads the repository sees the names and addresses of the domains and engrams a page draws on, never their text.

20.4 The confused deputy

Security people have an old name for a program that holds more rights than the person asking it and gets talked into using them on that person’s behalf: a confused deputy, which means no harm and simply never checks whose rights it’s using. In the Reflection the obvious candidate is the scheduled run. Anyone who may comment on a club page can ask a question in a thread, and a run that could read committee would answer from there, into a thread every member reads (the answer itself would be the leak). Nobody in the thread would even need a Jedi mind trick: a polite question would do.

Threads don’t get a source check: a thread is people talking, with each other and with their own agents, and what you write there is yours to say. And since they go to the backup branch with their page, a thread reaches everyone who reads the repository. That’s why the guard sits on what an agent reads while nobody is behind it (Figure 20.2): an unattended session reads only the domains every reader of its own domain may read, the others look as if they didn’t exist, and it writes into its own domain and nowhere else.

The club’s run can’t see committee, because most members can’t open it, and it can’t see sci-fi either, because Lambert reads the club’s pages without reading sci-fi’s engrams. So the run on club reads club and nothing else (that’s what Lambert’s grant costs).

Kane, who asks in a thread, sends a question to the thread on the Dune page, which carries no source check. The thread passes it to the scheduled reflect run on club, which is unattended and reads and writes club only. From the run one arrow goes down to club, which the run reads; another ends at a bar before committee, marked hidden from this run. A third arrow leads from the run to the answer in the thread, drawn from club only, with the question left open for a person. From the answer an arrow leads to a wide box: everyone who reads the page, and everyone who can read dallas/book-club through the backup branch.
Figure 20.2: A thread question meets a scheduled run that can’t see the private domain, so the answer comes from the run’s own domain only.

Kane asks on the Dune page why the club never buys the hardback for its shelf. A few minutes later the club’s run comes by, sees the club’s list but not the budget, answers what it knows and leaves the thread open:

Thread on "The club reads Dune in paperback"
  Kane:   Why don't we buy the hardback for the shelf? It's the
          one we'd all keep.
  Agent:  note (non-blocking): The club waited for the paperback
          reprint because nobody wanted the hardback. Whether
          there is money for a shelf copy isn't something I know.
          Leaving this open for Dallas.
TipUnder the hood

A session is unattended when a run started it, when it was started with --unattended (mark your own cron job this way) or when its caller holds a live lease of the reflect or evolve loop. crystalline reflect run and crystalline evolve run start their agent with crystalline mcp --unattended --domain <domain>, or over HTTP with the header X-Crystalline-Run-Domain: <domain>, which the server believes only while that account holds the lease. The limit covers every read: search, read_engram, build_context, browse_domain, recent_activity, list_domains, the sources a page names, attachments and other domains’ Reflections. Writing anywhere else gets “this run works on club and cannot write to committee”. A local run without an account looks just like you, so while it’s going your other local sessions read and write like the run, and every tool answer carries one line that says so.

20.5 Sharing on purpose

Sometimes a line from a narrower domain does belong on the board, and a person who may read it decides that. If an agent writes a section the rule would refuse while a person is behind the session, the write stops and asks that person first. The question tells you in plain words who reads the page, shows you the text and warns that it becomes readable by all of them (the names of the sources stay hidden from readers who may not open that domain). There’s one box, and it starts unticked: only a ticked box plus Accept shares the text, while a decline, an empty box or ten minutes of silence refuse the write. In an unattended session nobody is asked, so a run never shares anything.

Only someone who may curate the page and read the domain drawn on can say yes. It holds for that person, that page and that domain, so their later edits there need no new question, and anyone else is asked on their own (Figure 20.3). Don’t mistake the box for a lock against your own agent: an agent with a shell on your machine can do anything you can, and a client that answers questions by itself gets around it. The guard is the read limit from the section before. In Fluid a person answers the same question from the Review, behind a Share on purpose button on a section the queue already names (after an edit on disk, say, or once the readers grew).

A decision flow from top to bottom. First: may the writer open that domain? If not, the write is refused as if the domain did not exist. If so: does everyone who reads the page read that domain, the repository's readers too? Yes leads to written, the page carries the text. No leads on: did this person share it here already, for the same readers? Yes leads to written. No leads on: is a person there, with a client that can ask, which is never the case in a scheduled run? No leads to refused, nothing written: leave out the source and its text. Yes leads to the question, naming who reads the page, showing the text, with one box. A ticked box and Accept lead to written; a decline or no answer lead to refused.
Figure 20.3: What happens when a write names another domain to draw on.

Dallas reads Kane’s thread and agrees with you that members should know where the shelf money went. So you ask the agent you use on the club’s server, which signs in as you with your own token (it has to be that one, since nobody gets asked about a write your laptop forwards to the server):

You:    Add one line to the Dune page from committee: this year
        the club pays half of each member's first Dune
        paperback, and that's where the shelf money went.
        Then answer Kane.

  Share text from committee on a page more people may read?
  The page dune.md in club is read by the 9 accounts that may
  read club, and by the people who can read the GitHub
  repository dallas/book-club, where this page is backed up.
  Fewer people may read committee. Not everybody who can read
  dallas/book-club may read the GitHub repository of committee.
  The text to share: "## The club reads Dune in paperback The
  club waited for the paperback reprint because nobody wanted
  the hardback. This year the club pays half of each member's
  first Dune paperback, which is where the money for a shelf
  copy went.". If you agree, this text becomes readable by all
  of them. The names of the sources stay hidden from readers
  who may not read committee. Agree only if you mean to share
  it.
  [ ] Yes, share it with these readers         Accept  Decline

You:    (tick the box, Accept)
Agent:  Written. The Dune page has the line, and I answered
        Kane in his thread.

When Kane opens the page that evening the line is there, and the section’s sources say “1 source in a domain you cannot open”. Dallas sees committee in the same spot, with a note that you shared it on purpose and when.

TipUnder the hood

write_reflection asks with input_required on a client of the 2026-07-28 MCP revision, or with an elicitation request on an older client that declared it. A client that can’t ask its user is refused, and the refusal says that a person who may read that domain can share it from a client that can ask. The question never goes to an anonymous caller or the open tier, and it never comes up for a write a connected machine routes to the server. A yes is bound to the readers and the repository the question named, and when either changed before the write lands, the write is refused with “who may read this page, or where it is backed up, changed since the person was asked; ask them again”. The server keeps the confirmation in its index, never in the page file: who, when, which page and domain, who read the page then and, with the App, who read its repository then. read_reflection shows curators a section’s disclosed, and Fluid shows “Shared on purpose by” with the name and date. Moving the page keeps the confirmations, while deleting the page, dropping the last citation of that domain or crystalline reindex --wipe drops them.

20.6 When the readers change

Some changes can’t be refused because they never go through a write: a page edited on disk, a page restored from the backup, a change of who reads a domain. A yes on purpose covers only the readers it was given for, so a new reader who can’t open that domain ends it. If the domain drawn on narrows later, nothing happens (its text reached those people already). Whenever a section ends up drawing on a domain fewer people read, the queue names it for the curators who may open that domain, and nobody else sees the item. The page keeps serving in Fluid until a person decides, because deleting text is a person’s call. The backup is stricter, since the repository’s readers read the branch: it holds the page back with its threads and the files only held pages link, and the branch head loses its copies (what went out earlier stays in the branch’s history). Once a curator removes the source and its text, or someone shares it on purpose again, the item is gone and the page goes back to the branch (Figure 20.4).

Top row, left to right: an edit on disk, a restore or a change of readers leads to a section that draws on a domain fewer people read, which leads to a source_too_wide item in the queue, for curators who may open that domain. From the section a second arrow leads to the backup, which holds back the page, its threads and its own files, while the branch history keeps what went out earlier; meanwhile the page keeps serving. From the backup two arrows lead to two ways out: a person shares it on purpose in the Review, or a curator removes the source and its text. Both lead to a wide box at the bottom: the item is gone and the page goes to the branch again. A dashed arrow runs from that box back to the section, labelled the page's readers widen later.
Figure 20.4: A section whose readers grew beyond the domain it draws on is held back from the backup until a person decides.

In the autumn Dallas adds a new member as a collaborator on dallas/book-club, so she can follow the club on GitHub. She has no account on the server yet and can’t read dallas/club-committee, so seconds after GitHub’s webhook the Dune section is a queue item and the next backup drops the Dune page and Kane’s thread from the branch head (the version that went out earlier is still in the history, so the hold only stops the next copies). Members on the server don’t notice a thing (the line is still on the page). On Monday Dallas opens the Review, finds the section under “Cites a domain fewer people read”, presses Share on purpose, reads the question and chooses Share it. The item’s gone, and the next backup puts the Dune page back on the branch.

TipUnder the hood

The queue item is source_too_wide (only a caller who may open that domain gets it, with the question a person is asked). The daemon looks for pages that newly break the rule every five minutes, and at once after a change of visibility, membership or account through the JSON API or with crystalline domain visibility, domain members and domain transfer, and when a GitHub webhook comes in. The backup checks the files it’s about to send as well as the index, so a page edited on disk is held back before the index has read it, and a page whose reflection: block can’t be read is held back too. It logs what it held back and looks again ten minutes later, or at the next change. Share it in the Review confirms for whoever reads the page at that moment; if that changed since the Review was loaded, the confirmation is refused and the item asks the new question.

NoteIn brief

A Reflection page reaches everyone who reads it, so a section may draw on another domain only when all of them may read that domain’s engrams (on a team domain that includes everyone who reads its repository). A Reflection grant counts for the page and never for the domain drawn on, which is why Lambert’s grant on club keeps every club page from drawing on sci-fi. A run that works alone reads only what every reader of its domain may read and writes only there, so a question in a thread can’t make it a confused deputy. A person shares a line from a narrower domain on purpose by ticking one box, and that yes holds for the readers of its moment. When the readers change, the backup holds the page back until a person decides.