← Team guide

Team — technical notes for developers

Team mode makes promises: a station cannot read another station's mail, a Complete by the wrong role is refused on every device, and so on. This page shows how each promise is checked, how to run the checks yourself, and what is still a stated limit. It is for developers and reviewers; people using team mode only need the Team guide.

What is checked

Each promise is a term. A term is ENFORCED only when a test (a witness) passes and every one of its broken controls is found in the test's output. A broken control is the same test aimed at a deliberately broken case, so it shows the test can fail. A term that is stated but not tested is OPEN and is never shown as met. A test that judged nothing prints INCONCLUSIVE, never PASS.

Current record: 13 enforced, 0 open (run of 2026-10-31). It is published as Project quality objectives (tested properties and stated limits, not a warranty; see GOVERNANCE.md) and as the Terms button in the Team panel. The raw record is team_terms.json (schema terms-v1).

The checker can say no. Removing one broken control from a test's output turns that term UNCONTROLLED and the whole run FAIL; this was tried for the newest term (sealing). Many tests also run mutants: the product code is edited on purpose (one exact line, which must be found exactly once), and the test must go red. A mutant that crashes the test does not count as caught.

Run the checks yourself

The checks run in Node on your own machine. Two public repositories are needed: BIMCompiler (the terms runner and the comm-engine tests) and bim-ootb (this app, its browser tests).

git clone https://github.com/red1oon/BIMCompiler.git
git clone https://github.com/red1oon/bim-ootb.git
cd BIMCompiler && npm install
node scripts/dev_env_fetch.js --root-bim-ootb ../bim-ootb   # files git does not carry, from public storage, hash-checked
cd ../bim-ootb/tests && npm install                    # the bim-ootb tests need it (sql.js), with or without the browser layer
npx playwright install chromium                          # only for the browser layer (the real page in headless Chromium)
cd ../../BIMCompiler
node scripts/witness_terms.js --ootb ../bim-ootb

The last line it prints is the verdict, for example §TERMS_VERDICT PASS enforced=13 open=0 witness_failed=0 uncontrolled=0 browser=judged 5/skipped 0. Every test's log is written under build/scriptor/terms_run/.

OptionWhat it does
--browser 0Skip the browser layer (no Playwright needed). The verdict then says browser=judged 0/skipped 5, so a skipped layer is never read as a pass.
--only id,idJudge only some terms (ids as in team_terms.json).
--fresh 1Run every test again, ignoring the cache below. Published records are made this way.
--json fileWrite the record (terms-v1) that the Terms button and the objectives page are generated from.
--logs dirWhere the logs go.
Files git does not carry. Some tests read a file that is too large or too generated for git, for example the application dictionary build/erp/ad_full.db (45 MB, the public iDempiere demo data). Each such file is listed in dev_env/manifest.json with its sha256 and kept on public storage; dev_env_fetch.js downloads it and refuses it if the hash differs. The runner finds these files by itself: it records every file each test reads and names any that git does not have (§UNTRACKED), then prints how many terms a fresh copy can check (§TERMS_PORTABLE, today 13 of 13).
Tried from a fresh copy (2026-11-01, same machine): both repositories were cloned from GitHub into an empty folder, then npm install (in BIMCompiler, 199 s), then node scripts/dev_env_fetch.js --root-bim-ootb ../bim-ootb (4 s, it fetched the 45 MB dictionary and checked its hash), then node scripts/witness_terms.js --browser 0 --ootb ../bim-ootb. Clones took 184 s. The first attempt gave 12 of 13 terms: the runner still demanded exactly 9 mutants killed in the sealing test, and the current bim-ootb runs 10. A script bug, not a missing file, and it fixed itself once the runner accepted any all-killed count (BIMCompiler pull request 286, not yet merged when this was written). With that change in the fresh copy the runner gave 13 enforced, 0 open, 13 of 13 portable. No other file, install step or path was missing. On a busy machine a slow test can pass its 10-minute limit; WITNESS_TIMEOUT_MS raises it.
Not yet proven: a run on a different machine and operating system. This one used the same computer and the same user account.

The test cache

A full run takes minutes, and most of it repeats tests whose inputs have not changed. The runner therefore keeps each passing test's result together with a fingerprint of every file the test actually read. The files are recorded while the test runs, not taken from a hand-written list. If none of those files changed, the stored result is replayed, marked §CACHED with its fingerprint; nothing runs.

How team data moves

Stated limits: the relay still sees who sent how much and when (sender, box, counts, sizes); someone who holds a pair key can pass it on outside the system; an older app in a new POS team does not read mailboxes and silently misses that mail (the version floor is the lever); the first-ever download of a new device still contains the whole member list; in a mailbox team a checkpoint (a compacted history) carries no state at all, so a light client that would have adopted a checkpoint reads the history instead, which costs it more to download.

Where the specifications are

Design, test specifications and results, each with its log: TEAMWORK_FRAMEWORK.md in BIMCompiler — §48 the terms and their wording, §45.10 mailboxes, §45.11 sealing and the per-mailbox number, §51 the cost of keeping the checks honest and the cache. The tests themselves: scripts/witness_terms.js, scripts/witness_witness_cache.js (BIMCompiler); common/tests/witness_f1_mailbox.js, common/tests/witness_read_scope.js, erp/tests/witness_team_*.js (bim-ootb).