Skip to content

chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1 - #262

Closed
dependabot[bot] wants to merge 556 commits into
developfrom
dependabot/github_actions/actions/upload-artifact-7.0.1
Closed

dependabot[bot] wants to merge 556 commits into
developfrom
dependabot/github_actions/actions/upload-artifact-7.0.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 17, 2026

Copy link
Copy Markdown

Bumps actions/upload-artifact from 4.6.2 to 7.0.1.

Release notes

Sourced from actions/upload-artifact's releases.

v7.0.1

What's Changed

Full Changelog: actions/upload-artifact@v7...v7.0.1

v7.0.0

v7 What's new

Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can set the new archive parameter to false to skip zipping the file during upload. Right now, we only support single files. The action will fail if the glob passed resolves to multiple files. The name parameter is also ignored with this setting. Instead, the name of the artifact will be the name of the uploaded file.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

New Contributors

Full Changelog: actions/upload-artifact@v6...v7.0.0

v6.0.0

v6 - What's new

[!IMPORTANT] actions/upload-artifact@v6 now runs on Node.js 24 (runs.using: node24) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading.

Node.js 24

This release updates the runtime to Node.js 24. v5 had preliminary support for Node.js 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24.

What's Changed

Full Changelog: actions/upload-artifact@v5.0.0...v6.0.0

v5.0.0

What's Changed

... (truncated)

Commits
  • 043fb46 Merge pull request #797 from actions/yacaovsnc/update-dependency
  • 634250c Include changes in typespec/ts-http-runtime 0.3.5
  • e454baa Readme: bump all the example versions to v7 (#796)
  • 74fad66 Update the readme with direct upload details (#795)
  • bbbca2d Support direct file uploads (#764)
  • 589182c Upgrade the module to ESM and bump dependencies (#762)
  • 47309c9 Merge pull request #754 from actions/Link-/add-proxy-integration-tests
  • 02a8460 Add proxy integration test
  • b7c566a Merge pull request #745 from actions/upload-artifact-v6-release
  • e516bc8 docs: correct description of Node.js 24 support in README
  • Additional commits viewable in compare view

Test User and others added 30 commits August 4, 2026 23:57
🐛 fix: raise LMDB mapsize cap 8GB→16GB + PersistentEmbeddingCache auto-resize on MDB_MAP_FULL (#189)
…ed error messages

When the LMDB mapsize auto-resize cap is reached (7 sites: 4 in
vectordb/store.rs, 3 in embed/cache.rs), the error/warn messages said
'already at max size {}MB' or 'exceeds MAX_LMDB_MAP_SIZE_MB {}MB' but
never told the operator how to raise the cap. Appended '(set
CODESEARCH_MAX_LMDB_MAP_SIZE_MB to raise this cap)' to all 7 messages,
using backslash line-continuation per the repo's caller-facing-literal
convention (validated by tests/caller_facing_literals.rs - all 4 pass).
- CHANGELOG: renamed unreleased section 1.2.1 -> 1.2.4 (current pending
  version) and added the #189 fix entry (cap raise + cache auto-resize +
  error-message hint), alongside the existing build.ps1 entry.
- README: documented the new CODESEARCH_MAX_LMDB_MAP_SIZE_MB env var in
  the Environment Variables table.

PRs #187 and #176 (also merged since v1.2.0) were docs/AGENTS.md-only
changes with no user-facing code impact, so intentionally have no
CHANGELOG entries.
…remove dead PR trigger

- test-linux: remove `cargo build --release` (nothing consumes it; release.yml
  builds isolated per-platform artifacts at tag time). Was pure wasted CI
  minutes on every feature/develop push.
- Add `master` to push triggers: the develop->master release squash-merge
  previously got ZERO CI build/test coverage (protect-master.yml only checks
  the source-branch name, not code quality).
- Remove the pull_request: branches: [main] trigger: this repo has no `main`
  branch (default is `master`), and PRs target develop/master anyway — the
  trigger was permanently dead. push already covers every commit that matters.
master only ever advances via a squash-merged release PR (develop/release/*
-> master, per RELEASING.md). A direct git push to master is always either
a mistake or should go through that same PR path anyway. GitHub's branch
ruleset already blocks non-admin pushes, but the repo owner's own bypass
privilege makes that toothless against exactly this kind of accidental
local push -- which happened this session (a commit landed on master while
HEAD was there for the release flow, caught only by manual inspection).

Adds scripts/pre-push (tracked) with the master-push guard + QC gate, and
installs the equivalent (hand-maintained superset, customer-ref-leak check
stays local-only per existing convention) to .git/hooks/pre-push. Verified:
simulated stdin push to refs/heads/master exits 1 with the guard message;
refs/heads/develop passes through unaffected.
…s path gate

Two changes to .github/workflows/ci.yml, both reducing wasted CI minutes
without losing coverage:

1. concurrency: ci-${{ github.ref }}, cancel-in-progress: true — a stale
   in-flight run on the same branch (e.g. a stage commit immediately
   followed by a review-fix amend + re-push, which happened repeatedly
   this session) now gets cancelled instead of running to completion for
   a commit that is already superseded.

2. csharp-integration-tests now checks (via git diff on the pushed range,
   not a fragile commit-message convention) whether helpers/csharp/**
   actually changed before running its dotnet publish + cargo test cycle.
   That job was previously running unconditionally on every single push
   regardless of relevance — a full self-contained dotnet publish plus a
   cargo test compile for code nobody touched.

Not changed (deliberately): test-lib running on both linux and windows is
cross-platform coverage, not duplication — kept as-is. fmt/clippy running
both locally (pre-push hook) and in CI is intentional defense-in-depth
(CI cannot trust a hook that can be bypassed via --no-verify).
Diagnosed a user report: a local 'codesearch serve' instance was silently
keeping a mounted cloud federation peer warm, defeating its scale-to-zero,
with zero trace in the logs. Traced and ruled out TUI federated polling
(correctly gated behind --no-tui already) and explicit federated tool
calls (none logged). Root cause: the cloud keep-warm task
(CODESEARCH_KEEP_WARM_URL / --keep-warm-url) is not gated by --no-tui at
all, has no restriction that its target must be 'self', and every ping
was completely silent (success and failure both discarded with zero log
line) -- so a keep-warm URL accidentally pointing at another peer (e.g.
copy-pasted from a cloud deployment env into a local shell profile) would
silently generate periodic outbound traffic every KEEP_WARM_INTERVAL_SECS
(120s -- matches the reported 'every 2 minutes') with no way to see it in
the local logs.

Fixes:
- Per-ping logging: debug! on success, warn! on failure (was: silently
  discarded).
- Startup sanity check: new extract_host_from_url() helper (no new crate
  dependency) compares the keep-warm target's host against this server's
  own effective bind host; a mismatch (and not localhost/127.0.0.1/::1)
  now fires a loud warn! naming both hosts, explicit that keep-warm exists
  to self-ping THIS replica, not another peer.

Tests: 6 new cases for extract_host_from_url (plain http, https with real
hostname, no-scheme input, IPv6 literal bracket-preserving, query/fragment
stripping, empty-host edge case). Full serve:: suite green (104 passed).

Diagnosis write-up: docs/diagnose-federated-keep-warm.md
The embedded serve TUI ran a background `/status` fan-out to every mounted
federated peer on a cadence equal to the LOCAL serve's idle-suspend window
(2h by default). Each such poll WOKE the peer's scale-to-zero replica, which
then held itself warm for its own full idle window (~1h on the cloud deploy)
— roughly a 50% duty cycle on a peer nobody had queried. Ground truth from
Azure Log Analytics: wakes exactly 120/121/120 minutes apart, each warm
period ~67 min, with zero federated searches.

The design spec was that background polling of LOCAL repos is fine but a
FEDERATED peer must never be polled in the background. "Cannot keep a peer
awake past the host's own suspend term" is a strictly weaker property than
"never wakes it", and the two windows were unrelated values besides (local
host vs. remote peer).

- tui.rs: `spawn_remote_discovery` no longer polls on a timer. The periodic
  tick is now CONFIG-ONLY (`REMOTE_ROW_REFRESH_SECS` = 5s, zero HTTP): it
  rebuilds rows from the `remote_mounts` allowlist so mount/unmount edits and
  `l` reloads surface promptly. The activity poke (a real federated tool call
  landed on that peer) remains the only thing that ever contacts a peer, plus
  the explicit `i` info-overlay keypress. The `initial_cycle` startup gate is
  gone — every cycle is now config-only, so it had nothing left to gate.
- serve/mod.rs: drop `ServeState::idle_suspend_secs` (field, env init, getter
  and the `--idle-suspend-secs` override). It existed solely to feed the TUI
  poll cadence and is now write-only. The keep-warm task reads the flag/env
  directly, so `--idle-suspend-secs` behaviour is unchanged.
- Doc comments record WHY there is no baseline poll, to stop the reasoning
  from being reintroduced.

Local repos are entirely unaffected.

Review-fixes:
- [Important] tui_common.rs `activity_stale` doc still referenced "the slow
  baseline poll hasn't fired" as the reason a remote row goes stale → rewritten
  to state there is no background poll and that `-` on an idle mount is the
  normal steady state, not a fault.
- [Important] AGENTS.md and CHANGELOG.md still asserted the removed
  `idle_suspend_secs` cadence as current design (and named a field this commit
  deletes) → corrected, but deliberately NOT folded in here: both files carry a
  large unrelated pending doc-cleanup rewrite that must not enter a source
  commit. They land in the docs commit later on this same unpushed branch.
- [Pre-existing, fixed opportunistically] the discovery snapshot was gated on
  `!cfg.remotes.is_empty()`, so removing the last peer from repos.json left its
  rows rendered forever with no snapshot to clear them. The emit is now
  unconditional; with no peers `build_remote_rows` yields an empty vec, which
  clears them. Still zero HTTP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Second half of the federated scale-to-zero defect. Removing the TUI's timer
poll (previous commit) stops the peer being woken; this stops a wake that
does happen from costing a full warm hour.

The keep-warm loop computed its idle check as:

    let last = kw_state.most_recent_tool_call().unwrap_or(start);

`/status` and `/healthz` have their own handlers and never call
`record_tool_call`, so a replica woken by anything other than a genuine tool
call found no recorded call, fell back to the process start time, and
self-pinged its own ingress every 120s for the entire idle window.

The fallback was unreachable in the case it was written for ("a freshly
deployed replica stays warm for the full idle window before first use"): a
real tool call always records itself, so the fallback could ONLY ever fire
when the wake was not real work. Its entire practical effect was rewarding
spurious wakes — ~67 min warm instead of the ~6 min a bare wake costs,
roughly 11x amplification.

Keep-warm now requires a real recorded tool call; with none it does not ping
and lets the host suspend the replica, which the next real request wakes.
Verified this preserves the legitimate path: an inbound federated search hits
SEARCH_PATH -> crate::mcp::rest_search_handler -> the MultiStoreContext path
that calls record_tool_call, so after real use the peer keeps itself warm
exactly as before. A peer staying warm for an hour after real use is correct
behaviour and is unchanged.

Also fixes the startup "target isn't self" warning shipped in 55fa36b, which
false-positived on the ONLY deployment where keep-warm is correct: on Azure
Container Apps the process binds 0.0.0.0 while keep_warm_url is the ingress
FQDN, so the host comparison failed and the warning fired on every cold
start. A wildcard bind means our externally-visible host is genuinely
unknown, so the comparison cannot conclude anything and must stay silent — a
check that cries wolf on the correct configuration trains operators to ignore
the case that matters. The rule moved into a testable `keep_warm_foreign_target`
helper, covered by 5 new tests (wildcard binds, genuine foreign host, matching
host, loopback targets, unparseable URL).

cargo fmt / clippy -D warnings clean; 1134 passed, 42 ignored.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The diagnosis document's root cause was a hypothesis that turned out to be
wrong, and two project docs still described the removed poll cadence as the
current design — which is how this same behaviour got re-introduced twice
(PR #181, #184). Corrected against the code now on this branch.

DIAGNOSE_FEDERATED_KEEP_WARM.md (moved from docs/, rewritten):
- The old root cause blamed a misconfigured local CODESEARCH_KEEP_WARM_URL.
  Disproven on four independent grounds, now recorded under "What was ruled
  out": the env var is set nowhere locally (process env, HKCU, HKLM, all
  shell profiles); the one-time "keep-warm enabled" line appears in zero
  logs from 2026-04-26 on; that absence is meaningful because
  init_serve_logger is always file-only in serve mode and those logs do
  carry other INFO lines; and no local process held a :443 connection.
- Replaced with the confirmed two-defect root cause plus the Azure Log
  Analytics ground truth (wakes 120/121/120 min apart, ~67 min warm each,
  zero searches).
- Records the requirement being violated ("poll LOCAL repos, never
  federated") and the rejected reasoning, so it is not re-litigated.
- Notes one residual, not currently exploitable: the MCP `status` TOOL,
  when project-scoped, does record a tool call — unlike the HTTP /status
  endpoint that every known poller actually uses.

CHANGELOG.md:
- The consolidated fix entry goes under [1.2.4] (unreleased). An earlier
  draft wrongly rewrote the [1.2.0] section — v1.2.0 is a real tag and
  #181/#184 shipped in it, so editing it would have made released notes
  claim a fix that is not in that release. Both original 1.2.0 entries are
  restored verbatim as historical record, each marked superseded.
- Older version entries compressed to one-liners (existing convention).

AGENTS.md:
- The "Scale-to-zero-safe federated polling" bullet asserted the removed
  cadence as current and named ServeState::idle_suspend_secs, a field that
  no longer exists. Rewritten as an explicit design constraint with the
  rejected reasoning attached.
- Keep-warm bullet updated for the tool-call requirement and the
  wildcard-bind carve-out.
- Completed TODO sections removed, Implemented Features compressed.

README.md:
- The grep-guard bullet still described the 5-minute retry-unblock that
  1.2.0 replaced with a /healthz liveness probe. Rewritten to match.
- Verified NOT stale and left alone: "17 languages" (supported_languages()
  returns 17 — the table's 18th row, Jupyter, is JSON-parsed rather than
  tree-sitter) and the web-guard's 5-minute retry, which still exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Per-feature work log covering the whole cycle: the disproven original
hypothesis, the Azure Log Analytics ground truth, the two defects, the three
stages with their commit SHAs and review outcomes, and the open follow-ups.

Records why this behaviour took three attempts across PR #181, #184 and this
branch, so the rejected reasoning is not re-litigated a fourth time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`ci.yml`'s push trigger is a prefix allowlist that never included `fix/**`,
and there is no `pull_request` trigger. Every `fix/...` branch therefore
merged into develop having never run fmt, clippy or a single test in CI.

This is the repo's own documented naming convention — the comment directly
above the branch list even says "feature/fix -> develop". Only the prefix
was missing.

It was invisible because CodeQL is a separate, pull_request-triggered
workflow, so the PR still showed a green check. On PR #192,
`gh pr checks` listed CodeQL and nothing else; the local pre-push QC gate
was the only thing validating the branch.

Adds `fix/**` and documents the footgun plus how to verify coverage
(`gh pr checks <n>` should list the CI jobs, not just CodeQL).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
🐛 fix: stop waking the scale-to-zero federated peer (and stop it self-warming afterwards)
… duplicates

All hooks now live in .githooks/ and are enabled with a single
`git config core.hooksPath .githooks`. Removes the copy-into-.git/hooks step
that had let the tracked template and the installed hook drift apart.

Why this was broken:
- scripts/pre-push documented its own install as `cp scripts/pre-push
  .git/hooks/pre-push`, but the tracked copy had no customer-reference leak
  scan. Following the documented install silently removed that guard.
- .githooks/post-checkout documented `git config core.hooksPath .githooks`,
  which would have made git look only in .githooks/ — a directory that held
  neither pre-commit nor pre-push. Enabling one hook would have disabled the
  two that matter. core.hooksPath was in fact unset, so post-checkout had
  never run at all.

Changes:
- .githooks/{pre-commit,pre-push,post-checkout} + README.md; scripts/pre-commit
  and scripts/pre-push deleted (scripts/qc.ps1 stays).
- Customer patterns move to untracked .githooks/customer-patterns.local. The
  list is itself the thing being hidden, so it must never be tracked. When it
  is missing, pre-push prints a loud "SKIPPED — nothing was checked" warning
  instead of passing silently: a guard that quietly stops running is worse
  than no guard, because it is still trusted.
- pre-push skips the Rust QC gate when the branch changes no .rs/Cargo.* files
  vs origin/develop. Compared against origin/develop rather than the pushed
  ref range because stdin is already consumed by the master guard, and this
  avoids the all-zeros remote_sha case for a new branch. Every uncertain case
  runs the gate rather than skipping it.
- Leak scan uses `git grep -lIE` instead of `git ls-files | xargs grep`:
  space-safe paths, no argument-length limit, no stderr to suppress.
- ci.yml: add chore/** to the push branch allowlist — same prefix-allowlist
  footgun that left fix/** with no CI at all until PR #192.
- .gitattributes: drop the now-dead scripts/pre-commit eol=lf rule.

Master-push guard is unchanged.

Verified by running the hook directly: master push blocked (exit 1); normal
push passes with QC correctly skipped (exit 0); missing pattern file warns
loudly and exits 0; a planted customer reference in a tracked file blocks
(exit 1); the Rust-path filter matches src/foo.rs and Cargo.toml and not
docs/x.md, proving the skip can actually un-skip.

Review-fixes:
- [Important] `|| true` on the leak scan turned a git grep *failure* into a
  clean pass, and the comment-stripper could manufacture that failure: an
  inline `#` in a valid pattern like `Acme(NV#|BV)` was truncated to `Acme(NV`,
  producing an invalid ERE that exits 128. One bad line poisoned the whole
  alternation, so a real leak sailed through with "No customer references
  detected." Now: only whole-line comments are stripped (a mid-line `#` stays
  part of the pattern), and the git grep exit status is branched on — 0 blocks,
  1 is clean, anything else prints the loud SKIPPED banner. One rule overall:
  configuration problems warn, actual leaks block.
- [Important] RELEASING.md still documented `cp scripts/pre-commit
  .git/hooks/pre-commit` — a copy of a file this commit deletes, into a
  directory core.hooksPath makes git ignore. Replaced with the single
  `git config core.hooksPath .githooks` install.
- [Important] The QC-skip regex missed `rust-toolchain.toml` and `.cargo/`,
  both tracked here: a toolchain bump changes no .rs file yet flips fmt,
  clippy and tests, so the gate was skipped for exactly the change most likely
  to need it. Widened to cover rust-toolchain, .cargo/, scripts/qc.*, and
  rustfmt/clippy.toml (the latter two not tracked today, listed so adding one
  later cannot silently reopen the gap).
- [doc] README.md said `hooks git install` writes to `.git/hooks/`. It resolves
  the target with `git rev-parse --git-path hooks`, so it honours
  core.hooksPath and chains into an existing hook as a marker-delimited block.
  Corrected; no code change needed.

Re-verified after the fixes: master push blocked (exit 1); normal push passes
with QC skipped (exit 0); an invalid regex in the pattern file now warns
loudly and exits 0 instead of reporting clean; a mid-line `#` survives
parsing; rust-toolchain.toml, .cargo/config.toml, scripts/qc.ps1, src/a.rs and
Cargo.lock all trigger the gate while docs-only paths do not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
🔧 chore: unify git hooks in .githooks/ — one location, no hand-copied duplicates
The worklog still said "Not pushed. Three commits sit locally" while the work
was merged (PR #192) and running in production. A change record that is wrong
is worse than none, so this brings it to ground truth.

- Header: status is now shipped + verified, with the merge SHA and the
  deployed revision; test line records CI green, not just the local run.
- Stage 4 added: the branch had no CI at all until `fix/**` was added to
  ci.yml's prefix allowlist, with the self-test that proved it.
- Stage 5 added: deployment of both sides (local via copy-to-common, cloud as
  revision --0000024), config verified intact across the image update, and the
  scale-to-zero verification — replicas held at 0 across six consecutive
  checks with no traffic. Recorded as positive evidence: under the old binary
  the keep-warm fallback made reaching 0 at ten minutes impossible.
- Build note: two az acr build runs failed at the identical step with
  "layer does not exist" on a byte-identical Dockerfile; a local docker build
  succeeded. Root cause is the ACR Tasks agent, not this repo.
- Follow-ups: dropped the stale "not pushed" item; the production check is now
  a 24h Log Analytics sample rather than "unverified"; added the ACR Tasks
  failure as a blocker for any automated cloud deploy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📝 docs: worklog — record merge, deploy and production verification
…e forever

A repo whose database failed to open (typically a transient write lock - an
indexing run holding the DB when a query arrived) was cached as
RepoState::Conflicted, and the fast path in get_or_open_stores replayed that
error on every later call without ever retrying the open.

The state's only documented exit was idle eviction, and it was unreachable:
evict_idle_repos iterates last_access, but both paths that mark a repo
Conflicted (warmup_repo and the get_or_open_stores slow path) propagate the
failure with `?` before reaching their touch_access call. A repo that
conflicts on first open therefore never gets a last_access entry and is never
considered for eviction, however long it sits idle. Querying it did not help
either: the fast path replayed the cached error while calling touch_access on
the way, so the only queries that would have registered it for eviction were
also the ones resetting its idle timer.

Net effect: a momentary lock was indistinguishable from permanent corruption
and could only be cleared by restarting serve - while the error text promised
"the next query will retry automatically".

A cached conflict is now dropped on next access and the open genuinely
retried. Retrying is cheap when it still fails (a refused file lock), and this
mirrors the missing-DB path, which already refuses to cache Conflicted for the
same reason (missing_db_not_cached_as_conflicted).

Regression test asserts recovery without a restart and without an idle wait.
It carries two preconditions so it cannot pass vacuously (the first open must
genuinely fail, and that failure must actually be cached as Conflicted), and
was confirmed to FAIL with the fix neutralised - reproducing the exact
user-visible error string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Review-fixes:
- [Important] Non-atomic get()+remove() on the Conflicted cache entry could race with a concurrent insert (e.g. add_repo_handler or force-reindex installing a fresh RepoState::Write) and delete that live entry instead, dropping its cancel_token without cancelling it. Fixed by using DashMap::remove_if with a matches!(v, RepoState::Conflicted) predicate — same atomic check-and-remove primitive already used by is_indexing() in this file — so removal can only ever affect an entry still Conflicted at removal time.
…-retries

🐛 fix: retry a conflicted repo instead of replaying the cached failure forever
When an agent (or any non-MSYS caller, e.g. an MCP client) sent codesearch
a POSIX-style path like `/c/Users/foo`, Rust on Windows resolved the
leading `/` as "rooted on the current drive" — i.e. `<drive>:\c\Users\foo`,
silently creating junk directories like `C:\c\Users\...` and indexing the
wrong project. This is the path-pollution defect behind the orphan
`<repo>-propagate-tmp` indexes (diagnosed end-to-end: an agent-created
staging folder was indexed under a polluted `C:\c\...` mirror that nothing
ever cleaned up).

Fix: add `translate_msys_path()` to `cache/file_meta.rs`. It detects a
leading `/` + single ASCII letter (+ `/` or EOL) and rewrites it to
`<UPPER>:/...`. Idempotent on every other input; no-op on non-Windows.

Apply it at every user-supplied path boundary so existing AND not-yet-existing
paths are both caught:
  - `safe_canonicalize` calls it before canonicalising (existing-path case)
  - `ReposConfig::register` / `register_with_alias` fallbacks use it on the
    raw path (non-existing-path case)
  - `resolve_database_with_message` fallback uses it on the raw path too

Added tests:
  - `translate_msys_path_converts_single_letter_drive` (table-driven, Windows)
  - `translate_msys_path_leaves_non_drive_paths_untouched` (Windows)
  - `translate_msys_path_leaves_existing_windows_paths_untouched` (Windows)
  - `translate_msys_path_is_noop_on_unix` (non-Windows)
  - `register_translates_msys_posix_path` — integration regression for the
    exact defect (Windows)
  - `register_leaves_unix_path_untouched` — guards against the fix leaking
    to Unix where `/c/...` is legitimate

Validation: cargo check + cargo clippy -D warnings clean; cache:: + db_discovery::
tests = 101 passed, 7 ignored, 0 failed.

Review-fixes (round 1 → 2):
- [Critical] translate_msys_path missed a #[cfg(windows)] guard; the body
  ran on Unix too, rewriting legitimate `/c/...` paths to `C:/...` and
  breaking test-linux CI. Split into a Windows real impl + a Unix no-op.
- [Important] register_translates_msys_posix_path only pinned the
  existing-path branch (safe_canonicalize success path); the actual defect
  site — the non-existing-path fallback — was unpinned. Added a dedicated
  test `register_translates_msys_posix_path_when_dir_does_not_exist` that
  fails if the fallback is reverted to `strip_unc_prefix`.
- [Important] unregister_path and alias_for_path had the same fallback
  pattern as register() but weren't updated → register stored `C:\Users\foo`
  while unregister compared against the raw `/c/Users/foo`, leaving entries
  stuck. Added register/unregister symmetry test. Fixed by introducing a
  shared `normalize_user_path(path)` helper (translate_msys_path +
  strip_unc_prefix) and routing all 5 fallback sites through it, per the
  repo's "structural fix" rule for the warnings-channel class of defect.
…e_user_path

Stage 1 introduced `normalize_user_path` and applied it to the 6 db_discovery
fallback sites. Round-2 review flagged 5 more sites with the same pattern
(`safe_canonicalize(...).unwrap_or_else(|_| <raw path>)`) elsewhere in the
codebase that still leaked caller-supplied MSYS POSIX paths (`/c/...`) to
Windows file APIs when canonicalize failed. Same defect class, same fix.

Sites updated:
- `try_delegate_reindex_to_serve` (src/index/mod.rs ~2064)
- `try_delegate_add_to_serve`    (src/index/mod.rs ~2296)
- `try_delegate_rm_to_serve`     (src/index/mod.rs ~2394) + its inner
  `normalize_for_cmp` closure (~2397)
- `run_serve` `--register` loop  (src/serve/mod.rs ~4745)

All 5 now use `crate::cache::normalize_user_path(...)` on the fallback, so
the `validate_path_within_allowed_roots` check and the eventual
`config.register(...)` call both see the translated `C:/...` form, not the
raw `/c/...`.

Added tests for `normalize_user_path` itself (the helper shared across all
fallback sites):
- `normalize_user_path_translates_msys_and_strips_unc` (Windows)
- `normalize_user_path_only_strips_unc_on_unix` (non-Windows)

The 5 sites here are CLI-arg paths feeding serve-delegation flows; the
register/unregister symmetry tests from stage 1 cover the integration
guarantee indirectly (the delegation flows terminate in `register()`).

Validation: cargo check + cargo clippy -D warnings clean;
cache:: + db_discovery:: tests = 104 passed, 7 ignored, 0 failed.
…e_reindex_to_serve

Stage 2 swept 5 safe_canonicalize fallback sites for the MSYS path-pollution
defect, but missed the twin of the closure it fixed in try_delegate_rm_to_serve.
Stage-2 review round-1 flagged this site (src/index/mod.rs:2076) as the
identical pattern in the identical closure name in the sibling delegation
function. Same defect class, same one-line fix: route the fallback through
`crate::cache::normalize_user_path(p)`.

Post-fix detector sweep confirms every production `safe_canonicalize(...).
unwrap_or_else(_)` site now goes through `normalize_user_path`:
  - db_discovery/repos.rs: register, register_with_alias, unregister_path,
    alias_for_path, scan_for_remote (5 sites)
  - index/mod.rs: try_delegate_reindex_to_serve outer + closure,
    try_delegate_add_to_serve, try_delegate_rm_to_serve outer + closure (5 sites)
  - serve/mod.rs: run_serve --register loop (1 site)
The only remaining hits are a test helper (repos_tests.rs:12) and the
vectordb mapsize-pin key (vectordb/store.rs:67, input is already canonical
by design — flagged by stage-2 review as out-of-scope).

Validation: cargo clippy -D warnings clean. No test changes needed — the
closure is private and the register/unregister symmetry tests from stage 1
cover the integration guarantee.
fix: translate MSYS POSIX paths at the path boundary (path-pollution defect)
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code labels Sep 17, 2026
@dependabot
dependabot Bot requested a review from flupkede as a code owner September 17, 2026 08:34
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code labels Sep 17, 2026
@flupkede
flupkede changed the base branch from master to develop September 17, 2026 08:41
…ting (todo #153)

Two independent defects in remote chunk fetch:
1. The peer URL replaced '{id' without the closing brace, producing
   /chunk/2058%7D — axum's {id} param swallowed the stray '}' into the
   captured value, so mock-based tests passed while real peers answered
   400. Replace the full '{id}' placeholder; pinned by a test whose route
   echoes the exact path it was hit on.
2. get_chunk(project=<peer>/<alias>, chunk_id) died with 'Unknown alias':
   mounted remote projects now route through the same federated fetch
   search uses (local aliases win name clashes). Hermetic routing test
   (temp config file — the in-memory config is reloaded from disk, which
   previously leaked the developer's real peers into the test).
@flupkede

Copy link
Copy Markdown
Owner

@dependabot rebase

@dependabot @github

dependabot Bot commented on behalf of github Sep 17, 2026

Copy link
Copy Markdown
Author

The base commit for this pull request has not changed.

@flupkede

Copy link
Copy Markdown
Owner

@dependabot rebase

@dependabot
dependabot Bot changed the base branch from develop to master September 17, 2026 10:33
@dependabot
dependabot Bot force-pushed the dependabot/github_actions/actions/upload-artifact-7.0.1 branch from b649bad to b0effe9 Compare September 17, 2026 10:33
@flupkede

Copy link
Copy Markdown
Owner

@dependabot recreate

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@ea165f8...043fb46)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot changed the base branch from master to develop September 17, 2026 10:47
@dependabot
dependabot Bot force-pushed the dependabot/github_actions/actions/upload-artifact-7.0.1 branch from b0effe9 to 24aeb4e Compare September 17, 2026 10:47
@flupkede flupkede added the no-changelog Skip the CHANGELOG.md-touched CI check (docs/CI-only PR) label Sep 17, 2026
@flupkede

Copy link
Copy Markdown
Owner

Superseded by #275 (your bump, cherry-picked onto a real develop base and merged with full CI). This PR branch was recreated from a stale master fork, so its diff/CI could not validate against develop. Closing — dependabot will re-propose against develop next cycle now that target-branch: develop is in place.

@flupkede flupkede closed this Sep 17, 2026
@dependabot @github

dependabot Bot commented on behalf of github Sep 17, 2026

Copy link
Copy Markdown
Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/github_actions/actions/upload-artifact-7.0.1 branch September 17, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code no-changelog Skip the CHANGELOG.md-touched CI check (docs/CI-only PR)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants