From b0ece62e2d44c975e8950194f5beea3c946de11d Mon Sep 17 00:00:00 2001 From: garrytan Date: Wed, 7 Oct 2026 20:10:04 +0000 Subject: [PATCH] feat(skill-start): ARTIFACTS_SYNC attention lines for a stuck sync Skill start now prints one fixed attention line per sync-status-table row that applies (held, blocked, push_failed, error, unknown, stale-push, stale-drain), each naming gstack-brain-sync by absolute path. Values from the status file are clamped (status code to the table, counts to digits, timestamps to their shape), so the status message, file paths and scanner output never reach the line. The preamble tells the model to surface the line in one sentence and continue. Skill-start tests are generated from the table in bin/gstack-brain-sync, and docs/gbrain-sync-errors.md carries the same table. Co-authored-by: v639dragoon Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- SKILL.md | 15 +- autoplan/SKILL.md | 15 +- benchmark-models/SKILL.md | 15 +- benchmark/SKILL.md | 15 +- bin/gstack-skill-start | 3 + browse/SKILL.md | 15 +- canary/SKILL.md | 15 +- codex/SKILL.md | 15 +- context-restore/SKILL.md | 15 +- context-save/SKILL.md | 15 +- design-consultation/SKILL.md | 15 +- design-html/SKILL.md | 15 +- design-review/SKILL.md | 15 +- design-shotgun/SKILL.md | 15 +- devex-review/SKILL.md | 15 +- diagram/SKILL.md | 15 +- docs/gbrain-sync-errors.md | 60 +++++-- docs/gbrain-sync.md | 30 ++-- document-generate/SKILL.md | 15 +- document-release/SKILL.md | 15 +- health/SKILL.md | 15 +- investigate/SKILL.md | 15 +- ios-clean/SKILL.md | 15 +- ios-design-review/SKILL.md | 15 +- ios-fix/SKILL.md | 15 +- ios-qa/SKILL.md | 15 +- ios-sync/SKILL.md | 15 +- land-and-deploy/SKILL.md | 15 +- landing-report/SKILL.md | 15 +- learn/SKILL.md | 15 +- make-pdf/SKILL.md | 15 +- office-hours/SKILL.md | 15 +- open-gstack-browser/SKILL.md | 15 +- pair-agent/SKILL.md | 15 +- plan-ceo-review/SKILL.md | 15 +- plan-design-review/SKILL.md | 15 +- plan-devex-review/SKILL.md | 15 +- plan-eng-review/SKILL.md | 15 +- plan-tune/SKILL.md | 15 +- qa-only/SKILL.md | 15 +- qa/SKILL.md | 15 +- retro/SKILL.md | 15 +- review/SKILL.md | 15 +- scrape/SKILL.md | 15 +- .../preamble/generate-brain-sync-block.ts | 15 +- setup-browser-cookies/SKILL.md | 15 +- setup-deploy/SKILL.md | 15 +- setup-gbrain/SKILL.md | 15 +- ship/SKILL.md | 15 +- skillify/SKILL.md | 15 +- spec/SKILL.md | 15 +- sync-gbrain/SKILL.md | 15 +- test-audit/SKILL.md | 15 +- test/fixtures/golden/claude-ship-SKILL.md | 15 +- test/fixtures/golden/codex-ship-SKILL.md | 15 +- test/fixtures/golden/factory-ship-SKILL.md | 15 +- test/gstack-skill-start.test.ts | 167 ++++++++++++++++++ 57 files changed, 654 insertions(+), 401 deletions(-) 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;