Releases: openquanter/quanterdeck
Releases · openquanter/quanterdeck
Release list
Quanterdeck v1.0.0
The first tagged release. Everything below is "since the repository
started" rather than since a previous release.
Whether this console is behind quanterdeck's newest release
- The same card checks the console itself. Quanterdeck publishes
GitHub releases too; with each framework check the deck also reads the
newest release ofOQ_DECK_SELF_REPO(openquanter/quanterdeckby
default) and compares its tag with the version the deck was built as —
by version, not commit, because a build from agit archivehas no
commit to read while the version is always compiled in. Equal is
current, newer is ahead (built from a branch after the release), older
is behind. A tag that is notX.Y.Z(with or withoutv, optionally
with a pre-release) is "cannot tell", with the reason; no release yet
is its own state. The overview card gains a "This console (quanterdeck
release)" section, and the top-bar badge names which release is newer. - Kept apart from the framework check. One more GET per check (five
at most), on the same schedule, switch and proxy. Each half keeps its
own error and last success, so GitHub refusing one leaves the other's
answer standing.GET /api/v1/upstreamgains aconsoleobject; the
existing fields,behindincluded, still describe the framework.
Whether what runs is behind the framework's newest release
- The deck checks the framework's GitHub releases. Shortly after
startup and then everyOQ_DECK_UPSTREAM_CHECK_HOURS(6 by default),
it reads the newest release ofOQ_DECK_UPSTREAM_REPO, resolves its
tag to a commit, and asks GitHub to compare that commit with two
running revisions: the deck's own, embedded at build time from
Cargo.lock, and the trader's, from theframeworkfield of the
current release's manifest through the host agent. The overview has an
"Upstream release" card and the top bar a badge when something is
behind. A trader restart — a new journal inOQ_DECK_JOURNALS_DIR,
looked for every 5 minutes without touching the network — brings the
next check forward, so a deploy shows within minutes rather than at
the next scheduled check. - "Cannot tell" stays "cannot tell". A timeout, an exhausted rate
limit or a reply that does not parse is an error with its reason and
time, shown beside the last successful answer and that answer's age —
never as "up to date". No release published yet is its own state, and
a revision GitHub does not know (or no agent to ask) is that
revision's "cannot tell", with the reason. - One outbound request, and a way to turn it off. Unauthenticated
GETs toapi.github.comcarrying aUser-Agentand the repository
path, nothing else;OQ_DECK_UPSTREAM_CHECK_HOURS=0makes none at all,
and the capability says so.OQ_DECK_UPSTREAM_PROXYnames a proxy for
this check only. A manual check (POST /api/v1/upstream/refresh) is
checked forOriginlike any write but is not behind
OQ_DECK_ALLOW_WRITES— it changes nothing on the host — and runs at
most once a minute.
A large directory no longer stalls the console
- File work runs off the async workers. Listing runs, sweeps and
journals, a run's or a journal's detail, comparison, attribution and
reconciliation all parse files — the journal listing replays every
journal whole — and did it on the threads that answer every other
request, the session checks included. They run on the blocking pool
now. - A listing remembers what an unchanged file parsed to. Keyed by
inode, length, modification and change time; a file modified in the
last two seconds, or one that would not read, is read again every
time. The listing says exactly what it said before — an unreadable
file is still listed with its reason and still withholds the total —
and a removed file is forgotten with the listing that missed it.
Signing in once, on the machines you choose
- A browser you enrol is not asked again. The login page offers to
remember this device; that browser then carries a device credential
instead of a password and a code. It is a second way in with one
factor rather than two, which is why it is named, listed in Settings
and revocable — and why withdrawing one is deliberately not behind
OQ_DECK_ALLOW_WRITES. Only its SHA-256 is written, so a copy of the
file is a list of what exists rather than a set of keys to use. - Sessions no longer expire at a fixed hour.
OQ_DECK_SESSION_HOURS
andOQ_DECK_SESSION_IDLE_MINUTESare settings, bounded and refused
rather than clamped, and/runtime/settingsreports the ones in force
instead of the two numbers it used to hardcode. - Signing out ends the session, not the device. Taking a device away
is a separate act with its own page; otherwise signing out on a shared
machine would un-enrol it. - Sessions still live in memory, so a restart still ends them — and an
enrolled browser does not notice, which is what the device credential
is for. - A machine can be enrolled by proving an SSH key, for the case the
box above does not cover: a laptop you have a key on and no password
on.scripts/deck-enrol.shasks the deck for a challenge, signs it,
and prints a link; opening the link in the browser enrols it. The
keys trusted are the ones anallowed_signersfile lists
(OQ_DECK_TRUSTED_KEYS), verified with the samessh-keygen -Y verifythe host agent trusts a release with — under its own
namespace, so a release signature cannot be replayed here. Off unless
that variable is set, and the console reports which it is. deck-enrol.shtakes--cacert(orOQ_DECK_CA), because a deck
behind a proxy with its own CA is one curl refuses to talk to, and the
reference deployment is exactly that.--insecureexists too, and says
in the script what it costs: the challenge this script signs is what
authorises enrolling a browser, so a machine in the middle of that
connection can collect the signature and enrol one of its own.
The console says what it knows
- A fee the run has not measured is not a zero. The books charge a
fee from a schedule, and a live run is built without one — sofees
was zero for every live run and the console drew it beside realized
and funding as though it were a measurement. The venue states the
commission on each fill; a run books that now, checks the total
against the venue's own trade records when it ends, and reports
not measured until it has one. A measured zero and a figure that
could not be measured are opposite facts, and the page no longer
conflates them. - A venue reading older than the run is not a disagreement. The
console compares the newest journal against a reading it rewrites
about once a minute, so for that minute after a restart it was
comparing two runs — every order they have apart counted in both
directions. It says which run the reading is of, and that it catches
up. - A refusal says which fact stopped it.
undecodable,
no adoption record, orthe reading predates the runwere one
sentence; the sentence could not describe a case it did not know
about, and the new one had no sentence at all. - The step-up code counts its failures — five wrong ones close it
for fifteen minutes, the same numbers signing in uses. A six-digit
code is a million guesses and what sits behind this one is stopping
the trader. - Listing the strategies is a read. It called the code that sends
an instance whose configuration moved back to draft, so opening a page
moved a strategy. The step taken refuses instead, which is also where
the gate has to see it. - The two codes are two entries, and the console says so. The host
agent's step-up secret is the agent's — a compromised deck cannot mint
one — so nothing here can show it, and nothing said where it comes
from. The field that asks for it, first-run setup, and Settings all do
now; enrolling only the console's is why a first deploy stops at the
code. - The sign-in screens are in this round's style. They were not: a
different product mark, a card shadow heavier than every other card's
and not from the theme, and the language and theme switches — the two
things this release is about — unreachable until after signing in. - This repository names no deployment of its own. A release's
allow-list was a constant holding one operator's private binary, and
the unit, channel and prefix defaults were that deployment's. They are
configuration now, the mark and the copy are generic, and the
defaults a deployment must set are in the README's table.
English, beside Chinese
- The interface is in Chinese and English, switched from the top bar
or Settings and remembered in the browser. Every piece of copy is
written astr("中文", "English")where it is used, and
scripts/check-i18n.py(run in CI) fails on Chinese that has no
English beside it. - The deck answers in the reader's language: refusals, capability
reasons and attribution's missing inputs follow the request's
Accept-Language. - So does the host agent. Every sentence it words is a pair
(oq_deck_core::lang::Said) — a config file that changed under a
write, a deploy whose health check failed, a promotion the gate
refuses, a control port that stops answering. The agent does not know
which language the console is being read in, so it sends both and the
deck picks. - The promotion gate's refusal is a pair on the wire
(decision.reasonis{zh, en}). The console used to recover the
English by matching the gate's Chinese with a regex table that had to
be kept in step by hand; the table is gone. - Records keep both renderings, in sibling fields:
reasonand
reason_en,resultandresult_en,problem,outcome,step,
message. A record written before the console had two languages
carries one renderin...