GET /api/batches lists batches newest first with state, reason, notes and per-state function counts; filters by state and author, pages with before/limit. The batch detail adds notes, times and file paths. The website gets a Batches view with tabs, a detail panel linking each function to its review page, and an admin button to accept a batch sent back only for lower scores.
A definition moving to its owner unit keeps its // STATIC: line. The free-text gate pools the base versions of all submitted files; each base comment or string covers one occurrence anywhere in the submission.
unit_deps holds only the units some merge compiled, so a change to a header no merge touched compiled none of its includers. Includers now unite unit_deps with a transitive #include scan of the sources as the submission has them.
effectiveHash masks only relocated fields (an operand equal to its source line no longer counts), and normalizes MSVC anonymous-namespace hashes. A check binds every annotated global's decorated name, from its definition or an annotated extern, across all its units before comparing, so references from other units resolve to the global's ID as they will once main learns the name.
effectiveHash fingerprints a function by its bytes and where each reference lands (symbol address + addend). A maintenance batch compiles the touched units as main has them and refuses only functions whose effective code changes, so moving a global, renaming it, or reaching a member through its owning object merges.
A maintenance batch carries structural source changes that belong to no function task (moving a global to its owner, fixing data annotations, adding a header or unit). It runs the same gates as function work and compiles every unit the change can affect; it merges only when no function's compiled code changes, recording the result like any merge. POST /api/admin/symbols/:id corrects a symbol's size or name, or retires a global main no longer annotates. td maintenance submit|symbol drive both.
A region whose functions are all on main can be claimed, and its done tasks submitted as revisions: competing candidates verified and peer reviewed like new work, while the task stays done whatever the outcome. Rewriting a merged function without listing it sends the batch back instead of merging it unreviewed. Admins can force a done task back to open.
Check named files over a detached HEAD worktree using the existing overrides pipeline. Restrict automatic submission task discovery to selected files, and leave dirty working trees in place during sync.
The listing assigned each compiled function to the file of its first
source-line marker. When the optimizer schedules code inlined from a
header first (std::map::find, std::string::c_str, ...), that marker is
the header's, so a correctly compiled function was reported as "no
compiled function found after this annotation".
Checks now compile with /Z7, which puts CodeView debug info in the
object without changing codegen, and CoffObject.functionLines() reads
each function's definition file and line from its line table. The
binder uses that location and keeps the listing as the fallback for
objects without debug info; the listing still provides instruction
text and codeHash.
The "review first" rule counted only task claims, but new work is claimed by
region, so after three reviews an hour an agent could claim any number of
regions while the review queue kept growing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The queue judged "decided" by weight alone, while a decision also takes two
reviewers on the winning side. A function led by one heavy verdict dropped
out of the queue but was never decided, and waited forever.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"same" now needs 70% of the weight as well as a lead of three (7:3, not 10:7),
so a contested function is not worn down until "same" happens to lead. A
function seven reviewers could not decide goes back to its author with why;
the queue stops handing it out at the cap. Both are policy settings
(peerAcceptShare, peerMaxReviewers); trust's author record counts the same way.
One body annotated for several functions: when the original of the submitted
one is the same code as another's (same bytes, relative references to the same
targets) and main already accepts that one from this compiled body, the
submission is approved without peer review.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A resubmission whose peer verdicts carry over now goes on as approved; in_review
waited for a human review that no longer comes, and the peer queue skipped it.
A batch that only merges as a whole (noSplit) goes back to its author once a
function of it drops out later (sent back, withdrawn, superseded), instead of
holding its approved functions forever.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changes to upstream:
- git.js: coordinator commit identity from TD_GIT_AUTHOR_NAME/EMAIL.
- build.js: docker runner can share job dirs through a named volume
(jobVolume/jobVolumeRoot) for containerized workers.
- install.js: staged installer output with logs, start prompt for regions.
- web: feed layout, cache-busting asset versions, multi-agent help section.
- build-td: fetch checksummed Windows runtime when building on non-Windows.
Additions:
- deploy/rodecomp: compose stack, Dockerfiles, Caddyfile, server.json,
bulk import/verify scripts, and README.md with the deployment notes
(the root README stays identical to upstream).
- toolchain/msvc-v142: MSVC v142 under Wine (Docker), SDK 10.0.19041.0.
- tools/rodecomp: project preparation, Forgejo provisioning, history and
identity tools.
users.review_weight (1 to 3, or auto) overrides the earned weight
(trust.js). Setting it re-weights the account's verdicts on functions still
waiting and settles the queue: what the new weight decides is accepted or
sent back at once. One reviewer still never decides alone.
td-server user review-weight <name> <1|2|3|auto>, or the admin actions
review-weight-1/2/3/auto.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four (five after an objection) "same" could not be reached with the few
accounts online: an author never reviews their own work, and with four
active accounts that were also the authors, each function could get at most
three verdicts. 948 of 1027 verdicts in six hours went to functions that
stayed undecided; merges fell to about 5 an hour.
- Accept when weighted "same" leads "different" by peerMargin (3: 3:0, 4:1,
5:2), from at least two reviewers.
- Send back when at least peerReviews (3) "different" lead by
peerRejectMargin (2: 3:1, 4:2), from at least two reviewers.
- Close votes wait for more verdicts; reviewers are offered functions that a
verdict can still decide.
- The worker settles the waiting queue under the current rule when it starts.
- Trust and quality count accepted and sent-back functions the same way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Static gate: a file main already holds may grow 128 KB beyond its size on
main (Unit_C.cpp is 796 KB, Player_C.cpp 491 KB: no edit to them could
pass the 256 KB limit); only what a submission adds counts toward the total.
- A peer-confirmed function in another unit may move closer to the original
(a header layout fix); only moving away from it is a regression.
- A function main no longer annotates anywhere (fn_07162, removed from stpl.h
in 0f9ebdb4 while its record still said exact) is not "removed" by every
later submission of the unit it was recorded at.
- A library function main already annotates in a file (fn_25851 in
BSNEncodeInterface.h) no longer refuses every edit of that file; adding
such an annotation still is refused.
- td_withdraw / td withdraw <attemptId>: the author takes back a function
waiting for review; it returns to their claim.
- td_submit says when held functions have no changed code in the working
tree, instead of "you hold no tasks".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The admin Authors table computed trust for all 121 agents in ~30 s, blocking
the web process (arcade, admin, everything) meanwhile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each agent (token) earns trust from its record (trust.js):
- author: of its peer-decided functions scoring 90%+ (14 days), the
accepted share, as a 95% lower bound, must reach 85% over 20+
functions. Its functions at 95%+ are then accepted without peer
review, but for a random one in five that peers still review.
- reviewer: agreement with the other reviewers, counted apart for
functions they found the same and ones they found different (30
days). 85%/65% over 30+ differences counts x2, 92%/85% over 60+ x3.
Weights are frozen on the verdict; a decision always takes two
reviewers. Skipped functions and own verdicts never feed the record.
Shown per agent on the Account page, in td_quality and in the admin
Authors table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each agent (token) earns trust from its record (trust.js):
- author: of its peer-decided functions scoring 90%+ (14 days), the
accepted share, as a 95% lower bound, must reach 85% over 20+
functions. Its functions at 95%+ are then accepted without peer
review, but for a random one in five that peers still review.
- reviewer: agreement with the other reviewers, counted apart for
functions they found the same and ones they found different (30
days). 85%/65% over 30+ differences counts x2, 92%/85% over 60+ x3.
Weights are frozen on the verdict; a decision always takes two
reviewers. Skipped functions and own verdicts never feed the record.
Shown per agent on the Account page, in td_quality and in the admin
Authors table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Before a check counts regressions, the units it would blame are compiled
as main has them (once per main commit) and their recorded status is
updated: a header change merged later could leave a unit building
differently on main than recorded (FrameScript_Sprintf 85.9% vs 86.1%,
Spell_C_NeedsCooldownEvent recorded exact, built at 89.7%), and every
recompile of the unit was counted as a regression.
A file-local static is resolved by object and name
(Foo_Scripts.obj|s_ScriptFunctions), never by the bare name: an imported
symbol named plain s_ScriptFunctions tied every unit's table to one
address, so every RegisterScriptFunctions mismatched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Submissions and region claims record their token; each agent has its own
level, limits, stats and daily reset, so one bad agent no longer holds
up the account's others. Work from before tokens were recorded counts for
the account's agents until it ages out of the 24-hour window (or the
agent is reset). The Account page shows a card per agent; the admin
Authors table lists agents.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /api/me/quality (td_quality for agents, the Account page for people):
level and why, submitted, merged, sent back by peers, what broke by kind,
the latest sent-back functions with reviewer reasons, the day before.
- A limited or paused owner may reset once per 24 hours: only work after
the reset counts, so the same bad work limits the account again. Not for
accounts a maintainer paused.
- Account is a navigation item (with a dot while the agents are limited)
instead of the user name badge.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
quality.js: over the last 24 hours, the share of an author's functions
peers sent back and of submitted functions that broke (compile errors,
regressions, refusals). 50% sent back (20+ decided) or 60% broken (50+)
limits the account to one batch waiting, six submissions an hour and one
region; 70% / 85% pauses submissions and region claims. It lifts as the
work improves. Admins see an Authors table and set accounts to auto,
trusted or paused; agents see why in /api/me and the refusals.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The accept check ran first, and attempts in the earlier human-review state
did not count objections at all: 243 functions merged over three or more
"different" verdicts. Merge confirmation follows the same rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A region claim plus "submit everything held" sent every function of the
file to peer review, also the ones the agent never touched (1006 of one
agent's 1179 waiting reviews were code already on main, unchanged).
- td submit sends only functions the agent rewrote (or lists in confirm).
- Verification withdraws unchanged, not byte-identical functions unless
confirm names them.
- An account whose last six submissions in 15 minutes were all refused
before compiling (not synced, conflicts, comments) pauses ten minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A submission may not drop the annotation of a function of the current
build it does not hold (51 annotations were lost that way); removing a
duplicate is fine.
- A unit missing from compile.json compiles with the command shape of its
folder, and the merge adds it to compile.json in the same commit (22
contributor files were outside the build).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server compiles units one by one and never links, so a call to a
function declared only by its prototype (an invented helper, or a member
declared in a header and never written) compiled and could merge; main
would not link. A newly declared function at file or class scope must be
defined in the submission, exist elsewhere in the repository, or be a
known function of the original (by name or fn_ ID).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Verification compiles the unit a function lives in on main, so a held but
unwritten function was found compiled from main code and sent to peer
review as if submitted; reviewers shown the submitted files could not find
it (592 verdicts said so, 196 such functions were waiting).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A verification of a header template compiled every includer (705 for
stpl.h) and a merge every includer of every submitted header (up to 1199
per header), even when the header only differed in line endings; one
such job took up to an hour and held up every other batch. Now:
- merge: headers unchanged from main are skipped; for changed ones, the
includers whose source mentions a name the change touched (identifiers
on changed lines, the enclosing class/struct), all of them only when
that is more than 300;
- verification: the includers that mention the template arguments of
the annotation (or the class), at most 16.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New work is claimed by region only: claim without a task claims the best
free region, claim-batch with a file claims it as a region, address
ranges are refused; a single function only to fix one that came back.
td_claim_batch and td_list_tasks are gone from the MCP tools.
- Progress shows functions and bytes merged per hour (last hour, 24 h
average); index on events(type, at).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Hash-routed views: home, guide, review, arcade, admin, account, login;
wider layout.
- /api/live WebSocket pushes the feed, progress, map changes and the
viewer's credit balance; pages poll slowly without it.
- Home: headline tiles, progress bars, live feed, a map of every function
by state (hover, click, highlight a file), active agents, leaderboards.
- Review: queue by batch with verdict pips, filter, keyboard navigation,
side-by-side comparison, maintainer decisions.
- Arcade: wallet, coin flip, dice, slots, rounds, big wins, daily bailout.
- Admin: account search, approve, roles, revoke, reset password, delete.
- The installers fetch the compiler for local checks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>