Skip to main content

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 plain INVESTIGATE-*.md when 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), and using/onboarding/ollacrm/index.md was 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.sh takes the raw ingest/verify tokens, runs a real sovdev-selftest write+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 new tools/ 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 drafting PLAN-*.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.md mostly 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.13.10.2, PR #18, verified with a real local build since this repo has no CI configured to lean on), and @types/node/tsx consistency for tools/validation + tools/dashboards (PRs #22, #23) all done directly, each verified with a real tsc --noEmit rather 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 its typescript bump 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.2 breaks ambient Node global type resolution (process/Buffer/node:fs unresolvable) under this repo's tsconfig.json pattern — confirmed by isolating it in tools/validation, not assumed. typescript stays 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.md and its child PLAN-operator-dashboard-panel.md both shipped and moved to completed/: a new "Active Clients" panel (fleet-wide distinct client_name count) 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 of 0; 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 from 0 to 1 live 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 show 0 even with recent-but-just-outside-the-window activity.

Earlier: INVESTIGATE-npm-trusted-publishing.md and its child PLAN-npm-trusted-publishing.md both shipped and moved to completed/: .github/workflows/publish.yml (OIDC-based, workflow_dispatch-triggered) plus a real Trusted Publisher configured on npmjs.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 final npm publish step with the expected 404/permission error, everything before it green; a second dispatch after configuration published 1.0.1 for real — confirmed against the live registry (version, tarball URL) and a genuine SLSA provenance attestation with its own Sigstore transparency-log entry. Manual npm publish (personal OTP) confirmed still functional as a fallback, per npmjs.com's own package-specific settings page. contributor/publishing/typescript.md restructured with GitHub Actions as the primary path and the OTP flow as documented fallback.

Earlier: INVESTIGATE-library-best-practices.md and its child PLAN-library-best-practices-bugfix.md both shipped and moved to completed/: @opentelemetry/api moved to peerDependencies (^1.9.1), the root LICENSE copied into typescript/ (the published tarball had shipped zero LICENSE files since its first release — npm pack --dry-run --json confirms it's now included), and .github/dependabot.yml added 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.md and its child PLAN-otel-dependency-upgrade.md both shipped and moved to completed/: 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.0 floor 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.md checked every package.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.md shipped and moved to completed/ (no child PLAN needed, executed directly): helpers-no/sovdev-logger was a GitHub fork of the inactive norwegianredcross/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 unscoped sovdev-logger@1.0.0 — no npm org, by explicit maintainer choice to keep solo-maintainer overhead low — with the old package npm deprecated (not unpublished; ollacrm's existing install keeps working) and every live-facing doc/code reference updated. norwegianredcross/sovdev-logger itself 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.md and its child PLAN-service-principal-acting-user.md both shipped and moved to completed/: service_principal and acting_user added to sovdev_set_context(), wired into both the file-log and OTLP export paths (the exact spot client_name was missed the first time — not repeated), a one-time Grafana Cloud privacy warning for acting_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, as PLAN-context-merge-semantics.md.

Earlier: INVESTIGATE-context-propagation.md and its child PLAN-context-propagation.md shipped: 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 dropping client_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 distinct service_name values, not integrations — which the maintainer asked to generalize into a full terminology review: INVESTIGATE-terminology-review.md covers every schema field and every dashboard panel title, with real findings beyond the trigger (session_id reinvents OTel's own service.instance.id; trace_id silently 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 — a sovdev_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 a PLAN-*.md whenever picked up. INVESTIGATE-developer-first-onboarding.md still 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-retired INVESTIGATE-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 by service_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.13.10.2), and @types/node/tsx consistency for tools/validation+tools/dashboards are 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.md already has (wait, don't migrate), INVESTIGATE-hold-eslint9-migration.md still needs the maintainer's answers.

  • INVESTIGATE-hold-eslint9-migration.md — whether/how to bump eslint 8→10 (real flat-config migration) and @typescript-eslint 7→8 in typescript/ (PRs #14, #17). Real finding: the two bumps are actually independent — @typescript-eslint@8.x's peer range already accepts the current eslint@^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.mdresolved 2026-07-14: wait, don't migrate. All 5 open questions answered directly (including a real isolated test: installing typescript@7.0.2 in website/ 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-eslint peer-range ceiling that blocks typescript/ 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. typescript stays pinned everywhere. Prerequisite to promote out of this tier: @typescript-eslint ships TS7 support (currently caps typescript at <6.1.0) — check via npm 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 fuller full-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-selftest has no --backend azure/--backend gcp option 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 own package.json from @terchris/sovdev-logger (now deprecated) to unscoped sovdev-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-logger now that helpers-no/sovdev-logger no longer depends on it at all (per INVESTIGATE-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 from INVESTIGATE-multi-language-conformance.md (resolved and moved to completed/, 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 the client_name/peer_service precedent, per INVESTIGATE-service-principal-acting-user.md's Q5. Deliberately deferred until there's real production data to look at, same sequencing client_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 of PLAN-context-propagation.md and PLAN-service-principal-acting-user.md, excluded from compare-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_name is 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.

Retire candidates

(none yet)