Commit graph

284 commits

Author SHA1 Message Date
acamilo
eecd5744e0 docs: v0.6.4 status
Some checks are pending
ci / node 22 (test + typecheck) (push) Waiting to run
ci / rust stable (cargo test --workspace --release) (push) Waiting to run
ci / infra/tests/lint.sh (push) Waiting to run
ci / playwright apps/stage (allowed to fail) (push) Waiting to run
2026-09-28 21:38:07 +00:00
acamilo
dc64ffb4ea Merge feat/recovery-splash: an on-stream splash while recovery acts 2026-09-28 21:37:56 +00:00
acamilo
3922b82762 Merge feat/loop-recover-ladder: automatic loop recovery climbs restart, rung reset, rung below 2026-09-28 21:37:50 +00:00
acamilo
26892d8530 loop recovery: wait on the watchdog's ActiveState, and only a root flysim that is the running build
review-ladder r2: a oneshot probe mid-run is 'activating', which
is-active does not count, so the wait never waited. The root copy must
also be byte-identical to /opt/fly/current/flysim, so a manual rollback
cannot approve an archive the running build refuses. Docs: the hold
after an unrestorable rung, the post-deploy --list check, and never
stopping the unit mid-step.
2026-09-28 21:37:40 +00:00
acamilo
865d6f6b55 stage mockups: recovery splash, four phases by two actions 2026-09-28 21:34:37 +00:00
acamilo
c574e7b973 docs: recovery splash and the stream notice contract 2026-09-28 21:34:37 +00:00
acamilo
15f2e6dbae stage: auto-recovery splash over the game, polled from flystage-web
The loop-recovery helper's notice (/run/fly/wd/recovery-notice.json,
FLY_RECOVERY_NOTICE) is served by serve.mjs at /recovery-notice.json and
polled once a second by the page, independent of flysim. Countdown shows a
Game Boy text box over the bottom of the game; acting covers the game while
flysim is down; done/failed show briefly. Stale, malformed or oversized
notices are ignored and helper strings are clipped to a closed charset.
Adds ?recovery=, __stage.recovery(), the recovery-notice dev tool, unit
tests (model, poller, serve.mjs route) and an e2e spec.
2026-09-28 21:34:37 +00:00
acamilo
f205d95e5e loop recovery: review-ladder fixes, root never runs a fly-writable binary
B1: fly-loop-reset runs only /opt/fly/sbin/flysim, a root-owned copy
05-deploy installs from the release tarball after checking it against
the tarball's MANIFEST; fixed paths, fly.env parsed as data, env -i.
B2: the wrapper pauses fly-watchdog.timer (and waits out a running
probe) for the reset, and starts flysim and the timer on every exit.
H1: a step that raises or times out is a failed step; the ladder state
is saved before the step runs. H2: one --list call computes the build's
compatibility once; TimeoutStartSec 25 min. H3: level 2+ resets to the
rung below the best or restarts, never lower.
Tests run the wrapper against a fake flysim, systemctl and archives.
2026-09-28 21:34:32 +00:00
acamilo
9c9cec49a9 loop recovery: reset only to an archive the running build can restore
fly-reset-to-milestone does not check compatibility and a flysim that
refuses every checkpoint does not start. fly-loop-reset --check applies
05-deploy's rule (identical, or an adapter-only difference named in
FLY_ACCEPT_ADAPTERS); the ladder picks the highest restorable rung and
falls back to a restart when there is none.
2026-09-28 21:25:58 +00:00
acamilo
63ecc32b2f loop recovery: an escalation ladder that unsticks a trap on its own
Restart flysim, then reset to the current rung's milestone, then to the
archive below the best rung (never lower), one step per confirmed trap
that outlives the previous one. Two resets a day, three-hour restarts
once they are spent; the ladder starts over at a new best rung or after
six quiet hours. State and history live in the unit's StateDirectory so
a reboot does not forget where the ladder stood.

A router model list confirms each step; a 'not stuck' answer delays it
at most three probes and no answer leaves the watchdog to decide alone.
Each step is announced 60 s ahead in /run/fly/wd/recovery-notice.json
for the stage's recovery splash.

fly-loop-reset is the one new root surface (a sudoers line); 05-deploy
now converges config/fly-sudoers so a release can add it.
2026-09-28 21:23:33 +00:00
acamilo
1bd2223431 Require complete router configuration before veto 2026-09-26 01:23:31 +00:00
acamilo
dccc52ae1c Document recovery and run its regressions in infra gate 2026-09-26 01:15:44 +00:00
acamilo
432991cbc5 Add conservative automated loop recovery timer 2026-09-26 01:12:46 +00:00
acamilo
862e343e1c docs: v0.6.2 status
Some checks failed
ci / node 22 (test + typecheck) (push) Has been cancelled
ci / rust stable (cargo test --workspace --release) (push) Has been cancelled
ci / infra/tests/lint.sh (push) Has been cancelled
ci / playwright apps/stage (allowed to fail) (push) Has been cancelled
2026-09-23 23:48:20 +00:00
acamilo
d0ce10e3c9 Merge fix/loop-row61: a trainer's challenge is the cartridge's until its battle is over 2026-09-23 23:48:20 +00:00
acamilo
9b117dc4b2 docs: 12.25 and the row 61 audit on top of row 59, the bubble, game.scene in macros mode 2026-09-23 23:47:36 +00:00
acamilo
cff15804fb state, tests: the challenge covers the "!" bubble too, the doc block back above its impl, and the ROM test asserts no pad inside a challenge 2026-09-23 23:47:36 +00:00
acamilo
d6597b3e98 docs: the row 61 audit, a trainer's challenge text walled the forest's corridor 2026-09-23 23:28:17 +00:00
acamilo
0117a85354 docs: macros.md 12.24, a trainer's challenge is the cartridge's until its battle is over 2026-09-23 23:28:12 +00:00
acamilo
c78ca352f6 tests: the ROM proof from the forest's south gate checkpoint 2026-09-23 23:28:05 +00:00
acamilo
0e366cd4e4 state: a trainer's challenge is the cartridge's until its battle is over, in the macros' own scene 2026-09-23 23:27:54 +00:00
acamilo
16bc65b5a8 survey: FLY_PROBE_CATCH_FRAME reads the first free frame from a given one, FLY_PROBE_WHOLE prints a big map whole 2026-09-23 23:27:54 +00:00
acamilo
510727ccc0 docs: v0.6.1 status
Some checks are pending
ci / node 22 (test + typecheck) (push) Waiting to run
ci / rust stable (cargo test --workspace --release) (push) Waiting to run
ci / infra/tests/lint.sh (push) Waiting to run
ci / playwright apps/stage (allowed to fail) (push) Waiting to run
2026-09-23 23:08:10 +00:00
acamilo
f32352bd5e Merge fix/loop-row59: the map graph as the cartridge's headers and warps draw it, pieces and all 2026-09-23 23:08:09 +00:00
acamilo
9ccc0592b1 docs: macros.md 12.24 and the row 59 audit 2026-09-23 22:33:47 +00:00
acamilo
437dfa84a9 tests: from the live Route 4 checkpoint, the fly goes into Mt. Moon and Route 4's west doors are not a ring 2026-09-23 22:33:47 +00:00
acamilo
d181f952a7 tests: from the badge, the road to Mt. Moon is not a ring at the Pewter end, and Route 4's doors and sides are the cartridge's 2026-09-23 22:23:27 +00:00
acamilo
5147ab1a87 geography: a header connection no step on foot crosses is named and is not a way out; Pallet's shore, the sea routes, the League fence 2026-09-23 22:23:01 +00:00
acamilo
97a97a501d geography: a split map is pieces with their own doors and neighbours; Route 4 and Mt. Moon's lower floors, the hop matched on where an exit lands 2026-09-23 22:23:01 +00:00
acamilo
4108fec5ce macros: a push-back is a refusal once the overworld has stayed the fly's for half a second, not on the first frame of it 2026-09-23 22:23:01 +00:00
acamilo
d85ee5026f geography: Route 3/4, 14/15 and 24/25 as the headers connect them, and Mt. Moon's doors on Route 4 2026-09-23 22:23:01 +00:00
acamilo
288e958d19 survey: FLY_PROBE_SAVE_RANK writes the first safe overworld frame at a rung as a checkpoint 2026-09-23 22:23:01 +00:00
acamilo
4d82f7db74 Merge refactor/legacy-frame: FND-01, one LegacyFrame for the service and every harness, FLY_TRACE and the sugar journal 2026-09-23 21:43:45 +00:00
acamilo
2f7b7cebd0 docs: v0.6.0 status
Some checks are pending
ci / node 22 (test + typecheck) (push) Waiting to run
ci / rust stable (cargo test --workspace --release) (push) Waiting to run
ci / infra/tests/lint.sh (push) Waiting to run
ci / playwright apps/stage (allowed to fail) (push) Waiting to run
2026-09-23 21:23:57 +00:00
acamilo
ff49b56e2c docs: the explore row stays "new place" 2026-09-23 21:23:40 +00:00
acamilo
b484a077d4 stage: the explore row reads "new place" again (the operator, 2026-09-23) 2026-09-23 21:23:05 +00:00
acamilo
9301e395e8 docs: the trap hunt and the bench run the service's frame since FND-01, and hunts across the change do not compare 2026-09-23 20:15:20 +00:00
acamilo
9e2f90749f flysim: FLY_TRACE's boundary half read back with fly-session-types, the journal held to the service test, rustfmt on the new files 2026-09-23 20:15:20 +00:00
acamilo
60f09b79a3 flysim: every harness runs the legacy frame: the trap hunt, the benches, the ROM tests' and the probe's stub drivers
trap_hunt, palette_bench and room_escape ran the frame through NeuralAgent::tick, which installs
a frame and its rewards after the next ticks: one frame behind the stream, with the ratchet
observed without the objective signal and a rollback that never re-observed the scene. They now
restore the way the stream restores and run LegacyFrame::transition and ::boundary, looking in
through FrameObserver; FLY_TRACE works in each of them. The stub-readout drivers of
rom_macros_mode, rom_catch and scene_probe run LegacyFrame::execute and ::stub_advance, which are
the same calls they made, in the same order.
2026-09-23 20:15:20 +00:00
acamilo
ad1c0e3693 flysim: a frame-stamped sugar journal in the hot directory
Every admitted sugar and operator reward pulse is appended to sugar-journal.jsonl with the frame
counter it was applied at, which is the step of the next transition in FLY_TRACE, so a shadow run
can replay the audience's input. Append-only, not checkpointed, never read back into the fly.
2026-09-23 20:14:01 +00:00
acamilo
94cc91369a flysim: the legacy frame is one type, flysim::frame::LegacyFrame, and the sim loop runs it
prepare, execute, advance, evaluate, commit, then the boundary's ratchet capture and rollback,
in the order the stream runs them. The frame owns the remainder, the frame counter, the frame on
screen, the mask and the blocked-direction window; the sim loop keeps the feed, the event log,
the milestone archive between commit and boundary, and the checkpoints. Two moves between
disjoint state change no byte: the visual frame is installed at commit, and the stimulations
follow the scene's observation. The FLY_TRACE of a run from the rung-10 checkpoint is
byte-identical to the one the inline hooks wrote.
2026-09-23 20:14:00 +00:00
acamilo
ff74c07622 flysim: FLY_TRACE, a per-frame trace of the legacy loop in the step trace's field names
One JSON line per transition: ticks and the exact remainder, digests of the rates, of the
transition's spikes, of the frame and of work RAM, the decision and the mask, macro and reward
events in order, the rank, and the boundary's slot saves, rollback and captures in the shape of
TraceBehaviour.boundaryActions and TraceOperational.captures. Off unless FLY_TRACE names a file.
Recorded inline in step_frame first, so the frame's extraction can be held to it.
2026-09-23 20:14:00 +00:00
acamilo
bc117ad470 flybrain-gb: say what a move with power does not promise 2026-09-23 19:23:48 +00:00
acamilo
fa021918b4 Merge fix/loop-row60: a move the cartridge would refuse is not dealt beside one that works 2026-09-23 19:23:43 +00:00
acamilo
4591e7907a docs: macros.md 12.23, macros-wram.md section 13, the row 60 audit 2026-09-23 17:59:29 +00:00
acamilo
07f88c443a tests: the ROM proof from the Route 1 checkpoint 2026-09-23 17:23:05 +00:00
acamilo
b33af9e772 scene_probe: the route survey prints the battle bytes a MOVE n button's effect rests on 2026-09-23 17:23:05 +00:00
acamilo
a02d5f7995 trap_hunt: payouts by kind, battle lengths and wins, and MOVE n on a move without effect 2026-09-23 17:23:05 +00:00
acamilo
f3e3e9cf98 palette: a move the cartridge answers with nothing is not dealt beside one it does not
Row 60: TAIL WHIP against a Pidgey at DEFENSE -6 was MOVE 2 183 times. The
rule is PP's: a refused move leaves the pad while another move is usable, and
with none usable the moves stay as PP deals them, so an open list never
comes down to BACK alone.
2026-09-23 17:23:05 +00:00
acamilo
438b2d8540 state: the move table, and whether the battle engine will answer a move with nothing
move_data reads a row of Moves from the cartridge image ($0E:$4000, each row
checked against its own id); move_without_effect answers the refusals the
effect routines make on bytes already in WRAM: a stat stage at its limit or a
stat at 1/999, Mist or a substitute against a stat-lowering move, a status
move against a statused, Poison-type or (Electric) Ground-type target.
MacroState::move_without_effect defaults to false.
2026-09-23 17:23:05 +00:00