§8.8 Mirror refresh scheduler #12
Labels
No labels
Compat/Breaking
demo
hardening
identity
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
needs-verification
notify
ops
packaging
perf
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
process
rbac
research
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
scanning
stage-6e
stage-6f
stage-6g
Status
Abandoned
Status
Blocked
Status
Need More Info
transport
web
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
qwc-open/tulli#12
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Labels:
enhancement,scanningJittered nightly
git remote updateover all mirrors that triggers the on-update pipeline; tune window/jitter, upstream backoff, refresh age-out (§11.7).Current state (verified @
6769be5) + the--barecaveatNothing refreshes mirrors today. A mirror is materialised exactly once, on first fetch, then frozen:
internal/git/mirror.goEnsurePresent()is clone-once — if the bare repo already exists it returns immediately (isBareRepo(dir) → return dir, false, nil) and never re-fetches. There is nogit remote update/git fetchanywhere in the non-test code.internal/mirror/reconciler.go:5carries the placeholder for this: "(The refresh scheduler, §8.8, will also live here later.)"main.go's-reconcile-intervalsweep (default 30s) — reconciles DB verdicts → on-diskuploadpack.hideRefs. It touches no network and pulls no new commits. Don't confuse it with refresh.Consequence: once a repo is mirrored, upstream changes (new commits, new refs, force-pushes / rewritten history) are never picked up.
⚠️
--barewon't absorb rewritten history — needs a forced refspecCommit
e81746adeliberately switched the clone from--mirrortogit clone --bare(mirror.go:132–146) to stop HEAD leaking past ref-quarantine. But--baredoes not install the+refs/*:refs/*mirror refspec. So when this scheduler is implemented, a naivegit remote updateon these repos will not correctly reflect a rewritten upstream:+(force) in the refspec.--prune.The refresh job must therefore fetch with an explicit forced, scoped refspec (e.g.
+refs/heads/*:refs/heads/*+refs/tags/*:refs/tags/*--prune) rather than relying on the--baredefault — and scoped to preserve the HEAD/ref-quarantine invariant thate81746aestablished (don't reintroduce the--mirrorleak). Verify against thegit/head.go+hiderefs.gobehaviour when wiring it.Detecting a rewrite and re-evaluating correctly
Fetching the rewrite is only half of it — the verdict must be re-evaluated:
created-triggered scan pipeline today only runs on the first clone; there's no subsequent trigger because there's no subsequent fetch).verdict.RecomputeReffor changed refs so a rewrite actually re-evaluates the block. This matters directly for the §6.7/§11.3 lift semantics: for a secret finding, a history rewrite upstream is the only thing that lifts the block (delete-without-rewrite doesn't — the blob stays cloneable), so the rewrite has to be fetched and re-scanned for that lift to ever happen.Related