Skip to content

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/rosapi/README.md and internal/rosapi/LICENSE; and in the header of .golangci.yml.

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.

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/golangci-lint-config The module path

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.

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/dashboards/sections.go; mikroscope’s list is internal/dashboards/sections.go. 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.

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_cover_test.go), 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/go-routeros/routeros/v3 at v3.0.1 (upstream commit of 2025-02-16), MIT, copyright 2016 André Luiz dos Santos, whose LICENSE file stays in the package.

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.

These changes were made in cs-routeros-bouncer and arrive unchanged:

  1. The async/listen mode is removed, with its tests and the async branch of RunArgsContext. Nothing in the bouncer called Async(), Listen() or the context-cancelling run variants. The sentence-kind constants moved to reply.go, which consumes them.
  2. 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.ErrUnexpectedEOF on truncation, *DeviceError on !trap), and upstream’s suite green under go test -race. proto/reader_shape_test.go 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; internal/rosapi/README.md, where they come from, records no date and no host, so none can be given here.
  3. 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 ret challenge gets ErrLegacyLoginUnsupported instead.
  4. 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.

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.