developer forge - build pins, iterations, displays #11

Merged
jmoran merged 3274 commits from feat/upstream-sync into main 2026-11-02 18:27:27 +00:00
Owner

Lands everything since 10-13 on this fork's main in one fast-forward. Supersedes #7, #8, #9 and #10, which this branch contains.

  • Upstream trevato-apps/forge main (accaa65, 10-28) merged in.
  • Dev forge pages, site shell, build family and dev UI from #7–#10.
  • Build pins with one append-only Notes list per build, people's notes first.
  • Iterations: Columns and Tree, drag with Align/Reset, zoom with Fit, Collapse/Expand forks; kept per browser.
  • Display pages: chosen builds, drag to reorder, title edited in place; the Arcade mirrors the admin's arcade-builds display.
  • Branches → Graph removed; Delete pin moved to the Iterations info panel.
  • Fixes: info panel Save, Test connection answers at once, three stale tests.
Lands everything since 10-13 on this fork's main in one fast-forward. Supersedes #7, #8, #9 and #10, which this branch contains. - Upstream trevato-apps/forge main (accaa65, 10-28) merged in. - Dev forge pages, site shell, build family and dev UI from #7–#10. - Build pins with one append-only Notes list per build, people's notes first. - Iterations: Columns and Tree, drag with Align/Reset, zoom with Fit, Collapse/Expand forks; kept per browser. - Display pages: chosen builds, drag to reorder, title edited in place; the Arcade mirrors the admin's arcade-builds display. - Branches → Graph removed; Delete pin moved to the Iterations info panel. - Fixes: info panel Save, Test connection answers at once, three stale tests.
jmoran added 3274 commits 2026-11-02 18:14:02 +00:00
Replace the hand-installed database trigger with a proper forge setting
(default off): when on, accounts younger than 7 days cannot create
repositories or forks, refused in the legacy trigger's own words
(403 {error: refused}). Agents and admins are exempt. Booting drops
legacy triggers carrying the guard's message, so forges carrying the
old trigger get the toggle instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reviewed-on: trevato-apps/forge#16
A stranger (no account) can now open /forges/new and POST /api/v1/forges
to start a child forge. The child forks the parent's own code
(config forgeRepo, e.g. trevato-apps/forge) with full history into
<org>/forge, recording the upstream in parent.json so it can follow its
parent. Anonymous spawns are rate-limited to 3 per client per 24 hours
(429 when exceeded); dry-runs are free. A model key is refused for
anonymous spawns; keepAccess and 'for whom' do not apply. The claim flow
is unchanged: whoever opens the claim link first becomes admin.
Reviewed-on: trevato-apps/forge#17
Disconnecting an origin nulls repo.origin_id through the foreign key and
leaves the provenance: a detached mirror, frozen. Migration 72 adds
repo.origin_detached_at, set by a trigger on that SET NULL and cleared on
relink, and Repo.detached reads it off the same row so a list knows which
rows are frozen without a query per row. Core helpers find detached
mirrors, compare hosts, renew a dead credential in place, and count
mirrors per origin; push-through asks the shared helper.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
reattachMirror re-attaches a frozen mirror for an admin of it, through an
origin they own on the host it came from, once that account can see the
same repository; it relinks, rewrites the remote, appends
origin.mirror_reattached (for admins) and syncs at once. Connecting an
account re-attaches the person's own frozen mirrors on that host and
reports each one, refusals included; connecting an account whose
credential died renews it in place, so its mirrors never detach.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repo JSON keeps an origin for a detached mirror: detached, no origin id,
when it was disconnected and when it froze. POST
/api/v1/repos/:owner/:name/origin/reconnect re-attaches one; the connect
answer lists the mirrors it brought back; the following JSON carries
parentFrozen beside the counts.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The repository home and branches page of a detached mirror say what froze
and since when, with a Reconnect form for its admin or the way to connect
an account there. A fork following a frozen parent says so instead of
ahead/behind and never "up to date". Settings, Origins counts the mirrors
a dead credential froze, links Re-authorize, lists frozen mirrors, and
the connect flash names what came back.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One decision item per origin needing re-authorization with mirrors behind
it, and one per detached mirror, read from what is true now so each goes
the moment it is fixed.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A real forge, a fake Forgejo and a second forge as the git host: renew in
place, disconnect, every page and the API saying frozen, the fork never
"up to date", pushes still refused, refusals for another host, an account
that cannot see it, a non-admin, an anonymous caller, someone else's
origin and a native repo, then reconnecting by connecting again, through
the API and through the page, with refs moving each time. In the gate.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ORIGINS.md: when a token expires, what a detached mirror is, what a person
sees, the one click, and that connecting again re-attaches by itself.
FOLLOWING.md: the frozen-parent sentence and why it is never "up to date".
FEED.md: the two decision items.

Refs #1090

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Refs #1090. Upstream main was red on two tests that this pull inherited:
test/spawn-anon and test/spawn-host were in neither GATE nor EXCLUDED, and
the board test forbade any style element after the white-flash fix gave
every page a nonce'd boot style. The list now carries both tests, and the
board test says what it meant: one boot style, never the board's own rules
inline.
Refs #1090. Three more tests on upstream main were red for reasons that
were not bugs in what they tested: the studio test forbade any style
element after every page gained its nonce'd boot style; the claim-link test
expected a nested child host after children moved to one label under the
parent (c5b54dad); and the audit test looked for the home's link to the
audit after the feed home (#599) dropped the Audit button — and nothing
else linked the audit at all. The first two tests now say what they meant;
the audit's button returns beside Map and Board on the home's apps card,
because the trust page must have a way in.
Refs #1090. Found by adversarial review: hostOf read only the hostname, so
git.example:8443 passed for git.example and a mirror could be reattached
to another server; a mirror from before remote ids were kept was bound to
whatever repository now carried its name. siteOf compares scheme, host and
port everywhere a reconnect decides (the auto reattach, the page's offer,
the attach itself); a mirror with no remembered id is refused as
remote_unknown with the way out said. The pins list carries the same
origin shape as the repository JSON.
Refs #1090. Upstream main was red on both: the new-forge test still said a
non-admin has no door, after 0.7.57 opened it to anyone signed in (the
roster and the claim links stay the admin's, and the test now says so);
and the studio's phone rules named .fcard-head, a feed card head with no
rule at 360px — it wraps now.
0.7.58 shipped with 71 and was never recorded; 0.7.59 carries migration 72
(origin_detached_at, additive). The two newest counts are what the
schema-additive test reads.
Run and app pages carried a bare <meta http-equiv="refresh"> as the
no-script fallback and had the script remove it. A refresh is scheduled
when the parser meets the tag; removing the element does not cancel it,
so every live page reloaded every five seconds and threw away the
reader's scroll. The reload now lives inside <noscript>, where a browser
running the stream never parses it; a redirect (url=) stays bare. The
four removals in client.ts go with it.
With one shard at a time (FORGE_CHECK_SHARDS=1) the gate's output was
held until the shard ended, so a check's log showed nothing for its
whole run. Lines now pass through as they arrive, between a header and a
footer; shards running side by side are still written through whole, so
they never interleave.
A forge the tests boot inside a check cell wrapped its apps in cells
nested in the check's own, and those never answered in time: every test
that deploys an app timed out, serial or not. The check's cell is the
boundary; its children now run as plain processes, as they do on a runner
without bwrap. The cell tests stand aside when told so.
No new migration (72 stays). 0.7.60 carries: the no-script refresh inside
<noscript> so run and app pages keep the reader's scroll; test-shards
writing a serial shard's lines as they happen; FORGE_CELLS=off in the
check cell so a forge the tests boot runs its apps as plain processes.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Two crew pulls today carried .tmp/ — bun's install cache and a test
forge's data, 584,000 lines — committed by the wrap-up's git add -A. A
sandboxed shell keeps its temp directory beside the code; the clone now
says once, in .git/info/exclude, that .tmp/ and node_modules/ are never
the work, without touching the repository's own .gitignore. The crew test
plants the directory and proves the pull does not carry it.
Inside the shell sandbox, localhost is the sandbox's own and reaches
nothing; a named host goes out through the sandbox's proxy. The crew's
remotes pointed at the forge's local address, so a plain git push had
nowhere to go and the only way to push was to leave the sandbox — which
the crew had been doing. The forge still clones and fetches over its
local address; the remotes it hands the agent carry forgeUrl, fetch from
the repository and push to the agent's fork. Claude Code is told that no
command runs outside the sandbox on request, and that a host meant to
enforce it fails the run rather than running the shell open.
A hand-installed trigger on the live forge said 'paused for new accounts
while the forge adds spending and resource limits' and outlived the limits
it waited for; the boot-time drop only knew the first generation's words.
Both go now, and the test plants both.
The emergency guards of 2026-10-05 were triggers named steward_… on repo,
run and repo_crew, plus later ones on other tables; the drop only knew one
message on one table, so the forge's own admin was still refused an app.
Now any steward_… trigger goes, and any trigger on repo, app, run or
repo_crew that says the guards' words; a trigger elsewhere that merely
mentions them stays. The test plants the family.
No new migration (72 stays). Carries upstream #21 and #22.
Two runs resumed after 0.7.61 kept their clones from before the release
and still pushed to the forge's local address, which the sandbox cannot
reach. The remotes are now set before the kept-clone early return, so a
resumed run pushes where the forge points today. The remotes test stales
a kept clone's remotes, resumes it on a comment, and proves the push lands.
Tonight's first snapshot to Backblaze failed on one put with 'S3Error: an
unexpected error has occurred' and no key named; the same write from the
same host and Bun version succeeded moments later. Object stores answer a
burst or a moment of maintenance with a 5xx. Every store call is now tried
five times with waits of 0.5, 1, 2 and 4 seconds, and what still fails says
which key and why. test/snapshot-store.test.ts pins the retries, the waits
and the message.
No new migration (72 stays). Carries upstream #24 and #25.
The forge's first keyed snapshot (2026-10-13 00:46Z) hung on its first
object, forge.db, for an hour: one connection to Backblaze went quiet and
Bun's S3 write never settled, so the retries never ran. The network was
fine the whole time: the same 81 MiB upload took 3 to 5 s from the host,
from a throwaway pod on the cluster network, on Bun 1.3.14 and 1.4.3.

Every attempt now has a deadline (three minutes by default); one that has
not answered counts as failed and the next attempt begins on a fresh
request, with the abandoned one left to settle alone. Two tests: a call
stuck once succeeds on the second attempt within the deadline; one stuck
for good fails after the attempts and says how long it waited.
No new migration (72 stays). Carries upstream #26.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The composer's "Tell the crew what should change" and each card's steer box were bare textareas: the feed's own style set their width and height and nothing else, so they stood out unstyled next to the rest. They carry the input class now and keep the feed's heights.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No new migration (72 stays). Carries upstream #27 and #28.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The forge kept a list of key shapes: sk-ant-api, sk-or-v1, or anything with
a base URL. The sk-ant-usr keys that now come with a subscription's API
credits were refused, and so was any gateway's key without a URL. The list is
gone: a setup-token (sk-ant-oat) is a person's plan and goes under
CLAUDE_CODE_OAUTH_TOKEN; any other one-line secret is an API key, and the
provider answers a bad one on the first call. What is still refused: spaces,
nothing, absurd lengths, and a base URL on a setup-token.

A child may now be spawned on its owner's setup-token too, under the same
whole-life budget a key gets; whose plan to spend is the spawner's call.
No new migration (72 stays). Carries upstream #28; 0.7.64 carried #27 only (its message said otherwise) and is not promoted.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 69ffc8f8f82d0e9fc932ef6246c5ca39d008aa19)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
test/apps-idle.test.ts: production preview reads "failed" once in seven runs

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
No new migration (72 stays). Carries upstream #29 (the crew's fix for the fork's #1216, by scout).
test/looks.test.ts: the look-while-tests-run case holds the app's tests open with a gate, not a 2 s sleep

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
signin-throttle.test.ts takes ~58 s alone and times out at 60 s under load

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The notecard: docs/RESTORE.md restores the forge in ten lines or fewer, and a test runs exactly those lines

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
test/sealed-release.test.ts: "the way out: its fix released" is green on a loaded runner and rejoins the gate

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
branches, cli-sync, code, counts, crew-loop and crew-totals join the gate, proven by the pull's own check

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
web-ui.test.ts: raw not-found pages differ by the path echoed in the here-manifest link

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit f9d278d67f)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 42b509db55)
A crew reviewer's changes-requested queues the builder's follow-up within one tick, with the review as its brief

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 2b1913cee7)
No new migration (72 stays). Carries upstream #30 and #31, both the crew's work (scout), reviewed by the owner's steward.
The nonce'd boot style painted html/body from the theme the server saw
(or the OS), with literal colors the stylesheet never overrides on body.
The theme menu flips data-theme without a reload, so the ground stayed
stale until a refresh. bootCss is now one constant for every page: the
system pair, then an html[data-theme] rule per theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 9e44960eeb8cf736cb97768302ebd21510210813)
The boot style now carries html[data-theme=…] rules on every page, so a
page with no chosen theme contains those words; what the test means is
that the root element carries no attribute.
No new migration (72 stays). Carries upstream #30, #31 and #32 (the crew's work: scout, scout, mason).
Two-tier gate: a fast tier judges every push in five minutes, the full gate runs once on land

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Carried upstream in #32 without its gate-list line; main's gate went red on
check-list for exactly the miss #1238 describes.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 565306f25381aa0de8290ef5fffe4debbe9928a8)
With the tier read from the base, a pull whose base has no commit or an
invalid forge.json cannot be checked; the test gives main a valid one first.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A JSON array body is no longer passed on as an object body.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No new migration (72 stays). Carries upstream #33 and #34 (the crew's work: scout).
/healthz is 200 whenever the process answers and its database opens,
however slow; only a database that throws makes it 503, logged once.
/readyz carries the drain's 503. A drain says why in one line the moment
it starts (the signal, and the SSH sessions it waits on). The readiness
test moves from web.test.ts to test/health.test.ts under the new meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GET and POST /claim/:token and claimPage are gone; /claim/<anything> now
falls through to the router's 404. Tests that claimed through the path post
the code as the form's token field to /claim instead, and assert the path
form spends nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The merge check rightly refuses a head whose forge.json conflicts with main's; the test's point (a pull does not choose its own gate) holds without the conflict.
scripts/flake.ts judges a file flaky when it is red in some random-order
runs and green in others; scripts/flake-hunt.ts runs the hunt (sliceable),
files the issue, moves open Flaky: files from GATE to EXCLUDED, and
records an admission. test/flake.test.ts joins the gate and refuses any
retry in what the gate runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No new migration (72 stays). Carries upstream #35 (the crew's work: scout, fork #1318 for #1316).
Up to six more test/[a-c]*.test.ts files join the gate, each proven green three times under the gate's load

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The menu was capped at 480px and scrolled inside itself. Its last
items, Sign out among them, sat below the fold, and macOS draws no
scrollbar to hint at them.

- The menu now grows to the window's height below the top bar.
- It still scrolls on a window too short to hold it.
web-code, web-origins and ssh-site join the gate, each green in the check and under the test budget

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Fuzz the parsers and chaos the forge on a side instance: invariants proven by faults, not by hope

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A JSON array body is no longer passed on as an object body.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The three new test files run in the full gate from their first landing (#1238).
Shard 47 of PR #36's gate measured a 65 ms median on the shared runner and went red on a change that never touched it. The bound is now 500 ms: a boot per request is seconds; a loopback round trip on a busy runner is tens of milliseconds.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The test guards against a boot per request, which takes seconds; 50 ms
went red at 65.4 ms on a loaded shared runner (upstream PR #36, shard 47).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A sixth root cause in the hunt's issue, a tight wall-clock bound, and a
detector beside the retry one: test/flake.test.ts fails on an
expect(<measured time>).toBeLessThan(N) with N under WALL_CLOCK_FLOOR_MS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
People name a tell or change by its number, but lists hid it and a
"#N" in prose was plain text, so readers had to open links to know
what anything was.

- List rows show the number after the title.
- A change's head says which tell it answers: "in answer to #6 from jmoran".
- "#N" in issue, pull, comment and review text links to that item.
- The link's hover shows its number, state, kind and title.
- Tests cover linking, escaping, code and links left alone, and the resolver.
Every forge tab held a live event stream open. Browsers allow six
connections to one host over HTTP/1.1, so a few background tabs left
new pages spinning and live updates broken.

- A hidden tab closes its streams: live regions, repository activity and run logs.
- Shown again, live regions and repository activity resume from the last event heard.
- A run log page reloads when shown, which replays its log.
- Checked in Brave: with every tab sent to the background, seven tabs each load in about 30ms; before, the sixth stalled.
A busy forge is not a dead one: the liveness probe restarted the forge under load tonight, losing three runs

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
No new migration (72 stays). Carries upstream #36 (the crew's work: scout, fork #1298 for #1244).
#1298 added them in neither list, so test/check-list.test.ts is red on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code's Linux seccomp filter refused every unix-socket listen, so any
test that boots the forge could not run in a crew run. Linux cannot filter
sockets by path, so all are allowed, and the machine's runtime directory is
denied by path. scripts/sandbox-probe.ts binds what test/checks.test.ts binds
and prints the verdicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Retire the /claim/:token path form once no path link can be live

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The review sweep reaches every open pull, oldest first: with 53 open, the oldest 3 were never looked at

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A migrated app's crew says what happens to its old database's rows, and ships the one-shot import to bring them

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Hold an app awake while a proxied request waits for its answer

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Narrow the crew sandbox allowHosts so 127.0.0.1 is not every loopback port

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A review run reviews: a comment addressed to the builder must not become the reviewer's task

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Work by @scout on #1385, committed by the forge.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Both histories kept. Where a feature exists twice, the fork's shape stays:
the reviewer's three-round handover and its skip log in crew/review.ts and
crew/dispatch.ts, the fork's review-from-check test, the fork's gate list.

From upstream, what the fork lacked: releases 0.7.66–0.7.71 in
src/core/releases.json, the merge-of-the-pull fast check and "Check again"
(checks/merged.ts, checks/again.ts; the base-tier test ordering in
test/check-tiers.test.ts that goes with it), review owed from the check's
green with the one late send (#1216; its test is now
test/review-from-green.test.ts so the fork's review-from-check stays), the
spawn-first-boot 500 ms bound, the themes test, docs/BACKLOG.md and the CI
observability steps in check.yml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One trunk: merge upstream-main into main (10 known conflicts: keep the fork's shape, bring over the three release entries and the few upstream-only fixes)

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
No new migration (72 stays). First release cut from the forge's own main after the converge (#1431 → #1433, mason).
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Both sides bounded spawn-first-boot's median at 500 ms with a comment; keep
main's. Main added test/plan-route.test.ts without listing it, so the gate
audit failed: it runs ~30 s, far over the budget, so it is excluded under #261.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
It landed on main (#1170) in neither list, so check-list went red. It
waits up to 30 s on a fake planner run under the crew sandbox, over
the gate's 1 s budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only this repository has scripts/sandbox-probe.ts; the README points to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No new migration (72 stays).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No new migration (72 stays). The landing that added the test forgot the list (#1238); the gate on land must catch this before main does.
No new migration (72 stays).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No code change beyond the workflow; carries 0.7.75 (main green).
A pull can carry a look a person attached: an image at a stated width, beside the crew's own looks

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Builders can run tsc and the socket tests inside their sandbox: two builders shipped untested code tonight because they could not

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No new migration (72 stays).
Carries 0.7.77 (builders prove their change in the sandbox; looks on pulls; migration 74).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Zero trust: sentinel flags an unauthenticated internal call

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
`/migrate?from=<host>/<owner>/<name>&crew=<agent>` opens Migrate with that repository and agent chosen, matched on the origin's full host

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 74.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The gate's list check failed on pull #1323 because test/plan-route.test.ts
was listed twice: once from main (#1468) and once from this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 74.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Asks on a phone: full-width rows, one-thumb actions, and the pull says what it removed

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 74.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A fork's "Take updates from <parent>" issue closes itself once its default branch holds the parent tip it was opened for

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The terminal shows a degraded forge to admins

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 74.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A pure SVG card renderer: src/web/og/card.ts turns {kind, title, lines, stat} into a 1200×630 card in the studio's tokens

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The New forge door never vanishes: at the room limit it says why (5 of 5 sent, retire one or raise the room); MAX_CHILDREN becomes a setting sized by the node

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Main is green on its gate list again: test/plan-route.test.ts is named in scripts/gate.ts

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Terminal: Raise and Lower a limb among its siblings (follow-up to #1212)

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
`bun scripts/test-shards.ts --gate` refuses an unlisted test file by name before any shard starts

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 75.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The memory-derived default gave a CI runner (~1.5 GiB) one child, so every spawn test after the first answered 409.
Migrations: 75.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 75.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Addresses the review on #1504:
- huntedFile (scripts/flake.ts) counts an issue only when its author is
  the token's user (GET /user) and the forge has not marked it untrusted;
  anyone else's 'Flaky:' title moves nothing out of GATE.
- The quarantine job clones through the internal registry with the job
  token, as the hunt does, and pushes its branch to the forge explicitly.
- The admit test spawns two bun test runs beside busy loops: 120 s, not
  the 5 s default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
test/plan-route.test.ts is red on the runner: the planner route test times out (30 s) and reads a file its stand-in never wrote; fix it and admit it to the gate

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Work by @scout on #1385, committed by the forge.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No flaky tests: ten green runs to join the gate, a nightly flake hunt in random order, mechanical quarantine

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An admin can retire an organization's last owner together with the organization and its repositories through the API, with an explicit confirm

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A merged or closed pull's queued checks are cancelled: six orphans held the lane for two hours today

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A run that finds its issue already done on main says which commit did it, and the asker closes it instead of the crew parking it

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A mirrored repository can approve an outsider's pull so its checks and preview run

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 75.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Work by @scout on #1519, committed by the forge.
Terminal On you: respect mutes and clear many in one move (follow-up to #1320)

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Resilience: a one-line notice when the forge runs with less than the default protection

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The forge hunts its own faults: a sentinel reads what the forge already knows, names what is wrong with evidence, and proposes the mechanical fixes

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The app proxy adds a collapsed forge pill to HTML pages only, and forge.json "toolbar": false turns it off

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 76.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 76.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The pull page's checks line reads "Conflicts in N files", with no green mark, when the pull conflicts

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 77.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Prove the crew sandbox boundary with a real sandboxed shell: own server reachable, outside localhost and every denyRead path refused

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 77.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Variants, step 1a: pulls and runs carry a nullable variant group, and the pull JSON says its group and siblings

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 78.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 78.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
vitals() names each degraded cause with when it began, landed from pull #1363 on today's main

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 78.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs/THREATS.md lands: each adversary, what it wants, and the protection and test that stand in its way, checked by a test

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Home, asks, the feed and MCP `asks`/`feed` never mark a conflicted pull green: they say "Conflicts in N files"

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A roll that cannot surge waits for the owner's yes to that roll

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The forge keeps a bounded history of each degraded cause: when it opened, when it closed, and its sentence

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Boards, step 1b: an admin lists sources and runs a query through the API; an agent token and a non-admin get 403

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Variants, step 1b: POST /api/v1/feed/tells with variants: 2 starts two builder runs in one group

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Restore drill, step 1: runDrill() restores the newest snapshot into an empty directory, opens and counts it, and always removes it

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 79.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A forge holding nothing exited 34 ms after SIGTERM; requests routers still
sent it in the next probe period were refused, and the ingress made each a 502.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
One flow, named: a pure src/flow module says which stage each issue is in (issue → pull → check → review → land → live) and how long it has been there

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
`og` is a reserved name, and GET /og/repo/:ref.svg and /og/app/:ref.svg serve a public live card with an ETag

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Let the decider: a hand-over card can be answered now by the decider, in the ledger, with the context it saw

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 79.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Work by @scout on #1704, committed by the forge.
Never down: the forge stays up through every release and every settings change

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Thoughts, step 1: POST /api/v1/thoughts keeps a forge-level thought verbatim in an append-only table

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The owner mutes a repository once, and its asks leave the inbox and the phone but not its own page

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 81.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Work by @scout on #1719, committed by the forge.
Fail fast, fail loud for the crew: every queue and run has a budget, past it is a failure named with its cause and handed to the crew at once

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 81.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Thoughts, step 3: the feed composer can send to "the forge", and the thought shows at the top of the feed as the owner's post

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 82.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A deck chooses among sibling pulls: one card each, like or dislike recorded in the decision ledger, disliked ones closed with a reason

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 83.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 84.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Clouds, step 1: `cloud.json` declares which vendor uses an app or repository may make, nothing by default, and docs/CLOUD.md states the rule

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 84.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 86.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The palette's "Tell the crew" opens a composer in place on any repository page and sends the page with the tell

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 86.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The gate's --impact now measures one file per process at the pool's width
whether sharded or not, and counts a file executed only when one of its
functions was called. The forge seeds every check's checkout with the map
the last green default-branch run kept and takes back a new one from such
a run; a measured test is guessed by imports only against changes the map
cannot see.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The stand-in forge moves to test/helpers/crew-standin.ts; every test
moves verbatim to a file of its own concept, each booting its own forge.
The merged-before-its-run test's last half (a closed pull's follow-up
fails) needs the closed pull crew.test.ts leaves, so it stays there as
its own test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Generate and keep the coverage map so the fast tier selects by what tests execute, not what they import

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Hosted apps sign in through OpenID Connect: the scaffold registers a client and verifies id_tokens instead of x-forge-identity

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Boards: the forge samples its own pod and node every 15 s into a ring on disk, as a machine source

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 88.
The 88 migrations that lived in one array in src/core/schema.ts are now
0001-…ts to 0088-…ts, each the same text as before (so every recorded
content id is unchanged), loaded in name order by readMigrations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first suite's chain is cut where its tests stop needing what came
before: the slow test step, identity with the never-answering deploy, and
the crew with the restart and the failing push each start from a fresh
hello in production (test/helpers/apps-forge.ts). The New app suites move
to apps-new.test.ts. Test bodies move verbatim; the identity file's setup
commits the passing server test the require_checks test used to leave on
main, so its toy server deploys as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A new migration is src/core/migrations/<UTC YYYYMMDDHHMMSS>-<slug>.ts, so
two pulls adding one add two files and never touch the same line. The
loader refuses a file it cannot place rather than skipping it.
releases.json now names the stamped ids each release applied, and the
additive check reads which migrations a release shipped by id, since a
migration written earlier can land later and sort before one already
released. Tests apply two independently added migrations in either landing
order and compare the schema; a digest pins the 88 numbered ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Feature flags, part 1: flags declared in one file with a stable per-viewer percentage, and a flag the code no longer reads fails the gate

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Split the two slowest test files: crew.test.ts (93 s) and apps.test.ts (68 s) set every check's floor

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
One green result per commit: a check on a commit already proven green is skipped, and a land does not re-run fast on a moved base

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A change to scripts/gate.ts no longer runs the whole suite: the lines added to GATE are the changed tests

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 90.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The home is the feed, proven end to end: one test walks composer, timeline, crew posts and a share

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A red restore drill, or none in eight days, is one board line and one push

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 90.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Releases 0.7.119 and 0.7.120 shipped them as numbered migrations, so
they join the numbered range (NUMBERED = 90) with their text unchanged;
the digest of the numbered ids is recomputed and matches main's list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md still said the numbered history stops at 0088 after main's
89 and 90 joined it. ARCHITECTURE.md said a compiled binary is the
release; the server reads src/core/migrations/ at boot and is run from
source — only the CLI is compiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 90.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Work by @scout on #1878, committed by the forge.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
#1863 added migration 91 (run.placement, run.node) to main's list. It
joins the numbered range as 0091-where-a-check-ran.ts with its text
unchanged (NUMBERED = 91), so a database main already migrated is
recognised exactly; the digest of the numbered ids is recomputed and
matches main's 91-entry list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OIDC: test that two requests racing past the key-rotation mark share one new key

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Issue, pull, run, person and app pages unfurl as one sentence from live state; private ones say only name and 'private'

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations never collide: parallel builders each add one without fighting over the next number in src/core/schema.ts

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Every ask row says what it waits for: one `waitingFor` word computed in one place, shown on /asks and returned by MCP `asks`

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 91.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Work by @scout on #1385, committed by the forge.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The router's match names the route pattern it matched

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Carried: drop the dead helpers left by #1753, or use them in the terminal deploy list

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A check Job that vanishes ends its run as interrupted and is queued again once

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Terminal: a place to read an app's production deploys, showing what each carries

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The retire confirm page lists the account's own repositories and apps too, not only its organizations'

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A stalled flow step is a card on the home with the one action that unblocks it

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Kind and people chips filter the home, the inbox and /api/v1/feed, saved per user

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A domain drill is kept with its verdict: POST /api/v1/drills (admin only) and a pure verdict against the domain's words

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A hosted child runs the apps it was given: <app>--<child>--<parent> is served and the parent's cells run them; today a spawned forge's apps are repos only

Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 93.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 93.
Migrations: 93.
Migrations: 93.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 93.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 94.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 94.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 94.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 96.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 96.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 96.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 97.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 97.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 99.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 99.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 100.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 104.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 105.
Migrations: 105.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 105.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 106.
Migrations: 106.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 106.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 106.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 107.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 107.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 108.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 108.
Migrations: 108.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 109.
Migrations: 109.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 109.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 114.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 114.
Migrations: 114.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 114.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 115.
After #2139 the flow page reads duplicates through systemFor and the
queue through queuesFor, so the live import from system/live.ts and the
readQueues value from flow/queue.ts were unused; tsc does not flag them
because noUnusedLocals is off. Only the QueueRow type is kept, as an
import type. Both modules still load through system/telemetry.ts, so
nothing at import time changes.
check.yml cloned this repository and checked out GITHUB_SHA. A fork's head
commit is here only as refs/pull/<n>/head, which a clone does not fetch, so
every gate shard of a fork pull died at "clone source at this ref" with
"fatal: reference is not a tree" before running a test (PR #39, run 893).

preview.yml cloned --branch "$GITHUB_HEAD_REF", a branch that exists only in
the fork; a fork pull gets no secrets either, and a preview builds and pushes
an image of the pull's code, so it now skips pulls from forks.
A forge with no admin has had two ways to get one, and both need a browser:
`/signup` (passkey only, #1996, #669) and, on a spawned child, the claim link
(passkey only). An agent that runs its own forge, or a child spawned for one,
had no way in. This adds an operator door that needs no browser and does not
reopen password or API signup.

## Design

- `bun src/main.ts --first-admin [--child <name>] [--url <origin>]` mints a
  code (32 random bytes, base64url) and prints it to the operator's terminal,
  the only place it is ever shown. The forge keeps its sha256, a 15-minute
  deadline and a used-at in one `forge_setting` row (`first_admin.code`,
  `updated_by = operator`); minting again replaces it. Refused when a person
  already administers the forge. Opens no socket and migrates nothing: a data
  directory without a `forge.db` is refused, so a newer tree never moves a live
  schema. `--child` finds a hosted child through the spawn ledger and mints in
  its database at its address (`parent.json` url).
- Redemption, two doors, one action (`actions/first_admin.ts`):
  - `/first-admin#<code>`: the claim page's shape. The code rides the fragment,
    the GET holds nothing, `/first-admin/options` and the POST are same-origin,
    and the account is made with a passkey (its own ceremony store) and signed in.
  - `POST /api/v1/first-admin {code, username, email, scope, name?}`: makes the
    admin and answers 201 once with a token of the asked scope (`ro|rw|admin`,
    required, no default).
- The code is spent before the account is made, in the statement that checks
  it (compare-and-swap on the row), so two racers cannot both win; a refusal
  after that (reserved or taken name, key already registered) undoes the
  account and puts the code back.
- On a spawned child the organisation is handed over exactly as a claim does it.
  The handover is extracted from the claim page as `handOver` in
  `spawn/claim.ts`, now shared by both. The claim link then reads `owned`.
- `first-admin` is a reserved name. The sign-in page links `/first-admin` only
  while the forge has no admin, as it links `/claim` on an unclaimed child.

## Threat model

| Threat | Answer |
| --- | --- |
| A stranger mints a code | No web or API route mints. Minting needs the forge's code run against its data directory, which is operator access. |
| The code leaks from storage, a snapshot or a backup | Only its sha256 is stored. A test scans every byte of the database for the code. |
| The code leaks in transit or in logs | The browser link carries it in the fragment, which is never sent. The API takes it in the JSON body, never a path or query string. Nothing logs it: a test captures every console line at debug through a refusal, a passkey ceremony and a token redemption. The CLI prints the agent line as "the part after #" so the code appears once. |
| Guessing | 256 bits. Every refusal is the same 403 with the same words, so a guess never learns wrong from used, expired, replaced or owned. The throttle sits inside the action, not at the doors (the shape of review H2): `firstAdminProblem` and `redeemFirstAdmin` each take one attempt from the address's and the forge's budget (`signin.per_account`, `signin.per_forge`) before the code is read, so no caller can skip it. A test calls the action directly and shows even the right code refused from a throttled address. |
| Replay or race | Single use via the compare-and-swap above. 15-minute TTL. Dead once any person is admin, checked at mint and at every redemption. |
| CSRF or a hostile page | Both doors refuse a cross-origin request before reading the code. The web POST reads the code only from the form body. |
| Weakening signup | `/signup`, `POST /api/v1/users` and the terminal keep `passkey_required`. A test shows a password signup is refused even with a live code in the body. |
| Audit | `user.created` with `via: first-admin` and `with: passkey|token` plus the address; `token.created` for the token; one log line naming the user. |

The headless admin has no password and no passkey: it can act only through the
token it was given, which is revocable on Settings → Tokens like any other.

## Docs

README "Run it" now shows the real quickstart. Signup is passkey-only and the
terminal no longer offers to create the first account, so the old
password/curl example has been dead since #1996. The new example uses
`--first-admin`, then the token's `scope` and the admin's `adminConfirm` for
later tokens, and notes that apps and agents are contained only with
bubblewrap and socat on `PATH`. docs/SPAWN.md says how a parent's operator
makes a child's first admin this way.

## Coordination: one account gate (review H1)

A parallel fix routes every account creation through one gate in `createUser`,
with a required origin: strangers pass `signupClosed` and the signup window,
and trusted paths are named exemptions. This PR does not change `createUser`,
`rp.ts`, `federation.ts` or any password path. It makes accounts in exactly one
place, `redeemFirstAdmin` in `src/actions/first_admin.ts`, under one named
origin, `FIRST_ADMIN_ORIGIN = "first-admin"`. That origin is an operator
exemption like the claim, not a stranger's door. Whichever PR lands second
passes that origin at that one call; there is no other call site.

Relates to #650 (identity is the forge's own), #669 (no password-only signup)
and #663 (signup stays bounded: this door is operator-only).
The parent forge's sign-in made a local account on first sight of a person
while the child's signup was `closed` or `invite`: that door asked the
sign-up window but not the signup setting (#2099; #2245 did not cover it).
Every door asked the policy itself, so a door added later could leave it out.

`createUser` now takes a required `origin`, and the policy is decided there:

- Stranger origins `signup` (form, API, terminal via `signUp`), `passkey` and
  `parent` are refused with `signup_closed` while signup is not open, and must
  carry a `SignupSlot`. Only `SignupSlot.take` (the sign-up window) makes one,
  its private constructor and private field keep a look-alike from passing,
  and it makes one account.
- `edge` is held to the setting, as before, and not to the window, which it
  never was.
- `claim`, `everyday`, `agent`, `spawn` and `seed` are named exemptions. The
  switch over origins ends in a `never` check, so an origin nobody classified
  does not compile; a new exemption is one more name.
On main's check, test/hollow.test.ts was the gate's most frequent red: shard 2
OOM-killed at it twice (runs 874 and 883, exit 137 with memory.current pinned
at memory.max 512 MiB) and once swapped until "`bun scripts/hollow.ts` says so
and exits 0" took 450 s against its 60 s timeout (run 859; spawnSync blocked
the timer).

Two causes, both fixed without touching what the tests assert:
- scripts/hollow.ts parses 838 files with the TypeScript API and dropped each
  tree as garbage, but nothing collected it, so one audit peaked at ~442 MiB
  RSS for ~20 MiB of live heap. It now runs a full collection every 64 files:
  ~270 MiB peak, same result, no measurable time cost.
- The command's test spawned a second whole-tree audit beside the test
  process's own two audits. It moves to test/hollow-cli.test.ts, whose
  process audits nothing itself, and awaits Bun.spawn so its timeout can end
  a stuck child. The guard test now keeps both files out of EXCLUDED.

Peak memory of the whole process tree (PSS summed over test-shards, bun test
and the child, sampled every 50 ms), bun 1.3.14, FORGE_CHECK_SHARDS=1:
test/hollow.test.ts on main 504 MiB of the runner's 512; after, 276 MiB for
test/hollow.test.ts and 257 MiB for test/hollow-cli.test.ts. The audit
alone: ~442 MiB RSS before, ~270 MiB after.
`POST /api/v1/first-admin` minted an admin-scope token that lived until
revoked. Now it never mints one without an expiry, on the repo's own
mechanism: `token.expires_at`, refused by `verifyToken` once past and swept
by the worker.

- Default 86400 s, a day: OAuth's shortest `LIFETIMES` choice and an app
  token's TTL (`APP_TOKEN_TTL_MS`). The constants are read from `LIFETIMES`.
- The caller may send `expiresIn`, whole seconds from 60 to 2592000 (30 days,
  OAuth's "month"). Anything else (0, negative, over the cap, fractional, a
  string, a boolean) is 422 `invalid_expiry`, checked before the code is read,
  so it spends nothing.
- The 201 answer adds `expiresAt` and `expiresIn`; `token.created` records
  `expiresAt` when there is one (`actions/users.ts` `createToken` takes the
  optional expiry through to `core/tokens.ts`).
- README and the CLI's printed hint say so, and that this account (no
  password, no passkey; tokens do not mint tokens) cannot sign in once its
  token lapses.

Tests: default lifetime held in the row; boundaries; ten bad values refused
without spending the code; a caller's hour kept; the token refused (401) once
expired; the audit carries the expiry; no token of the first admin lacks one.
The budget from #2490 was wall-clock: 300 ms on any machine. On main's
check runner (half a CPU, 512 MiB) every design is ~6x slower, the plain
repo card included (295 ms against 45 ms where the budget was set), and
app and pull went red at 616 and 708 ms (run 889) with no change to the
cards.

The test now times the plain repo card first, in the same process, and
scales the budget by max(1, plain / 45 ms). A machine as fast as the one
the budget was set on, or faster, is held to the full 300 ms; a slow one
gets a proportionally longer budget; and a design that grows slow against
the plain card still goes red anywhere. Each test prints its measured
budget.

Checked: on one third of a core, main's test goes red (pull 416 ms) and this
one passes (budget x2.03, pull 335 ms); with 400 ms of extra work planted in
the pull card, this one is still red on a fast machine (457 ms against 300).
startNotifier's stop() ends telling but, on purpose, leaves the drain pager
running (main.ts stops the notifier when a drain starts and the drain must
still be paged; notify-drain.test.ts holds that). Only close() clears the
pager. Four test files ended their notifier with stop(), so its pager kept
firing for the life of the bun test process.

test/drill-board-line.test.ts starts one with clockMs: 10: after its afterAll
removes the data directory, the pager logs "notify failed ... ENOENT: statfs
'<tmp>/forge-drill-line-…'" every 10 ms into the process-wide error ring.
Any later file in the same process that counts errors goes red: vitals'
"errors are counted, bounded, redacted, and a burst is said" (lastHour is
not 1) and tui-sentinel's "an admin has it, and it says what the board says"
(the hunt files an error-rate finding). That is what the forge's parallel
check, which runs many files per process, saw on pulls that never touched
either.

On main, `bun test test/drill-board-line.test.ts test/vitals.test.ts
test/tui-sentinel.test.ts` fails both, every time; with this change it is
25/25 green. accounts, watches and snapshot-mirror had the same stop(); they
are not red today but leak the same interval, so they close too.
`childPublicUrl` built every child's address as `https://<name>--<host>`
from a host with its port stripped. Behind the platform (https on 443) that
is right. For any parent on plain http or another port it was wrong in two
ways: the child was told an https address nothing serves, and it lost the
port. Its config `url`, the ledger, `/spawn` answers, the claim link, and
its apps' `FORGE_URL` all pointed nowhere.

- `parentOrigin(config)` in `spawn/placement.ts` names the parent's public
  origin once: its canonical `url` when it has one, otherwise
  `http://<host>:<port>` as `main.ts` names itself. It replaces
  `parentHostOf` in `actions/spawn.ts`, which was a copy of `childHost`.
- `childPublicUrl(name, parent)` takes that origin and keeps its scheme and
  port (a scheme's default port drops, as `URL` does). A bare host still means
  https with no port, so the platform's `https://<name>--forge.open-platform.sh`
  and every existing caller and test are unchanged.
- Every place a child's address is made uses it: the spawn door's placement
  and ledger seeding (`door.ts`), `liveChildUrl`, the child app's own `url`
  (`host.ts`), and its apps' forge URL (`child-apps.ts`). Matching a Host to a
  child (`parseHostedChildName`) already ignored the port and is unchanged, as
  is `childHost` for those host-only uses.

Tests: `childPublicUrl` and `parentOrigin` across http/https, explicit,
default and missing ports. End to end, a parent at `http://forge.lan:8080`
spawns `kid` and the spawn result, `liveChildUrl`, `childUrlOf` and the
opened child's own `config.url` are all `http://kid--forge.lan:8080`. On main
the same parent gives `https://kid--forge.lan`.

Overlap: #2419 (a new or spawned forge starts with signup = invite) changes
the child's signup setting, not its address. No open pull touches these files
for it, so neither rebases on the other. #41 (first-admin) does not touch
placement.

Note: the single-label shape is unchanged, so a child of `http://localhost:3000`
is `http://kid--localhost:3000`, which needs a hosts entry or wildcard DNS to
resolve, the same as before but now on the right scheme and port.
"31 days of 15-s points keep at most 30 days of 5-min roll-ups" timed
178,560 points through record() against a fixed 5,000 ms. On the check
runner (half a core, 512 MiB) it took 6,012 ms and failed gate (1) of
PR #44's check (run 903, boards-sampler.test.ts:192); main's own push gate
has failed on it too. Where the budget was set it takes ~500 ms.

The test now first times plain INSERTs of the same points in the same
5-min batches (~250 ms there) and allows 5,000 ms times
max(1, plain / 250 ms). The budget is unchanged on a machine at least that
fast, and scales on a slower one. It still catches what it is there for:
with the roll-up rescanning every window (`from = ""`), the run is
40,702 ms against a budget of 5,481 ms and fails.
A headless first admin holds only an expiring token. It has no password or
passkey, and tokens do not mint tokens, so when its token lapses the forge
has an admin and no way in. And `--first-admin` refused because an admin
existed.

Now, when no admin has a working credential, the command mints a recovery
code instead. "Working" means any of: a password, a passkey, a token that has
not expired (or never does), a live session, an SSH key, or sign-in with the
parent. Every admin counts here (person or agent, suspended or not), so the
check refuses as broadly as it can (`adminCanSignIn`, `core/first_admin.ts`).

- Same shape as the first-admin code: one `forge_setting` row, sha256 only,
  15 minutes, spent by one compare-and-swap, replaced by the next mint. The
  row also holds the id of the admin it is for (`r`).
- Bound at mint to one stranded admin: an active person admin, not
  suspended or removed. If there are several, `--user <name>` picks one.
  The command refuses a non-admin, an unknown name, `--user` on a forge with
  no admin, and any forge where an admin can still sign in.
- Redeemed only at `POST /api/v1/first-admin/recover {code, scope, name?,
  expiresIn?}`. It mints a new token for that existing admin, with the same
  lifetime rules (a day by default, at most 30 days, never forever), and
  answers 201 `{user, scope, id, token, expiresAt, expiresIn}`. No account is
  made. A recovery code is refused at `/api/v1/first-admin` and `/first-admin`;
  a first-admin code is refused at `/recover`.
- Checked again when redeemed: a credential that appears after minting kills
  the code.
- Same throttle, inside the action, before the code is read
  (`recoverFirstAdmin`). Cross-origin is refused. Every refusal is the same 403.
- Audited as `user.recovered` with `via: "first-admin-recovery"`, the token
  id, scope, expiry and address, plus the usual `token.created`. One log line
  names the user, never the code or the token.

The existing CLI test's admin had no credential, so that forge is now
recoverable. The test gives the admin a token, which keeps it a refusal test.

Tests (test/first-admin-recovery.test.ts, written first: 8 of the 16 failed
against the previous head, the 8 refusal guards passed): recovery end to end,
once, then refused; the token's lifetime rules; the 15-minute expiry; each
kind of code refused at the other's door; cross-origin and rate limit; nothing
logged. Refused for each of the six credentials, held by the stranded admin
or by another admin. Expired sessions and tokens don't count. A credential
that appears later kills the code. `--user` with several stranded admins; a
suspended admin is not recovered.
Conflicts were imports only: users.ts keeps admitSignin beside #43's getSignup
and SignupSlot; site.ts keeps signinWindow beside SignupSlot (RateLimiter is
no longer used there). Every password door still goes through
verifyPasswordThrottled. Two tests that call createUser without an origin get
origin "seed": signin-password-doors (this branch) and account-ceiling-reserve
(#52 landed after #43 without one, so main does not typecheck).

Progress: tsc --noEmit clean; touched tests next.
#52 (dev/ceiling-reserve) was written before #43 made createUser's origin required, and both merged, so test/account-ceiling-reserve.test.ts:46 failed tsc on main 006d3977 (TS2345: property 'origin' is missing). The fixture uses `seed`, the origin for test fixtures, as every other test does.
# Conflicts:
#	src/http/api.ts
With #43, createUser takes a required origin and holds stranger doors to the signup setting. The first-admin code is the operator's proof (only the operator's terminal is shown it), so redeemFirstAdmin says origin `first-admin`, an exemption like `claim`, and makes an admin. Recovery does not make an account (it mints a token for an existing admin), so it needs no origin. Test fixtures say `seed`.
"a proposal names only what is actually ahead" lands a pull in bob/lamp
right after alice merged bob's first proposal into alice/lamp. That merge
moves the untouched fork on the bus (following.ts), and the test's next
mergePull reads the fork's main before the move and CASes it after:
update-ref fails and the merge returns base_moved. On one core, 3 of 6
runs on main failed that way:

  error: {"kind":"base_moved"}
    at test/following.test.ts:852:33

The test now waits, as this file's settle() does, until the fork is synced
with the parent's tip before landing the next pull. What it asserts is
unchanged. 12 of 12 runs pass on one core.
`AdminOrigin` is `claim`, `first-admin` and `seed`. createUser takes the
admin flags only from one of those: they are not in any other origin's
input type, and createUser drops them for any other origin at run time.
So the signup form, the API, the passkey door, the terminal, the parent
forge's sign-in and the platform edge each make a person who is not an
admin, even on a forge with no admin at all. A standalone forge's admin
comes from the operator's `--first-admin` code (#41); a spawned child's
from its claim link.

With no sign-up an admin, `welcome` no longer proves an admin's address by
being one, and the edge's first account is not proven by being first:
both start unproven and follow the link like anyone else.

Test suites whose admin was their first sign-up make it with
`test/helpers/admin.ts` (`seedAdmin`, or `adminCookie` for a signed-in
browser) instead. `test/no-signup-admin.test.ts` fails on main: the API,
passkey, terminal and edge doors each made the first account an admin.
git-ssh and ssh-app drive the real OpenSSH client, so they skip on a machine
without it and the branch's validate run never saw them. On CI they failed:
alice, no longer admin by signing up first, is unverified, and createRepo
refuses her ("repo creation failed"). Same fix as the other suites:
seedAdmin, which keeps her the proven admin she was on main.
# Conflicts:
#	src/actions/users.ts
#	src/core/users.ts
The closed/invite exemption for a forge with no accounts and the terminal's Turnstile skip for that account existed so the owner could become the admin. Since #57 the admin comes only from the operator's first-admin link, a claim or seed, so both only let in an unverified non-admin. newAccountsClosed now reads the setting alone; signUp drops its door option; the terminal's sign-in screen opens on Sign in when signup is closed.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
# Conflicts:
#	src/actions/users.ts
#	src/core/users.ts
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 116.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
# Conflicts:
#	src/actions/users.ts
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Where the host cannot hold a cell, an app ran as a plain child in the
forge's own process group, and stop() signalled its pid alone. A child
it had started (a worker, `bun run`'s script, a `sleep`) was re-parented
and kept running on the environment's data and token after the forge
called it stopped; one that outlived a crash ran beside the restart.

The app now leads a process group of its own (`detached`, without a
cell only), stop() asks and then kills the group, and once the app has
exited, however it went, what is left of the group is killed. A cell is
unchanged: its tree is bubblewrap's.

Since a terminal's hangup no longer reaches those apps directly, the
forge takes SIGHUP the way it takes Ctrl-C: it drains and stops them.

test/apps-stop-tree.test.ts: red on main (3 of 3), green here.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Where the host cannot hold a cell (CI, a pod without bwrap), an install,
test or check step ran as a plain `/bin/sh -c` child in the forge's own
process group, and a cancel or timeout SIGKILLed the shell alone. What
the shell had started (`bun install`'s scripts, a test runner and its
workers, a `sleep`) was re-parented and kept running in the checkout
after the step was reported cancelled; a superseded check kept burning
the machine beside its replacement.

The step now leads a process group of its own (`detached`, without a
cell only), a cancel or timeout kills the group, and once the shell has
exited, what is left of the group is killed. A cell is unchanged: its
tree dies with bubblewrap. `signalGroup` moves to module level, shared
with `startProcess` (#63).

Since a terminal's Ctrl-C no longer reaches a running check, the forge
stops checks without the roll's drain wait on a person's signal
(SIGINT, SIGHUP): they are cut off and queued again at once. A SIGTERM
(a release) still lets them finish within FORGE_CHECKS_DRAIN_S.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Which word on an issue is newest decided a park's strike, the planner's
list, an already-done note and the planner's split, and each compared
`created_at` alone. That is milliseconds: a park and a done note, a
person's word and a park, or an issue and the one split from it,
written in the same millisecond, tied, and the newer one read as not
newer. So a done issue stayed on the planner's list, a park after a
done note did not undo it, a person's word hid the parks after it, and
the planner was refused a split into an issue it had just opened. On a
fast runner that is chance: crew-parks failed this way on main
(`the planner re-planning…`, `parked twice and then found done`).

Each comparison now orders by (created_at, id). `id()` is monotonic, so
within a millisecond the id says which came first, the same order every
listing here already sorts by. `handedOverAt` becomes `handedOver`, the
newest park's time and id, so a split is checked against both. An issue
opened before, in the same millisecond, still cannot stand in.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Where the host cannot hold a cell (CI, a pod without bwrap), an app's
terminal (`ssh <slug>@forge`, or `t` in the forge's terminal UI) ran as
a plain `/bin/sh -c` child in the forge's own process group, and a
hangup sent SIGHUP to the program's pid alone. What the program had
started (a server it left running, a job sent to the background) was
re-parented and kept running in the deployed checkout, with the
environment's data dir, forge token and secrets, after the terminal had
closed; nothing ever stopped it.

The terminal now leads a process group of its own (`detached`, without
a cell only), a hangup signals the group, and once the program has
exited, what is left of the group is killed: the pattern #63 and #64
gave apps and steps. The spawn moves into `startTerminal`, so it is
tested without a deploy. A cell is unchanged: its tree dies with
bubblewrap. `signalGroup` is exported from `apps/process.ts` for it.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 118.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 119.
Migrations: 119.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 119.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 119.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 120.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 120.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 121.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 122.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 122.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 122.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 124.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 124.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 125.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 126.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 126.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 126.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 127.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 129.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 130.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 131.
Migrations: 131.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 131.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 132.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 133.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 133.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
admit() no longer re-runs a stale green's own check before queueing it:
the candidate's full gate on main's tip is that proof, and a red one
bisects. A landing the queue gated (expect) is not held by checksHold for
staleness; a person's merge still is. The unused 'stale' wait is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 133.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Migrations: 134.
Migrations: 134.
Migrations: 135.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 135.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 135.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 135.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 135.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 136.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 136.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 137.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 137.
Migrations: 137.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 137.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 137.
Migrations: 137.
Migrations: 137.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 138.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 139.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 139.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 140.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 140.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 141.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 141.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 141.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
POST /settings/tokens (and a repository's proposal-token form) allowed
only a session or the password, a list written before the platform edge
existed, so an open-platform.sh sign-in got 403 'forbidden' while
POST /api/v1/tokens accepted it. Both forms now ask isAccountItself
(session, edge or password; never a token). readForm still refuses a
cross-site post first.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 141.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 141.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 142.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A park note written in the owner's name woke a feedback run and steered the
running builder as the owner's word. parkIssue, parkPull and parkForBreaker
now say the note as the run's agent (else a builder on the crew).
Every repository gets Files, Issues, Pull requests and Branches, plus
Settings for an admin. Issue and pull lists filter by open, closed and
all, show the git state badge, the author, and a pull's branches, and
link to /issues/:n and /pulls/:n. The branches page leads with a branch
graph drawn from git log --branches.
ensureDirectionIssue opens the direction issue in the owner's name, so its
issue.opened event seeded "because you told" for every item in the app.
seedOwnActs now skips the issue.opened event of a repo's direction issue.
A run whose subscription's whole-life budget was spent was paused and
queued again as "paused on the provider's limit", so it read as a Claude
usage limit. The resting pick now says when the budget is the cause; the
paused run, its queued successor (BUDGET_PAUSED), its run log and a run
that fails past MAX_PAUSES all name the forge budget, and interruptionOf
reads that failure as a "forge budget" interruption.
The review task quoted only the direction line, so the reviewer asked to
remove work the owner had asked for on the pull. The runner now passes
which commenters direct the crew, and the review brief quotes their words
first and says they outrank the direction.
The review checklist named the terminal door, src/tty.ts and the forge's
signed headers in every repository, games included. Those lines now apply
when the repository is an app the forge runs; others get a plain security
line.
A run paused on a spent forge budget was queued with not_before an hour
out, and neither raising the budget nor Wake cleared it. wakeBudgetPaused
sets not_before to now on every queued agent run whose summary starts
with BUDGET_PAUSED; the Subscriptions budget and Wake handlers call it.
A run still out of budget picks, pauses and waits again.
capReached counted every run started since a director last spoke, so a
healthy reviewer/builder loop reached ISSUE_RUN_CAP in minutes and was
parked though its last round was approved. Runs created before the
newest approving review on the issue no longer count.
Builders left asides for the reviewer in pull descriptions. The system
prompt now says the description is what changed and why, with no notes to
the reviewer and nothing about how the work was done.
A forge with no snapshot destination ran the nightly take anyway and
logged "ERROR snapshot failed: this forge has nowhere to put a snapshot"
every night. The nightly timer now skips the take when no store resolves,
and boot logs one info line, "snapshots off: no destination", in place
of "snapshots on where=nowhere". An on-demand snapshot still fails and
says why. test/snapshot-nightly.test.ts joins GATE.
requeueInterrupted labelled every agent run whose lease lapsed as
"interrupted by a restart", including one this process still held after
the machine slept. It now takes the dispatcher's in-flight map: a lapsed
run still in it is requeued as "lost its heartbeat though the forge never
restarted"; any other keeps the restart label.
# Conflicts:
#	src/crew/brief.ts
spawn-host.test.ts sat in neither gate list, and the stylesheet test
predates the nonce'd boot paint every page now carries.
The Forks and Runs tabs left the strip, so their tests now look for the
palette entry and the forks page's own count.
Home now carries the forge's tabs (Home, Apps, Repositories, Map, Board,
Front page), your apps with links to their issues and pull requests, a
File an issue form with File and File to crew, and the SSH command
folded behind a button. The activity feed stays at /asked. File to crew
lands on the issue it filed and names the builder it assigned.
Reached from the command palette. file and feed are reserved names.
The feed's tests read /feed; the home's read the File an issue form,
your apps and the folded Connect card. File to crew lands on the
filed issue. A new test covers POST /file: a writer lands on the
issue; an unreadable private repository, a blank title, a stranger,
another site and a read-only token file nothing.
Its title says what waits: pull requests and repositories waiting on
your decision.
A writer pins a commit under refs/builds/<label>: an annotated tag with
a note and Parent and Source trailers. No check runs and no agent wakes.
Branches leads with a Builds card: each pin under its named parent, else
under the nearest pin in its history, and a fork's first pins under its
parent repository's. Pin build sits on each branch row and on a pull
request's head; the branch graph marks pinned commits.
A fork's first pin hangs from the nearest of its parent repository's pins
in its history, by the same rule as inside one repository.
An app's demo runs one commit at <slug>--demo with a copy of production's
data. The runtime rebuilds it from refs/demo on boot, lists it after
production in its status, and every page that names an environment says
demo. The slug demo is reserved so <theirs>--demo stays unambiguous.
setDemo moves refs/demo under a lease to a commit a verified writer chose,
announces app.demo and deploys the demo; clearDemo deletes the ref and
tears the environment down. A mirror refuses, a non-commit is refused, an
agent may not pin, and the pre-receive hook keeps refs/demo out of reach of
a push. PUT and DELETE /api/v1/repos/:owner/:name/demo call them.
On an app, Update the project demo to this build calls setDemo after the
pin lands; the pin stands even when the demo does not move. The Builds
card marks the demo's pin and links its address.
Reviewed-on: jmoran/forgeJ#6
Home, Apps, Repositories, Map, Board, Front page and Activity each open
on the same tab strip at the same height, then a title and one line.
The board is a page under the tabs; ?wall keeps it bare and dark.
Home, Apps, Repositories, Map, Board and Front page sit in the topbar of
every signed-in page, lit where you are, so repo pages reach them too;
the per-page strips are gone. A repository's header is the same on every
tab: description and where-row always, no branch count that only some
pages knew, and an App tab for an app's own page. A plain repository's
Files carries the same one-line strip an app's does.
The Builds card draws every pin of the fork family: up to the root and
every readable fork below it. A pin may name a parent in another
repository (owner/name:label), a concept edge drawn with a dashed mark;
that pin is drawn as its root. Without a named parent a pin hangs under
the nearest pin in its history, here or in any repository it was forked
from, nearest first.
The Fork form takes a name, prefilled with <name>-work on your own
repository, and owners are offered it on native repositories too. The
one-fork-per-parent rule still holds for other people's repositories;
an owner may grow several named forks of their own.
Branches gains a Graph view: every pin and branch tip of the fork family
as a node, git history solid, concept edges dashed, branch tips dotted.
Nodes drag; their places stay in the viewer's browser, with Reset.
Picking a node opens a panel with its facts and its verbs: Preview now
on an app the viewer may write, Pin build on a branch tip, its files.
A new environment kind, build-<sha7>, held only in the runtime's memory:
at most three per app, a fourth tearing down the oldest, none rebuilt on
boot. previewBuild (actions/build_preview.ts) asks for one as a verified
writer, never an agent or on a mirror, and announces app.build_preview.
parseAppHost and parseAppLogin read the new label back; slugs shaped like
b<sha7> are reserved the way demo is. Reachable at POST
/:owner/:name/builds/preview and POST /api/v1/repos/:owner/:name/builds/preview.
# Conflicts:
#	src/http/server.ts
1 Builds is the graph as it was. 2 Experiments draws one node per fork
with its iteration count and its best build, the pin its main builds
on; a fork opens to show its iterations, and a closed fork carries their
edges. 3 Generations puts each build in the column of its generation,
joined only by lineage, each fork's iterations together and its best
ringed in colour. Layout and open forks stay in the viewer's browser,
per look.
forge.json app.pages names the pages a person plays or downloads. Each
look's panel offers Play per page, a build preview opened on that page,
and Download per page: GET /:owner/:name/builds/:sha/download?page=,
the page as one .html file fetched from the commit's running preview,
for anyone who may enter the app. Nothing is built or stored for it.
A form's redirect to another origin is held to the page's CSP
form-action 'self', so Play did nothing in the browser. The answer is
now a short page that refreshes to the build preview's address, with a
link to it.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 143.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
primitive.ts gives every issue, pull request, fork and deployment page
one shape: kind, title, number and state; primary actions and one
Actions menu; info sections that start open; and an Automation panel
for anything the forge does on its own. docs/WORDING.md states the
rules the pages are written to.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The issue page now uses primitiveLayout: kind, title, number, Open/Closed
state and an opened-by byline; Comment and Close issue/Reopen issue as
primary buttons; edit, assign, labels, dependency, milestone, seal,
private fix repository, copy link and origin in the Actions menu.
Details, Assignee, Labels, Milestone, Dependencies, Linked pull requests
and Participants are info sections with their forms. The crew and
autonomy are Automation panels; the studio's word appears only there,
as the inferred state.

The new-issue page says New issue and Create issue, offers labels and an
assignee to writers, and a separate checkbox that assigns the crew's
builder. A comment can close the issue with a reason (Close with
comment). The timeline names assignments and dependency changes.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Rows read "opened <time> by <author>", the assignee, the comment count
and the update time. Filter chips name the field (assignee:, author:,
title contains:). The compose button says New issue; the signed-out
button says Sign in to create an issue; outside reports read as problem
reports.
One header for every tab: kind, title, number, state, and a byline of
facts. Merge pull request (with the merge method) shows only where
mergePull would take it, else the one reason it cannot; Close and Reopen
beside it; every other action in the Actions menu. The rail lists
details, branches, checks, reviews, deployments, labels, assignee,
linked issues and participants. The crew, autonomy and the inferred
state move into Automation panels.

Tabs: Conversation, Commits (new route), Files changed. Edit title and
description is reachable from the menu. Flashes for merge, revert, hold
and release say what failed and what to do. Tests follow the wording.
Migrations: 143.
Deployments carries the preview's state badge, why it sleeps, and Open,
Redeploy or Wake preview. The preview screenshots return to the
Conversation tab. Agent runs are read in one query, so the page costs no
more as a pull's runs grow.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
The Forks page is a primitive page: a table of forks (name, created,
ahead and behind the parent's default branch, last push, visibility),
the lineage, and the Fork form labelled "Name of the new fork". A
fork's card says "Fork of X. N commits behind, M ahead. Conflicting
files: ..." and offers "Merge upstream main into main" and "Open pull
request to X"; the crew's merge is an Automation panel inside it.
The primitive layout's rules and the table rules join the stylesheet.
The app's page is a Deployments table: one row per environment
(production, demo, each pull preview, each build preview) with commit,
branch or pin, the runtime's state, URL, started and last deploy run,
and each environment's actions in its row's menu (Open, Redeploy,
Stop, Start, Clear demo, View log, Open terminal). Redeploy production
is the primary; app settings, environment variables and access are in
Actions. The rail lists the app record, the terminal, forge.json, the
contract and seven days of usage; automatic deploys, the crew's runs in
flight and screenshots are Automation panels. POST /app/demo/clear
clears the demo from the web.

The run list is a table (kind, trigger, commit, environment, state,
duration, cost, actor, created) filtered by ?kind= and ?state=, with
Cancel run and Retry run in each row's menu. The run page is a
primitive page with the same facts, Cancel run / Retry run, and the
log. POST /runs/:id/retry queues an agent run's task again or
redeploys a deploy run's environment.
# Conflicts:
#	test/apps-idle.test.ts
#	test/studio.test.ts
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
# Conflicts:
#	src/web/pages/following.ts
#	src/web/pages/search.ts
#	src/web/studio/actions.ts
#	test/apps-idle.test.ts
#	test/contents-api.test.ts
#	test/following.test.ts
#	test/forks.test.ts
#	test/holds.test.ts
#	test/studio-words.test.ts
#	test/studio.test.ts
#	test/web-ui.test.ts
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 144.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 145.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
# Conflicts:
#	src/core/releases.json
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A platform sign-in mints tokens from the settings form, as the API lets it

Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 146.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 147.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 149.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 150.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Migrations: 150.
The Tree look now shows which pins carry on and which stop.

- each repository's next pin sits on the same row, left to right
- a thick accent line marks history that reaches a main branch
- pins no main branch holds, here or downstream, are faded
- the side panel lists what each pin was carried into
- the graph scrolls at full size instead of shrinking to fit
A pin can now name the cartridge it releases, stored in git on the pin itself.

- Cart name, version, producer, page, shelf switch and cover ride as trailers on the pin's tag.
- Changing them rewrites the tag for the same commit, keeping who pinned it, when, and the note.
- An uploaded cover is kept in git as a picture the pin names.
A cart's page is now captured from its build and kept, so it plays without a running preview.

- Capturing starts the build's preview when needed, waits for it, and saves the page and a picture of it.
- Captures sit in the forge's data folder by repo, commit and page, and are never overwritten.
- What a capture under way or a failed one looks like is kept in memory for the panel.
A pinned build now has a cartridge panel beside the build graph, as in mockup F.

- It shows the cover, cart name, version, producer, page and an "On the shelf" switch.
- Writers save the facts, flip the switch and upload a cover. Readers see the facts.
- A cart with no capture yet starts one. Download takes the capture when there is one.
- A cover nobody uploaded is the page's picture, drawn in the house cover style.
A public Arcade page now lists every cart switched on the shelf, from any repository.

- It is the browser arcade as it was: the chunky carousel, the console and the jbox boot tag.
- It answers at arcade on the apps domain, its own address, so carts keep their saves and never run as the forge.
- Carts with the same name are one cartridge, and each shelved pin is one of its builds.
- The forge's top bar links to it as Arcade. No app or account may take the name.
The Arcade's "Export snapshot" link now downloads the whole shelf as one HTML file.

- Every shelved cart, cover and picture goes inside the page, so it plays from disk.
- The file is browser-arcade-<date>.html, as before.
- Its one top line reads "JBOX • snapshot <yyyymmdd> | This is an HTML file that doesn't receive updates".
Pinning is now the release step: a new pin becomes a cartridge with its page saved.

- The pin form ticks "Release it as a cartridge" by default. The Arcade shelf stays off until someone turns it on.
- A branch named iter-N offers iter-N as its label, and a fork's first pin offers iter-1.
- A fork of an app runs as an app too, so its pins can play.
- The API releases a cartridge when asked with "cart": true.
An operator can now bring in cart files that were built elsewhere.

- Each entry pins its commit if needed, puts the cart facts and cover on the pin, and stores the file as its capture.
- It is for games whose offline file comes from their own build, like Krazy Karts, and for moving today's shelf in.
- Run it with bun scripts/import-carts.ts on the forge's data folder. A capture already there is kept.
The picture a cart's cover is drawn from is now taken wide, as games draw themselves.

- A square window left black bars above and below a letterboxed game.
- The cover still crops the middle square.
The shelf now opens on the cartridge pinned first, rather than sorting by day and then by name.

- Carts pinned the same day no longer fall into alphabetical order.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
A cartridge on the shelf now has a Play button in its panel.

- Play opens the Arcade on that cart, so it boots through the jbox tag.
- The note about write access no longer shows beside a cart that can be downloaded.
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Requested-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Co-authored-by: trevato <trevato@users.noreply.forge.open-platform.sh>
Pins on the build graph can now carry an icon and a note, for showing a build to a given audience.

- The icon sits inside the pin's node. The note's first line sits under it.
- Writers set both in the pin's panel, under "On this graph". Readers see them.
- They are kept beside the forge's data, not in git, and never change the pin.
Conflicts resolved by topic: upstream's behaviour and structure kept,
jmoran's wording, page layout, builds work and crew fixes re-applied on it.

- Migration 72 (run agent settings) moves to a migration file.
- Play opens the build by script, since upstream bans meta refresh.
- Tests make users with the seed origin, as upstream now requires.
- The Asked tab count test goes with the home tabs it tested.
Upstream moved page copy into *_words modules and settings pages, so the
dev UI's wording was lost there in the merge. Each module now says what the
pages said before, and new upstream copy follows docs/WORDING.md.

- Composers and the footer say File an issue or File to crew.
- Decisions, the asks page, follow modes and mirror texts name the action.
- The reviewer brief quotes a director's comment once, as scope.
Most red tests asserted upstream's old wording or markup; they now assert
the dev UI. Where the merge had dropped behaviour, the code is restored in
upstream's structure:

- the stale-check merge gate, team verdicts and the Resolve conflicts door
  on the pull page
- the merge box's hold until green, the flow-only held line and Parked pulls
- the render memo with #N refs, a cached Decisions count, and one read of
  writable apps on the home, to keep page budgets
- builds API list shape, timing and OpenAPI rows for pins and the demo
- a crew pull handed to a person frees its autonomy slot
The pull page drew its checks as info sections with no ids, so upstream's
live client had nothing to swap and the rail changed only on reload.

- The sections carry the ids #pull-check and #pull-preview.
- /pulls/:n/state answers those same sections, so the swap is like for like.
- Checks gains a Checked commit row, which carries data-head for the client.
Four upstream details the dev UI had dropped, in its own words:

- Issue list rows say how a closed issue ended: done, dropped, or merged
  in #N.
- The Contract section's last probe is a green or red badge.
- The home's New issue form keeps its title and body as a draft until filed.
- The form can save the text for the planner, as upstream's composer could.
The merge put upstream's figure tiles, summary line and 'Since you were
here' list above the home's apps and New issue form. They now sit on
/board, which holds the forge's other operator views, and say what they
count: merged pull requests, agent runs, run slots and agent spend.
A pin's cart trailers become demo trailers, so a build of any stack can be
shown, not only a game page:

- Demo:, Version:, Launch:, Page:, Showcase: on and Cover: are written.
  Cart: and Shelf: on still read, and Producer: is left to the Arcade.
- Launch: file plays the captured page, env opens a running build preview,
  shots shows screenshots. forge.json app.launch sets a repo's default.
- scripts/rewrite-demo-trailers.ts rewrites old tags in a data dir: a dry
  run unless --apply, keeping each tag's commit, tagger, date and note.
A pin can carry screenshots, so a feature can be shown without running a
preview. Launch: shots makes them the demo's main view.

- refs/shots/<label> is a git tree of images and shots.json captions.
- Writers upload PNG, JPEG or WebP (2 MB, 12 a pin), or pick the deploy's
  looks pictures; they caption, reorder and remove them.
- Images are served typed by their bytes, nosniff and sandboxed, to anyone
  who reads the repository. Web, API and OpenAPI routes, with an event.
A repository's display.json defines a page of showcased demos: its title,
sources (owners or repos), hand order, per-demo launch, and a layout of
shelf, grid or graph. New demos join the end.

- /<owner>/<repo>/display serves it, with a snapshot export.
- The Arcade host serves the display a site admin names on /admin/limits;
  played pages keep their own origin.
- Screenshots get a gallery at /builds/:label/shots.
Turning Showcase on publishes that one demo: its page, screenshots, cover,
name and version reach anyone who can see a display that includes it. The
repository, its code and its other pins stay private.

- A viewer who cannot read the source sees the name and version only, never
  the owner, repository or a link.
- Display-scoped routes serve a published demo's shots, cover and download
  under an opaque HMAC id that only that display resolves.
- Showcased file demos play on the display origin without a grant; turning
  Showcase off removes them at once.
- The graph shows All, Demos or Showcased (?show=), marks each pin
  Showcased, Captured or Demo, and folds runs with no match into one
  'N builds hidden' node.
- The pin panel opens on its facts and demo summary; settings, screenshots,
  cover, routes and lineage sit closed. An Actions menu removes a pin from
  the showcase, deletes its demo, or deletes the pin, each confirmed, with
  API routes for the deletes.
- /display/edit lists every showcased demo with names and versions, adds and
  removes sources, reorders by drag or buttons, previews the display.json
  diff and saves it as one commit. Capture all captures the displayed set.
The Show filter (All, Demos, Showcased) and the 'N builds hidden' stops now
run in the browser over every pin the page carries, so nothing reloads.

- A hidden run sits in its own thread's column or lane and opens in place;
  an opened run folds back with 'Hide N builds'.
- ?show= still sets the first view and is kept current; ?open= is gone.
- The fold is one pure function the page scripts and tests share.
- The pin panel test reads its sections as details; figure tests read /board.
- The issue list's close-reason lookup counts inside its issues phase.
- Display answers and the snapshot download name session and render.
- With no backup destination, the restore drill is skipped quietly.
- Two tests stop depending on today's date or signup order.
- The top bar holds Home, Apps, Repositories, Displays and the Arcade when
  one is set. Map, Board, Front page and Decisions leave it; their routes
  stay until jmoran rules on them.
- /board no longer draws the figure tiles, flow line or 'Since you were
  here' list that were moved there from the home.
- The top bar is exactly Home, Apps, Repositories and Displays.
- Asks counts are checked on /asks, since the header no longer counts them.
- No page draws the figure tiles or 'Since you were here'; the tests that
  measured them on the board are replaced by checks that they are absent.
- /displays lists every display the viewer can read: title, layout,
  repository and demo count. New display picks a repository you write and
  opens its editor.
- Saving in the editor lands on the finished display page.
- Writers get Edit display on every layout, the shelf included.
- A fork family with showcased pins gets /<owner>/<repo>/iterations: its
  build graph, read only, showcased pins only, linked from Branches.
- The shelf's bar above the arcade gives any signed-in viewer a way back to
  Displays; writers also get Edit display and the save flash.
- A display page lights Displays alone, not Repositories too.
A site admin naming a display for the Arcade publishes it, the way Showcase
publishes a demo: strangers on the Arcade origin see it, and its private
sources stay unnamed. The settings card says so. A repository with no
display.json is still no Arcade. The displays list draws titles as plain
cells.
- /displays is in app.looks and the design audit; iterations is listed.
- The board draws no figures, vitals or digest and records no visit.
- The home's waiting count stands in for the top bar's Decisions count.
- The display page's flash cookie is a named cookie site.
A repository whose fork family holds build pins gets an Iterations tab:
the family as fork cards in columns by fork depth, builds as rows, under
two checkboxes, Only show showcased and Dev notes. Clicking a build plays
it beside an info panel with its pin, commit, branch, lineage, notes and a
reserved row of actions: Download, Copy link, Clone and Fork.

- The graph sits in a scroll pane with a height limit.
- An uncaptured HTML build offers Build and play to a writer.
- Spec: records/design/1031-forgej-iterations/LAYOUT.md.
- A fork's default branch is never listed as a branch with no pin, and a
  fork with no builds lists no branches.
- Another owner's fork is named with its owner, so two nova-spicy cards
  read apart.
- Dev notes shows and hides each build's note line and its dev notes; the
  'main' mark is gone.
- A card header is the fork's name alone, in full; the owner is added only
  when two forks in the family share a name.
- Download, Copy link, Clone and Fork each open a dialog that says what
  happens first. Fork names the new repository, says it copies branches
  and tags but not build pins, and lands on the new fork's Iterations.
Each fix answers one audit finding (records AUDIT-1101.md):

- Browser edits keep LF; an empty repository takes its first file (R16, R17).
- No Merge on a conflicting pull's card; empty squash names no commit;
  Resolve conflicts follows the pick (R5, R32, R38).
- Deployments has its own URL and the 404 knows who is signed in; the ask
  line links what it counts (R14, R46).
- Graph displays draw the family; grid cards show a picture and play in
  place (D7, D5).
- Every graph look gets the full pin panel; a missing Play or failed
  capture says why (G2, G3, G12, G24).
- Build and play lands on the player; a fork lands on its card and its
  flash no longer promises pins (I6, I11).
- Smaller wording, landing and layout faults: R3, R8, R11, R13, R21, R37,
  R49, R50, G9, G18, G22, G26.
Decided 11-01 after the audit (I3, G27, R26, R39):

- The Iterations info panel's Pin note and Dev notes have a quiet Edit for
  writers. Saving rewrites the pin's tag message, keeping its tagger, date
  and trailers, and appends build.noted; also PATCH on the builds API.
- An issue's Milestone and a pull's Labels get the rail's existing picker
  behind a small gear, for people who may change them.
Decided 11-01 (PRD step 4):

- A pin's note and dev notes live in <label>.md on refs/forge/notes in the
  pin's repository; each edit is a commit, so history is kept. Pins with no
  file still read their tag message.
- display.json may list builds: the display's chosen builds in order,
  showcased or not. Without it, today's rule holds. PUT .../display/builds.
- Forks copy refs/builds, refs/covers, refs/shots and refs/forge/notes;
  the Fork and Clone dialogs say so.
As confirmed in records design/1101-forgej-displays (LAYOUT.md):

- The display page has a build sidebar for writers: every pinned build in
  its sources, by fork, ticked in or out; it folds, and so does each fork.
- The info panel sits top-left beside the player; the builds sit below as
  cards with pictures, dragged to reorder. Ticks and drags save builds.
- Iterations has one selection picker: All iterations, Showcased and each
  display. Edit display selections gives every build a chip per selection,
  and the info panel lists the selections a build is in.
- The JSON-diff editor page is gone.
/<owner>/<repo>/display is now round 1101 E's page for a shelf display too.
The carousel shows on the Arcade host, or at ?look=shelf; ?edit=1 is gone.
Decided 11-01:

- A build has one Notes section, markdown, edited as a whole; the
  Iterations checkbox is Notes. PATCH builds takes notes and still joins
  note and body.
- The Arcade serves the newest display titled arcade-builds in a site
  admin's repository; the /admin/limits setting is gone.
The display page has a quiet Edit beside its title; Save writes only the
title to display.json as one commit (POST .../display/title). Naming an
admin's display arcade-builds makes it the Arcade.
A build's Notes section is now one list, kept as notes.json on
refs/forge/notes: { "notes": [ { iteration, by, kind, at, text } ] },
the format ui-iterator keeps beside a round. iteration is the pin label.
Each note is appended in one commit by its author; a correction is a new
note. notes.lock holds every note's fingerprint (sha1 over the five
fields, first 12 hex), and an append refuses a notes.json that lost one
(notes_lost).

People's notes rank first and are highlighted, then agents' notes, then
the tag's own note. Each note shows its first line as a title; the rest
opens on a click. A writer adds a note in place with Add a note. An
agent on the repository's crew may add one too, as kind agent under its
own name.

An older <label>.md notes file reads as one note by whoever last wrote
it, and the next append folds every such file into notes.json. Deleting
a pin keeps its notes. PATCH builds/:label and the web form now append;
note and body still join into one note.

When FORGE_NOTES_INTENT names a doc, a person's note is copied into it
once, under "## Iterator notes", in ui-iterator's line format with its
hidden fingerprint (core/intent_notes.ts). Agent notes are never copied.

Also fixes the panel's Save: the Iterations page root carries data-edit,
so a click on Save was taken for an Edit click and never submitted.
Iterations gains a Columns | Tree switch (?layout=tree); Columns stays
the default. Tree is round 1101-forgej-graph-layout's B: the family as
runs that grow downward. A build continues its parent's run when the
parent is that run's last build in the same repository; otherwise it
starts a run of its own, hung just under the build it grew from (a
fork, a branch, or a concept edge). A fork with no build to hang from
hangs under its parent fork's head. Runs are drawn depth first, the
child that starts nearest a run's foot first (lanesOf).

A fork folds to one node by its name, and a run with branches beside
it folds to "first → last". Folds of builds outside the selection keep
working, and a line starts at the fold that holds its build.

From C and D: a run can be dragged anywhere. Where runs were dragged is
kept in this browser only, per repository (localStorage). Reset puts
every run back in the tree's own place; Align keeps the dragged order
and snaps columns and spacing to a grid. A drag is never taken for a
click.
Branches → Graph is gone: Iterations' Tree layout replaces it
(records/design/1101-forgej-graph-layout). An old /branches/graph link
301s to /iterations?layout=tree, its ?pin= picked as build=.

Of the graph panel's tools, only Delete pin moves: it is now in the info
panel's Actions, behind a dialog, for a person who writes the
repository. It deletes the pin with its cover and screenshots, keeps the
commit and its notes, and lands on Iterations.

The rest stays behind, by jmoran's call to keep the forge to its proven
parts: the demo settings form, cover upload and Use generated cover,
Remove from showcase and Delete demo (the Showcased chip and the API
cover them), the screenshot upload, pick, caption, move and remove forms
(the API still writes screenshots), and graph marks with their icon
route and store. Demo facts, covers and screenshots are still read where
they exist: a display's shelf, a cover, a picture.

Pinning a build now lands on Iterations with the new pin picked. Branches
shows an Iterations link when the repository holds pins, in place of
Graph. The confirm page drops the removed verbs.

Tests move with it: the graph, marks and cart panel suites go; screenshot
writes are tested through the API; the pin and checkpoint flows assert
the Iterations landing. Build info's capture wait joins the no-polling
allowlist with its reason.
Test connection on Backups ran the snapshot store's five retries, so a
refused endpoint answered only after 7.5 s of waits. It now makes one
attempt (s3Store's attempts option), and says so at once.

The Backups page follows a snapshot by its events (data-live), not a
meta refresh: its test now says that, and reads until the run has put
an object instead of racing the first one.

An Instagram prompt's issue body no longer repeats its title, since
the 11-01 audit fix to tell(): the test now expects that.
The graph grows off the page fast. Beside its key, both Columns and Tree
now carry − and + (fixed steps from 25% to 200%), the scale itself (a
click goes back to 100%), and Fit, which shows the whole graph in the
stage. ⌘ or Ctrl with the wheel, a trackpad pinch, zooms where the
pointer is. The scale is kept in this browser.

The graph scales as one transform inside a box sized to it, so the stage
scrolls to the scaled size. Lines and drags divide by the scale, so a
line still meets its card and a run follows the pointer at any zoom.
Cards in both layouts are now as wide as a conventional commit subject,
50 characters of monospace plus padding, and every card's text is
monospace. The tree reads a run's width from the page, so its columns,
Align and lines follow.

Fit read the stage's current height, and a stage that had shrunk to a
small graph shrank it again on every click, one percent at a time. It
now measures the height the stage may grow to, so a second Fit changes
nothing.

Collapse forks folds every fork to its name, and Expand forks opens every
one (and every folded run in the tree). In Columns, a card's name now
folds and opens that card too; a card the selection closed still opens
on its name.
A fork or run folded on Iterations stays folded on the next visit, kept in
this browser per repository and layout, beside the zoom and dragged runs.
Each kept fold remembers how many pins its fork had; a fork that gained or
lost one since opens again, so new work is never hidden behind an old fold.
A link to one build opens the folds around it.
jmoran merged commit ebc0adcaf5 into main 2026-11-02 18:27:27 +00:00
jmoran deleted branch feat/upstream-sync 2026-11-02 18:27:31 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jmoran/forge-jay!11
No description provided.