Both halves

Install

Here is what having this installed is actually like. You are in the middle of something, the work turns into a judgment only you can make, and you get a page instead of another four paragraphs. You print it and take it to a kitchen table. Later you photograph what you wrote, and the work resumes from your handwriting.

Take both halves or neither. Every sheet the forward half prints closes with SCAN IT BACK TO CONTINUE., and the return half is the thing that honours that. Installing one and not the other leaves you holding a finished page with nowhere to send it.

Find the setup that sounds like yours.

One of these four is true of you, and that is the whole decision. The cards are only a way in. The directions themselves are further down this page in a single block, in the repository’s own words, and that block is complete and current whether or not a card here describes your case.

  • You work in a browser tab or an app.

    There is somewhere to attach a file and no terminal to type into. Both halves ship as packaged bundles for exactly this, so the install is two downloads and an upload. The ledger below calls this path supported, and means it: a phone photographing the finished pages is the return trip this was built around.

    The directions ↓
  • You live in a terminal or your editor.

    You have a shell, and Node with it. One installer knows this repository, finds both skills inside it, and knows where they go for your particular setup, including setups nobody here has tested. If you would rather look before you install, it will list what it is about to give you.

    The directions ↓
  • A terminal, but no Node.

    Then you are not missing anything. The bundles are not a special format, whatever unpacks an archive on your machine is enough, and the destination is a folder your agent already reads.

    The directions ↓
  • Nothing to install here.

    Nothing installs, because nothing reads a skills folder. The forward half travels as text you paste, and what comes back is a card you copy into a notebook by hand. Never a PDF, and nothing checked, because nothing is rendered. Better to know that now than halfway through.

    The no-printer path →

Python comes into it twice, and which of those two lands on you depends on where Python runs for you rather than on which card you just read. One library draws the page. The other reads the finished PDF back and checks that no line of type has wandered off the paper or landed on top of another line, which is a check the project does not let a sheet skip. You are going to sit with that page for a while, and a collided label is exactly the kind of small wrongness that makes a person put the pen down.

On a chat surface neither is your problem. The Python runs on that end, not yours. Everywhere else, the directions below name the two packages and where to point pip, and the ledger after that tells you, setup by setup, whether they apply to you.

The directions

These are the repository’s words, not ours.

Mono means one thing on this site: you are reading something quoted straight out of the project. The block below is the repository’s own install section, read out of the file when this page was generated. There is exactly one copy of these commands in the project and this page is not it, which is why the directions cannot quietly go stale while the repository keeps moving.

Verbatim · README §Install

Get both halves, whatever your setup — they're a loop: paper-session prints "SCAN IT BACK TO CONTINUE." on every footer, and scan-back is what honors that promise. There are four routes below; three of them end in an agent that reads a SKILL.md folder, and the last asks nothing of your AI but a text box.

If your AI lives in a chat app — claude.ai, the Claude desktop or mobile apps, or any client that accepts skill bundles — download the two packaged bundles and upload them where your client takes skills. No terminal, no unzipping:

paper-session.skill · scan-back.skill

If your AI runs in a terminal or IDE — the skills CLI finds both skills in this repo and routes them to Claude Code, Cursor, Codex, Copilot, and 70+ other agents:

npx skills add welovejeff/paper-session

Project-level by default; -g installs user-level (for Claude Code, ~/.claude/skills/). --list shows what you're getting first; -a <agent> names the target.

No Node? The bundles are ordinary zips — clone and unzip into your skills directory:

git clone https://github.com/welovejeff/paper-session.git
cd paper-session
unzip -o paper-session.skill -d ~/.claude/skills/
unzip -o scan-back.skill -d ~/.claude/skills/

What the two Python packages are for. reportlab draws the sheet; pdfplumber runs verify_layout.py, the layout gate no sheet is allowed to skip. The list ships inside the bundle, so point pip at the copy that arrived with the skill rather than at this repo:

python3 -m pip install -r ~/.claude/skills/paper-session/requirements.txt

Substitute wherever your agent installed the skill — .claude/skills/paper-session/ inside the project when npx skills add runs without -g — and add --break-system-packages where pip reports the environment is externally managed. Nothing to install by hand on a chat surface, where the skill runs its own Python; nothing at all on the paste channel, which renders no file.

If your AI can't install skills at all — ChatGPT, Gemini, Copilot chat, Perplexity, Le Chat, DeepSeek, Grok, Poe. None of them read a SKILL.md folder, so there is nothing to install and one file to paste: paper-session-paste.md, which is SKILL.md, references/prompt-craft.md, and references/page-patterns.md concatenated by build.sh — byte for byte, apart from one deleted block of install metadata addressed to a runtime that isn't there. Paste the whole file into the chat, say what you're working on, and add this sentence:

I can't print, and you can't make a PDF here, so dictate the setup card for me to copy by hand — there is nothing to annotate.

The sentence is load-bearing, not politeness: it is what routes the host onto the setup-card path, where the AI dictates a short card you copy into a notebook by hand. What you get is that card, never a PDF — no typography, no grayscale, no printed ink key — and no verify gate, which the card path never had in the first place. What you also don't get is authority: a pasted protocol is user text with no standing against the host's own system prompt, so a model tuned to be maximally helpful can still pre-fill a zone or volunteer a duration that the rules in the paste forbid. How often, on which product, is unmeasured.

The return half travels further than the forward half. scan-back is one markdown file with nothing behind it — no scripts, no Python, no fonts, no second document to fetch — so it pastes into a single chat message anywhere text goes: scan-back/SKILL.md. Paste it into the chat the photos are going to land in, when they land — not alongside the forward paste, which would leave the host holding transcription instructions for pages that do not exist yet, and the failure there is a host that narrates the return trip or invents its contents. Reading the pages still takes a surface that accepts photographs, and nothing else.

That means the pages can come back somewhere other than where they were made — printed from Claude Code, photographed into whatever chat is on your phone — and that costs something specific rather than nothing. scan-back calls it the orphan path: the chat holds no memory of the session, so it reconstructs from what the sheet itself prints (title, date, intent line, footer numbering) and spends its one re-anchoring question there. Its authority rule — where your handwriting conflicts with what the AI proposed earlier, the handwriting wins — has nothing to override in that chat, because the proposal it would have beaten was made in a different one. The pages are the whole record. That is why the intent line is written for a cold reader, and why sheets still carry no QR code, session ID, or machine-readable block: nothing printed on them is addressed to a machine that was already there. A notebook page copied from a card some other AI dictated comes back colder still — no printed layer, no card in the chat to check it against — and scan-back reads it as its own structure instead of asking you to account for pages you have already sent.

Where it actually stands

Where the loop stands, agent by agent

A table like this is usually a grid of ticks. This one has rows saying the loop is untested, set in the same type and boxed the same way as the rows that worked, because the alternative is that you find out on your own afternoon with your own printer. Every verdict reports what someone has actually done on that agent, never what ought to work. Where nobody has carried a page all the way round yet, the row says so in those words.

An untested row is a finding rather than an apology. It marks a place where one person running one real session would tell us something nobody currently knows, and it takes exactly that to close: one person, one report.

Verdict Each row’s status is boxed like this, in the ledger’s own words. The box is the whole encoding. Nothing here is colour-coded and nothing is amber, because a traffic light would turn an honest finding into a warning, and colour alone carries no meaning anywhere on this site.

Your agentInstallThe loop todayAlso install
Claude Code (CLI, IDE, web)npx skills add, or clone-and-unzipVerified end to end — discovery, install, sheet generation, and scan-back all testedreportlab + pdfplumber, on the machine running the agent
claude.ai · Claude desktop · mobileupload the two .skill filesSupported — the chat-native path; a phone photographing the pages is what the return trip was built aroundNothing by hand — the skill installs what it needs where it runs
Cursor · Codex · Copilot · other CLI-routable agentsnpx skills add … -a <agent>Installs cleanly, loop untested — the sheets need an agent that can run reportlab and read photographs back. A session report from one of these is the contribution we want mostreportlab + pdfplumber, wherever that agent runs Python
Anything else that reads SKILL.md foldersdownload a .skill (it's a zip), unzip into the agent's skills directorySame as aboveSame as above
Chat AI with no skills runtime — ChatGPT, Gemini, Copilot chat, Perplexity, Le Chat, DeepSeek, Grok, Poepaste paper-session-paste.md, then scan-back/SKILL.mdUntested, per surface — the forward half produces a hand-copied card, never a PDF, and nothing is verified because nothing is rendered. A pasted protocol also has no authority over the host's system prompt, so the bright lines hold only as far as the host chooses to hold themNothing — no PDF is generated, so no library is needed
Verbatim · README §Install

Copilot appears twice on purpose, in two different products: the CLI-routable IDE agent in row three, the chat surface in row five.

Reading the printed page is a requirement no row above states, and there is a path for people who can't. Say so and the session is dictated instead — the same linear card the no-printer path produces, for a braille slate, a typed file, a voice memo, or a scribe. The return matches it: dictated, typed, and scribed pages carry exactly the authority handwriting carries, and a scribe is never read as a second participant. It is not the same session, and nothing in either skill is allowed to imply it is: most of what the evidence brief measures depends on someone looking at a page, and references/evidence.md names which clusters stop applying, one by one. No study tests a dictated, typed, or scribed return, and no session report has come back from one yet.

What the sheets can be set in. Latin, Cyrillic, and Vietnamese work today, in all eight bundled faces — every character modern Russian, Ukrainian, Bulgarian, Serbian, Macedonian, Belarusian, and Kazakh need, and all 134 precomposed Vietnamese letters, are in every face's cmap, and a sheet set in them renders and passes verify_layout.py. CJK, Arabic, Hebrew, Devanagari, and Thai have no coverage at all: those characters print as blanks. Fonts alone would not fix that, which is the part worth knowing before anyone tries — reportlab maps characters straight through the cmap with no bidi reordering and no complex-script shaping, so even with a font that has the glyphs, Arabic sets left to right in isolated forms and lam-alef never joins. Greek is a half case: the Sans faces carry it, Serif and Mono don't, and the three-voice rule needs all three. A new script therefore means coverage and a shaping path, which is a larger contribution than it looks and a welcome one.

Install directions live in this section and nowhere else in the repo — other documents link here rather than restating commands, so there is exactly one place to keep true.


The ledger covers what has been run. What the method itself can and cannot claim, including the parts of the evidence that argue against this design, is on the limits page.

Once it is in

You will mostly forget it is there, until the work turns into a judgment and a page is what you reach for.

If you would rather start it yourself the first time rather than wait to be offered, there are twelve sentences you can copy, one per situation, each saying what it prints and where it is the wrong choice.

And you do not have to install a thing to find out whether you want it. A specimen the skill generated, and put through its own layout verifier, prints from your browser right now, with no account and nothing to agree to.

Get a sheet I already have paper

Open territory