architecture.md: 138 components, counted as the .tsx files of
src/components outside tests (find src/components -name '*.tsx'
! -name '*.test.tsx' | wc -l), was 61; per domain, balance 12 with its
actual names (BalanceOnboardingCard is gone), categories 8, reports 35,
and the missing categories-migration/ line (5). The /reports hub has 5
navigation cards, named. The useImportWizard row says SET_IMPORT_FOLDER
empties rootFiles and keeps the scanned sources until the next scan.
"La mise en évidence" notes that a Ctrl+click on the Trends card fires
onClick, so it checks the "Browse the reports" step while the router
does not navigate; judged theoretical without tabs in the webview.
CLAUDE.md: 138 components (was 53), import 18 (was 14).
CHANGELOG (EN, FR): Changed for the help texts, Fixed for the root
files warning after choosing another import folder.
Resolves#446
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
architecture.md: the Tauri commands recounted from generate_handler! (45,
was 39), with the five that were never named documented in new sections
of their modules (feedback_commands.rs: send_feedback,
get_feedback_user_agent; backup_commands.rs: ensure_backup_dir,
get_file_size, file_exists) and fetch_price described as it is, not as
"to come in Phase 5" (also in the balance service and the tree's command
modules, now 10). Hooks: 29 files, the three undocumented ones added to the
table. The Transactions empty state reads the count alone (D1), the mount
reads stand alone, and the sample folder flow describes its codes, its
errorValues and its Journal line.
CLAUDE.md: 29 hooks in the tree. Guide and docs.gettingStarted.steps:
"the keywords that come with the app" instead of the seed jargon.
CHANGELOG (EN, FR): Changed for the Transactions card, Fixed for the sample
folder messages and banners.
Resolves#384
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
User guide (section 11) and the in-app docs.settings keys, FR and EN: the
order of Settings → System and how the version history folds. One Changed
entry in both changelogs. docs/architecture.md: the /settings/systems row,
why ChangelogContent keeps a local Set rather than useCollapsibleGroups,
and the utils count (19: startupConnection and rootFiles were not counted).
CLAUDE.md no longer describes /changelog as a page with the full history:
it redirects to Settings → System since #190.
Resolves#372
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Release skill, step 2: right after the hand edit of Cargo.lock and
before the windows-sys guard, `cargo metadata --format-version 1
--locked` must exit 0, since the tag builds with -- --locked and the
release commit goes to main without a pull request. Step 0 runs cargo
check and cargo test with --locked, like CI, so the pre-flight cannot
fold a lockfile rewrite into the release commit.
- ADR 0023: the windows-sys guard reads the committed lockfile, cargo
check having already refused one it would have had to rewrite.
- CLAUDE.md, REVIEW.md and docs/architecture.md: CI commands with
--locked, release builds on the committed lockfile, cargo-xwin pinned
(REVIEW.md said it was installed unpinned), the stale REVIEW.md
sentence about #449 removed, and why the dormant .github mirror is
not aligned.
Resolves#449
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-ups of the review of PR #418.
- check-latest-json.jq wants exactly one document and release.yml calls it
with -s: under jq 1.6, the release container's, an empty file passed the
check (no output, status 0) and two documents were judged on the last one,
so the job would have deleted the published manifest and uploaded the bad
one. Two tests cover both cases.
- build-latest-json.test.mjs runs the text of release.yml's "Publish
latest.json to package registry" step against a fake curl: DELETE then PUT
on a valid manifest, exit 1 and no request on a refused one.
- check-frontend no longer ignores .claude/** and release.yml (decision of
Max): the test reads verify-release.sh and runs the Publish step, so "on
every pull request" holds. REVIEW.md, CLAUDE.md and architecture.md follow.
- release.yml: stale ".deb fallback" comment fixed.
- qa-update-cycle.md: a tauri dev build on Linux shows TargetsNotFound,
expected since #418.
Refs #461Resolves#419
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
REVIEW.md sets the review level of a PR from the files its diff touches
(high, normal or low; the highest wins, never the author), lists what
matters in each zone with its source (a CLAUDE.md section or an ADR,
completed by the repo file where the fact lives), the verification
commands of the CI, and the review pitfalls of this repo. The pitfalls
taken from the global pr-review skill are corrected for this repo:
stacked PRs do get CI here since #232.
Calibration on the merged PRs #344 to #452: the 39 reference PRs of the
pilot document come out 3 low / 28 normal / 8 high (20.5 %, target
20 %), the whole range of 51 PRs 6 / 33 / 12 (23.5 %), against 3 / 19 /
17 with the trial patterns. A lockfile-only version bump of a package
already present stays normal, per Max's decision of 2026-10-17.
CLAUDE.md points to the file.
Fixes#456
Note: plan check bypassed after 3 passes, last findings applied (Max's
decision of 2026-10-18).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up of PR #417. CLAUDE.md and docs/architecture.md said
nothing re-evaluates `npm audit` in CI. No job fails on it, but the
`npm ci` step of check-frontend audits on every run and prints the count
(run 520: found 0 vulnerabilities; runs 512 and 519: 8), and the
Defenseur reports advisories on its side, which is where #358 came from.
Refs #358
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm audit reported 8 vulnerabilities (5 high, 3 moderate) on the lock
of main: react-router and react-router-dom (one advisory,
GHSA-qwww-vcr4-c8h2), vitest and @vitest/mocker (one advisory,
GHSA-82fw-gwwq-j7x9), browserslist, baseline-browser-mapping, nanoid
and source-map-js. Every fix sits within the range package.json
already declares, so only the lock moves; package.json is untouched.
Lock generated with npm 11.21.0 exactly:
npx --yes npm@11.21.0 update react-router-dom react-router vitest \
@vitest/mocker browserslist baseline-browser-mapping nanoid \
source-map-js --package-lock-only --ignore-scripts
259 entries before and after, 20 changed, each resolved from
registry.npmjs.org with a new sha512 integrity. npm ci, under npm 10
and under npm 11.19.0, leaves the lock as is; npm audit: 0.
Only react-router 7.18.1 -> 7.18.4 changes the built app: a build from
a lock where only react-router moved equals the full build byte for
byte. Since 7.18.3, useNavigate() and <Navigate> reject a navigation
to another origin; the app only navigates to internal paths.
CLAUDE.md and docs/architecture.md no longer describe 2 high
advisories accepted for good: npm audit is at 0 on 2026-10-10, a
dated reading that nothing re-runs in CI.
Resolves#358Resolves#317
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seven crates in Cargo.lock accept windows-sys through a wide bound
(colored, dirs-sys, errno, rustix, rustls-platform-verifier, tempfile,
winapi-util), so cargo may point them at any windows-sys version already in
the graph. All seven point at 0.61.2, the state every Windows release has
shipped with since v0.14.0. Some updates re-resolve them (cargo update -p
hyper, -p h2, -p rustls-webpki -p tar did) down to 0.48/0.52/0.59 while
cargo only reports the packages it bumped: the Windows build then compiles
five windows-sys versions instead of three, and nothing says so.
A new blocking step, "Verify windows-sys pinning", reads the lockfile with
awk right after the suppression guard and fails if any edge of the seven
crates leaves 0.61.2 (a bare edge only passes when the lockfile holds a
single windows-sys, at 0.61.2), if a guarded crate has no block, or if the
set of windows-sys versions changes. awk's exit code is tested apart from
its output, every check is logged with a summary line, and a canary
(tempfile) must be read and checked by the loop.
The step text was extracted from the YAML and run as is, with the runner's
bash options, on copies of the lockfile: main's and the five release tags'
locks pass (9 checks, exit 0); the hyper-bumped lock, an added
windows-sys 0.53.0, a renamed guarded crate, a missing lockfile and a
guarded list without the canary all exit 1.
ADR 0023 records why 0.61.2, the measured cost (3 versions compiled for
Windows instead of 5), the triggers, the exit condition (windows-sys 0.62,
or convergence on a single version) and the repair when the step fails.
CLAUDE.md and docs/architecture.md cite the guard next to the suppression
check. Cargo.lock and .cargo/audit.toml are untouched.
Resolves#345
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0021 records the catch-up rules and amends ADR 0003 and 0005, whose
claims about secondary profiles were false. architecture.md, CLAUDE.md
and the migration rule describe the two migration paths; the guide tells
where the pre-update copy lives and how to remove a database a deletion
on Linux left behind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Applies the three suggestions of the review of #375:
- The runner's cleanup keeps one entry per key, whatever its scope: a PR
run that saves under the shared entry's key evicts it for every PR until
the next Monday, and two PRs on the same non-main lockfile evict each
other. Added to the list of cold runs.
- The cache key also hashes the job's CARGO*/RUST*/CC*/CFLAGS*/CXX*/CMAKE*
variables, and ignores the app's own version: changing env: means a cold
run until Monday, a release does not.
- A Monday restore that fails with a 404 after a quiet week is a known
runner race (forgejo/runner#1741), not #234 coming back.
Refs #234
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md and docs/architecture.md still said the Actions cache was
removed until #234 was fixed. They now describe rust-cache, the per-PR
isolation of what a pull_request run saves, the weekly run on main that
writes the shared cache, the expected cold runs, and why check-frontend
has no npm cache. The audit.yml paragraph no longer quotes the outdated
"1 PR in 40" figure.
Refs #234
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump 0.14.0 -> 0.15.0 in the five manifests, open the 0.15.0 section in
both changelogs (17 entries: edition-based feature gating, the CSV import
rework with migration v17, three dependency advisory batches), and fix the
stale "Version actuelle" line in CLAUDE.md (was 0.6.3).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013CNa9VVF5C3y47MX1SSJ1S
Last link of the ten-link import-format stack. Links 1-9 deliberately wrote
no changelog and no documentation, to avoid a conflict at every level of a
linear pile; this link owes all of it.
- ADR 0019 records the structuring decision: the import format is a fully
persisted value, never re-inferred. It documents the three independent paths
by which it used to be lost (hardcoded restore, header drift, data export),
and why a single codec with a completeness test closes the class rather than
a composed type -- the two carriers are structurally incompatible
(`has_header` is boolean on one and number on the other). `template_id` is
recorded as a provenance label, never re-read as format.
- `docs/architecture.md` gains a dedicated "Import CSV" section covering the
codec, the lexical detection layer and its separate dictionary module, the
bank signatures, the now-mandatory preview step, and sources/templates in
the SREF envelope. Migration v17 and its four CHECK-guarded columns are
listed in the migrations table.
- Stale counts corrected against the tree, not by arithmetic: 16 -> 17
migrations (both files), `src/components/import/` 13 -> 14, `src/utils/`
4 -> 13. Tables (20) and indexes (24) were re-measured and are NOT stale --
v17 is an ALTER TABLE only -- so they are left as they are, with the reason
written down. ADR 0018, missing from the ADR table, is added.
- The user guide and the `docs.*` keys in both locales carry the same new
import journey: automatic detection, confidence score, mandatory preview
with its signed recap, sign inversion, recognised bank formats, drift panel,
and the safe repair path.
- Both changelogs carry the same entries, translated, verified section by
section including issue references. The `public/` copies sync automatically
via `syncChangelogs()`.
1176 vitest green, build clean, cargo check clean. No DB migration.
Resolves#332
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
npm update postcss moves it 8.5.13 -> 8.5.23, clearing GHSA-r28c-9q8g-f849
(path traversal in previous-source-map auto-loading via a sourceMappingURL
comment, arbitrary .map disclosure, 7.5 high). No overrides entry needed,
unlike #241: vite declares postcss ^8.5.3 and 8.5.23 is published, so the
existing range already permitted the fix and only the lockfile carried a
stale resolution. nanoid 3.3.11 -> 3.3.16 comes along as postcss's own
dependency, within its declared range.
postcss IS the CSS pipeline, so a green build only proves compilation. The
emitted stylesheet was diffed across the bump and is byte-for-byte identical
(same content hash, same asset filename).
The remaining react-router advisory (GHSA-qwww-vcr4-c8h2, RSC Mode CSRF
bypass) is accepted rather than fixed. It targets React Server Components,
which a Tauri desktop app never runs — App.tsx mounts a client-only
BrowserRouter and src/ has no createStaticHandler, StaticRouter or server
rendering. There is also nothing to move forward to: react-router-dom is
frozen at 7.18.1 since v8 merged the package into react-router, so npm's
proposed "fix" is a downgrade to 7.11.0, and leaving the affected range
means migrating to react-router v8. Re-evaluation trigger tracked in #317.
Unlike the Rust side, no CI gate is involved: check-frontend.yml runs no
npm audit step, so nothing turns red. That expectation is now written down
in docs/architecture.md and CLAUDE.md so the two permanent high findings do
not read as a regression.
npm audit: 3 findings -> 2 (high 3 -> 2), postcss cleared.
npm ci + npm run build + 871 vitest green.
Resolves#311
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cargo update -p rustls-webpki -p tar moves rustls-webpki 0.103.9 -> 0.103.13
and tar 0.4.44 -> 0.4.46, both within the existing Cargo.toml bounds. They sit
under tauri-plugin-updater, which downloads and unpacks application updates, so
all six of their advisories were reachable in the shipped binary.
The remaining three can neither be fixed nor reached. quick-xml (2x 7.5 high)
is pulled by plist, which tauri only needs for Apple bundling: its per-target
trees are empty for both shipped targets and it appears solely under
x86_64-apple-darwin. Its fix is >= 0.41.0 while plist requires ^0.38, a
semver-incompatible boundary [patch.crates-io] cannot cross. rsa has no
published fix at all and is never compiled — its only parent is sqlx-mysql, an
artifact of sqlx's multi-backend graph on a SQLite project.
Leaving those three to red the daily gate forever would reproduce the signal
loss that #232 removed the `|| true` to fix, so they move into a versioned
.cargo/audit.toml. Entries are keyed by advisory ID, never by crate, so a new
advisory against the same crate still reds the gate; each carries its
reachability proof and its removal condition.
A blocking step in check-rust.yml re-proves that justification on every PR
touching src-tauri/ or .cargo/, and fails if a suppressed crate enters a
shipped target's graph — the scenario that would rot the list is itself a
src-tauri change. It separates cargo tree's exit status from its output (an
absent crate and a failed invocation both print nothing) and asserts a canary
crate is still found, so its silence proves something.
cargo audit: 9 vulnerabilities -> 0, warnings unchanged at 23
(cargo-audit 0.22.2, advisory-db 0bfde9d6 of 2026-07-27).
cargo check + cargo test green (106 tests); npm build + 871 vitest green.
Resolves#310
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The rust job cost 21m44s on every PR while only ~1 PR in 40 touches
src-tauri/, and the runner has capacity 1 — the frontend job queues behind
it, so every PR paid ~24.5 min of feedback.
Measured on run 326 (2026-07-21), 12m15s of that was pure waste:
- 6m54s tarring target/ and the cargo registry for saves that time out
against the runner's unreachable cache server (#234). The restore times
out into a miss too, so nothing was ever cached at either end.
- 4m41s recompiling cargo-audit from source on every run.
- ~40s on the two doomed restores.
Split check.yml into check-rust.yml (paths: src-tauri/**) and
check-frontend.yml (paths-ignore denylist), drop every actions/cache step
until #234 is fixed, and install cargo-audit as a prebuilt binary via
taiki-e/install-action. The audit step keeps continue-on-error — advisories
are informational and can land on unrelated crates — but loses the `|| true`
that also hid tooling failures; the install step is blocking.
The frontend filter is a denylist on purpose: that job costs ~2.5 min, so
running it needlessly is cheap while silently not running it is not. The
expensive job keeps a strict allowlist.
Neither workflow filters on `branches:` anymore. `branches: [main]` never
matched a PR stacked on another feature branch, which is what /autopilot
produces: PRs #305-#308 of the feature-gating milestone ran no CI at all.
Adds audit.yml for daily RustSec coverage, since check-rust.yml now only
runs on Rust PRs. It skips the Rust toolchain entirely — cargo-audit only
reads Cargo.lock — so it costs ~1-2 min rather than the ~22 a scheduled
check-rust would burn daily on a capacity-1 runner.
The GitHub mirror is left untouched (#233: it receives no PRs).
Expected: Rust PR ~9-10 min, frontend-only PR ~2.5 min instead of ~24.5.
Resolves#232
simpl-resultat n'avait jamais ete opt-in pour le pattern STATE.md
malgre son statut de produit final commercial. Cette commit pose le
seed (3 sections : Position actuelle / Decisions recentes /
Blockers actifs) et ajoute l'import @STATE.md dans CLAUDE.md pour
qu'il soit auto-charge en session.
Step 10.5 de /fix-issue prendra le relais sur les prochaines PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds .forgejo/workflows/check.yml (and a GitHub mirror) that runs on
every branch push (except main) and on every PR targeting main.
Two parallel jobs:
- rust: cargo check + cargo test, with cargo registry/git/target caches
keyed on Cargo.lock. Installs the minimal Rust toolchain and the
webkit2gtk system deps that the tauri build script needs.
- frontend: npm ci + npm run build (tsc + vite) + npm test (vitest),
with the npm cache keyed on package-lock.json.
The Forgejo workflow uses the ubuntu:22.04 container pattern from
release.yml. The GitHub mirror uses native runners (ubuntu-latest)
since the GitHub mirror exists for portability and uses GitHub-native
actions.
Documents the new workflow in CLAUDE.md alongside release.yml so future
contributors know what CI runs before merge.
syncChangelogs() in vite.config.ts already handles copying changelogs
to public/ on dev/build start. The prebuild npm script was redundant
and introduced a platform dependency (cp command).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The in-app changelog page reads from public/CHANGELOG*.md which were
stale (last synced at 0.6.3). Add automatic sync via Vite config
(runs on dev/build start) and npm prebuild script so public/ copies
are always up to date without manual intervention.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CLAUDE.md: bump version to 0.6.3
- architecture.md: update version, component counts, dashboard description
- guide-utilisateur.md: rewrite dashboard section (budget table, chart, no recent transactions)
- i18n docs: update dashboard help text in both FR and EN
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create CHANGELOG.fr.md with full French translation of all versions
- Add ChangelogPage (/changelog) accessible from Settings
- Replace hardcoded i18n release notes with file-based approach:
loads CHANGELOG.md or CHANGELOG.fr.md based on user language
- CI copies changelogs to public/ during release build
- Update CLAUDE.md with bilingual changelog deployment process (fixes#10)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bump version to 0.5.0 and update CHANGELOG with all unreleased changes
including error handling, log viewer, report improvements, and GPL-3.0
license addition.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent infinite spinner when DB connection fails at startup by adding
a 10s timeout on connectActiveProfile(). Add ErrorBoundary to catch
React crashes and ErrorPage with refresh, update check, and contact links.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract changelog sections in CI to populate GitHub release bodies dynamically.
Expose the update body from tauri-plugin-updater and render it in the settings
page when an update is available. Add CHANGELOG discipline rule to CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite CLAUDE.md to match actual stack (React 19, Tauri v2, TypeScript,
Tailwind v4), current project structure, features, conventions, and
add documentation maintenance rules for architecture.md and ADRs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>