Skip to content

docs: record audit remediation in CHANGELOG, fix stale schema claim - #2

Merged
ra-co88 merged 1 commit into
developfrom
chore/audit-docs-and-changelog
Oct 10, 2026
Merged

ra-co88 merged 1 commit into
developfrom
chore/audit-docs-and-changelog

Conversation

@ra-co88

@ra-co88 ra-co88 commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Fork-internal housekeeping. Not for upstream yet — the fork still needs an upstream sync and a branch-consolidation pass before any contribution is proposed.

What

The audit remediation landed on main in PR #1 (d08a6928 backend security, 91545401 dashboard a11y/theme) without a CHANGELOG entry, leaving [Unreleased] empty across 87 changed files of user-facing behaviour. CONTRIBUTING.md requires a changelog entry for user-facing changes.

  • CHANGELOG.md — fills [Unreleased], grouped as 安全 / 修复 / 可访问性 / 界面. Each bullet is tagged with the originating finding ID (SEC-, A11Y-, UI-, GATE-, FE-, RACE-) for traceability back to the audit.
  • AGENTS.md:223 — the schema-version note claimed v == 7; the assertion in tests/unit/db/test_db_pool.py is v == 17 (migrations dir is at 017). Anyone following that line would have edited the wrong assertion.

Scope

Documentation only — 2 files, +40/−1. No code, no schema, no dependency changes.

Verification

Pre-commit gate (make precommit + npm run build) run in full, no bypass:

  • format-all, make lint, make typecheck (mypy --strict, 517 files) — clean
  • testmon: 3744 passed, 50 skipped, 0 failed in 48:41
  • npm run build — succeeded (49.35s)
  • tsc -b — clean

Follow-ups tracked separately

  • develop did not exist on this fork (PR Feature/audit a11y reliability #1 merged feature/* straight into main); it has since been created from main, so this branch is correctly based.
  • Open items before upstream contact: sync develop with upstream/main (46 commits behind), consolidate 14 stranded fix branches, and fix AgentSelector.tsx:120 — a react-hooks/rules-of-hooks violation introduced by 91545401, still unreproduced.

The audit remediation landed on main in PR #1 (d08a692 backend security,
9154540 dashboard a11y/theme) without a CHANGELOG entry, leaving
[Unreleased] empty across 87 changed files of user-facing behaviour.
CONTRIBUTING.md requires a changelog entry for user-facing changes.

- CHANGELOG: fill [Unreleased] with the security, reliability,
  accessibility and theme-token changes, grouped by theme and tagged
  with the originating finding IDs for traceability.
- AGENTS.md: the schema-version note claimed `v == 7`; the assertion in
  tests/unit/db/test_db_pool.py is `v == 17` (migrations dir is at 017).
  Anyone following that line would have edited the wrong assertion.

Docs only. Ship bar re-verified on this tree before the commit:
make all = format-all/lint/typecheck clean + 3744 passed, 17 skipped;
tsc -b clean.
@ra-co88
ra-co88 merged commit 451a8f9 into develop Oct 10, 2026
@ra-co88
ra-co88 deleted the chore/audit-docs-and-changelog branch October 19, 2026 20:39
ra-co88 added a commit that referenced this pull request Oct 19, 2026
…hed-node race, and a DOMMatrix collection crash (#23)

The reported symptom was ONE intermittently failing test. Root-causing it found
FOUR defects across three causes. Full diagnosis:
.agents/audit/vitest-intermittency.md

## 1. Worker-pool starvation (the actual cause of the intermittency)

`pool: "threads"` opens up to cpus-1 workers - 7 on an 8-core machine. Under that
contention, timing-sensitive assertions failed in files that pass BOTH alone and
in small groups. Bound the pool and the suite goes green AND gets faster:

  default pool   -> 2 failed files / 10 failed tests / 597s
  maxWorkers: 3  -> 253 passed  / 1331 passed     / 277s

Faster because the run is dominated by setup/environment time, not parallel
throughput: the workers were contending, not scaling.

## 2. A detached-node race in AuthGuard.test.tsx

Reported as flaky; it was deterministically broken under parallelism. The test
took an instantaneous snapshot - `await screen.findByText(...)` then
`.toBeInTheDocument()` - of a node it EXPECTS to churn (NavProbe navigates on
every render, so the shell is briefly replaced by the gate spinner). When that
landed in the window, findByText resolved, the node detached, and the matcher
failed in ~25ms.

That duration is what disproved my first hypothesis. findByText cannot resolve
early with a failure - @testing-library/dom retries until its deadline and then
reports "Timed out in waitFor" - so a 25ms failure meant the element WAS found and
then removed. My initial fix (raising the timeout to 5000ms) still flaked 1 in 3,
which is what sent me back to the timing evidence. Replaced with a `waitFor` that
re-queries, which is also what the test already did two lines below.

Mutation-verified: original form fails 8/8, waitFor form passes 8/8.

## 3. DOMMatrix missing, breaking whole files at COLLECTION

pdfjs-dist instantiates a transform at module scope
(node_modules/pdfjs-dist/build/pdf.mjs:9387, `const SCALE_MATRIX = new DOMMatrix()`).
jsdom ships no DOMMatrix, so merely importing react-pdf throws during collection -
reported as a whole-file failure with "Tests: no tests", so the real tests never
run at all.

This reached far past the PDF components: a plain .ts test with no DOM
(pages/Agent/Skills/skillMarkdown.test.ts) died because it imports a helper from
components/SkillDrawer, which renders react-pdf. Same for AuthGuard.test.tsx and
Settings/Models/ModelListEditor.test.tsx.

Stub added to src/test/setup.ts beside the existing matchMedia / ResizeObserver /
IntersectionObserver shims - that is what the file is for. Deliberately minimal:
the module-scope constructor is the no-arg form and only .a/.d are read (both
identity 1). A full transform implementation would be untested scaffolding.
Mutation-verified: removing it restores the ReferenceError.

## 4. A lazy-import latency vs waitFor's 1000ms default

TrajectoryInspector renders Preview through LazyMarkdown (React.lazy ->
import("./index")). A cold import of that chunk measures 2086ms; waitFor's default
is 1000ms (asyncUtilTimeout, @testing-library/dom config.js:15). The assertion
therefore could only pass when another file in the worker had already warmed the
chunk. Given an explicit 5000ms budget.

Proven causally with an artificial 2.2s import delay: the unpatched assertion
fails at 1140ms, the patched one passes.

## Rejected: raising testTimeout to 15000

Tried and reverted. The flagging failures were starved, not slow, and #2 is a race
no budget can fix. A generous timeout turns a hard failure into a slow pass
without removing the race - worse for diagnosis, not better.

## Verification

  cd dashboard && npx tsc -b     # clean
  cd dashboard && npx vitest run # 253 files / 1331 tests, 277s

Baseline on pristine develop for comparison: 4 failed files / 1 failed test, and
three files that could not even collect.

Co-authored-by: pt-act <211776491+pt-act@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants