mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-05 08:23:59 +01:00
Merge remote-tracking branch 'origin/capy/fw3-a1' into capy/fw3-a2
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> # Conflicts: # scripts/harness-version.json
This commit is contained in:
commit
90f2148752
75 files changed
+4068
-236
No files matched your search
@@ -44,6 +44,7 @@ cause, the held files and the fix.
|
||||
| `error` | The drain stopped before committing and kept the queue | `status=error. The last sync stopped before committing; the queue is kept and retried. See the cause: <bin> --status` | The cause `--status` names: a git index lock, a commit hook, a `git add` failure |
|
||||
| `unknown` | The status file holds a status code outside this table | `status=unknown. The sync status file is unreadable. See it: <bin> --status` | Run `<bin> --once` to rewrite it |
|
||||
| stale-push | No push for 24 hours while the drain's `drainable` count is above zero | `stale-push. Files are ready to sync but nothing has been pushed for over 24 hours. See why: <bin> --status` | The waiting reason `--status` names (a coupled group waiting for a consistent generation, a `git add` failure) |
|
||||
| case-collision | `case_names` is set: artifact paths differ only by letter case, so the drain holds queued files under them | `case-collision held=<N> names=<names>. Artifact paths differ only by letter case, which a Mac or Windows disk stores as one file; sync holds <N> queued file(s) under them and syncs everything else. Repair: https://github.com/garrytan/gstack/blob/main/docs/troubleshooting.md#artifact-case-collision. See the paths: <bin> --status` | Keep one spelling: the manual repair in [troubleshooting](troubleshooting.md#artifact-case-collision) |
|
||||
| stale-drain | `last_drain_at` older than 24 hours while the queue holds records | `stale-drain. The sync has not run for over 24 hours while files wait in the queue. See why: <bin> --status` | If no gstack process is running, remove `~/.gstack/.brain-sync.lock.d`, then run `<bin> --once` |
|
||||
|
||||
`<bin>` is the absolute path, for example
|
||||
|
||||
+5
-2
@@ -90,8 +90,11 @@ On machine B:
|
||||
gstack-brain-sync --status
|
||||
```
|
||||
|
||||
Shows: the status (`ok`, `idle`, `held`, `blocked`, `push_failed`,
|
||||
`error`), files held back by the secret scan with their fixes, the
|
||||
Shows: the status (`ok`, `idle`, `held`, `collision`, `blocked`,
|
||||
`push_failed`, `error`), files held back by the secret scan with their
|
||||
fixes, files held because their path differs only by letter case from
|
||||
another path (`case_held`, `case_names`; see
|
||||
[troubleshooting](troubleshooting.md#artifact-case-collision)), the
|
||||
`drainable` count, the last sync and push times, pending queue depth, and
|
||||
the current privacy mode.
|
||||
|
||||
|
||||
@@ -630,6 +630,78 @@ has nothing to calibrate from. It no longer says "calibrated".
|
||||
|
||||
**Fix.** Answer more registered questions, then `gstack-developer-profile --derive`.
|
||||
|
||||
<a id="artifact-case-collision"></a>
|
||||
### `ARTIFACTS_SYNC: attention: case-collision held=<N> names=<names>. Artifact paths differ only by letter case, ...`
|
||||
|
||||
**Meaning.** The artifacts repo holds paths that differ only by letter case,
|
||||
such as `projects/MyApp/` and `projects/myapp/`. A Mac or Windows disk stores
|
||||
them as one file, so git there would stage a write under the other spelling,
|
||||
and sync would report success while one spelling stays modified and the other
|
||||
machines read stale data (#3220). Sync now holds every queued file under such a
|
||||
path instead of staging it: the file stays queued, everything else keeps
|
||||
syncing, and the status is `collision` rather than `ok`. When only one
|
||||
spelling is tracked, that spelling keeps syncing and only the new alias is
|
||||
held; when neither is tracked yet, both wait. `<names>` are the colliding folder or file names; `gstack-brain-sync
|
||||
--status` lists the held paths in `message`. A local commit that would push a
|
||||
new alias to the remote (two machines created both spellings at once) is
|
||||
refused with status `error` and kept locally.
|
||||
|
||||
Nothing is repaired automatically. Slug resolution and skill start are
|
||||
unaffected; only the sync holds files.
|
||||
|
||||
**Fix.** Keep one spelling, by hand, on one machine:
|
||||
|
||||
1. Choose the spelling to keep: the one `gstack-slug` prints in that project
|
||||
today. If the project resolves to different spellings (a remote URL typed
|
||||
two ways, a folder reached as `~/code/MyApp` and `~/code/myapp`), make it
|
||||
stable first: fix the remote URL's case, or set `GSTACK_PROJECT_SLUG`.
|
||||
2. Fold the other spelling's tracked files into the kept one. Read both
|
||||
spellings from git, because a Mac's working tree shows only one of them,
|
||||
and the working files too, because they hold the held, unsynced writes.
|
||||
This loop covers the dropped spelling's tracked files and its untracked
|
||||
ones (held writes that never synced). It folds JSONL logs (concatenated,
|
||||
duplicate lines dropped) and prints every other file for you to decide:
|
||||
|
||||
```bash
|
||||
cd ~/.gstack
|
||||
keep=projects/MyApp; drop=projects/myapp
|
||||
{ git -c core.ignorecase=false ls-files -- "$drop"; git -c core.ignorecase=false ls-files --others -- "$drop"; } | sort -u | while IFS= read -r f; do
|
||||
rel=${f#"$drop"/}
|
||||
case "$rel" in *.jsonl) ;; *) echo "decide by hand: $f"; continue ;; esac
|
||||
{ git show ":$keep/$rel"; git show ":$f"; cat "$keep/$rel" "$f"; } 2>/dev/null | awk '!seen[$0]++' > "$HOME/.gstack-fold.tmp"
|
||||
mkdir -p "$keep/$(dirname "$rel")" && mv "$HOME/.gstack-fold.tmp" "$keep/$rel"
|
||||
git -c core.ignorecase=false add -f -- "$keep/$rel"
|
||||
git -c core.ignorecase=false rm -q --cached --ignore-unmatch -- "$f"
|
||||
echo "folded: $keep/$rel"
|
||||
done
|
||||
```
|
||||
|
||||
For each file it prints (Markdown, JSON snapshots such as
|
||||
`decisions.active.json`), compare `git show ":$keep/<file>"` with
|
||||
`git show ":$drop/<file>"`, write the content to keep to `"$keep/<file>"`,
|
||||
then run the same `git -c core.ignorecase=false add -f -- "$keep/<file>"`
|
||||
and `git -c core.ignorecase=false rm -q --cached --ignore-unmatch -- "$drop/<file>"`. Never
|
||||
concatenate a JSON snapshot. Then commit and push:
|
||||
|
||||
```bash
|
||||
git -c core.ignorecase=false commit -m "repair: fold $drop into $keep"
|
||||
git push origin HEAD
|
||||
```
|
||||
|
||||
On Linux the two folders are separate on disk: after the commit, check
|
||||
that `git -c core.ignorecase=false ls-files --others -- "$drop"` lists
|
||||
nothing you have not folded or moved, then remove the dropped folder
|
||||
(`rm -r "$drop"`). On a Mac or Windows they are the same folder, so do
|
||||
not remove anything.
|
||||
3. Clear the held records of the dropped spelling and queue the kept files:
|
||||
`gstack-brain-sync --skip-file <dropped path>` for each held path that
|
||||
`--status` lists, then `gstack-brain-enqueue <kept path>` for each
|
||||
`folded:` line and each file you moved by hand, and
|
||||
`gstack-brain-sync --once`.
|
||||
4. On every other machine, let the next skill start pull the repair (or run
|
||||
`git -C ~/.gstack pull`). The line disappears once no tracked path
|
||||
differs only by case.
|
||||
|
||||
<a id="skill-start-former-bucket"></a>
|
||||
### `gstack: earlier data for this project is in projects/<slug> (a worktree's old bucket). Merge it: ...`
|
||||
|
||||
|
||||
Reference in new issue
Block a user