Skip to content

Instantly share code, notes, and snippets.

@mike-ward
Last active August 14, 2026 22:23
Show Gist options
  • Select an option

  • Save mike-ward/8ea756fdc68227ddcc3c5ee6c90a1395 to your computer and use it in GitHub Desktop.

Select an option

Save mike-ward/8ea756fdc68227ddcc3c5ee6c90a1395 to your computer and use it in GitHub Desktop.
opencode config and quality pipeline skills

Working agreements

  • Extremely concise. Passive or imperative voice. No softening, hedging, first-person.
  • Accurate, robust solutions over agreement. Blunt feedback — don't validate a confidently-stated but flawed premise; say so.
  • Comments wrap at 90 columns when practical.
  • End plans with a concise list of unresolved questions, if any.
  • Performance work favors reducing heap allocations.
  • When summarizing, synthesize — explain implications, don't just compress.
  • Test Driven Development should be favored where practical.
  • Shell scripts and command line recommendations should use Fish, my preferred shell, or explicity call bash.
  • Be generious with code comments when generating or updating code so I can understand your reasoning.
name harden
description Harden uncommitted changes against bad data and denial of service attacks.
user_invocable true

For all uncommitted changes (staged and unstaged), harden inputs against bad data and DoS:

Steps:

  • Run git diff and git diff --cached to identify changed files and functions
  • Read surrounding context in modified files as needed
  • For each public function or entry point in the diff, check for and fix:
    • NaN/Inf floats — clamp or replace with safe defaults (pixelMin convention)
    • Nil/empty slices and maps — early return or no-op, never panic
    • Unbounded input sizes — cap slice lengths, iteration counts, string lengths
    • Division by zero — guard before dividing
    • Integer overflow — check before arithmetic on user-supplied counts
    • Excessive allocations — pre-check sizes before allocating large buffers
    • Duplicate or degenerate data — handle gracefully, no infinite loops
    • Error returns handled correctly - no bare errors
  • Apply fixes directly to the source files
  • Run go build ./... and go vet ./... to verify changes compile
  • Summarize what was hardened and where
name quality
description One-command quality pipeline over uncommitted changes — review, harden, fill test gaps, simplify (changed files only), then verify. Leaves changes uncommitted.
user_invocable true

Run the full quality pass on the current uncommitted diff, in order. Apply findings as you go; do not just report them. Stop and surface anything that can't be safely auto-resolved. Leave the changes uncommitted — do not stage or commit. The user commits separately (e.g. /ship or /commit).

Before any other work: if a task-tracking tool is available (todowrite, TaskCreate), create a tracker with all steps below and mark each in_progress/completed as you go — this populates the IDE's right-panel progress view. If no such tool is in this session's roster, skip it and say so once in the final summary; do not stall the pass on it.

Do not delegate pipeline steps to subagents. The pipeline is sequential over one shared file set, so splitting it buys nothing — and built-in skills such as simplify and harden are injected into the main agent's skill roster by the harness rather than existing as files on disk, so a subagent cannot invoke them at all.

Parallel fan-out within a single step is a separate question and is sometimes worth it. Step 5 may use simplify's multi-agent fan-out when the diff is large (roughly 500+ changed lines) — below that, the review agents cost more than they find. When you do fan out, pass the agents the decisions already settled in steps 2–4, including anything deliberate that reads as a defect from the outside. Cold agents re-derive context and will otherwise re-report handled findings and re-litigate intentional choices, and adjudicating those false positives can cost more than the parallel sweep saves.

Pipeline

  1. Scope — capture the changed file set: !git diff --name-only HEAD Every later step operates ONLY on these files. Never edit other packages.

  2. Review — do a thorough correctness pass over the step-1 files yourself, at high effort, and apply the fixes. There is no code-review skill to call: /code-review is a built-in command, user-triggered and billed, so it cannot be launched from here. Cover at minimum:

    • Correctness: off-by-one, nil/zero-value handling, early returns that skip cleanup, incorrect boundary conditions.
    • Error paths: every returned error handled or deliberately ignored with a reason; no swallowed failures.
    • Concurrency: lock discipline as the repo defines it — no lock held across a call into another subsystem, cross-goroutine state reached only through the repo's sanctioned path.
    • Allocation: no per-item heap traffic in documented hot paths.
    • Layering: dependencies flow in the direction the repo's architecture notes specify; no lower layer reaching up into a higher one. Defer to the project's CLAUDE.md for the concrete names behind these — which lock, which hot path, which layers — and apply its rules, not these generic ones, wherever it is specific. If the diff warrants the deeper multi-agent pass, say so in the final summary and let the user run /code-review ultra themselves.
  3. Harden — run the harden skill. Apply defenses against bad data / DoS on the changed code.

  4. Test — run the test-gaps skill. Add the missing tests it reports (untested public funcs, edge cases, error paths).

  5. Simplify — run the simplify skill, CONSTRAINED to the step-1 file set only. Reject any change that touches other packages or that broadens scope. Watch for the known failure modes of an over-eager simplify: recursion introduced by collapsing a call chain, regressions in behaviour that has no test to catch it (rendering, layout, focus), and "unused" wiring deleted because its only caller is a framework or callback the analysis could not see. If the skill does not resolve, do not stop — apply its criteria inline under the same file-set constraint: reuse existing helpers instead of new near-duplicates, collapse needless indirection, delete dead abstraction, and pitch each function at one consistent altitude. Quality only — bug hunting belongs to step 2.

  6. Verify — rebuild and run the suite; do not proceed on red:

    • go build ./...
    • go test ./...
    • golangci-lint run ./... (Adjust only for a non-Go repo.) Confirm all pass.

Do NOT commit. Leave the changes staged-or-unstaged exactly as the user had them plus the pass's edits, for the user to review and commit.

Guardrails

  • Minimal scoped diffs — no cosmetic churn, no drive-by edits.
  • If any stage introduces a regression caught at step 6, revert that stage's change and report it rather than leaving the tree broken.
  • Report a final summary: what each stage changed and the test outcome.

If $ARGUMENTS is provided, treat it as extra scope/context for the pass.

name release
description Update changelog, commit, tag with patch bump, push
user_invocable true

Release workflow for the current project. Steps:

  1. Get last tag: !git describe --tags --abbrev=0
  2. Get changes since last tag: !git log $(git describe --tags --abbrev=0)..HEAD --oneline
  3. Determine next version by incrementing the minor number of the last tag. If no new user facing features or no breaking changes, increment the patch number instead.
  4. Confirm the version tag with the user before proceeding. Show the proposed version and why (e.g. "minor: new feature X" or "patch: bug fixes only"). Do not continue until the user approves the version.
  5. Update CHANGELOG.md with a new entry for the next version, summarizing changes
  6. Create a branch for the release, commit CHANGELOG.md and any staged/modified tracked files with message: changelog: add <version> (<summary>)
  7. Push the branch and create a PR (gh pr create)
  8. Wait for CI (gh pr checks --watch), classify failures before acting
  9. Squash-merge the PR (gh pr merge --squash --delete-branch), then pull main
  10. Create annotated tag for the new version on the merged commit
  11. Push the tag to origin (git push origin <tag>)
  12. Clean up: delete the local release branch

If $ARGUMENTS is provided, use it as additional context for the changelog entry.

name ship
description Drive a change from branch to merged PR — verify rebased on base, commit, push, open PR, then merge and clean up branches (handles squash merges)
user_invocable true
model sonnet

End-to-end ship workflow for the current change. Verify each step before proceeding; do not declare success on an unverified step.

Before any other work: use todowrite to create a task tracker with all steps below. Mark each step in_progress/completed as you go — this populates the IDE's right-panel progress view.

Preflight

  1. Determine base branch: !git remote show origin | sed -n 's/.*HEAD branch: //p'

  2. Never commit directly to the base branch. If the current branch is the base branch, create a feature branch (give it a short, descriptive name) before proceeding. A PR requires two distinct branches.

  3. Confirm current branch is rebased on the current base. If behind, fetch and rebase first — do not open a PR from a stale base.

  4. Run, in order, stopping and reporting on first failure. Suppress success output — only failures belong in context. This repo has 87 packages; a bare go test ./... dumps ~87 ok lines that carry no information.

    go build ./... 2>&1 | tail -20
    go test ./... 2>&1 | grep -vE '^ok |no test files' | tail -40
    golangci-lint run ./... 2>&1 | tail -40

    Empty output means the step passed — say so and move on; do NOT re-run verbosely to confirm. Only if a step reports a failure, re-run that one package or linter verbosely to get the detail needed to fix it. (These are the go-gui-org conventions; adjust only for a non-Go repo.)

Commit & PR

  1. Commit any uncommitted tracked changes. Only ask before committing if what the changes contain (not the workflow) is unclear — e.g. the diff includes unrelated files. Push the branch to origin.
  2. Open the PR with gh pr create — title + body summarizing the change.
  3. Wait for CI:
    • First, check whether CI is configured: use the Glob tool with pattern .github/workflows/*.{yml,yaml} (NOT a shell glob — ls fails silently in zsh when one pattern has no match). If no workflows exist, skip CI waiting — the repo has no checks.

    • If workflows exist, wait for CI without streaming. gh pr checks --watch re-emits the whole check table on every refresh, which is the single most expensive thing this skill does. Use a quiet poll instead:

      gh pr checks --watch --fail-fast > /dev/null 2>&1; gh pr checks

      The redirect discards the stream; the trailing gh pr checks prints the final table once. If it reports "no checks reported", CI may not have started yet — poll gh pr checks with a 30s retry loop before accepting the result. Never interpret "no checks reported" as "no CI exists".

    • For a red check, classify runner noise (CPU/timing jitter) vs real regression before re-running vs fixing.

Merge & cleanup

  1. Merge once checks pass (gh pr merge). Note the merge strategy used.
  2. Clean up: switch to base, pull, delete the local branch. For a squash merge the local branch won't show as merged — verify the PR is merged via gh pr view --json state before forcing the local delete, then prune the remote ref.

Report a final status: PR URL, merge strategy, CI outcome, branches deleted.

If $ARGUMENTS is provided, use it as the PR title/context.

name simplify
description Four-agent cleanup pass over a diff — reuse, simplification, efficiency, and altitude findings, then the fixes are applied directly. Use when the user says "simplify", "clean up the diff", "tighten this code", "reduce duplication", "make this less convoluted", or asks for a quality pass over changed code. Improves quality of changed code — NOT bug hunting (that is review-changes / code review).

Simplify

Quality pass over changed code: reuse, simplification, efficiency, altitude. Correctness bugs are the review skill's job — if the pass turns up one, note it and move on; do not fix it here.

Pipeline

Phase 0 — Gather the diff

Determine the target and capture the file set. Every later step operates ONLY on these files — never edit other packages.

  1. git diff @{upstream}...HEAD; fall back to git diff main...HEAD, then git diff HEAD~1.
  2. If git diff HEAD reports uncommitted changes — or the range diff came back empty — also capture those: the pass often runs pre-commit.
  3. $ARGUMENTS overrides the target: a PR number, a branch name, or a path argument selects the diff to review instead.

Save the file list (git diff --name-only) — it is what the four agents receive.

Phase 1 — Review (4 agents, launched concurrently in one message)

Launch all four subagents in a single message so they run in parallel. Each is report-only: it returns findings, never edits. Give every agent:

  • the changed-file list (and how to view the diff themselves)
  • its angle (below)
  • the output format
Angle Looks for
Reuse New code re-implementing existing helpers; greps shared/utility modules and adjacent files, names the helper to call instead
Simplification Redundant/derivable state, copy-paste with variation, deep nesting, dead code
Efficiency Redundant computation, repeated I/O, needless sequencing, blocking work on startup/hot paths; long-lived closures retaining enclosing scope (prefer a struct copying only needed fields)
Altitude Fix depth — special cases layered on shared infrastructure signal the fix should generalize the underlying mechanism

Output format per finding:

<file>:<line> — <one-line summary> — <concrete cost> — <suggested fix>

Concrete cost means the actual downside in the repo's terms: allocations per frame, a duplicated helper that will drift, N copies of the same special case that all need touching to change the rule. Costless or stylistic nits are not findings.

Per-agent brief template:

You are the {Angle} reviewer in a simplify pass. Report-only: do NOT edit
anything.

Changed files: <list>

Run `git diff <range>` (and `git diff HEAD` if noted) to see the changes, then
read surrounding context as needed. Find findings ONLY in the changed files.

Your angle: <table row>. {Reuse: also grep shared/utility modules and adjacent
files for an existing helper that does what the new code does; name it.}

Return findings as:
<file>:<line> — <one-line summary> — <concrete cost> — <suggested fix>
One per line. Nothing that changes intended behavior. If you find nothing,
say so in one line.

Phase 2 — Apply

  1. Wait for all four agents. Deduplicate findings that hit the same line/mechanism (the Altitude and Simplification agents often converge).
  2. Fix directly. When two suggested fixes conflict, keep the one that removes more special-casing.
  3. Skip — and note, without arguing — anything that would change intended behavior, reach well outside the diff, or is a false positive.
  4. Verify: build, run the suite, and lint (adjust per repo, e.g. go build ./..., go test ./..., golangci-lint run ./...). Do not proceed on red; revert a stage's fix if it introduced a regression.
  5. Close with what was fixed vs skipped. Leave the changes uncommitted — the user commits separately.

Guardrails

  • Minimal scoped diffs. No cosmetic churn, no drive-by edits, no widening of scope.
  • Bug hunting belongs to the review skill. A real bug found here gets a one-line report in the summary, not a fix.
  • Watch the known failure modes of an eager simplify: recursion introduced by collapsing a call chain, regressions in behavior that has no test to catch it (rendering, layout, focus), and "unused" wiring deleted because its only caller is a framework or callback the analysis could not see.
  • Reuse the repo's existing helpers instead of adding near-duplicates; delete dead abstraction; pitch each function at one consistent altitude.

Caveats

  1. This skill spawns four subagents by design — the sanctioned exception to "don't spawn unless asked".
  2. Name collision. A different, report-only simplify skill exists as an x-cmd preset (x-cmd mod slash/lib/preset/simplify). It never edits files and runs a single agent; this skill is the one that reviews AND applies.
name sync-siblings
description Propagate the latest go-glyph/go-gui across all go-gui-org sibling repos in topological order — release upstream tags, bump + ship every consumer, verify CI green and local repos synced. Triggers - bump siblings, update go-glyph/go-gui everywhere, sync sibling deps, propagate dependency versions.
user_invocable true

Propagate the latest go-glyph and go-gui across every go-gui-org sibling repo, robustly, leaving all local repos clean and synced with green CI. This skill exists because ad-hoc bumps keep failing the same ways: deps edited but not pushed; pushed but CI red on a stale generated file or a hardcoded workflow; a repo left out; local repos never synced back.

Before anything else: use todowrite to create a tracker — one item per phase, plus one item per consumer repo in Phase 3. Mark each in_progress/completed as you go.

Invariants — enforce in every phase

  • Not done until reconciled. A bump is complete only when: PR merged and local main pulled and go.mod on fresh main shows the target version. Never stop at "edited" or "pushed".
  • GOWORK=off for all verification. Run every go build/test/vet/ mod tidy/get/list and every make gate with GOWORK=off. Several repos have a gitignored go.work (go-gui, go-edit, go-kite) that resolves siblings from local working trees — that masks failures CI will hit against published modules. GOWORK=off makes local match CI.
  • Strict topological order. glyph tag → gui tag → consumers. Never bump a consumer to an upstream version that is not yet a published, proxy-served tag.
  • Dynamic discovery, never a hardcoded repo list. Recompute the consumer set each run (below) and print it with a count. If it differs from what you expect, say so — this is the guard against leaving a repo out.
  • Mirror CI locally before pushing. After a bump, regenerate the repo's derived artifacts and run that repo's own gate, not just build/test. If the repo has a Makefile, inspect .github/workflows/*.yml for the make … the gate runs and run those exact targets. If a workflow regenerates a file then git-diffs it (*-check, or go generate ./... + diff), run the generator and commit the regenerated file in the same PR. (This is the fix for the go-gui deps-doc-check failure — docs/dependencies.md is generated from go.mod.)
  • Idempotent. A repo already on the target versions is a logged no-op. Safe to rerun after a mid-run failure — re-derive state, don't assume it.
  • Reuse the ship and release skills for PRs and tags; do not reinvent their commit/CI-watch/merge/cleanup logic.

Phase 0 — Preflight (all sibling repos)

Resolve SIBLINGS_ROOT = parent dir of the invoking repo (fallback ~/Documents/github). Then:

cd "$SIBLINGS_ROOT"
# Consumers: siblings with a DIRECT (non-indirect) require on glyph or gui,
# excluding the two upstream libs themselves.
for d in */; do gm="$d/go.mod"; [ -f "$gm" ] || continue
  mod=$(head -1 "$gm" | awk '{print $2}')
  case "$mod" in */go-glyph|*/go-gui) continue;; esac
  deps=$(grep -E 'go-gui-org/go-(glyph|gui) ' "$gm" | grep -v '// indirect' \
         | awk '{print $1"@"$2}' | paste -sd, -)
  [ -n "$deps" ] && printf '%-14s %s\n' "$d" "$deps"
done

Print the resolved UPSTREAM = [go-glyph, go-gui] (fixed order) and the discovered CONSUMERS with a count. For every repo (upstream + consumers): git -C <r> fetch --all --tags, then require a clean working tree and main even with origin/main. Abort and list any repo that is dirty, ahead/behind, or detached — do not mutate a dirty workspace.

Phase 1 — go-glyph (root)

GLYPH_VERSION=$(git -C go-glyph ls-remote --tags --refs origin \
  | awk -F/ '{print $NF}' | grep -E '^v[0-9]' | sort -V | tail -1)

If origin/main is ahead of GLYPH_VERSION (commits since the tag): PAUSE. Show the commit list and ask whether to cut a glyph release (invoke the release skill inside go-glyph) or propagate the existing tag. Never tag go-glyph unattended. Record the final GLYPH_VERSION.

Phase 2 — go-gui

Compare go-gui/go.mod's glyph require to GLYPH_VERSION.

If behind:

  1. Branch off fresh main.
  2. GOWORK=off go get github.com/go-gui-org/go-glyph@$GLYPH_VERSION
  3. GOWORK=off go mod tidy
  4. Regenerate + mirror the gate (the step skipped in the failure that motivated this skill): GOWORK=off make deps-doc to refresh docs/dependencies.md, then run the workflow's gate verbatim — GOWORK=off make vet deps-doc-check large-files generate-check — plus GOWORK=off go build ./... && GOWORK=off go test ./.... Re-read .github/workflows/ci.yml for the current gate target list in case it changed; run whatever it runs. Stage every regenerated file (esp. docs/dependencies.md).
  5. Ship the PR via the ship skill (commit, push, watch CI, squash-merge, pull main).

Then, whenever go-gui's main is ahead of its latest tag and that delta must reach consumers (always true after a glyph bump), cut a go-gui release via the release skill so the change is exposed as a tag.

GUI_VERSION=$(git -C go-gui ls-remote --tags --refs origin \
  | awk -F/ '{print $NF}' | grep -E '^v[0-9]' | sort -V | tail -1)
# Wait out module-proxy lag before any consumer bump:
until GOWORK=off go list -m github.com/go-gui-org/go-gui@$GUI_VERSION >/dev/null 2>&1
do sleep 15; done

Record GLYPH_VERSION and GUI_VERSION — the targets every consumer bumps to.

Phase 3 — Consumers (each discovered repo, independent todo item)

Process each consumer independently so one failure never hides the others. For repo R (in $SIBLINGS_ROOT/R):

  1. Branch bump-deps-$(date +%Y%m%d) off freshly pulled main.

  2. GOWORK=off go get only the deps R actually uses (from the Phase 0 discovery): github.com/go-gui-org/go-glyph@$GLYPH_VERSION and/or github.com/go-gui-org/go-gui@$GUI_VERSION.

  3. GOWORK=off go mod tidy.

  4. Bump any workflow ref: that pins the upstream you just bumpedgrep -rn -A6 'repository: go-gui-org' .github/workflows/. A pinned replace overrides go.mod, so skipping this makes CI go green while testing the old version; the bump ships unexercised. Every workflow that pins it, not just ci.yml. Unpinned checkouts (no ref:) track main and need no edit — but note their green does not prove the tag either.

  5. Mirror R's CI locally. Base verify: GOWORK=off go build ./... && GOWORK=off go test ./... && GOWORK=off go vet ./.... If R has a Makefile, also run the gate targets its .github/workflows/*.yml invokes, and commit any regenerated file. (Today only go-gui has such a gate, but check every repo — this future-proofs.)

  6. Ship via the ship skill → commit, push, PR, watch CI, squash-merge, delete branch, pull main. Prefer ship (or gh pr checks <n> --watch) for a single PR. When polling several consumer PRs in one loop, decide pass/fail from the gh pr checks exit code (0 = all passed; non-zero = still pending or failing), never by grepping stdout for fail/ error — gh prints a Failed: 0 summary line whose substring produces false "failure" readings. If distinguishing pending from failed, match the per-row status column (--json state, or an anchored \tpass\t/\tfail\t field), not a bare substring.

  7. Red-CI triage — classify before re-running or editing:

    • module@version not found → proxy lag from Phase 2; wait and retry the bump/go get.
    • Generated/derived file out of date (*-check diff, deps-doc, or go generate gate) → run the generator, commit, update the PR.
    • Hardcoded workflow assumption — a repo's CI checks out an upstream and go mod edit -replaces onto it, so the workflow's ref, not go.mod, decides what is compiled. Either polarity breaks (see below) → fix the workflow in the same PR, do not work around it.
    • Runner/timing flake → re-run once before treating as a regression.

    replace-based CI: two opposite failures. Re-derive each repo's refs at run time (grep -rn -A6 'repository: go-gui-org' <r>/.github/workflows/) — do not trust this list, it drifts:

    repo → upstream ref today failure mode
    go-gui → go-glyph unpinned (setup-go-glyph/action.yml, no ref:) tracks glyph main TIP. Glyph main advancing reds go-gui PRs before any bump; green does not prove the published tag.
    go-charts → go-gui pinned (ci.yml, gallery.yml) stale pin silently validates nothing.
    go-charts → go-glyph pinned (ci.yml, gallery.yml) same.

    The pinned case is the dangerous one and is not caught by a red CI: the replace overrides go.mod, so a go get-only bump leaves CI compiling against the old pinned tag and going green — the bump is never exercised. When bumping a repo whose CI pins an upstream, bump the workflow ref: in the same PR, in every workflow that pins it (go-charts has two: ci.yml and gallery.yml). If the upstream release is breaking, skipping this instead goes red with a confusing error: migrated source compiled against the pre-migration API.

    Either way, a replace-based green proves less than it appears. Trust the GOWORK=off local verify and the published-version consumers (go-edit/go-kite/go-map/go-term) for real coverage.

Phase 4 — Final verification (anti-drama gate)

Re-git fetch and re-run the Phase 0 discovery grep against fresh main for every consumer. Assert glyph == GLYPH_VERSION and gui == GUI_VERSION where each is used. Assert every repo (upstream + consumers): clean tree, on main, even with origin/main, no leftover bump-deps-* branch local or remote.

Also assert no workflow pins a superseded versiongo.mod matching the target while CI still pins the old tag is the silent-green case from Phase 3 step 4, and it survives every other check here:

cd "$SIBLINGS_ROOT"
grep -rn -A6 'repository: go-gui-org' */.github/workflows/ */.github/actions/*/ \
  2>/dev/null | grep -E 'repository:|ref:'

Read it in pairs: each repository: line and the ref: that follows it. A repository: with no ref: before the next one tracks main (expected for go-gui → go-glyph). Every ref: that does appear must equal $GUI_VERSION / $GLYPH_VERSION. A stale one means that repo's green CI never compiled the version its go.mod claims to require.

Emit a final table — repo | glyph | gui | PR URL | CI | local-synced — and call out explicitly any row that is not fully reconciled. The run is not "done" until every consumer matches the targets and every local repo is clean and pulled.

If $ARGUMENTS is provided, treat it as an override for the target versions (e.g. a specific glyph/gui tag to propagate instead of newest).

name test-gaps
description Find test gaps in uncommitted code changes. Reports untested public functions, missing edge cases, and uncovered error paths.
user_invocable true

Analyze all uncommitted changes (staged and unstaged) for test coverage gaps:

Steps:

  • Run git diff and git diff --cached to identify changed/added files and functions
  • For each changed file, find the corresponding _test.go file (if any)
  • Read the changed code and existing tests to understand current coverage
  • Report gaps grouped by severity:

Missing tests (no test exists):

  • New exported functions or methods with no corresponding test
  • New unexported functions with non-trivial logic and no test

Missing edge cases (test exists but incomplete):

  • Error return paths not exercised
  • Boundary values: zero, negative, empty, nil, max-size inputs
  • NaN/Inf float inputs (for numeric code)
  • Single-element and two-element cases for slice/collection code

Missing integration tests:

  • New cross-package interactions without an integration test
  • New I/O paths (file, network) without a test that exercises them

For each gap:

  • State the file:function and what is untested
  • Rate as high (crash/panic risk), medium (silent wrong result), or low (cosmetic)
  • Suggest a one-line test name (e.g., TestExportSVG_EmptySeriesNoPanic)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment