1PRIORITY — the backlog triage
The priority view across all open INVESTIGATE files: what to investigate next, what can wait, and what's been overtaken by shipped work. A triage tool, not a roadmap.
How to use this doc
- Tier 1 is the queue: the top row is what gets picked up next when the maintainer says go. Everything below waits.
- Tier 2 is real but not urgent — promote when Tier 1 drains.
- Tier 3 is blocked on a prerequisite — promote when the prereq lands. Files in this tier are named
INVESTIGATE-hold-*.md, so the block is visible from the filename alone, not just this doc's placement of it. Rename back to plainINVESTIGATE-*.mdwhen promoting out of Tier 3. - Tier 4 is investigated future ideas: the INVESTIGATE is written (options, Q-IDs, recommendation), but whether/when to implement is not decided. These wait for the maintainer's decision, not for capacity — promote to Tier 1/2 when they say go; they can also stay here indefinitely or be rejected (note the rejection, keep the file).
- Tier 5 is raw ideas: no INVESTIGATE yet.
- Retire candidates are investigations likely superseded by shipped
code: verify the remainder, harvest anything still open into a new
investigation or Tier 5 idea, then move the file to
completed/with a historical banner. - Update triggers (PLANS.md): new INVESTIGATE lands → tier it; one completes → strike it and promote dependents; a child PLAN ships → re-rank the parent. Full re-rank quarterly or after every 3 ships.
Last triaged: 2026-07-14 — Most of INVESTIGATE-developer-first-onboarding.md shipped, but not exactly as originally planned. Real end-to-end proof: ollacrm's own upgrade to sovdev-logger@1.0.2 was carried out for real — GitHub issue #414 filed, a mechanically-verified handover file generated and ready to send. What shipped, vs. the original [Q1]–[Q9] decisions:
- Option A (3-way docs split) — done differently than specified: rather than three generic templates,
using/onboarding/index.md(the operator recipe) got a new automated step (onboard-system.sh, below), andusing/onboarding/ollacrm/index.mdwas rewritten from a historical worked-example into a clean, current-state 4-step checklist — closer to a real developer quickstart than the original "3-way template" idea, but ollacrm-specific rather than a generic reusable template for the next customer. - Option B (bundled connection string, JSON→base64) — not built as specified. Instead, a stronger mechanism:
tools/validation/grafana-cloud/onboard-system.shtakes the raw ingest/verify tokens, runs a realsovdev-selftestwrite+read-back check, and only writes the handover file if that check passes — verified both directions (a real pass produces a correct file, a deliberately broken token produces no file at all). Not a single opaque string; a plain multi-var file, but one that can't be handed over broken. The maintainer judged this a better fit than the originally-planned bundled string. - Option D (shutdown-handler convenience function) — still deferred, untouched.
- Option E1 (public "Share externally" dashboard link) — still not done. This was called out as the single highest-value, lowest-cost action in the whole investigation — genuinely the next real gap.
- Option E3 (
sovdev-selftest) — already shipped earlier, unchanged; now also the fail-fast stage of the new CI gate (see below).
Separately, two more things shipped in the same session: (1) a real Grafana Cloud consistency-check CI gate — .github/workflows/ci.yml's new grafana-cloud-consistency job runs sovdev-selftest (fail-fast) then a full write→validate-file→read-back→diff-against-file check via the new tools/validation/grafana-cloud/full-consistency-check.sh, using dedicated sovdev-ci-ingest/sovdev-ci-verify credentials — this is what would have caught the uuid ESM-crash regression (see the dependency-sweep entry below) before it shipped; verified live in production CI before merging. (2) INVESTIGATE-tenant-write-isolation.md — while setting up those CI credentials, confirmed a real, structural finding: Grafana Cloud's Label-Based Access Control only restricts read scopes, never write — any ingest token in this project (ollacrm-ingest, sovdev-ci-ingest, every future customer's) can write fabricated data under any service_name in the shared stack, not just its own, confirmed both empirically (a spoofed write test) and via two first-party Grafana docs. The real fix (separate Grafana Cloud stacks per system) exists but costs the single shared dashboard this project's whole onboarding design is built around — maintainer decided not to pursue it, accepted as a documented, known limitation; corrected using/onboarding/index.md's previously-overstated "blast radius stays contained" claim to be explicit about read-only isolation. Investigation moved straight to completed/, no child plan.
Earlier:
INVESTIGATE-developer-first-onboarding.md's remaining 6 open questions ([Q1]–[Q5], [Q9]) all answered by the maintainer: ollacrm developers confirmed to have no Grafana Cloud login today (settles [Q1]/[Q9] decisively in favor of Option E1's public, no-login dashboard link); Option B (bundled connection string) ships TypeScript-first as JSON→base64, generated by a newtools/script, strictly one-per-system (no shared-string design); Option D (shutdown-handler convenience function) deferred until a second server-shaped consumer exists. Nothing left blocking a plan — next action is draftingPLAN-*.md(s) for E1, Option A (the 3-way docs split), and Option B, likely as 3 separate plans given how independently each ships.Earlier:
INVESTIGATE-hold-dependency-upgrade-sweep.mdmostly shipped: GitHub Actions (all 5 actions bumped, confirmed via a real triggered run that the recurring "Node.js 20 is deprecated" annotation is gone), Docusaurus (3.10.1→3.10.2, PR #18, verified with a real local build since this repo has no CI configured to lean on), and@types/node/tsxconsistency fortools/validation+tools/dashboards(PRs #22, #23) all done directly, each verified with a realtsc --noEmitrather than trusting a green Dependabot check. Also found and corrected a real mistake from the 2026-07-13 pass: PR #12 had been closed with a comment claiming itstypescriptbump was "superseded by a manual commit" — it wasn't; that comment was wrong and has been corrected. That correction led to the pass's one substantive new finding:typescript@7.0.2breaks ambient Node global type resolution (process/Buffer/node:fsunresolvable) under this repo'stsconfig.jsonpattern — confirmed by isolating it intools/validation, not assumed.typescriptstays pinned everywhere until a dedicated migration is scoped; 3 open PRs (#13, #15, #19) closed/deferred with this recorded on each. ESLint 8→10 (PRs #14, #17) also deliberately left open — a real flat-config migration, not a mechanical bump. Demoted from Tier 1 to Tier 2: the urgent/mechanical parts are done, what remains needs two dedicated follow-up investigations (INVESTIGATE-hold-eslint9-migration.md,INVESTIGATE-hold-typescript7-migration.md) not yet written.Earlier:
INVESTIGATE-operator-dashboard-panel.mdand its childPLAN-operator-dashboard-panel.mdboth shipped and moved tocompleted/: a new "Active Clients" panel (fleet-wide distinctclient_namecount) added to both dashboard variants, next to "Active Integrations." This investigation replaced an earlier informal Tier 5 spot-check that turned out to be wrong when re-checked against realistic data — the naive query counted "no client set" as a distinct client, and a genuinely-zero-clients service returned empty instead of0; both fixed and re-verified. Validated end-to-end on both real backends, including the maintainer visually confirming both live dashboards and watching "Active Clients" flip from0to1live as fresh data landed — which also surfaced a real, not-a-bug finding the investigation had predicted: this panel respects the dashboard's time-range picker literally (unlike "Active Integrations," a persistent Prometheus counter), so it can show0even with recent-but-just-outside-the-window activity.Earlier:
INVESTIGATE-npm-trusted-publishing.mdand its childPLAN-npm-trusted-publishing.mdboth shipped and moved tocompleted/:.github/workflows/publish.yml(OIDC-based,workflow_dispatch-triggered) plus a real Trusted Publisher configured onnpmjs.com/package/sovdev-logger/access. Fully validated with real publishes, not just green CI: a first dispatch (before the Trusted Publisher existed) correctly failed only at the finalnpm publishstep with the expected404/permission error, everything before it green; a second dispatch after configuration published1.0.1for real — confirmed against the live registry (version, tarball URL) and a genuine SLSA provenance attestation with its own Sigstore transparency-log entry. Manualnpm publish(personal OTP) confirmed still functional as a fallback, per npmjs.com's own package-specific settings page.contributor/publishing/typescript.mdrestructured with GitHub Actions as the primary path and the OTP flow as documented fallback.Earlier:
INVESTIGATE-library-best-practices.mdand its childPLAN-library-best-practices-bugfix.mdboth shipped and moved tocompleted/:@opentelemetry/apimoved topeerDependencies(^1.9.1), the rootLICENSEcopied intotypescript/(the published tarball had shipped zero LICENSE files since its first release —npm pack --dry-run --jsonconfirms it's now included), and.github/dependabot.ymladded covering all 5 npm-ecosystem directories plus GitHub Actions — confirmed genuinely active within minutes of merging (real PRs opened; a minor bump passed CI cleanly, three major bumps correctly failed on real peer-dependency conflicts, exactly the "majors need individual review" behavior the config was designed for).Earlier:
INVESTIGATE-otel-dependency-upgrade.mdand its childPLAN-otel-dependency-upgrade.mdboth shipped and moved tocompleted/: Option A (one big jump), 49 vulnerabilities (including 1 critical) → 0, 4 real breaking changes found and fixed, validated end-to-end against both real backends plus a cross-language check against Python. Answering a maintainer follow-up ("is there any reason sovdev-logger needs a higher Node version than OTel itself, are we using any Node-22-specific functionality?") confirmed no — the>=22.0.0floor is a deliberate EOL-avoidance policy already on record in git history, not a technical requirement; OTel's own packages only need^18.19.0 || >=20.6.0.Earlier: maintainer asked to check whether OTel had actually been upgraded yet (it hadn't — still exactly where the investigation left it), then to investigate updating every software component in the repo:
INVESTIGATE-hold-dependency-upgrade-sweep.mdchecked everypackage.json/requirements.txt/workflow file directly and found real drift everywhere except Python (already current by design, unpinned>=constraints) and the DevContainer image (already tracks:latest, externally managed) — TypeScript dev tooling, Docusaurus, and GitHub Actions are all 1-3 major/minor versions behind; OTel (this sweep's most urgent item) has since shipped separately, the rest of the sweep is still open.Earlier:
INVESTIGATE-repo-and-package-ownership.mdshipped and moved tocompleted/(no child PLAN needed, executed directly):helpers-no/sovdev-loggerwas a GitHub fork of the inactivenorwegianredcross/sovdev-logger— copied outright into a fresh non-fork repo at the same name (old fork archived, issue #23 preserved there), GitHub Pages/custom domain moved over with no real downtime. The npm package@terchris/sovdev-logger(personal-account-owned) was renamed to unscopedsovdev-logger@1.0.0— no npm org, by explicit maintainer choice to keep solo-maintainer overhead low — with the old packagenpm deprecated (not unpublished; ollacrm's existing install keeps working) and every live-facing doc/code reference updated.norwegianredcross/sovdev-loggeritself was left untouched, archiving it is now optional.terchris/ollacrm's own dependency still needs migrating, tracked separately, out of this repo's scope.Earlier:
INVESTIGATE-service-principal-acting-user.mdand its childPLAN-service-principal-acting-user.mdboth shipped and moved tocompleted/:service_principalandacting_useradded tosovdev_set_context(), wired into both the file-log and OTLP export paths (the exact spotclient_namewas missed the first time — not repeated), a one-time Grafana Cloud privacy warning foracting_user, README documentation, and end-to-end validation against real Grafana Cloud and UIS at every phase — including a 3-field merge regression test and a clean cross-language comparator run against Python. Dashboard treatment (Q5) and Python parity are explicitly deferred, now tracked as their own Tier 5 raw ideas below rather than open items on the completed investigation. The merge-vs-replace correctness gap this investigation originally surfaced in already-shipped code had already shipped separately, ahead of this plan, asPLAN-context-merge-semantics.md.Earlier:
INVESTIGATE-context-propagation.mdand its childPLAN-context-propagation.mdshipped:sovdev_set_context({client_name}), README updates, a "Client" column on the Grafana dashboard, end-to-end validation against real Grafana Cloud and UIS. Two real bugs found and fixed along the way (the OTLP export path silently droppingclient_name; a stale cross-reference link), plus an unscoped cleanup (removed 4 redundant, fragile dashboard panels found during the maintainer's own live review). Checking the operator-dashboard idea (Tier 5) then surfaced a real naming problem — "Active Integrations" actually counts distinctservice_namevalues, not integrations — which the maintainer asked to generalize into a full terminology review:INVESTIGATE-terminology-review.mdcovers every schema field and every dashboard panel title, with real findings beyond the trigger (session_idreinvents OTel's ownservice.instance.id;trace_idsilently means two different things depending on whether a span was active; a couple of smaller naming inconsistencies) — no PLAN drafted yet, still Tier 5-adjacent pending a maintainer decision.INVESTIGATE-otel-dependency-upgrade.md(from GitHub issue #23) still needs a bump-strategy decision. The issue's remaining two items — asovdev_test_otlp_connection()bug (204 misread as failure), and four documentation gaps — have a clear solution already and don't need investigation; ready to go straight to aPLAN-*.mdwhenever picked up.INVESTIGATE-developer-first-onboarding.mdstill Tier 1: the current onboarding recipe was written for a maintainer setting up shared infrastructure, not for a customer developer who knows nothing about OTLP/Grafana — a real risk of "this library is bad, I'll just use console.log" if the first-contact experience stays this heavy.
Tier 1 — next up
INVESTIGATE-docs-site-structure.md's [Q5] — Option E1, Grafana Cloud's public "Share externally" dashboard link. Absorbed from the now-retiredINVESTIGATE-developer-first-onboarding.md(every other option there shipped; this was the one piece left, see that doc's own completed banner). Called out as the single highest-value, lowest-cost action across both investigations: a public, no-login dashboard link pre-filtered byservice_name— closes the "prove it's working" loop for a developer who (confirmed, for ollacrm) has no Grafana Cloud login at all. No code changes, just a Grafana Cloud portal setting + confirming the pre-filtered URL pattern works.
Tier 2 — real, not urgent
(none yet)
Tier 3 — blocked
-
INVESTIGATE-hold-dependency-upgrade-sweep.md— the parent sweep across every other software component in the repo. Mostly shipped (2026-07-14): OTel (done separately, security-relevant), GitHub Actions (all 5 bumped, deprecation annotation confirmed gone), Docusaurus (3.10.1→3.10.2), and@types/node/tsxconsistency fortools/validation+tools/dashboardsare all done and verified with real builds, not just green Dependabot checks. Prerequisite to promote out of this tier: both of its two spun-off follow-ups below resolve —INVESTIGATE-hold-typescript7-migration.mdalready has (wait, don't migrate),INVESTIGATE-hold-eslint9-migration.mdstill needs the maintainer's answers. -
INVESTIGATE-hold-eslint9-migration.md— whether/how to bumpeslint8→10 (real flat-config migration) and@typescript-eslint7→8 intypescript/(PRs #14, #17). Real finding: the two bumps are actually independent —@typescript-eslint@8.x's peer range already accepts the currenteslint@^8.57.0, so PR #17 can likely unblock alone, with no flat-config work, once the parser+plugin are bumped together (the root cause of #17's current conflict). The ESLint 9/10 migration itself is real but not urgent (dev-only, no security exposure) — recommends keeping it separate. Prerequisite to promote out of this tier: maintainer answers the 5 open questions in the doc. -
INVESTIGATE-hold-typescript7-migration.md— resolved 2026-07-14: wait, don't migrate. All 5 open questions answered directly (including a real isolated test: installingtypescript@7.0.2inwebsite/and running its actual typecheck script). Found a second confirmed TS7 break beyond the original Node-globals one —website/tsconfig.json's own"baseUrl": "."hard-fails under 7.0 (TS5102, removed) — plus the pre-existing@typescript-eslintpeer-range ceiling that blockstypescript/regardless of any fix here. Maintainer's own framing settled it: TS7 is 6 days old, several blockers are outside this repo's control, so there's nothing to gain from migrating piecemeal now.typescriptstays pinned everywhere. Prerequisite to promote out of this tier:@typescript-eslintships TS7 support (currently capstypescriptat<6.1.0) — check vianpm view @typescript-eslint/eslint-plugin@latest peerDependencies.
Tier 4 — investigated, undecided
INVESTIGATE-external-backend-verification.md— verification status across all four backends this investigation covers: UIS (local, done —sovdev-selftest --backend uis) and Grafana Cloud (done —sovdev-selftest --backend grafana-cloud, plus the fullerfull-consistency-check.sh) both have real, working verification tooling. Azure Monitor and Google Cloud are still just research (query APIs, auth models, cost/retention, TypeScript-vs-bash tooling choice) — no OTLP export or verification tooling built for either,sovdev-selftesthas no--backend azure/--backend gcpoption at all. Remaining open question is narrower than it looks: not "verify 3 backends," just "build Azure and/or GCP support, in what order" — a maintainer values call (cheapest-first vs. production-target-first), not a technical one — see [Q2] in the doc.
Tier 5 — raw ideas
-
Migrate
terchris/ollacrm's ownpackage.jsonfrom@terchris/sovdev-logger(now deprecated) to unscopedsovdev-logger— that repo's own work, out of this repo's scope; no urgency since the deprecated package still installs and works fine, just won't get further updates. -
Decide whether to archive
norwegianredcross/sovdev-loggernow thathelpers-no/sovdev-loggerno longer depends on it at all (perINVESTIGATE-repo-and-package-ownership.md's Q2) — no longer blocking anything, purely a "tidy up the now-orphaned original" cleanup. -
Decide whether Go/C#/Rust/PHP restart from scratch or from their archived
terchris/implementation-tests/state — the one remaining open item fromINVESTIGATE-multi-language-conformance.md(resolved and moved tocompleted/, all four child plans merged); no INVESTIGATE written for this yet, no urgency signal from the maintainer. -
Dashboard treatment for
service_principal/acting_user— a "Service Principal"/"Acting User" column on the "Recent Errors" table, following theclient_name/peer_serviceprecedent, perINVESTIGATE-service-principal-acting-user.md's Q5. Deliberately deferred until there's real production data to look at, same sequencingclient_name's own dashboard work used. No INVESTIGATE written yet. -
Python parity for
client_name/service_principal/acting_user— all three are TypeScript-only as ofPLAN-context-propagation.mdandPLAN-service-principal-acting-user.md, excluded fromcompare-log-files.py's cross-language diffing with a comment noting the exclusion should be removed once Python has parity. No INVESTIGATE written yet; no urgency signal from the maintainer.
Notes (not triage, just don't want to lose it)
-
Slogan idea, in progress: something along the lines of logging for hundreds of frontends and thousands of APIs — echoes the actual driving use case behind
INVESTIGATE-context-propagation.md(ollacrm: "gather logs from hundreds of APIs and many clients... filter out one client... across many APIs"). Not decided/finalized, just parking it here. -
Two-customer framing, in progress: sovdev-logger has two distinct customers, and both must be happy at once, not traded off against each other.
- The developer — just wants to log from her application. Wants this simple: one
sovdev_log()call, zero-effort metrics/traces, nothing extra to think about unless she needs it. - The operator — manages all the logs, across all the applications, and by extension needs visibility into all the developers/teams producing them. Wants the fleet-wide view: which API, which client, how many are actually logging, where the errors are.
- This isn't just a slogan angle — it's already a real design principle behind decisions made in
PLAN-context-propagation.md:client_nameis entirely optional/additive (Q9) specifically so the developer who doesn't care about fleet management never has to touch it, while the operator gets fleet-wide filtering once a service opts in. The still-open "operator dashboard panel" idea (Tier 5 above) is the operator-side half of this same framing — a developer-facing feature (client_name) that only pays off once there's an operator-facing view built on top of it.
- The developer — just wants to log from her application. Wants this simple: one
Retire candidates
(none yet)