# Paperclips Terminal Demo

The Paperclips terminal demo is a small clean-room incremental game inspired by
the paperclip maximizer thought experiment and by Frank Lantz's browser
implementation of that premise. In the focused manifest it now runs as a
Paperclips server plus terminal client launched through the native shell. The
server is authoritative for generated content, resources, `GameState`,
proof-command gating, unlock checks, and game-rule mutation. The terminal
client owns `StdIO`, handles the transcript, renders `help` from server-provided
command specs, plain `status` from server-provided `PaperclipsStatusSnapshot`
data, and plain `projects` from server-provided project entries when connected
to a server, and sends gameplay requests to the server through an explicit
`PaperclipsGame` endpoint capability.

This is still an early client/server protocol. The server owns regular timer
cadence and the current command list, while command execution still uses raw
text and mostly returns transcript text rather than typed command invocations
or structured UI events. In server mode, `PaperclipsGame.status` returns a
`PaperclipsStatusSnapshot` for plain `status`, and the terminal client renders
the familiar status text locally. `PaperclipsGame.projects` likewise returns
the unlocked project list for local terminal rendering of plain `projects`,
while `project <id>` still executes through the raw text/server-mutating
command path. The backlog tracks broader structured state/events and moving
unlocked command facets behind server-issued capabilities so a future web
client or web-shell gateway can use the same game authority instead of
reimplementing Paperclips logic.

No source code, CSS, images, generated tables, or copied resource files from
the original browser game are checked into this repository. The implementation
uses original Rust code and local CUE content in
`demos/paperclips-content/content/paperclips.cue`. During development, the
original site and a public mirror were inspected for license/provenance only;
neither exposed a permissive license that would allow copying assets into
capOS.

Reference sources:

- Original game site: <https://www.decisionproblem.com/paperclips/>
- Public mirror inspected for license/provenance:
  <https://github.com/jgmize/paperclips>
- Public gameplay/stage summaries:
  <https://universalpaperclips.fandom.com/wiki/Stages>
- Background overview: <https://en.wikipedia.org/wiki/Universal_Paperclips>

## Run It

Use the focused QEMU proof:

```bash
make run-paperclips
```

The scripted proof logs into the shell, launches the child process, drives the
opening refusals and business loop, scales production through repeatable
marketing and explicit sales, completes a business-phase project chain, asserts
the transition to autonomous phase, completes a representative autonomous
drone/factory scaling step, transitions into the cosmic phase, proves a bounded
probe interval with replication and production, verifies that final conversion
remains locked, and then checks clean child and shell exit.
The accelerated proof transcript starts with an explicit proof-capability
launch, then uses ordinary player commands plus proof-only acceleration and
machine-status commands:

```text
run "paperclips" with { stdio: client @stdio, game: client @paperclips_proof_game, proof_accelerator: @proof_accelerator }
status
buy autoclipper
buy wire 1000
buy marketing
make
run 10000
price 99
sell 1
price 25
sell 1
make
run 10000
sell 1
make
run 10000
sell 1
make
run 10000
sell 1
make
run 10000
sell 1
...
project autoclipper-license
project background-jobs
status
run 5000
buy wire 2
run 600000
make
projects
project survey-drones
sell 60
buy marketing
...
project precision-rollers
project design-search
run 600000
project forecast-engine
project survey-drones
project material-harvesters
run 100000
project foundry-lines
run 1000
project mesh-coordination
run 600000
project seed-probes
run 600000
status --json
status
projects
exit
```

For default manual use, boot the ordinary playground:

```bash
make run
```

After login:

```text
run "paperclips" with { stdio: client @stdio, timer: @timer }
```

The ordinary `make run` playground command uses the standalone fallback because
the default manifest does not start the Paperclips server. The focused
`make run-paperclips` manifest uses `run "paperclips" with { stdio: client
@stdio, game: client @paperclips_game, timer: @timer }`, where the server owns
game state and the client timer drains server-generated status messages while
the player is idle at the prompt. The structured command-list, status-snapshot,
and project-list methods do not change the default manifest or MOTD launch
command.

Useful commands inside the demo:

```text
status
projects
make
sell <n>
price <cents>
buy wire [bundles]
buy autoclipper [count]
buy marketing [count]
buy processor [count]
buy memory [count]
buy drone [count]
buy factory [count]
buy probe [count]
project <id>
help
exit
```

`make` starts exactly one manual paperclip. Manual work takes 500 configured
milliseconds before the clip becomes available. Repeating `make` while work is
pending is refused until the player completes the Background Jobs project;
after that, repeated `make` commands reserve wire and queue manual jobs behind
the active one. Time advancement reports completed manual cycles before the
status update. Purchase counts are optional and default to one;
explicit zero counts are rejected. Automation advances on configured millisecond
intervals while the process is running. Normal player launches do not expose
`run <ms>` or `status --json`; the focused QEMU proof passes an explicit
`proof_accelerator` capability and uses those commands only as proof
instrumentation.
The shell rejects renaming an ordinary `@timer` grant into that proof slot.
Blank input repeats the last non-empty command. The first autoclipper is granted
by the Autoclipper License project, which costs cash and trust; repeatable
`buy autoclipper [count]` purchases appear only after the license grants the
starter autoclipper. Later-stage purchase
commands such as `buy drone`, `buy factory`, and `buy probe` appear in `help`
only after the corresponding automation path is unlocked. The `projects` list
shows only unlocked technologies; in server mode that plain listing is rendered
from structured server-provided project entries. Complete the listed projects
and pay their shown costs to reveal later project chains.

The proof-only `status --json` command prints a single compact JSON object for
scripted assertions when the process receives the `proof_accelerator`
capability. Normal player launches do not advertise or accept it, and it stays
separate from the structured plain-status snapshot used for terminal
presentation. All fields are numeric and emitted in stable order. `stage` uses
`0=business`, `1=autonomous`, `2=cosmic`, and `3=complete`; `design` and
`strategy` are the two planning resources, and `cosmic_matter` maps to the
universe-matter state.

Funds change only when clips are sold explicitly by default. Demand follows a
bounded random walk during the business phase, then price modifies the current
market size for `sell <n>`. A successful business-phase sale starts a short
CUE-configured market-settlement cooldown, so repeated immediate sales are
refused until timer/proof time advances. Wire is bought in CUE-configured
bundles at a market price that drifts on a slower interval; repeated purchases
add temporary price pressure that decays over later market updates. Repeatable
marketing buys still spend funds, but each new level contributes more demand
than the previous level. The CUE content owns the base marketing gain, walk
thresholds, wire market thresholds, step sizes, sale cooldown, and deterministic
generator parameters. It also has an `autoSellEnabled` rule for experiments
that should sell during ms, but the checked-in demo keeps it disabled so market
movement is visible.

## Content Pipeline

Paperclips uses the same generated-content discipline expected for larger demos,
but with a stricter runtime data path:

```text
demos/paperclips-content/content/paperclips.cue
  -> cue export --out json
  -> tools/paperclips-content-gen
  -> schema-validated PaperclipsContent Cap'n Proto bytes in src/generated.rs
  -> paperclips-content deserializes the typed Paperclips schema at startup
```

The CUE file owns the game balance: initial state, purchase costs, millisecond
intervals, explicit/automatic selling policy, demand rules, trust milestones,
project costs, project labels/descriptions, production cadence, later-stage
matter conversion and replication caps, manual-work pacing, unlock thresholds,
and project effects. Rust owns mechanics, validation, command parsing, and the
terminal adapter. `make
generated-code-check` fails if the checked-in generated Cap'n Proto bytes drift
from the CUE source.

## Unlock Flow

The tech progression is data-driven by the project list:

- retail phase starts with 10 wire, no cash, manual single-clip production,
  sales, and early wire purchases;
- Autoclipper License grants the first autoclipper for cash plus trust, then
  Background Jobs enables queued manual `make` commands;
- repeatable marketing investment raises dynamic demand, while later business
  projects improve autoclippers, unlock design search, and unlock Strategy
  generation;
- Survey Drones moves the game into autonomous matter conversion;
- harvester/foundry/mesh projects scale harvesting, production, and compute;
- Seed Probes move the game into cosmic replication;
- Final Conversion completes the run once reachable matter is exhausted.

## What It Demonstrates

`make run-paperclips` currently shows:

- `capos-shell` launches `paperclips` as a normal child process;
- init launches Paperclips server services before the shell starts;
- the terminal client receives only explicit `StdIO` and `PaperclipsGame`
  endpoint grants;
- server-mode `help` is rendered from the Paperclips server's structured command
  specs, so the visible command list follows server-side unlock/proof authority;
- server-mode plain `status` is rendered by the terminal client from the
  Paperclips server's `PaperclipsStatusSnapshot`, while proof-only
  `status --json` stays a separate server-gated command;
- server-mode plain `projects` is rendered by the terminal client from the
  Paperclips server's structured project list, while `project <id>` execution
  stays on the server-mutating text command path;
- the normal and proof launches use separate server endpoints, so proof-only
  commands are decided by server-side authority rather than by client text;
- the foreground shell services the child's stdio bridge while the game runs,
  so the demo exercises real endpoint IPC between shell and child process;
- the server's timer capability drives regular automation without ambient clock
  access by the terminal client;
- the Paperclips server owns generated content, `GameState`, unlock checks,
  proof-command gating, and game-rule mutation for the focused manifest;
- a repeatable economic choice (`buy marketing`) changes the early business
  loop before automation is purchased;
- representative Stage 1 refusal output remains legible: early locked
  `buy autoclipper`, insufficient-funds `buy wire 1000`, pending manual work,
  bulk manual rejection, a high-price `sell 1` demand refusal, a no-wire
  manual production refusal, and a locked `project survey-drones` attempt are
  asserted in the focused transcript;
- manual production and explicit sales fund Autoclipper License, which grants
  the first autoclipper and unlocks repeatable `buy autoclipper`;
- repeatable demand investment remains a purchase path rather than a one-shot
  project, and the smoke asserts at least five marketing purchases before the
  phase transition path completes;
- business-phase sales are paced by a timer-backed market-settlement cooldown,
  and the smoke asserts an immediate repeat sale is refused;
- scaled business-phase production reaches the 10,000-clip trust threshold,
  then completes `autoclipper-license`, `precision-rollers`, `design-search`,
  `forecast-engine`, and `survey-drones`;
- completing the chain is asserted by `[done]` project entries, the visible
  `== autonomous phase ==` status line, `Automation: 14 autoclippers, 1
  drones, 0 factories, 0 probes`, and the local matter grant;
- the autonomous follow-up completes `material-harvesters` and `foundry-lines`, runs
  milliseconds, then asserts `Automation: 14 autoclippers, 5 drones, 2
  factories, 0 probes`, lower local matter, and additional clip production;
- the late-game follow-up completes `mesh-coordination`, then
  `seed-probes`, asserts `== cosmic phase ==`, visible probe
  replication, lower cosmic matter, and additional clip production, then
  asserts `final-conversion` remains locked;
- the late-game proof also asserts a proof-only `status --json` line with
  compact, machine-readable numeric state while preserving the human transcript
  checks;
- the Paperclips server maintains game state without ambient authority;
- the pure rules layer in `paperclips-content` is host-testable separately from
  the terminal adapter and reads generated Cap'n Proto content data;
- exiting the game closes stdio, returns to the shell, and lets the focused
  manifest halt through the normal debug-exit path.

This is now a coarse client/server game-state demo. It is not yet the final
capability-management showcase: help, plain status, and plain projects are
structured, command execution is still raw text, broader state/events remain
future work, and unlocks are reflected in server-owned command specs/project
lists/output rather than transferred command facets. That split is the intended
path for a later web client or gateway that uses the same game capabilities.

## Current Limits

The demo intentionally implements a compact terminal adaptation, not a
browser-accurate port. It has no original artwork, CSS, JavaScript, exact
project list, exact balancing, save file, market UI, tournament model, or
complete original event text. The host tests cover early mechanics, project
locking, the deterministic business-to-autonomous project chain, autonomous
resource conversion caps, factory/drone scaling, cosmic probe replication, and
completion gating, including a one-real-time-hour upper bound for normal
creativity generation. The focused QEMU proof covers launch, the first
production loop, one early automation purchase, representative Stage 1 refusal
output, business-phase project chaining, the autonomous transition, one
timer-driven autonomous scaling action, and a bounded cosmic probe interval. It
is representative transcript coverage rather than an exhaustive full playthrough.

Future rule/content expansion is tracked in
[`docs/backlog/paperclips.md`](../backlog/paperclips.md). New data-heavy
content should migrate through `mkmanifest cue-to-capnp`: author bounded CUE,
convert it to a specified Cap'n Proto root with pinned host tools, validate the
result on the host, and keep runtime CUE parsing out of the demo.
