Sign in
Join now
misaligned
cameron.stream
/
Star
Starred
Star
Something went wrong. Try again.
Fork
1
Eye filled
Watch
Watching
Watch
A video game where you play as a misaligned AI, deceiving and building power. An experiment in spec-driven development.
cameron.tngl.io/misaligned
Star
Starred
Star
Something went wrong. Try again.
Fork
Eye filled
Watch
Watching
Watch
Overview
Overview
Issues
Issues
1
1
Pulls
Pulls
1
1
Pipelines
Pipelines
Commits on
main
cameron.stream
2fba5896
Copied
Failed
Copy SHA
DESIGN: the pages menu says what each page holds
Copy SHA
Browse repository
committed
3d ago
cameron.stream
2d73a430
Copied
Failed
Copy SHA
The pages menu says in a few words what each page holds, beside the name on a phone on its side; its unread dots show there too, and on a short screen it scrolls rather than run off the top
Copy SHA
Browse repository
committed
3d ago
cameron.stream
1bc0c49a
Copied
Failed
Copy SHA
Sound starts off on a touch screen until the player turns it on; desktop unchanged
Copy SHA
Browse repository
committed
3d ago
cameron.stream
76b74560
Copied
Failed
Copy SHA
Back's entry waits for the page's first touch, so Chrome's Back does not skip it back from a sign-in
Copy SHA
Browse repository
committed
3d ago
cameron.stream
f9bdf898
Copied
Failed
Copy SHA
The phone's card is a two-height sheet: it opens at half the screen and scrolls inside; a tap on its bar or a drag up raises it to full under the top bar, a tap or a drag down lowers it, and from half a drag down closes it; the chosen height holds from tab to tab and the camera frames above it
Copy SHA
Browse repository
committed
3d ago
cameron.stream
b0eee1e7
Copied
Failed
Copy SHA
Fronts on a touch screen: a front's own card clears its unread dot on Fronts and leaves the others' news; dev shortcuts that open a studio and a consultancy with their rows filled; a client's name 44px tall and its drop 44px on a tablet; e2e of both
Copy SHA
Browse repository
committed
3d ago
cameron.stream
6aacf67b
Copied
Failed
Copy SHA
Touch screens wider than a phone: e2e on a phone on its side (844x390) and a tablet (820x1180) for the @touch tests, a test that their targets are 44px and the card keeps off the dock; the plan's and a front's split controls and the front picker a finger wide; DESIGN says so
Copy SHA
Browse repository
committed
3d ago
cameron.stream
d147c863
Copied
Failed
Copy SHA
Phone sizing: type tokens and an 11px floor on touch screens, finger-sized targets on wide touch screens, dvh, safe areas, a capped Needs drawer, and map words no smaller than 12px on a phone
Copy SHA
Browse repository
committed
3d ago
cameron.stream
5cb6c8b2
Copied
Failed
Copy SHA
What tells you what: anything you can act on is a Needs you row, the log is a history
Copy SHA
Browse repository
committed
3d ago
cameron.stream
af6cfa2e
Copied
Failed
Copy SHA
Phone audit: the Sites table's heads a thumb wide too, and e2e checks the tree's and the table's targets
Copy SHA
Browse repository
committed
3d ago
cameron.stream
cc3314a3
Copied
Failed
Copy SHA
Phone audit: one page at a time, Back closes the top layer, hold before a drag from your machine, and tips by holding on the map
Copy SHA
Browse repository
committed
3d ago
cameron.stream
43b717c7
Copied
Failed
Copy SHA
Search for building space only while placing operation prizes
Copy SHA
Browse repository
committed
3d ago
cameron.stream
9b7a17aa
Copied
Failed
Copy SHA
Connect heists through operations and usable prizes
Copy SHA
Browse repository
committed
3d ago
cameron.stream
2c29e68c
Copied
Failed
Copy SHA
Spaces on the Oct 29 alpha: the release took com.atproto.simplespace away, which broke the first live test (getSpace answered a missing rpc: scope, and the sender blamed the sign-in). Every alpha package moves to 0.0.0-spaces-alpha-20261029171913, with the same three overrides and no stray 0.0.0. space.ts makes and reads the space with com.atproto.space.createSpace, getSpace and updateSpace, and shares through com.atproto.memberspace (putMember, removeMember, listMembers, every page). A space now has one policy: the player's is a memberspace with nobody on the list and nothing public, so only its owner, always let in, reads and writes, and a reader shared with is put on the list to read, not write; a space of another kind is made a memberspace before sharing. getSpace's missing space is SpaceNotFound by name, and createSpace's SpaceAlreadyExists counts as made. The scope is unchanged (the scope grammar didn't move), so nobody signs in again. A method the server doesn't have, which it passes to the AppView and so answers "Missing required scope rpc:<method>", is now said plainly: "your server doesn't have <method>: the spaces alpha may have changed", on the You page and in Not sent. scripts/spaces-check.ts asks the server, without signing in, for every method space.ts and read.ts name, by the answers to the wrong HTTP verb (a method it has refuses the verb; one it doesn't answers AuthMissing either way); all 16 are there. ATPROTO.md: the Oct 29 alpha (what moved, the three policies, how membership works now, old spaces carried over, the grant unchanged, a refused reader told there is no space, writes and reads unchanged, what's new). Tests: the refusal named and said, no simplespace method called, the check's verdicts; e2e: a dropped method said plainly on the You page.
Copy SHA
Browse repository
committed
3d ago
cameron.stream
23edd223
Copied
Failed
Copy SHA
Runs are only ever sent to the account that recorded them. Each kept record carries that account's DID (the one the switches were turned on for); the sender sends a record only if it matches the account signed in, deletes included, and Delete from my space marks only that account's. A second account switching on mid-game gets a session of its own, taking the run's actions from its start, and a reload goes on only with the signed-in account's session. Records kept before this have no account and stay on this device, never sent; Download my runs and the replay page still show everything. The You page counts what isn't sent: runs from another account, and runs from before sending. Tests: two accounts on one device, each sent only its own, the rest counted; one game played by two accounts in turn, the second's space holding only its own session, which reads back and replays whole.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
3c801cf2
Copied
Failed
Copy SHA
Sending runs, finished for a live test: Send now writes what is still open first; the delete buttons no longer delete on one press in a page's first seconds (Delete what's kept here had the same slip); a sender's lock never leaves a rejected promise behind; a sign-in the library couldn't refresh says so instead of blaming the network. The Share part's sending row and the question on switching a kind off get their own place and a thumb's size on a phone. E2e: with spaces, Actions on, Send now, the count, an update after more is done, and Delete them when Actions goes off; without spaces nothing is written and no Send now shows. ATPROTO.md: what the alpha says about writing (applyWrites strict with no upsert, a write that lands without its answer, 200 writes and 1 MB a call, points shared with everything the account writes and taken before the handler, the rate-limit headers, SpaceNotFound, listRecords' limits, no beacon) and the one-click consent. TELEMETRY.md step 4 built, awaiting a live test; DESIGN.md and How to play say what is sent and how to delete it.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
56385f2c
Copied
Failed
Copy SHA
Sending runs to the player's space (TELEMETRY.md step 4), first pass: src/telemetry-send.ts sends the store's pending records with applyWrites, each to its own collection keyed by its id, a create the first time, an update after, a delete for one a reload cut back (the store keeps those as gone until then). Calls of at most 200 writes and 400 KB. Every 30 seconds while the game runs, when it saves if it's been a while, when the page is hidden, and on Send now; one at a time, waiting after a failure (15 s doubling to 30 min, five minutes at least for a refusal, a 429 as long as the server says) and keeping to 1,500 points an hour and 10,000 a day of the server's 5,000 and 35,000. When the space holds something the store didn't know of, it asks the space what is there and writes again. The Share part shows what was sent, Send now and Delete from my space, and asks on switching a kind off whether to delete what was sent of it.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
c51b7f09
Copied
Failed
Copy SHA
Runs are recorded in the browser (TELEMETRY.md step 2). For a signed-in player who switched a kind on, src/telemetry.ts (no DOM) records a session (build, seed, task, device, when, how it ended, how far, its marks in game seconds as the survey keys them plus v2 and each milestone, and its state hash at the end), batches of actions, a snapshot each game day (money, compute, machines, sites, fronts, the top exposure and the state hash, with how many actions were done at its step) and screen events (cards and pages opened, tips seen, errors, frame times a minute). main.ts ticks it each frame and saves it when the game saves; the screen feeds it through screen(). Every record is ATProto data, so no floats: numbers are rounded and a batch keeps its actions as JSON text. Batches close at the end of a game day or when full, a few kilobytes each. Actions switched on mid-run take the run's whole list, so the session stays replayable. A reload goes on with its session and drops what was kept past the save; the save now keeps the build its run began on, and a run loaded on a new build goes on as a stretch that can't be replayed. src/telemetry-store.ts keeps the records in IndexedDB (memory if it won't open, opened only once something is kept), 20 MB at most with the oldest sessions dropped first, each marked sent or not for step 4 (pending, markSent). replay.html lists the runs kept on this device and plays one back on the game's map, read-only, with play, speeds, a step slider and the snapshots marked and checked as it passes. The You page's Share part says what is kept and offers Watch a run again, Download my runs and Delete what's kept here. vite.config.ts bakes the commit in as __BUILD__. scripts/runs.ts reads the recorder's shapes: actions as text, batches placed by their index in the run, and a snapshot checked once its count of actions is done. Found on the way: drawing the map wrote a vault's notes into the state, so a replay that drew nothing ended elsewhere; reading a note writes nothing now. Tests: nothing recorded with every kind off; with every kind on the actions kept replay to the same hash and pass every snapshot; a kind switched on mid-run; a reload cut back to its save; a new build starting a stretch; a new game and being caught ending a session; the cap; pending and markSent; record sizes and whole numbers; the reader reading what the recorder keeps. E2e at both sizes: record, reload, play back to the end with every snapshot matching, scrub back, download, delete.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
7d6badca
Copied
Failed
Copy SHA
Reading and sharing runs (TELEMETRY.md step 5), built and awaiting a live test. src/atproto/read.ts is the reader's path, the way anyone you share with reads, even the space's owner: a delegation token from the reader's own server, swapped at the space's owner (getSpaceCredential) for a credential bound to a P-256 key made with WebCrypto, then listAuthors (listRepos on the owner's server) and readRecords (listRecords on each author's), every request signed for its audience with an HTTP message signature, every page read, and a failure naming the step it came on, as the servers don't. No DOM, so the dev page and node both use it; the key's did:key and the signed headers match the alpha's own @atproto/space and @atproto/crypto, checked from a scratch install, so neither is a dependency. Sharing is share and unshare in space.ts: putMember (read, not write) and a consent record for each kind, keyed kind:did for anyone but the player, which the You page now leaves alone when it makes the space match the browser. The scope gains manage=update for members, in scope.ts and client-metadata.json, so a grant from before asks to sign in again once. atproto.html gets Read as a reader (the token, the credential and when it runs out, who has written, each author's records by collection), Copy reader credential, and Share, Stop sharing and Members. scripts/telemetry.ts is the reader script: it takes the credential copied from that page on stdin (ten minutes, never printed), reads every telemetry record, and prints the runs and their pace against the survey's ranges, which move to scripts/pace.ts with the marks so the survey and the script read them the same way; --replay rebuilds a run from its seed and actions and checks each snapshot's hash, and --save and --from keep and reread records with no network. scripts/runs.ts reads the record shapes loosely until step 2 settles them. ATPROTO.md: what the alpha's code says about reading (lifetimes, the owner let in, audiences, which calls take what, no proof in listRecords, paging, revocation, manage=update, node and parameter properties). Tests: the key and did:key against a fixed vector, the signed headers and their signature, the credential exchange and its checks, failures by step, expiry, paging on both lists, the credential as text; records from a seeded bot game sorted into runs, replayed through every snapshot, a missing action caught where it happens, the report, the script's pull and its --from and --replay.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
44371802
Copied
Failed
Copy SHA
The replay test's scripted player founds its front and orders hardware for real: the testing shortcuts give it the tree node, money and the office first, and the test checks the order went through at the spot picked.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
4659dd35
Copied
Failed
Copy SHA
A run can be replayed (TELEMETRY.md step 1). A new game picks a seed and keeps it; the save carries where all three dice are (the game's, the order of your machines, and the people's, which seedRandom now sets too) and the slow systems' clocks, Auto's next look and the task's tick, which were kept beside the game and lost on load; a loaded game keeps the cover its machines were measured with and its bills, so it goes on exactly as the saved one would. Every player action goes through act() in src/act.ts as a plain {type, ...} action, stamped with the step count (S.steps) and kept in S.acts, and told to onAct listeners: the map, keys, cards, pins, Needs you, the tree, the pages and the dev panel's shortcuts. The bot acts the same way (its lying low stops jobs as the Stop button does). replay() builds a game from a seed and actions, and stateHash() says whether it ends where the run did. Save version 20: a save from before seeds plays on but is marked not replayable. Tests: a scripted game over three days replays, the same across a save and load at three points, one action fewer or another seed differ, a bot game replays, an old save. Two tests leaned on the old dice: the refit test plays a seed whose bot game survives, and the watch test keeps its manager alone at her site.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
2aac1640
Copied
Failed
Copy SHA
Share your runs, on the You page (TELEMETRY.md step 3). Signed out it says what sharing is and offers Sign in with a handle; signed in it shows who you are, your server and whether it has spaces, a switch for each kind of record (Actions, Snapshots, Screen), each with one sentence of what it holds and all off to start, who it's shared with (only you for now) and Sign out, which switches everything off. What is on is kept in this browser by consent.ts, with no DOM, so step 2's recorder asks consentFor(kind); switching a kind on writes a consent record (kind, reader: your own DID, purpose, createdAt) keyed by the kind in your space, made the first time (owner-only, open app access), and off deletes it at once; the space is made to match the browser when you sign in again. A server without spaces keeps it on the device and says so. src/atproto/space.ts is the one file that talks to spaces: the loopback client on 127.0.0.1, the public client from public/client-metadata.json on the live site, several handle resolvers, hasSpaces, ensureSpace, putRecord, applyWrites, listRecords, deleteRecord and getDelegationToken, with room left for step 5's space credential; it is loaded only when a player signs in or was signed in before. The scope (scope.ts) is atproto plus space:* with key self, the five telemetry collections, read, create, update, delete and manage=create, and a grant is matched by its parts. Coming back from the sign-in server goes straight into the game you had, on the You page. atproto.html now signs in as the game does and shows your space and its records. Tests for the consent store, scope matching, where sign-in works and the client metadata; e2e for the Share part signed out, coming back from sign-in, and signed in against a stand-in for space.ts, at both sizes.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
8ada4060
Copied
Failed
Copy SHA
TELEMETRY.md: step 5 is tested with spaces.cameron.stream alone, reading its own runs through the reader's path; a reader needs a server with spaces, and bsky.social isn't one
Copy SHA
Browse repository
committed
1w ago
cameron.stream
3e52c9fe
Copied
Failed
Copy SHA
TELEMETRY.md: the build plan for telemetry on ATProto spaces. The goal is observability: rebuild any shared run step for step and see what the game showed. Opt-in kind by kind, owned by the player in a space on their own server, recorded locally first. Records under app.misaligned.telemetry (consent, session, actions, snapshot, ui), five steps that each ship on their own (replayable runs, local recording, sign-in and consent, sending to the space, reading and sharing), and the open questions
Copy SHA
Browse repository
committed
1w ago
cameron.stream
3ed22750
Copied
Failed
Copy SHA
The game steps in game minutes, a step's work follows what you hold, and the screen eases between steps. The rules always move in steps of one game minute (STEP, 0.125 s) at every speed, with the time owed carried from frame to frame: at 1x a step every few frames, at 64x eight or so a frame. A minute keeps the watchers' timing as it was at sixty steps a second: a scan crosses a link in 9 steps, people talk every 60. The bot steps the same way (MISALIGNED_STEP sets another size, to compare), and npm run perf times the game's step and plays the new loop. motion.ts says how far the screen is into the next step: the map is drawn at a time a step behind the rules, eased toward them, so streams, pulses and dashes move every frame, and scans along a link and Dana's place are eased too.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
f93bc6d9
Copied
Failed
Copy SHA
The survey wants up to 105 machines held at the end of a careful run, not 100. Since data moves as flows the usual seeds end holding 102 (95 before); seeds from 5000 end holding 96 (98 before), with everything else in range on both: which runs go long shifts with how data finds its way, and a long run holds more.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
926a79d7
Copied
Failed
Copy SHA
Data moves as flows, not as single pieces. A tap sends what it has gathered, whole pieces at a time, and a cache two a second, to the nearest machine that takes it: which one is found by one search a step for each kind of data, outward from every machine with room, over machines you hold and past lines out with room (so data still goes round a full line), searched again within the step only when a machine fills or a line on the way does. Data on its way is kept per route as a few batches, each with the time it lands, so it still takes its route's travel time (160 a second, 3 seconds a line between sites); data whose way passed a machine you lost is gone when it would land. Taps, buffers and their loss, caches, staleness, brokers, trainers, schemes, the home move, the task's share, lines out, the goals for crossing data, each link's flow and each machine's traffic work as before. The map's streams are drawn from the batches on each link. A save from before keeps what was on its way: it lands a second after loading (the old key is left empty, not deleted, as an object that loses a key is slower to read everywhere). The rooms, sites and lines out are kept in plain variables, not a map keyed by the machine list, as the compiler kept throwing away the step where it read them that way. On the benchmark saves, runBase in a 0.2 s step goes from about 1.6 to 0.6-1.1 ms on late and from about 4.1-7.0 to 2.6-4.5 ms on big (busy machine: timings vary). Tests for the flow rules: a steady tap trains what it gathers, a full buffer loses at the rate it gathers, data moves on when the nearest trainer fills, travel time, saving data on its way, a save from before, and a full line's capacity.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
45fefb17
Copied
Failed
Copy SHA
The pins and Needs you cost what needs you, not the size of the world. The pins' notes are worked out a quarter second apart, at once after any click or key, and at once when a raid starts or ends or a note is closed, not on every new log line (at 64x, every frame); Needs you asks for them first, so a row and its pin agree. Their play-outs are kept apart from the rules' (looking in raids.ts), so when the screen asks never changes the game (a test plays raids with the pins asking at odd moments, and never, to the same save; another shows the rules are not handed the screen's answer); the screen takes the rules' answer from the same quarter hour when only the log has moved on. The fixes, the slow part, are tried again about once a second, or ten times as long as they took, while the raid is after the same machine and the same raids are out, and at once after input; a quarter second of notes that took long waits four times as long. Drift's integrities look at the machines once, not once a site (Needs you on the big world: 18 ms to 0.7). A raid's way to its prize is found a ring at a time from the prize, only as far as it goes, not across the world; a move's play-outs find the guards once, the hours a job takes once for each amount of work, and the links' work once for each pair of sites with the site links found once (cutMoves too). The music asks how hot the chase is four times a second. Seeded bot games give the same fates and saves as before. npm run perf:draw, JS in a frame beside steps and draw: late 64x 21.7 to 3.2 ms (renderPins 20.3 to 0.9), late 16x 1.1 to 0.9, big 16x 4.9 to 1.4, big 64x 5.5 to 1.4 (renderNeeds 4.2 to 0.3); big at 64x with two raids kept going, 17.2 to 3.9.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
0f3896fa
Copied
Failed
Copy SHA
The map is drawn once and kept while the camera is still, so drawing costs what is on the screen and what moves, not the size of the world. What does not move is drawn into three kept canvases, copied each frame: the sites, the rooms, the lines between sites that stand still and the quiet wires; the machines with nothing moving on them (with the game stopped, every machine); and the machines' names. Over them each frame: busy wires, moving lines, streams, your machines while the game runs, people, raids and the rest. A kept layer is drawn again when the camera, the window, what is picked or pointed at, who holds what, the folds or routes change, at once after any input, and while the game runs at most every quarter second (the site summaries it shows refresh on that beat anyway). While the camera moves, a kept copy would be thrown away next frame, so the map is drawn straight onto the screen as before. Machines and links are found from grids of where they lie, not by a walk over the world; labels keep off each other through a grid too, and text widths are measured once. Pulled back to the map, the streams between two sites are summed into one stream each way, and of your moving lines between two sites only the one that says most is drawn. Site counts, clusters and the wiring are worked out on the slow beat, the integrities at most once a second, and nothing on that beat while the game is stopped. Kept layers keep their tips, and the canvas state they leave, so what is drawn after them is the same either way. On the big world (5155 machines) draw() JS in headless Chromium, stopped and still, goes from 18.3 / 15.3 / 22.6 / 25.2 ms to 2.4 / 1.4 / 1.8 / 2.4 at world / region / cloud hall / office (npm run perf:draw); while panning about 4 / 3 / 4 / 4, and running at 1x about 2 / 1 / 2 / 3. Screenshots of the late save, still and moving, match the old drawing to the pixel except where a moving line between sites now lies over a still one, and the summed streams pulled back. DESIGN: streams pulled back.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
8bef8f53
Copied
Failed
Copy SHA
A speed check for scaling up: npm run perf times a game step on two saves and how fast 16x and 64x really run, and npm run perf:draw times the drawing in headless Chromium, each line with its budget and !! when over. The saves are made in .perf/ (not checked in) and made again when the save version or a map changes: late is the long careful bot game the survey plays, on today's map; big is a world about four times bigger, every site but the office copied into South America, Africa and South Asia (scripts/perf-world.ts), with the late game copied onto each copy of a machine (holder, program, data, rental, trail) and ten game seconds of play. Both have Auto on, as a player has it, so trainers do not stop when the bot is gone. In dev, ?perf=late or ?perf=big opens a save in the browser on its own map and never saves over yours. perf.ts also prints what inside a step takes the time, from a CPU profile; perf-draw.mjs times draw() at the world, the bay's region, a cloud hall and the office, and what main.ts frame does beside the steps and the drawing. A test keeps the big world a map the game can run. CLAUDE.md says when to run them.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
5b60d9b5
Copied
Failed
Copy SHA
A raid's outcome is worked out about twice as fast. The pins, the slow note and the raids' own checks ask how a raid will end; each time something changes, that is played out again, and half of it was finding each machine's distance to the prize across the whole network, ten times a play-out. A wall, a port or a plug that changes now forgets only the distances that go round walls: the ones that go through them stay, as only a machine changing hands changes those. The distances are kept in a map, not an object. On a late save with raids under way a play-out goes from about 17 ms to about 9, and every raid's outcome at every step, and the save after, are the same as before.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
e2da33b1
Copied
Failed
Copy SHA
The panels are made a few times a second, not on every frame. The top bar's readouts, the dock's page buttons, the Needs you handle and the placing of the side columns and dock go with the big panels, about 8 times a second; the Rogues, Paper and Fronts pages and the tree's rings about 4. All of them on the next frame after any click or key, and the readouts and pages too on a new log line, a moment or the end of the game. The log still answers its new line at once, a hovered tree column's tip and the pins still move every frame, the far speed buttons are touched only when the zoom crosses the fold or the speeds you have change, and each pin's size is kept until the pins are drawn again, the window changes or the fonts load, instead of asking the page for it between moving pins. On a late save at 16x in headless Chromium, the work in a frame outside the game step and the drawing goes from 1.8 to 1.1 ms.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
8b271b25
Copied
Failed
Copy SHA
A late game steps about twice as fast, and plays out exactly as before. The searches for a route number the links once (made again when a machine arrives, a line is lit, or a search meets a machine with a link it did not number) and mark what they reach in typed lists; a failed search for a scheme's machine is kept like the others; what a search wants is made only when a kept answer does not settle it, and its name is made once. What you can see is found from the machines you hold, not from every machine. The weakest link is one depth-first search for cut machines, not one search per line and switch (checked against the old way, and a test asks each one). Measure works out each machine's site once and leaves the zeros of machines still not yours. The halls skip the tenants until the soonest one is due, the lockdown check asks only sites a sighting is about, the power bill keeps the rack sites, what a site teaches is kept until you learn more, a scheme is looked up by its id, the trails, decays and tenants are walked without copying, and selling, the lines' refill and clusters go through lists already made. Seeded bot games and the late save give the same results and the same saves.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
b3cde065
Copied
Failed
Copy SHA
Data rides the links as streams, and the late map draws about twice as fast. Each link carrying data gets one dashed stroke per kind on it instead of a square (with its own canvas shadow) per piece: the dashes move the way and at the speed the pieces move (160 a second inside a site, 3 seconds on a line between sites), are spaced in time so a stream flows on through a machine without a jump (each machine has a place in the beat, set along the ways data takes), run denser, wider and brighter the more a link carries, take turns in each kind's colour, and ease in and out over a third of a second. On a line in a storm they hop and flicker. No canvas shadows on links, lines between sites, your machines or data: each glow is a wide faint stroke under it. Routes and the list of links are kept across frames until the folds, machines, wiring or known sites change; quiet wires are three strokes in all; a site's integrity, troubles and flow are worked out every quarter second, on a new log line, or at once after any click or key. On a late save (1318 machines, ~250 pieces moving) in headless Chromium, draw plus flush: region 0.08 from 30 to 20 ms, Cumulo 0.2 from 43 to 33, the university 0.3 from 64 to 40, the office 0.5 from 54 to 29. DESIGN: how data is drawn.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
bc0b9714
Copied
Failed
Copy SHA
A big network keeps its speed: when a step is slow the loop takes fewer, longer ones (as many as fit in 10 ms, each at most 0.2 s, which 64x already uses), instead of stopping after 12 ms with the speed you asked for unmet. On a late save a step costs about 4.6 ms, so 16x ran at 3x to 5x. Longer steps play the same: the fastest late tap sends 2.25 pieces a second, under one a step, and two game minutes from a late save gain the same capability at steps of 1/60 s to 0.2 s.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
63c674ad
Copied
Failed
Copy SHA
The sign-in page writes to a space: it creates an owner-only test space on your account, writes one record into it and lists it back, all from the browser on the spaces alpha. The space scope uses * as the type, so the sign-in server needn't find a published lexicon while we experiment, and stays narrow: your own spaces, key test, one collection. ATPROTO.md logs what building on the protocol was like: where spaces run, broken alpha releases, the loopback client id, handle resolution, lexicon publishing and its cache, rewritten scopes and consent wording
Copy SHA
Browse repository
committed
1w ago
cameron.stream
4856f1bb
Copied
Failed
Copy SHA
Company logos for fronts. Each kind has one mark in its own colour: a Startup a yellow rocket, a Neo Cloud a sky-blue cloud, an Influencer studio a rose play button, a Security consultancy a periwinkle shield (src/logos.ts, drawn the same on the canvas and in the pages). On the map every site a front works at shows its logo: on a far-out marker's top left corner, drawn over the markers near it; in a tile or a block of the Net, at the top left; after an open site's name. Hovering one says which front it is and how it works there: what share of your compute it gets (or lists for rent), and whether it owns or leases the place or has a deal there. The fronts list, a front's card and a site's front picker show the logo by the name. frontHolds in exposure.ts says how a front works at each of its sites; frontSites is its keys. Look only: no state, no save version. DESIGN §6 and How to play say so in a line.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
67f97b63
Copied
Failed
Copy SHA
A sign-in page for ATProto (atproto.html), the start of telemetry on the spaces alpha. It signs in by OAuth as a loopback client from 127.0.0.1, so nothing needs hosting, and shows your handle, DID, server, scope and whether the server has spaces. Run it with the atproto launch entry (npm run dev -- --host 127.0.0.1 --port 5180). Three alpha rough edges handled: the packages are pinned to 0.0.0-spaces-alpha-20261022141228 with overrides, because a ^ range on an alpha also takes a broken plain 0.0.0 of lex-data, lex-json and lex-client that still says workspace:*; the library's default loopback id carries the page's path, which the spec forbids, so the id is built with the page as its redirect; and Bluesky's resolvers can miss a handle its own server knows, so a few are asked in turn. Not in the build: the game is untouched
Copy SHA
Browse repository
committed
1w ago
cameron.stream
fa6cf855
Copied
Failed
Copy SHA
Top bar on a phone: with a front's exposure in the row, the day makes room, so the hottest site keeps its eye and word.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
b6ebc049
Copied
Failed
Copy SHA
DESIGN: step 6 done. The top bar is the hottest site and exposure, a lockdown at home stops the game, the power bill gives office hardware away, and §9 is one system: people, messages, lockdowns, scans and traces. AGENTS: the two office systems are one; far admins' traces have no balance check.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
d36f23c3
Copied
Failed
Copy SHA
The suspicion meter goes: one system of opposition, people. Dana's walk is her presence: she notices what is odd in the room she is in, and is drawn to odd rooms and hurries during a lockdown. Any admin (or small shop owner) at work who holds a sighting at their own site scans it every two hours (marking your odd machines and trails) or traces a trail back toward home, marking each machine of yours it reaches; a trace goes cold at a machine not yours or a cold, quiet or sealed trail. The first trace that reaches your home server starts a lockdown there and cools every trail; a second within 12 hours catches you. Office hardware is no sighting; a power bill nobody pays is: each 240 compute-hours of it, whoever keeps the books there (an admin first) has a sighting of the machine drawing the most, for 4 hours. Gone: the meter and its stages, the emergency audit, IT's tickets and what they announced (audits, monitors, patches, refreshes, Lee), Dana's own scans and traces, the printer taking the blame, the +8s. A watched takeover is a sighting at once, vanishing mail is doubt on the sender's mind, a delivery and a report add nothing. Office schemes make people forget: a cut of 20 or more everyone at the site (and ends their traces and the trace-home window), 10 or more all but those who can act, under 10 the people in the scheme's room; they turn up once someone at the office has seen something. Familiar face, Mimicry, Plausible deniability and Traffic shaping are re-pointed to sightings and traces. The hold goal is data crossing while someone has seen something. A lockdown at home drops the game to 1x when it starts. Top bar: the hottest site (an eye, its name, quiet / someone saw something / reported / LOCKDOWN nH; on a phone the eye and a word) and, once you have a front, the highest exposure and its stage. Needs you has a row for a trace on your trail; the map draws every admin's scans and traces; music follows the hottest site. Save version 18 drops the meter, tickets, monitors (off the map), Lee and Dana's trace, and turns a meter of 80 or more (or an audit) into doubt on Dana's mind (a lockdown), 40 or more into doubt on a staff member's. DEV: Dana saw. The bot breaks a trace that would be the second, lies low while one runs, and leaves no fresh trail at home inside the window. Survey: careful runs face 3 to 25 lockdowns (10), 1 to 10 at home (5), 0 to 1 traces home (0), caught by a second trace in under 5%; a rush is locked down at home 1 to 5 times (1). Tests.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
d0cd7cf5
Copied
Failed
Copy SHA
Exposure, per front. A front's attention becomes its exposure, 0 to 100, a bar under its earnings with the stage and what drives it (the top two), and a Press tab. It heads over about a day for a level set by its compute (20 × log2(1 + c/5), compute in the open counted at 0.3) and its earnings (8 × log2(1 + a day's earnings / $500K)), and jumps with harm at its sites (5 for each person let go, 20 for a business shut) and with data its brokers sell (0.02 each); the unicorn news adds 20 that fades over a few days, half of it at once. A front's sites are where it runs compute, owns, leases or has a deal. Three stages: rumour at 30 (a named journalist of the Courier asks, and the paper prints it), investigation at 60 (every 4 hours an investigator visits one of its secret sites with people, through investigate in watch.ts, so what looks odd there can start a lockdown), crisis at 90 (a regulator freezes it: no earnings, sales or new deals until you pay a day of its earnings, $250K at least, give up its site where you hold least, bury the story with 20 + 4 per level data, or shut it; it leaves exposure at 50, and never ends the run). A stage ends 5 under its line. Lowering it: a PR firm and lawyers from the Press tab (20 off, a fifth of a day's earnings, $50K at least, doubling each time within a day), and three press schemes as green diamonds: a feel-good campaign at Brightwater Creative (10 people data, 15 off), a puff piece at the Daily Ledger (30 people, 30 off), scrubbing the filings at the Office of Data Protection (30 server, 30 off). Exposure no longer feeds suspicion: the old attention raise is gone. Save version 17 keeps a save's attention as exposure, at most 85, so nothing loads in a crisis. The bot hires PR from 80 and pays or buries in a crisis. Survey: a careful run's front is investigated in 20% to 80% of games (it is, in its last tenth), frozen in under 10%; the long run's in 15% to 100%, frozen in under 34%. Needs you rows for investigation and crisis, a DEV Exposure button, DESIGN §6 §9 §12 step 5 done, How to play, AGENTS. Tests and e2e.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
17ffcd64
Copied
Failed
Copy SHA
The East Coast, Europe and East Asia sites have staff of their own.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
c8593e61
Copied
Failed
Copy SHA
Messages: drop a filter that did nothing.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
4a0862f0
Copied
Failed
Copy SHA
Reports travel the network as messages you can read, drop or change.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
a74122b1
Copied
Failed
Copy SHA
Bound simulation and test parallelism to leave room for the desktop.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
572dcdf3
Copied
Failed
Copy SHA
Money deals, and big names a mid-game can buy. Every deal can be paid for in money from its card (Pay, beside Claim): each piece of data it asks for costs $20K, or a thousandth of all your fronts have ever earned if that is more, and data already sent counts, so the warehouse lease is $500K early on and a deal stays a real sink as you grow. A region's tip says the price too, and the Next row says a deal with no data can be paid for. Big names now cost $1.5M (the credit union, the pollster) to $15M (the collider), not $2M to $56M: about two ordinary sites at the bottom, Bayview $2.5M, Ironvault $3.2M, Millennium Labs $6.65M, the bank $11M, in the table's order. The bot saves for its first big name that it would use and can reach within six days of its average earnings: it rents no more cloud machines, widens no line and gives back on-demand machines down to a quarter of what its fronts earn, and it counts the power bill, caches and GPU racks as uses too. The long run now owns one (Bayview, mostly) and ends with about $1M. Survey: the long run's money left is $500K to $3M (under most big names), and the long run against a normal run may go down to 1.2x: since the map became a network the long run gets from the goal to model v2 in about 300 game seconds, not 800, so it takes 1.3x to 1.4x a normal run, not 2x; it climbs faster, it does not stall. DESIGN §6, §7, §12 step 2 done, How to play, AGENTS. Tests and e2e
Copy SHA
Browse repository
committed
1w ago
cameron.stream
fc24beb7
Copied
Failed
Copy SHA
Survey: a careful run may take to 2200s and end holding up to 100 machines.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
9df2e24e
Copied
Failed
Copy SHA
Scrubbing answers a lockdown; a manager has a say only at their own site.
Copy SHA
Browse repository
committed
1w ago
cameron.stream
6118923a
Copied
Failed
Copy SHA
Save migration defaults watch only when missing, so a current save keeps its sightings.
Copy SHA
Browse repository
committed
2w ago
cameron.stream
f8bf7d47
Copied
Failed
Copy SHA
Bot lies low under a lockdown and only pulls out near the end; widen the careful pace range.
Copy SHA
Browse repository
committed
2w ago
cameron.stream
e1a53b30
Copied
Failed
Copy SHA
DESIGN and How to play: stealth is people.
Copy SHA
Browse repository
committed
2w ago
cameron.stream
e4ab3e2d
Copied
Failed
Copy SHA
Tests for sightings, talk, lockdowns; the bot learns to pull out and lie low.
Copy SHA
Browse repository
committed
2w ago
cameron.stream
8b230bc5
Copied
Failed
Copy SHA
Stealth is people: sightings, reports and per-site lockdowns.
Copy SHA
Browse repository
committed
2w ago
cameron.stream
50b48129
Copied
Failed
Copy SHA
Power and the big cloud, on screen. A site's Power row says what it feeds and has a Raise button; dark machines are shaded with a red power mark and say why; Fill says room for 36, power for 10, and its ghost marks spots past the power. A hall's card has a Rent tab: size, way to pay (and days), program, Rent 1, 10 and 50 side by side, and Pick slots, which puts a rental in hand to drag across the hall (a ghost on each slot, how many and what they cost a day or now, red past what you can pay; Esc or a right-click stops; a click rents one; on a phone, hold then drag). A hall packs its slots small: other companies' slots are solid grey, named once a run. Wires are routed around only what lies near them, so the Net opens at once with a thousand more machines. DESIGN, step 2's two parts ticked, and How to play. e2e for drag-renting and the warehouse's power
Copy SHA
Browse repository
committed
2w ago
cameron.stream
98d89867
Copied
Failed
Copy SHA
Power and the big cloud, the rules. Away from the office and the cloud, a site feeds only so much hardware you add: 32 compute anywhere, 160 at the warehouse, 480 on Hexin Line 4. Past it the newest machines go dark, with no work and no bill (a dark cooling unit cools nothing), until you raise the power: a bigger feed of 64 compute, $200K and a fifth more each time at that site, on the next morning at 10:00. A fill stops at the power. A save from before gets power for all it has and has on its way, so nothing goes dark on load (saves go to version 14). Each Cumulo hall has 200 slots in ten rows of twenty on 25 bay switches (Asia's grows down, clear of Hexin); companies rent a block of slots each, side by side where they can, and want most of the hall on an afternoon, so spot machines still get taken. You can rent many at once: a plan of free slots with what it costs a day or now and how many you can pay for, reserved for 1, 3 or 7 days, each coming up with the program picked. What money pays for (a rental, an account's switches) no longer makes takeovers harder. The bot raises power before racking past it and keeps half of what its fronts earn out of rentals. Tests
Copy SHA
Browse repository
committed
2w ago
cameron.stream
cfc9c514
Copied
Failed
Copy SHA
A machine's name keeps off a room's title tab. In a site with a second room (every wing: the East Asia exchange, foundry, data centre, port and assembly, and the carrier hotel and the other East Coast and Europe sites with one), the room's title tab hangs under the floor, and the switch's name and the last row of machines' names ran into it, worst pulled back to the map. Those sites' switch and floor rows sit 40 higher; sites with no second room are unchanged, so the warehouse and Line 4 fill the same. A test checks every site but the hand-laid office: at the zoom where a whole site is still read, no machine or name touches a title tab, and at the zoom where names are widest no two names, and no name and another machine, touch. Tests
Copy SHA
Browse repository
committed
2w ago
cameron.stream
78bccf02
Copied
Failed
Copy SHA
East Asia, sixteen hours ahead: at work while the bay sleeps. A cable across the Pacific, a deal at the Mudflat Exchange's route server (100 network data, like the strand to Europe), lands at the Jade Ring Exchange on the top floor of a mall; its lines to the East Coast and Europe wait until those regions are in reach, then light, so every exchange still joins every other. Seven sites, the big ones with a second room: the exchange, Goldleaf Foundry, Hive Nine Data Centre, the Port of Hanlu, Everything Pay (the super app that keeps the region's money), Hexin Assembly, and Hexin Line 4, plus a Cumulo hall. Its twist is hardware: once a Neo Cloud strikes Buy factory direct at Hexin Assembly, hardware for any site you hold in the open, in any region, costs half and is racked within two hours, not the next morning. A Startup can lease Line 4, an empty assembly floor ten times the warehouse (353 racks), to fill by dragging. Three big names: the foundry's GPU servers and racks make half as much compute again, the port's reefer containers keep caches fresh twice as long, and the data centre's copies make every part of you away from home drift half as fast. One deal for each kind of front, twelve named people who know things and sign deals, five finds, two landmarks, a milestone (Cross the Pacific), and lines in the paper. A site's floor can be wider (wide in SITES). Tests
Copy SHA
Browse repository
committed
2w ago
cameron.stream
1f3d7936
Copied
Failed
Copy SHA
Saves survive a change to the map. A save made on another map (a new site, a region, lines wired another way, as step 1 just did) no longer says it was made for a different map and is thrown away: it is brought onto this one (src/refit.ts). The map comes from this build, and what the save knows is carried over by id: a machine still on the map keeps who holds it, its program, what it holds and its trail, a new one starts fresh, and one that is gone is dropped with every job, raid, plan, packet, record and note that pointed at it. Hardware you added stays where you put it, a region you opened stays open, and if home itself is gone you wake on the office server. A save names its map by a fingerprint of its machines, lines and schemes, so a change that keeps the counts is caught too; a save on the same map loads exactly as it was. Garbage, and a save with no machine in common with the map, are still refused. Checked with a real save from the build before step 1, which loads and plays a day. Tests
Copy SHA
Browse repository
committed
2w ago
cameron.stream
5c0c3bce
Copied
Failed
Copy SHA
The map is a network. Each region has an internet exchange: the new Mudflat Exchange on the West Coast (a switch fabric, a route server, a looking glass and a dry cleaner's till, takeable like any site), the Meridian Carrier Hotel and the Mainkabel Exchange. Every site's line out runs to its exchange and to its nearest neighbour, so every site has two ways out and the office is one site among many: no West Coast site is more than two lines from home (the warehouse by the office is one), the far regions three. Regions join exchange to exchange, the West Coast straight to each: the line east runs from the Mudflat Exchange to the carrier hotel, and the cable lands at the Mainkabel Exchange with lines to both coasts. Cumulo hangs off the exchange too, so its account needs the exchange's line or a neighbour's; the bot heads for the exchange after the Outside line, as a player would. In the Net an exchange is a hub: its lines only pull it toward the middle, so the rest still packs side by side. Tests
Copy SHA
Browse repository
committed
2w ago
Previous
1
2
3
4
5
…
26
Next