diff --git a/SKILL.md b/SKILL.md index 36313bbaf..eedcd0771 100644 --- a/SKILL.md +++ b/SKILL.md @@ -63,14 +63,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index 00ea5148a..9e654d46e 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -197,14 +197,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/benchmark-models/SKILL.md b/benchmark-models/SKILL.md index e9e6ad378..9dedb187b 100644 --- a/benchmark-models/SKILL.md +++ b/benchmark-models/SKILL.md @@ -67,14 +67,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index e0c575bc7..7c2549327 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -67,14 +67,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/bin/gstack-skill-start b/bin/gstack-skill-start index 6a922158f..6dbaaa698 100755 --- a/bin/gstack-skill-start +++ b/bin/gstack-skill-start @@ -358,6 +358,9 @@ elif [ -d "$_GH/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then [ -f "$_GH/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(head -1 "$_GH/.brain-last-push" 2>/dev/null | tr -cd 'A-Za-z0-9._:+-' || echo never) _BRAIN_LAST_PUSH=${_BRAIN_LAST_PUSH:-never} echo "ARTIFACTS_SYNC: mode=$_BRAIN_SYNC_MODE | last_push=$_BRAIN_LAST_PUSH | queue=$_BRAIN_QUEUE_DEPTH" + # A stuck sync (scanner hold, failed push or commit, no push or no drain for + # 24 hours) prints fixed attention lines; a healthy sync prints none. + "$_BRAIN_SYNC_BIN" --attention 2>/dev/null | grep '^ARTIFACTS_SYNC: attention: ' || true else echo "ARTIFACTS_SYNC: off" fi diff --git a/browse/SKILL.md b/browse/SKILL.md index 740c287c7..ae139d535 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -63,14 +63,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/canary/SKILL.md b/canary/SKILL.md index 25974f309..52b29161a 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -178,14 +178,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/codex/SKILL.md b/codex/SKILL.md index 330c87a0e..82614174a 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -181,14 +181,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/context-restore/SKILL.md b/context-restore/SKILL.md index 6df0d3965..fa5a03bc0 100644 --- a/context-restore/SKILL.md +++ b/context-restore/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/context-save/SKILL.md b/context-save/SKILL.md index db781f7c4..561a958db 100644 --- a/context-save/SKILL.md +++ b/context-save/SKILL.md @@ -179,14 +179,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index b2f2c3418..9e8b41a6d 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -204,14 +204,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/design-html/SKILL.md b/design-html/SKILL.md index 0d7b2f9e3..fb4369040 100644 --- a/design-html/SKILL.md +++ b/design-html/SKILL.md @@ -185,14 +185,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 1530bd59c..6ab4db87f 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/design-shotgun/SKILL.md b/design-shotgun/SKILL.md index 4bdd21bfe..e2aac6c4e 100644 --- a/design-shotgun/SKILL.md +++ b/design-shotgun/SKILL.md @@ -198,14 +198,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/devex-review/SKILL.md b/devex-review/SKILL.md index ff12938d8..b6c56a120 100644 --- a/devex-review/SKILL.md +++ b/devex-review/SKILL.md @@ -184,14 +184,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/diagram/SKILL.md b/diagram/SKILL.md index e6ec92011..74c64cdd1 100644 --- a/diagram/SKILL.md +++ b/diagram/SKILL.md @@ -66,14 +66,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/docs/gbrain-sync-errors.md b/docs/gbrain-sync-errors.md index 001c72dc4..8c4152326 100644 --- a/docs/gbrain-sync-errors.md +++ b/docs/gbrain-sync-errors.md @@ -29,33 +29,57 @@ gstack-config set artifacts_sync_mode_prompted true --- -## `BRAIN_SYNC: blocked: :` +## `ARTIFACTS_SYNC: attention: ...` at skill start -**Problem.** Sync stopped because the secret scanner detected credential-shaped -content in a staged file. The queue is preserved; nothing was pushed. +**Problem.** The artifacts sync is stuck or partly stuck. Skill start prints +one fixed line per problem; `ok` and `idle` print nothing. Every line names +the absolute path of `gstack-brain-sync`; run it with `--status` to see the +cause, the held files and the fix. -**Cause.** One of the pre-commit secret patterns matched the file contents — -likely an AWS key, GitHub token, OpenAI key, PEM block, JWT, or bearer token -embedded in JSON. +| State | Trigger | Attention line (after `ARTIFACTS_SYNC: attention: `) | Fix | +|---|---|---|---| +| `held` | The secret scan held back flagged files and synced the rest | `status=held held=. The secret scan is holding back file(s); everything else still syncs. See which files and how to fix them: --status` | Edit the file so the scan no longer matches, or ` --skip-file ` (permanent; undo with `--unskip-file `) | +| `blocked` | A re-scan still flagged after the hold, so nothing was committed | `status=blocked. The secret scan flagged a file it could not hold back on its own, so nothing is syncing. See the fix: --status` | Edit or skip the files `--status` names, or clear the batch with ` --drop-queue --yes` | +| `push_failed` | A commit is saved locally but the push failed | `status=push_failed. Synced files are committed locally but the push failed; it retries at skill start. See the cause: --status` | The fix `--status` names (usually `gh auth status`) | +| `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: --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: --status` | Run ` --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: --status` | The waiting reason `--status` names (a coupled group waiting for a consistent generation, a `git add` failure) | +| 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: --status` | If no gstack process is running, remove `~/.gstack/.brain-sync.lock.d`, then run ` --once` | -**Fix (three options).** +`` is the absolute path, for example +`~/.claude/skills/gstack/bin/gstack-brain-sync`. The source of truth is the +usage header of `bin/gstack-brain-sync`; skill start's tests are generated +from it. -1. **If it's a real secret**: edit the offending file to remove the secret, - then re-run any skill to retry sync. +**Held files.** When the secret scan flags a file, only that file is held +back (with any file coupled to it, such as a decision log and its active +snapshot); everything else syncs. The held file stays queued and is +re-scanned on every sync, so editing it clears the hold automatically. +`--status` lists each held file under `held`, with the scanner rule that +matched (never the matched text), the files held with it (`dependents`) and +both fixes: -2. **If the pattern is a false positive** (e.g., your learning contains a - GitHub token pattern in an example string that you *want* to publish): +1. **If it's a real secret**: edit the file to remove it. The next skill run + re-scans and syncs it. +2. **If the match is a false positive** you never want synced: ```bash - gstack-brain-sync --skip-file + ~/.claude/skills/gstack/bin/gstack-brain-sync --skip-file ``` - This permanently excludes the path from future syncs. - -3. **If you want to abandon this sync batch entirely** (start fresh): + This permanently excludes the path from future syncs (for a coupled file, + the files coupled with it stop too). To undo it and queue the path again: ```bash - gstack-brain-sync --drop-queue --yes + ~/.claude/skills/gstack/bin/gstack-brain-sync --unskip-file ``` - This clears the queue without committing. Future writes will re-populate - it normally. +3. **To abandon the whole batch** (start fresh): + ```bash + ~/.claude/skills/gstack/bin/gstack-brain-sync --drop-queue --yes + ``` + +**Git index lock.** A git process killed mid-write leaves +`~/.gstack/.git/index.lock`. The sync removes it once it is older than 10 +minutes, because every gstack writer to `~/.gstack` takes the same sync lock +first. A younger lock means a git process is running there; the sync reports +`error` and retries at the next skill start. --- diff --git a/docs/gbrain-sync.md b/docs/gbrain-sync.md index 330ed29e2..6e308d89e 100644 --- a/docs/gbrain-sync.md +++ b/docs/gbrain-sync.md @@ -90,11 +90,15 @@ On machine B: gstack-brain-sync --status ``` -Shows: last successful push, pending queue depth, any sync blocks, and the -current privacy mode. +Shows: the status (`ok`, `idle`, `held`, `blocked`, `push_failed`, +`error`), files held back by the secret scan with their fixes, the +`drainable` count, the last sync and push times, pending queue depth, and +the current privacy mode. -Every skill run prints a `BRAIN_SYNC:` line near the top of the preamble -output. Scan it for problems. +Every skill run prints an `ARTIFACTS_SYNC:` line near the top of the +preamble output. When the sync is stuck it adds an +`ARTIFACTS_SYNC: attention:` line; the table of those lines and their fixes +is in [gbrain-sync-errors.md](gbrain-sync-errors.md#artifacts_sync-attention--at-skill-start). ## Privacy modes in detail @@ -122,20 +126,22 @@ your machine. Blocked patterns include: - JWTs (`eyJ…`) - Bearer tokens in JSON (`"authorization": "…"`, `"api_key": "…"`, etc.) -If a scan hits, sync stops, the queue is preserved, and your preamble -prints: +If a scan hits, only the flagged file is held back (with any file coupled +to it); everything else syncs. The held file stays queued and is re-scanned +at every sync, and skill start prints: ``` -BRAIN_SYNC: blocked: : +ARTIFACTS_SYNC: attention: status=held held=1. The secret scan is holding back 1 file(s); everything else still syncs. See which files and how to fix them: --status ``` To remediate: -1. Review the offending file. -2. If the match is a false positive on content you explicitly want to - sync, run `gstack-brain-sync --skip-file ` to permanently - exclude that path. -3. Otherwise, edit the file to remove the secret and re-run any skill. +1. Run `gstack-brain-sync --status` (the line prints its absolute path). Each + entry under `held` names the file, the scanner rule and both fixes. +2. If the match is a false positive on content you never want synced, run + `gstack-brain-sync --skip-file ` to permanently exclude that path; + `gstack-brain-sync --unskip-file ` undoes it. +3. Otherwise, edit the file to remove the secret; the next skill run syncs it. There's a defense-in-depth hook at `~/.gstack/.git/hooks/pre-commit` that runs the same scan if you manually `git commit` against the repo. diff --git a/document-generate/SKILL.md b/document-generate/SKILL.md index b4a274ead..087e1b490 100644 --- a/document-generate/SKILL.md +++ b/document-generate/SKILL.md @@ -184,14 +184,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/document-release/SKILL.md b/document-release/SKILL.md index 17d3a158e..a5c37f71f 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/health/SKILL.md b/health/SKILL.md index 322a967c7..e45520ca2 100644 --- a/health/SKILL.md +++ b/health/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/investigate/SKILL.md b/investigate/SKILL.md index 930b98366..45d2a2083 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -219,14 +219,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ios-clean/SKILL.md b/ios-clean/SKILL.md index 3bb422330..82d52986c 100644 --- a/ios-clean/SKILL.md +++ b/ios-clean/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ios-design-review/SKILL.md b/ios-design-review/SKILL.md index 6b6e22a04..384c50781 100644 --- a/ios-design-review/SKILL.md +++ b/ios-design-review/SKILL.md @@ -184,14 +184,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ios-fix/SKILL.md b/ios-fix/SKILL.md index cbf765e09..ea959a160 100644 --- a/ios-fix/SKILL.md +++ b/ios-fix/SKILL.md @@ -185,14 +185,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ios-qa/SKILL.md b/ios-qa/SKILL.md index 100599489..18bbc70fc 100644 --- a/ios-qa/SKILL.md +++ b/ios-qa/SKILL.md @@ -188,14 +188,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ios-sync/SKILL.md b/ios-sync/SKILL.md index cf44a470f..e8cbddb8d 100644 --- a/ios-sync/SKILL.md +++ b/ios-sync/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index 324e9119a..33de0b5eb 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -177,14 +177,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/landing-report/SKILL.md b/landing-report/SKILL.md index 9deba7b91..ea0715ecf 100644 --- a/landing-report/SKILL.md +++ b/landing-report/SKILL.md @@ -179,14 +179,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/learn/SKILL.md b/learn/SKILL.md index 996955a14..f8aa1a821 100644 --- a/learn/SKILL.md +++ b/learn/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/make-pdf/SKILL.md b/make-pdf/SKILL.md index 8c04f7df8..a7984fea1 100644 --- a/make-pdf/SKILL.md +++ b/make-pdf/SKILL.md @@ -104,14 +104,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index ad39c5541..f326b8f17 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -225,14 +225,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/open-gstack-browser/SKILL.md b/open-gstack-browser/SKILL.md index 2754d9db5..aa4071bb7 100644 --- a/open-gstack-browser/SKILL.md +++ b/open-gstack-browser/SKILL.md @@ -65,14 +65,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/pair-agent/SKILL.md b/pair-agent/SKILL.md index 1d4b9302b..f7086a8e4 100644 --- a/pair-agent/SKILL.md +++ b/pair-agent/SKILL.md @@ -181,14 +181,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 5fff78478..0131f5e41 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -206,14 +206,15 @@ Before emitting a tool or prose decision brief, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index deb5e1031..c8a49f274 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -206,14 +206,15 @@ Before emitting a tool or prose decision brief, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/plan-devex-review/SKILL.md b/plan-devex-review/SKILL.md index 5a20d9568..c0384e9f9 100644 --- a/plan-devex-review/SKILL.md +++ b/plan-devex-review/SKILL.md @@ -178,14 +178,15 @@ Before emitting a tool or prose decision brief, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index ad41beac6..008519c98 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -222,14 +222,15 @@ Before emitting a tool or prose decision brief, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/plan-tune/SKILL.md b/plan-tune/SKILL.md index 674c537ad..4bc67d841 100644 --- a/plan-tune/SKILL.md +++ b/plan-tune/SKILL.md @@ -190,14 +190,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index a8801d33c..2e4396520 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/qa/SKILL.md b/qa/SKILL.md index 167508805..137b68cd6 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -184,14 +184,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/retro/SKILL.md b/retro/SKILL.md index e7591bfbd..1e6514433 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -198,14 +198,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/review/SKILL.md b/review/SKILL.md index 851508312..3e620cebe 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/scrape/SKILL.md b/scrape/SKILL.md index 6aeaea27f..b5ef731dd 100644 --- a/scrape/SKILL.md +++ b/scrape/SKILL.md @@ -62,14 +62,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/scripts/resolvers/preamble/generate-brain-sync-block.ts b/scripts/resolvers/preamble/generate-brain-sync-block.ts index e5552b955..7731f378a 100644 --- a/scripts/resolvers/preamble/generate-brain-sync-block.ts +++ b/scripts/resolvers/preamble/generate-brain-sync-block.ts @@ -20,14 +20,15 @@ export function generateBrainSyncBlock(ctx: TemplateContext): string { const isBrainHost = ctx.host === 'gbrain' || ctx.host === 'hermes'; return `## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer \`gbrain\` over Grep; -\`ARTIFACTS_SYNC:\` reports sync health (\`off\`, \`mode=... | queue=N\`, -\`remote-mode\`, or a restore hint naming \`gstack-brain-restore\`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer \`gbrain\` over Grep. \`ARTIFACTS_SYNC:\` reports sync health +(\`off\`, \`mode=... | queue=N\`, \`remote-mode\`, or a \`gstack-brain-restore\` +hint). On an \`attention:\` line, tell the user in one sentence what +it says and the command it names, then continue. ${isBrainHost ? `If output shows \`ARTIFACTS_SYNC: artifacts repo detected\`, offer \`gstack-brain-restore\` via AskUserQuestion; otherwise continue. -` : ''}The one-time privacy stop-gate (artifacts-sync consent) arrives as a -\`GSTACK_INSTRUCTION\` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs.`; +` : ''}The one-time privacy stop-gate arrives as a \`GSTACK_INSTRUCTION\` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed.`; } diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 23f193d0c..1814e7dda 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -61,14 +61,15 @@ If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index a1df1d1d3..7748750b1 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -181,14 +181,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/setup-gbrain/SKILL.md b/setup-gbrain/SKILL.md index 5facd7fff..c1f145a8a 100644 --- a/setup-gbrain/SKILL.md +++ b/setup-gbrain/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/ship/SKILL.md b/ship/SKILL.md index 1ffde620c..b1505e910 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/skillify/SKILL.md b/skillify/SKILL.md index a9aaed03e..514a0b3ad 100644 --- a/skillify/SKILL.md +++ b/skillify/SKILL.md @@ -179,14 +179,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/spec/SKILL.md b/spec/SKILL.md index 14667d269..dec672c64 100644 --- a/spec/SKILL.md +++ b/spec/SKILL.md @@ -180,14 +180,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index 53fed3475..845e8eb4c 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -181,14 +181,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/test-audit/SKILL.md b/test-audit/SKILL.md index 352a14c76..13d7fb84d 100644 --- a/test-audit/SKILL.md +++ b/test-audit/SKILL.md @@ -176,14 +176,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index 1ffde620c..b1505e910 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -182,14 +182,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index 36b112e73..dfcc30550 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -164,14 +164,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (gpt) diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index d9153af7a..00bf178bf 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -166,14 +166,15 @@ Before calling AskUserQuestion, verify: ## Artifacts Sync (skill start) -The skill-start output above already ran artifacts sync. Act on its lines: -GBrain hint text (if present) tells you when to prefer `gbrain` over Grep; -`ARTIFACTS_SYNC:` reports sync health (`off`, `mode=... | queue=N`, -`remote-mode`, or a restore hint naming `gstack-brain-restore`). +Skill-start already ran artifacts sync. GBrain hint text (if any) says +when to prefer `gbrain` over Grep. `ARTIFACTS_SYNC:` reports sync health +(`off`, `mode=... | queue=N`, `remote-mode`, or a `gstack-brain-restore` +hint). On an `attention:` line, tell the user in one sentence what +it says and the command it names, then continue. -The one-time privacy stop-gate (artifacts-sync consent) arrives as a -`GSTACK_INSTRUCTION` block from skill-start when consent is actually pending -— fire it via AskUserQuestion exactly as the block instructs. +The one-time privacy stop-gate arrives as a `GSTACK_INSTRUCTION` block +from skill-start when consent is pending; fire it via AskUserQuestion +exactly as instructed. ## Model-Specific Behavioral Patch (claude) diff --git a/test/gstack-skill-start.test.ts b/test/gstack-skill-start.test.ts index 0d159a046..0cadd4bd8 100644 --- a/test/gstack-skill-start.test.ts +++ b/test/gstack-skill-start.test.ts @@ -434,6 +434,173 @@ describe('gstack-skill-start behavior', () => { }); }); +// --------------------------------------------------------------- +// ARTIFACTS_SYNC attention lines. The cases are generated from the sync +// status table in bin/gstack-brain-sync's usage header: every row needs a +// fixture, and each fixture must print exactly that row's line. +// --------------------------------------------------------------- +describe('ARTIFACTS_SYNC attention lines (sync status table)', () => { + const SYNC = path.join(ROOT, 'bin', 'gstack-brain-sync'); + const iso = (ms: number) => new Date(ms).toISOString().replace(/\.\d{3}Z$/, 'Z'); + const NOW = () => iso(Date.now()); + const OLD = () => iso(Date.now() - 2 * 86_400_000); + type Row = { state: string; trigger: string; line: string; fix: string }; + + function statusTable(): Row[] { + const rows: Row[] = []; + for (const raw of fs.readFileSync(SYNC, 'utf-8').split('\n')) { + const head = raw.match(/^# ([a-z_-]+)\s+trigger: (.+)$/); + if (head) { rows.push({ state: head[1], trigger: head[2], line: '', fix: '' }); continue; } + const field = raw.match(/^#\s+(line|fix):\s+(.+)$/); + if (field && rows.length) rows[rows.length - 1][field[1] as 'line' | 'fix'] = field[2]; + } + return rows; + } + const attention = (out: string) => out.split('\n').filter((l) => l.startsWith('ARTIFACTS_SYNC: attention: ')); + + /** An initialized sync home whose drain lock is held by this (live) test + * process, so skill start's merge and drain skip and the fixture's status + * file is what skill start reads. */ + function syncHome(status: Record | string | null, queued = 0): string { + const gh = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-attn-')); + execFileSync('git', ['init', '-q', '-b', 'main', gh], { timeout: 30_000, stdio: 'pipe' }); + fs.writeFileSync(path.join(gh, 'config.yaml'), 'update_check: false\nartifacts_sync_mode: full\nartifacts_sync_mode_prompted: true\n'); + fs.mkdirSync(path.join(gh, '.brain-sync.lock.d')); + fs.writeFileSync(path.join(gh, '.brain-sync.lock.d', 'pid'), `${process.pid}\n`); + if (status !== null) { + fs.writeFileSync(path.join(gh, '.brain-sync-status.json'), typeof status === 'string' ? status : JSON.stringify(status) + '\n'); + } + fs.mkdirSync(path.join(gh, '.brain-queue.d')); + for (let i = 0; i < queued; i++) { + fs.writeFileSync(path.join(gh, '.brain-queue.d', `${Math.floor(Date.now() / 1000)}-1-q${i}.json`), '{"file":"projects/p/x.md"}\n'); + } + return gh; + } + const status = (code: string, extra: Record = {}) => ({ + status: code, held_count: 0, drainable: 0, last_drain_at: NOW(), last_push_at: NOW(), ts: NOW(), held: [], message: 'm', ...extra, + }); + + const FIXTURES: Record Record; queued?: number; n?: number }> = { + held: { status: () => status('held', { held_count: 2 }), n: 2 }, + blocked: { status: () => status('blocked') }, + push_failed: { status: () => status('push_failed') }, + error: { status: () => status('error') }, + unknown: { status: () => status('rebooting') }, + 'stale-push': { status: () => status('idle', { drainable: 3, last_push_at: OLD() }), queued: 3 }, + 'stale-drain': { status: () => status('ok', { last_drain_at: OLD() }), queued: 1 }, + }; + + test('the table names every state skill start can report, each with a line and a fix', () => { + const rows = statusTable(); + expect(rows.map((r) => r.state).sort()).toEqual(Object.keys(FIXTURES).sort()); + // The docs carry the same table (one source of wording). + const docs = fs.readFileSync(path.join(ROOT, 'docs', 'gbrain-sync-errors.md'), 'utf-8'); + for (const r of rows) { + expect(r.line).toStartWith('ARTIFACTS_SYNC: attention: '); + expect(r.line).toContain(' --status'); + expect(r.fix.length).toBeGreaterThan(0); + expect(docs).toContain('`' + r.line.slice('ARTIFACTS_SYNC: attention: '.length) + '`'); + } + }); + + for (const row of statusTable()) { + test(`${row.state}: ${row.trigger}`, () => { + const fx = FIXTURES[row.state]; + expect(fx).toBeDefined(); + const gh = syncHome(fx.status(), fx.queued ?? 0); + try { + const expected = row.line.replaceAll('', SYNC).replaceAll('', String(fx.n ?? 0)); + expect(attention(runStart([], { GSTACK_HOME: gh }))).toEqual([expected]); + } finally { + fs.rmSync(gh, { recursive: true, force: true }); + } + }); + } + + test('ok and idle print no attention line', () => { + for (const code of ['ok', 'idle']) { + const gh = syncHome(status(code), 1); + try { + const out = runStart([], { GSTACK_HOME: gh }); + expect(out).toMatch(/^ARTIFACTS_SYNC: mode=full \| last_push=\S+ \| queue=\d+$/m); + expect(attention(out)).toEqual([]); + } finally { + fs.rmSync(gh, { recursive: true, force: true }); + } + } + }); + + test('attention lines carry no status text, artifact path or bare helper name', () => { + const leak = 'ghp_abcdefghij1234567890abcdef1234567890'; + const gh = syncHome(status('held', { + held_count: 7, + message: `secret pattern detected (github-token:${leak.slice(0, 30)}...) in projects/p/learnings.jsonl`, + held: [{ path: 'projects/p/learnings.jsonl', rule: 'github-token', dependents: [], fixes: ['gstack-brain-sync --skip-file projects/p/learnings.jsonl'] }], + last_drain_at: `${NOW()}"; echo pwned`, + }), 1); + try { + const lines = attention(runStart([], { GSTACK_HOME: gh })); + expect(lines.length).toBeGreaterThan(0); + const text = lines.join('\n'); + expect(text).not.toContain('ghp_'); + expect(text).not.toContain('projects/p'); + expect(text).not.toContain('pwned'); + // The only path is the absolute helper path; no bare gstack- command remains. + const stripped = text.replaceAll(SYNC, ''); + expect(stripped).not.toContain('/'); + expect(stripped).not.toContain('gstack-'); + // A forged last_drain_at fails the timestamp clamp, which reads as a drain that never ran. + expect(lines).toContain(`ARTIFACTS_SYNC: attention: stale-drain. The sync has not run for over 24 hours while files wait in the queue. See why: ${SYNC} --status`); + } finally { + fs.rmSync(gh, { recursive: true, force: true }); + } + }); + + test('a held file is reported at skill start while other files keep pushing; a privacy-held queue raises no alarm', () => { + const home = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-sync-home-')); + const gh = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-sync-gh-')); + const remote = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-sync-remote-')); + const env = { PATH: process.env.PATH!, HOME: home, GSTACK_HOME: gh }; + const bin = (name: string, args: string[]) => + execFileSync(path.join(ROOT, 'bin', name), args, { timeout: 30_000, encoding: 'utf-8', cwd: home, env, stdio: 'pipe' }); + const remoteFiles = () => execFileSync('git', ['--git-dir=' + remote, 'ls-tree', '-r', '--name-only', 'main'], { encoding: 'utf-8', timeout: 30_000 }); + try { + execFileSync('git', ['init', '-q', '--bare', '-b', 'main', remote], { timeout: 30_000 }); + bin('gstack-artifacts-init', ['--remote', remote]); + bin('gstack-config', ['set', 'artifacts_sync_mode', 'full']); + bin('gstack-config', ['set', 'artifacts_sync_mode_prompted', 'true']); + bin('gstack-config', ['set', 'update_check', 'false']); + fs.mkdirSync(path.join(gh, 'projects/p/ceo-plans'), { recursive: true }); + fs.writeFileSync(path.join(gh, 'projects/p/learnings.jsonl'), '{"gh":"ghp_abcdefghij1234567890abcdef1234567890"}\n'); + fs.writeFileSync(path.join(gh, 'projects/p/ceo-plans/clean.md'), '# a plan\n'); + bin('gstack-brain-enqueue', ['projects/p/learnings.jsonl']); + bin('gstack-brain-enqueue', ['projects/p/ceo-plans/clean.md']); + + const held = runStart([], env); + expect(held).toMatch(/^ARTIFACTS_SYNC: mode=full \| last_push=\S+ \| queue=\d+$/m); + expect(attention(held)).toEqual([ + `ARTIFACTS_SYNC: attention: status=held held=1. The secret scan is holding back 1 file(s); everything else still syncs. See which files and how to fix them: ${path.join(ROOT, 'bin', 'gstack-brain-sync')} --status`, + ]); + expect(held).not.toContain('ghp_'); + expect(remoteFiles()).toContain('projects/p/ceo-plans/clean.md'); + expect(remoteFiles()).not.toContain('projects/p/learnings.jsonl'); + + // Privacy-held records never count as drainable: no alarm, even with + // the last push two days old. + bin('gstack-brain-sync', ['--skip-file', 'projects/p/learnings.jsonl']); + bin('gstack-config', ['set', 'artifacts_sync_mode', 'artifacts-only']); + fs.writeFileSync(path.join(gh, 'projects/p/timeline.jsonl'), '{"skill":"x"}\n'); + bin('gstack-brain-enqueue', ['projects/p/timeline.jsonl']); + fs.writeFileSync(path.join(gh, '.brain-last-push'), `${OLD()}\n`); + const quiet = runStart([], env); + expect(quiet).toMatch(/^ARTIFACTS_SYNC: mode=artifacts-only \| last_push=\S+ \| queue=\d+$/m); + expect(attention(quiet)).toEqual([]); + } finally { + for (const dir of [home, gh, remote]) fs.rmSync(dir, { recursive: true, force: true }); + } + }, 60_000); +}); + describe('gstack-skill-end', () => { test('computes duration from --tel-start and reports the outcome', () => { const start = Math.floor(Date.now() / 1000) - 7;