← Back to Documentation
Documentation
Architecture Decision Records
This directory records significant architectural decisions for bloqr-core — the kind of choice that's expensive to re-litigate later without knowing why it was made in the first place: engine/dependency selection, build-vs-adopt calls, cross-language integration strategy, and structural conventions that future contributors (and future PRs) need to stay consistent with.
Index
| ADR | Title | Status | Summary |
|---|---|---|---|
| 0001 | Canonical Rules-Compilation Engine Strategy Across Languages | Accepted | Extracts a minimal, dependency-free compilation engine (@bloqr/compiler-core) from the commercial bloqr-compiler product and dogfoods it across TypeScript (in-process) and .NET/Python/Rust (via deno run subprocess), instead of coupling every open-source compiler to the commercial product's full AGTree-dependent surface. |
| 0002 | AGLint/tsurlfilter/ExtendedCss/ecsstree/DiffBuilder Integration Strategy | Accepted | Settles how the .NET side consumes AdGuard's npm/TypeScript linting and diffing tooling (AGLint, tsurlfilter, ExtendedCss, ecsstree, DiffBuilder) — subprocess wrapper vs. an embedded JS engine — based on an empirical spike against the AGLint CLI. |
| 0003 | AdGuard HostlistCompiler Compatibility for bloqr-validator-core |
Accepted (Phase 1 and Phase 2 both implemented) | Scopes "compatible with AdGuard's compilers" down to HostlistCompiler specifically (not the browser-extension-oriented FiltersCompiler, which this repo doesn't target), and replaces bloqr-validator-core's hand-rolled pre-validation heuristic with one that matches HostlistCompiler's real Validate* transformation behavior. |
| 0004 | src/ reorg naming blueprint — the validation pilot |
Accepted | Records the validation/ directory migration (from rules-validator/{rules-validator-core,rules-validator-cli}) as the pilot for the org's target src/ taxonomy and per-language naming convention, and the scope boundary later migrations followed. |
| 0005 | Browser-Syntax Validation Engine for bloqr-validator-core |
Accepted | Rejects adopting bloqr-enginelib (a adblock-rust fork) for browser-syntax validation, after its MPL-2.0 license was confirmed compatible but its toolchain (Rust 1.97/edition 2024) proved incompatible with this workspace's MSRV — and instead hand-rolls a narrow browser-syntax grammar in bloqr-validator-core::syntax, gating epic #432's closure. |
Process and numbering
- Numbering: ADRs are numbered sequentially, zero-padded to four digits (
0001,0002, ...), in the order they're accepted. Numbers are never reused or renumbered, even if a later ADR supersedes an earlier one — supersession is recorded in the superseding ADR's own text (and ideally a note added to the superseded one), not by renumbering. - Filename:
NNNN-short-kebab-case-title.md, matching the ADR's own# ADR NNNN: Titleheading. - When to write one: an ADR is warranted for a decision that (a) was genuinely contested — more than one reasonable option existed and was weighed, (b) is expensive to reverse once other code depends on it, or (c) future contributors are likely to second-guess without knowing the context that ruled out the alternative. Routine implementation choices, bug fixes, and anything already covered by an existing
docs/architecture/*.mdstrategy doc don't need a new ADR. - Structure: follow the existing ADRs' shape —
Status,Date,Related(issue/PR/other-ADR links),Context(the problem and the options considered),Decision, andConsequences. Investigation-heavy ADRs (like 0003 and 0005) also include anInvestigationsection documenting what was actually tried, with real commands/output where relevant — reproducibility for whoever revisits the decision later matters more than brevity. - Status values:
Acceptedis the normal end state for a decision that's been implemented. UseProposedwhile a decision is still under discussion, andSuperseded by ADR NNNN(with a link) if a later ADR replaces this one's decision outright. - Updates after acceptance: ADRs are allowed to gain dated "Update" notes (see ADR 0001) when a fact they describe changes without the underlying decision changing (e.g. a package rename) — this keeps the historical narrative intact rather than silently editing history. A change to the decision itself gets a new ADR instead.
- Related architecture docs: not every architectural decision belongs in
docs/adr/— ongoing, evolving standards (versioning, licensing, release packaging, NuGet/JSR distribution) live underdocs/architecture/instead, since they're expected to be revised in place rather than recorded as a point-in-time decision. Use an ADR for the "why we chose X over Y" moment; use an architecture doc for "how X currently works, kept up to date."
When adding a new ADR, update this table in the same PR.