The hooks need no jq, and the prompt boundary retrieves against prompts #171

Merged
bvandeusen merged 4 commits from dev into main 2026-09-20 18:50:03 -04:00
4 changed files with 19 additions and 19 deletions
Showing only changes of commit 4bfa0cbbc0 - Show all commits
+13 -14
View File
@@ -111,7 +111,7 @@ jobs:
# Guards the one part of this repo that ships to users without a build step.
# See scripts/check_plugin.py for what it checks and, as importantly, what it
# can't check yet (shellcheck and jq are absent from ci-python).
# can't check yet (shellcheck is absent from ci-python).
plugin:
name: Plugin hooks
if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
@@ -133,12 +133,15 @@ jobs:
# the only consumer today. Promotion into ci-python is filed as an issue
# on CI-runner rather than assumed here.
#
# jq is not optional for the smoke test: every hook exits at line 1
# without it, so the check would pass while exercising nothing.
# jq WAS installed here too, because every hook exited at line 1 without
# it and the smoke test would have passed while exercising nothing. The
# hooks need no jq since #4107 — they use only what POSIX guarantees — so
# the smoke test now runs on a bare image, which is the condition it is
# actually meant to be asserting.
- name: Install shell tooling
run: |
apt-get update -qq
apt-get install -y -qq --no-install-recommends jq shellcheck
apt-get install -y -qq --no-install-recommends shellcheck
# On main the comparison would be against itself, so only the syntax and
# pattern checks mean anything there.
@@ -223,16 +226,12 @@ jobs:
UV_PROJECT_ENVIRONMENT: /opt/venv
run: uv sync --locked --extra dev
# The hook-EXECUTION tests (test_write_path_trigger's nudge pair) run the
# real bash hook, which exits silently without jq — and those tests skip
# rather than fail when it's absent, so without this step they would
# quietly never be verified anywhere (ci-python ships without jq; same
# install the Plugin hooks job does).
- name: Install jq for hook execution tests
run: |
apt-get update -qq
apt-get install -y -qq --no-install-recommends jq
# An "Install jq for hook execution tests" step stood here. The hook
# EXECUTION tests run the real bash hook, which exited silently without
# jq and skipped rather than failed, so the step existed to stop them
# being silently unverified. Since #4107 the hooks need no jq, so the
# step is gone and those tests run against a bare image — and the point
# of removing a dependency is lost if CI keeps installing it anyway.
- name: Run tests
# Integration tests (real Postgres) run in the `integration` job below.
run: /opt/venv/bin/python -m pytest tests/ -q -m "not integration"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "scribe",
"description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting), and syncs your saved Scribe Processes as skills (/scribe:sync).",
"version": "2026.09.20.1620",
"version": "2026.09.20.1623",
"author": {
"name": "Bryan Van Deusen"
},
+1 -1
View File
@@ -119,7 +119,7 @@ turn_facts() { window | tail -n +"${1:-1}" | scribe_json_flat_lines \
# slow way — correct, and slow, which is the right way round for a check that
# can block a stop.
start=$(window | grep -n -F '"message":{"role":"user","content":"' 2>/dev/null \
| cut -d: -f1 | awk 'END { if (NR) print $0 }')
| cut -d: -f1 | awk '{ last = $0 } END { if (NR) print last }')
case "$start" in ''|*[!0-9]*) start=1 ;; esac
facts=$(turn_facts "$start")
+4 -3
View File
@@ -1091,8 +1091,9 @@ def test_hook_keeps_sync_and_reuse_dedup_apart():
assert ".sync.ids" in src # its own state file
assert "exclude_sync_ids=" in src # its own query channel
# The reuse file must NOT swallow sync ids — the write-back subtracts them.
assert "(.note_ids // []) - (.sync_note_ids // [])" in src
assert "(.sync_note_ids // [])[]?" in src
# Spelled with the readers that replaced jq (#4107); the claim is unchanged.
assert "scribe_json_list_minus \"$body_flat\" '.note_ids' '.sync_note_ids'" in src
assert "scribe_json_list \"$body_flat\" '.sync_note_ids'" in src
def _hook_runtime_env():
@@ -1668,7 +1669,7 @@ def test_hook_keeps_the_rule_channel_apart_from_the_other_three():
src = HOOK.read_text()
assert ".rules.ids" in src # its own state file
assert "exclude_rule_ids=" in src # its own query channel
assert "(.rule_ids // [])[]?" in src # its own write-back
assert "scribe_json_list \"$body_flat\" '.rule_ids'" in src # its own write-back
# And it rides the same request as the rest, not a second round trip.
assert "${rule_exclude_q}" in src