Anabasis (by RollyTech) is a stereo mastering loudness maximizer: one large "Push" knob driving an adaptive chain of compression, clipping/saturation and true-peak limiting, with loudness-compensated monitoring so louder and better can be told apart honestly. It is the second product in the RollyTech line, alongside Anamorph (stereo width / stereo-field expander), and shares that product's frame layout, brand system and engineering standard.
Built with CMake + JUCE only — it configures and builds entirely from the command line on a headless Linux machine, no IDE.
- v0.1.0 CODE COMPLETE (2026-08-02, under the owner's blanket approval; what remains is the
post-v0.1.0 human fine review — the brand pass, the DAW matrix audition and the listening pass
over every constant marked ⊕) — a MILESTONE, not the current version: the tree has moved on
through later rounds,
CMakeLists.txtcarries the version of record andHANDOVER.md's Release Status row carries whether anything has shipped. P0 closed on 2026-07-31 with the owner's sign-off ofdocs/DESIGN.md; the Accepted ADRs registered indocs/architecture/design-decisions/ADR_INDEX.mdgovern the implementation. No count is written here on purpose — the same rule the pluginval strictness follows, and for the same reason: this file is the first one a contributor opens, so it is the copy whose staleness costs most. Two numerals in this document disagreed with each other for exactly one round; the index is the registry.docs/HANDOVER.mdcarries the status of record. - In the tree:
CMakeLists.txt(ADR-0008's five-target graph) andsrc/— the 50-parameter surface (49 at the P0 freeze; ADR-0019 addedcompStereoLink), the full §2 processing chain (EQ · glue compressor · ADAA clipper/saturation · true-peak lookahead limiter · oversampling to 16× · dither) behind the POD engine boundary on the constant 10 ms allowance, the §2.8 click-free transition layer, BS.1770-4 metering with the §2.7 loudness-compensated monitor, the §5.4 adaptive engine with Learn including the ADR-0014 frozen-trim restore, the P5 editor (Simple and Advanced views, meters, spectrum, curve display) and the P6 per-slot undo / 13-preset factory bank (Default + 12) / performance bench — verified bytests/(2433 checks —AnabasisTests795 +AnabasisStateTests1638 — re-count from the suites' own output when editing, the same rule HANDOVER's status row carries — green on Linux, together with pluginval at the strictness.github/workflows/build.ymlsets, in both modes ×3; seedocs/TEST_REPORT.mdfor the measured DSP numbers — aliasing, latency, accuracy, each with the machine and method that produced it (constraint C2); it does NOT carry the suite COUNT, and this line used to imply it did. The count's home isdocs/HANDOVER.md's Test Status row, re-counted from the suites' own printed output — anddocs/policies/TESTING_POLICY.mdfor the gate, which is deliberately stated in one place). - Decided and frozen from the first build: the JUCE pin (9.0.5 at commit
d60b7a7…; ADR-0047 records 9.0.1 → 9.0.4; Accepted ADR-0051 records 9.0.4 → 9.0.5) and the plugin identity (RTec/Anbs/tech.rolly.anabasis) — both now written intoCMakeLists.txtas ADR-0008 specifies. - Still open — the JUCE licence tier (OQ-002, blocks distribution not development) and
the remaining entries in
docs/OPEN_QUESTIONS.md— which is the list of record, so this sentence cannot drift out of date. None of them may be guessed at. Resolved entries stay in that file'sResolvedsection; they are decisions, not choices to revisit.
- Signal chain (fixed for v1): Input Gain → EQ (pre by default) → Compressor → Clipper + Saturation → Limiter (lookahead + true peak) → Ceiling → Dither → Output.
- Simple mode: one large Loudness/Push knob plus Ceiling, Character and Tone, driven by an adaptive engine (short-term LUFS, crest factor, spectral tilt, transient density).
- Advanced mode: per-stage control over the same parameter model — switching modes must not change the sound.
- Metering: LUFS (momentary / short-term / integrated, BS.1770-4 gated), true peak (dBTP), PLR, gain-reduction history, input/output spectrum. (The brief's streaming-target lines were removed by owner directive 2026-08-05 — platforms normalise; a master is pushed against the ceiling, not a platform figure.)
- Formats: VST3 (all platforms), AU (macOS, for Logic Pro), Standalone (debugging). AAX is not supported.
- Platforms: Linux x86-64 (headless CI build), Windows x86-64, macOS universal (arm64 + x86_64).
The Linux binary is built by a pinned Clang since 0.2.1 (ADR-0032) and carries a declared,
gated ABI floor;
scripts/check-linux-abi.pyholds the numbers and the CI job asserts them on every push.
- CMake ≥ 3.22, a C++23 compiler (GCC 13+, Clang 17+, MSVC 19.35+, AppleClang 15+ — ADR-0030), Ninja (recommended).
- JUCE 9.0.5, fetched automatically by CMake
FetchContentand pinned to that tag's immutable commit SHAd60b7a78030661574a615b586d9325ba7a7fa7dd(ADR-0051). Anamorph's reference checkout pins the same commit. Existing 9.0.0/9.0.1 build caches are rejected with a reset command; clear both fields before rebuilding:cmake -S . -B build -UANABASIS_JUCE_TAG -UANABASIS_JUCE_VERSION.docs/policies/DEPENDENCY_POLICY.mdcarries the version-lock reasoning, the record of the divergence and re-convergence, and what the next bump owes the family; changing the pin is an Architecture Review Gate item. - Linux build deps install via
scripts/setup-linux.sh. Seedocs/procedures/BUILD.md.
# 1. Install build dependencies (Ubuntu; safe to re-run)
scripts/setup-linux.sh
# 2. Configure + build (fetches the pinned JUCE commit via CMake FetchContent)
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release # ...or: scripts/build.sh
# 3. Run the headless self-tests (DSP + state compatibility)
scripts/run-tests.sh
# 4. Validate the VST3 with pluginval, at the strictness CI ENFORCES.
# Read out of the one place that holds it rather than pasted: the literal
# here was `5`, and stayed 5 through two raises, under a comment claiming it
# was current — so the front page told contributors to validate at a weaker
# bar than the build actually requires. `docs/procedures/CI_CD.md` carries
# this same snippet with the full reasoning (POSIX `sed`, not `grep -oP`,
# which BSD grep rejects; the `^ ` anchor pins the match to the `env:`
# assignment so the job steps' references cannot supply a second value).
STRICTNESS=$(sed -n 's/^ ANABASIS_PLUGINVAL_STRICTNESS:[[:space:]]*\([0-9][0-9]*\).*/\1/p' \
.github/workflows/build.yml)
: "${STRICTNESS:?could not read ANABASIS_PLUGINVAL_STRICTNESS from build.yml}"
scripts/run-pluginval.sh "$STRICTNESS" deterministic
scripts/run-pluginval.sh "$STRICTNESS" randomiseTo build without network (JUCE already on disk):
cmake -B build -DANABASIS_JUCE_PATH=/path/to/JUCE ...
Developer decision record: Accepted ADR-0052 documents the measured Linux CI environment correction and owner approval.
The JUCE 9.0.5 review packet supports Accepted ADR-0051. It is investigation evidence outside the authority classes; the configured dependency is 9.0.5 under explicit owner Architecture Review approval; Level-5 listening and native/manual acceptance are now PASS — owner-attested for 9.0.5, recorded 2026-11-04 (Asia/Shanghai). Exact tested payload/environment details were not supplied. PR #60 is merged; no release is authorized.
Ordinary validator acquisition provenance and offline limits are recorded in the pluginval acquisition worklog, supporting evidence outside the documentation authority classes; the dependency policy owns the upgrade procedure.
The full technical documentation lives in docs/:
-
Contributor and agent entry point:
AGENTS.md(primary instructions) ·CLAUDE.md(Claude-compatible import) -
Start here:
docs/DEVELOPMENT_BRIEF.md(the product spec) ·docs/architecture/design-decisions/ADR_INDEX.md(the binding decisions — read before writing code) ·docs/DESIGN.md(the signed-off P0 design: architecture, the 49-parameter table, macro curves, wireframes) ·docs/SOURCE_OF_TRUTH.md·docs/REPOSITORY_MAP.md·docs/OPEN_QUESTIONS.md -
Rules (binding):
docs/policies/— real-time audio, threading, DSP, mode/adaptation, compatibility, AI-agent, testing, release, dependency, code style -
Architecture & decisions:
docs/architecture/— the Accepted ADRs, enumerated inADR_INDEX.mdand nowhere else. This bullet used to spell the list out ("twelve Accepted ADRs: ADR-0001…0011 plus ADR-0012") and went stale the moment ADR-0013 and ADR-0014 were accepted, contradicting the status section of this same file two screens up — in the one document that tells a contributor which decisions bind them. The index is the registry; this line points at it.DESIGN.mdranks below the ADRs it spawned and loses to them on any disagreement — seedocs/SOURCE_OF_TRUTH.md§"WhereDESIGN.mdsits" -
How-to:
docs/procedures/(build, development, CI/CD, testing, release) -
Audit records:
docs/reports/— dated, per-commit analysis snapshots; currently2026-09-03-scanner-audit.html(CodeQL + PREfast raw-SARIF findings, dispositions and Roadmap) and2026-09-26-anabasis-product-ux-audit.md(product / UX / UI / interaction audit: verified findings, decisions, priorities and the roadmap) with its Phase 0 follow-up2026-09-27-phase0-follow-up.md(what the first implementation round decided and verified, finding by finding), the owner decision material2026-09-27-phase0-owner-decisions.mdand the closure record2026-09-27-phase0-closure.md(the decisions taken, the review closed item by item, the Phase 0 status matrix), and the Phase 1 record2026-09-27-phase1-roadmap.md(what landed, what is next, what waits for the owner), and the third review round's closure record2026-09-28-pr42-review-closure.md(two true-peak paths closed, a low-rate residual recorded, GR max's contract, the copy decisions), and the fourth round's2026-09-28-pr42-round4-closure.md(the low-rate true-peak contract closed with a stated 12 kHz rail, KI-024 dispositioned, the statistics RESET, the TP matrix and the roadmap), and the fifth round's2026-09-29-pr42-round5-closure.md(ADR-0046 ratified, the low-rate contract, OQ-020, KI-028 dispositioned, the session clock, DSP-005, the TP matrix on the final engine, the roadmap) -
History & status:
CHANGELOG.md·docs/HANDOVER.md·docs/KNOWN_ISSUES.md·docs/FUTURE_RISKS.md·docs/POSTMORTEMS.md -
JUCE 9.0.4 upgrade: ADR-0047 and verification record.
The documentation falls into four classes, kept deliberately separate — Developer, User
(docs/user/), Internal/testing, Legal. worklogs/ sits outside all four: session-local
investigation records that are never cited as policy. See docs/SOURCE_OF_TRUTH.md.
| Level | What | Status |
|---|---|---|
| 1 | Compiler warnings, CodeQL, MSVC /analyze |
scaffolded, activates at P1 |
| 2–3 | Headless DSP + state-compatibility self-tests | activates at P1 |
| 4 | pluginval — both modes ×3, blocking on all three platforms, editor under xvfb; strictness is ANABASIS_PLUGINVAL_STRICTNESS in .github/workflows/build.yml, which carries the phase ladder and is the only copy |
activates at P1 |
| 5 | Manual audition in a DAW | required for release sign-off; not headlessly reproducible |
A green build + pluginval pass is "ready to audition," not final sign-off
(docs/policies/TESTING_POLICY.md).
Anamorph is a read-only reference for this project. Anabasis inherits its governance system,
CI/CD shape, testing conventions, build structure and brand system, and may copy and adapt
first-party code from it. Anabasis never modifies the Anamorph repository. What is
deliberately shared and what deliberately differs is tabulated in
docs/DEVELOPMENT_BRIEF.md §23.
Anabasis is a closed-source commercial product — it is not open-source software. The source
being readable here is not a licence: no LICENSE file is present, and this repository grants no
right to use, copy, modify or redistribute the code or binaries beyond what written permission
from RollyTech provides (all rights reserved by default).
Anabasis is built on JUCE, whose modules are dual-licensed AGPLv3 or commercial; a
closed-source distribution model cannot use the AGPLv3 arm, so the commercial JUCE tier must
be in place before commercial distribution. Commercial VST3 distribution requires reviewing
Steinberg's licensing requirements separately. The licence tier this project ships under is an
open decision — docs/OPEN_QUESTIONS.md OQ-002.
Third-party attribution: NOTICE carries the notices that must accompany a binary
distribution, and THIRD_PARTY_LICENSES.md is the complete verified
inventory (component, purpose, licence, and the exact file each licence was read from). Since
0.1.1 they ship as version-named release-page assets rather than being copied into the
archives — the one carrier every download route passes through, since neither installer ever
carried them (ADR-0021; docs/policies/RELEASE_POLICY.md §"Third-party attribution").
Contributors and AI agents: read AGENTS.md and
docs/policies/AI_AGENT_POLICY.md before changing code. CLAUDE.md is a Claude-compatible import of AGENTS.md. — some changes (parameter IDs,
serialization, threading, DSP order, latency) are hard-stop, human-review-required.
Namespace inventory and validation: product namespace worklog. ADR-0048 is Accepted under explicit final owner approval; implementation is merged. The namespace worklog retains its original native-validation limits. Later macOS receipt evidence keeps its exact head/package scope; DAW recall remains manual.
Installed-receipt decision: ADR-0050 is Accepted by the owner's direct
confirmation on 2026-10-25. Human architecture/ADR approval is complete.
PR #54 merged as 1afe5730a4fe3e9d918af91f17abcce0085a43d9; its implementation is effective on main.
Native fixtures are in scripts/fixtures/macos-receipts;
scripts/test-macos-receipt-gates.py checks the production scheduling contract.
Accepted ADR-0049 records the Windows optional-component uninstall icon and new runtime
gate in TESTING_POLICY. The owner's direct confirmation on 2026-10-25 completes
human architecture/ADR approval. PR #53 merged as 6dba5871b42d0d4c7323e21a1d226f5bf246164a;
its Windows implementation is effective on main. PR #54 also merged as
1afe5730a4fe3e9d918af91f17abcce0085a43d9; both platform decisions are implemented on main.
The ADR index is the decision-status and effectivity authority.