Skip to content

tech-debt Wave 3: trigger-gated backlog (18 findings, deliberately not scheduled) #177

Description

@mmcky

These 18 findings from the 2026-07-23 technical-debt audit are deliberately not scheduled. Each is real and verified, but acting on any of them now would be speculative — each has a trigger that makes it worth doing, and until that trigger fires the cheapest correct action is to leave it alone.

This issue exists so they are not rediscovered by the next audit. It is a tracking parent and carries no Type label; convert an entry to its own issue when its trigger fires.

Waves 1 and 2 are in the Technical debt — 2026-07 audit milestone.

# Finding Sev Effort Trigger
F35 Jest runs in a CJS island with node10 resolution; production's ESM/node16 boundary is untested high L/m An ESM-only dependency becomes required, or an advisory lands against @actions/core 2.x / @actions/github 8.x. Not for testing index.ts — T1 solves that. Also unblocks F59's oracle
F50 evaluateDiff still parses model JSON through any; a missing key gives no "the model never answered" signal low s/s Bundle into the next review-verdict.ts change
F114 init bootstraps every new edition; ~436 of ~560 executable lines have no test entry point, at 23.7% branch med s/m Next time init.ts is opened for a behaviour change. Both entry points are already exported — the whole cost is the tmpdir harness
F49 The empty-PR short-circuit is undocumented: a PR changing no markdown still emits review-verdict: PASS low t/t Bundle into the next review-verdict.ts change
F23 The F107 localization defence and the --localize rule set are CLI-only; the Action's sync path sets no customInstructions med m/m The first merged sync PR that reverts a localized code cell or figure label (the F97 pattern). Pull into T2·3 if it fires sooner
F14 Localization reaches the model only from init, and the one free-text slot is double-booked with forward's pinning low s/m After T5 lands and someone asks for a localized edition to stay localized through ongoing sync
F25 Three incompatible "don't really do it" concepts; forward — the only command that force-pushes — has neither med s/m Before the next 40+ file drift-recovery wave
F56 Section prompts re-send the same ~6.5K-token prefix uncached on every call low s/s When a bulk wave's input-token bill becomes worth an afternoon; measure first
F62 No prompt-cache breakpoint on the static prefix — re-billed at full input price low s/s When a bulk wave's input-token bill becomes worth an afternoon; measure first
F9 Two glossary loaders remain — deliberately different candidate sets, duplicated read/parse code low s/s Only if a third consumer appears. The two that exist differ deliberately — see §6
F96 All 7 npm advisories trace to one EOL devDependency chain; no baseline note records that low m/m The audit-baseline note rides in Wave 1 PR K; dependabot next quiet week; the ESLint 9 migration when a plugin drops .eslintrc support
F34 ESLint 8 (EOL) + @typescript-eslint 6 is the sole source of all six high advisories low s/s The audit-baseline note rides in Wave 1 PR K; dependabot next quiet week; the ESLint 9 migration when a plugin drops .eslintrc support
F101 No dependabot or renovate config — dependency drift has no automated discovery channel low t/t The audit-baseline note rides in Wave 1 PR K; dependabot next quiet week; the ESLint 9 migration when a plugin drops .eslintrc support
F97 deploy-docs.yml runs an unpinned npm install -g mystmd in a job holding pages: write low t/t Bundle into the next CI edit; they are one line each
F98 Zero of seven third-party action uses are SHA-pinned; each is 1-3 majors behind low t/t Bundle into the next CI edit; they are one line each
F100 chalk is pinned at ^4 because of the CJS harness — load-bearing and undocumented low t/t Bundle into the next CI edit; they are one line each
F73 The 2,100-LOC e2e eval harness has no type-check gate anywhere low t/t Next time the eval harness is run and fails at run time, or the next scripts/glossary edit
F107 12,159 tracked LOC live in side trees every gate skips — including the hand-copied glossary formatter low s/m Next time the eval harness is run and fails at run time, or the next scripts/glossary edit

Three worth reading before acting

F35 (Jest → ESM/Vitest) is the largest item in the audit, and its trigger matters: do it when an ESM-only dependency becomes required, or when an advisory lands against @actions/core 2.x / @actions/github 8.x. Not in order to test src/index.ts — that is what T1 (#169) solves, at a fraction of the cost.

F9 (two glossary loaders) should be acted on only if a third consumer appears. The two that exist differ deliberately: the CLI adds repo-local candidates because it runs inside a checkout; the Action does not, because it reaches the target repo over the API and uses glossary-path. Documented at docs/user/glossary.md:76-86. v0.23.0 already collapsed four loaders with three behaviours down to these two — unifying further would reintroduce CWD-relative lookup in the Action.

F100 (chalk pinned at ^4) is load-bearing, not stale: ^4 is the last CJS release and the ts-jest CJS harness requires it. That it is undocumented is the actual defect, and a one-line comment prevents a well-meaning upgrade.


From the technical-debt audit of 2026-07-23 (141 candidates adversarially verified, re-validated against v0.23.0, 139 live). Effort is stopgap / full — t≈0.5h, s≈3.5h, m≈11h, L≈28h.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions