Lineage and licence
Parts of mikroscope started as code from cs-routeros-bouncer, ghchronicle and
go-routeros, all MIT-licensed. Below: which packages, what changed when they
arrived, and the licence. The attribution is also in the code, so it survives being read without this
site: in the package doc comment of internal/router/, of the image
builder internal/image/, of the chart internal/chart/ and
of the dashboard generator internal/dashboards/; in the API client’s
own internal/ and internal/rosapi/LICENSE;
and in the header of .golangci.yml.
Sampler origin
Section titled “Sampler origin”The sampler that proved this works is cmd/perfmon in
cs-routeros-bouncer, built
for one benchmark and kept there as a developer instrument. The deployment steps, the
dockerless image builder, the deterministic chart and the vendored RouterOS
API client come from that repository, under its MIT licence.
Imported packages
Section titled “Imported packages”| mikroscope | Taken from | What changed on the way |
|---|---|---|
internal/router |
cs-routeros-bouncer cmd/perfmon, the deployment steps after PR #123 |
Extended with quoted ports in every find, the optional --expose firewall pair, mikroscope’s own container settings, and a listing of every write before it happens |
internal/router tests |
cs-routeros-bouncer cmd/perfmon, the containment tests |
Adapted to mikroscope’s option names and to two rules of its own: quoted ports, and the --expose pair as part of the plan |
internal/image |
cs-routeros-bouncer cmd/perfmon/image.go |
Reworked for the agent’s name, the ARM variant (an arm image declares its GOARM level: v5 by default, v7 with --goarm 7) and a build goreleaser can reuse |
internal/chart |
cs-routeros-bouncer cmd/perfmon/chart.go |
The original drew its palette from a docs theme; this one carries its own, validated for the light surface (adjacent-pair CVD ΔE 9.1, normal-vision 22.9) |
internal/rosapi |
cs-routeros-bouncer internal/rosapi, taken 2026-09-11 |
The import path; since then tests and the package README only (1.0.1, 1.1.0), nothing in the shipped code |
.golangci.yml |
ghchronicle and gitlab-mcp-server, themselves based on maratori/ |
The module path |
Scroll sideways to see every column
What PR #123 brought, and what mikroscope’s installer keeps from it, is the
containment rule: every object created carries one exact comment tag, every
removal selects by that tag plus the object’s identity (never by pattern), and
uninstall verifies by ownership counts before it reports success.
Nothing is written without being listed first.
The chart’s output is deterministic: the same input always yields the same bytes.
Modelled designs
Section titled “Modelled designs”The model is ghchronicle, the other
telemetry project of mikroscope’s maintainer, José Manuel Requena Plens, which
collects what GitHub reports about an account. internal/dashboards takes its
Grafana export shape from ghchronicle’s
cmd/gen_dashboards
— “the shape, not the code”, as its package comment says — and
dashboards check checks every panel on a real Grafana the way ghchronicle
does. Two more pieces are modelled on ghchronicle the same way, the shape and
not the code. The dashboards’ named sections, the first open and every other one
collapsed, follow its
internal/;
mikroscope’s list is internal/. And the
end-to-end suite under test/e2e/ follows
ghchronicle’s test/e2e/,
which builds its binary and drives it against a fake GitHub with one test file
per sink.
RouterOS API client
Section titled “RouterOS API client”internal/rosapi has two generations of lineage. mikroscope’s copy is
cs-routeros-bouncer’s, with nothing modified in the shipped code. What changed since is
tests and the package’s own README.md: 1.0.1 added one Windows-only skip to
client_test.go; 1.1.0 added two coverage tests (dial_cover_test.go,
unknownreply_), extended proto_test.go, and wrote that 1.0.1 skip into
the lineage note of README.md. mikroscope uses it
for the API tier’s reads, for mark --log-markers, and for the /tool fetch
relay. The bouncer’s copy is
itself a pruned vendoring of
github.com/
at v3.0.1 (upstream commit of 2025-02-16), MIT, copyright 2016 André Luiz dos
Santos, whose LICENSE file stays in the package.
Why vendored
Section titled “Why vendored”Upstream is effectively unmaintained: its last commit predates the copy by
eighteen months, and the pull requests and issues filed against the async mode
in mid-2026 (#31–#34) have had no maintainer response. No maintained
alternative exists: swoga/go-routeros is a copy that only receives
dependabot bumps for its GitHub Actions, and jda/routeros-api-go stopped in 2016. Vendoring keeps the code buildable and lets the copy fix and prune what it
uses.
Changes from upstream
Section titled “Changes from upstream”These changes were made in cs-routeros-bouncer and arrive unchanged:
- The async/listen mode is removed, with its tests and the async branch of
RunArgsContext. Nothing in the bouncer calledAsync(),Listen()or the context-cancelling run variants. The sentence-kind constants moved toreply.go, which consumes them. - The protocol reader and writer read and write directly, instead of
dispatching every call to a fresh goroutine with a channel and a copy
buffer; only the removed async mode ever cancelled an in-flight read. At the
bouncer’s production scale (22k address-list entries fetched every cycle)
that layer cost ~294 000 goroutine spawns, ~62 MB of garbage and ~76 % of
all allocations per reconcile cycle. The rewrite was checked against pristine
upstream with a differential test: the SHA-256 fingerprint over all 22 037
parsed sentences identical, error shapes identical (
io.ErrUnexpectedEOFon truncation,*DeviceErroron!trap), and upstream’s suite green undergo test -race.proto/pins that behaviour. Those four figures are cs-routeros-bouncer’s own, measured on its own host against its own workload, not on a router and not by this project;reader_ shape_ test.go internal/, where they come from, records no date and no host, so none can be given here.rosapi/ README.md - The pre-6.43 MD5 challenge login is removed. That login exists only
before RouterOS 6.43 (2018), and answering it means hashing the password with
MD5. A router that sends a
retchallenge getsErrLegacyLoginUnsupportedinstead. - The async and listen-mode tests are removed with the mode; the pre-6.43 login tests assert the rejection instead of the handshake. The rest of upstream’s suite is kept and passing.
Compare against upstream’s v3.0.1 tag, not its master branch.
Licence
Section titled “Licence”mikroscope is MIT-licensed, copyright 2026 José Manuel Requena Plens, whom the
licence names by his handle, jmrplens; the full text is LICENSE
at the root of the repository. The code taken from cs-routeros-bouncer arrives
under that repository’s MIT licence, and internal/rosapi keeps go-routeros’s
MIT LICENSE beside the code it covers. What each release changed,
corrections to this page included, is in CHANGELOG.md.