Buttons: one definition, aligned to the design system — plus local prior-art recall #94
+56
-1
@@ -181,13 +181,25 @@ def check_shellcheck() -> None:
|
|||||||
# pinning: the bug and the healthy no-results case look identical from outside.
|
# pinning: the bug and the healthy no-results case look identical from outside.
|
||||||
# Pinning it does NOT make the failure visible; it makes sure the fail-open
|
# Pinning it does NOT make the failure visible; it makes sure the fail-open
|
||||||
# behaviour is deliberate rather than accidental.
|
# behaviour is deliberate rather than accidental.
|
||||||
|
# A symbol that exists nowhere, ASSEMBLED rather than written literally.
|
||||||
|
# The prior-art hook's local arm (#2280) fires with no credentials, so the
|
||||||
|
# silence assertion below needs a name the repo genuinely lacks. Two traps,
|
||||||
|
# both hit while writing this:
|
||||||
|
# - `def f` matched real code, so the hook spoke and "silent" was asserting
|
||||||
|
# the wrong thing;
|
||||||
|
# - spelling the replacement out in full put `def <name>(` INTO this file,
|
||||||
|
# so the smoke event defined the very symbol it claimed was absent.
|
||||||
|
# Concatenating keeps the contiguous string out of the source.
|
||||||
|
_ABSENT_SYM = "zz" + "_absent_" + "9f3a2b"
|
||||||
|
|
||||||
SMOKE_EVENTS: dict[str, str] = {
|
SMOKE_EVENTS: dict[str, str] = {
|
||||||
"scribe_autoinject.sh": json.dumps(
|
"scribe_autoinject.sh": json.dumps(
|
||||||
{"session_id": "smoke", "cwd": ".", "prompt": "a multi-line\nprompt\nhere"}
|
{"session_id": "smoke", "cwd": ".", "prompt": "a multi-line\nprompt\nhere"}
|
||||||
),
|
),
|
||||||
"scribe_prior_art.sh": json.dumps(
|
"scribe_prior_art.sh": json.dumps(
|
||||||
{"session_id": "smoke", "cwd": ".", "tool_name": "Edit",
|
{"session_id": "smoke", "cwd": ".", "tool_name": "Edit",
|
||||||
"tool_input": {"file_path": "src/x.py", "new_string": "def f():\n pass\n"}}
|
"tool_input": {"file_path": "src/x.py",
|
||||||
|
"new_string": f"def {_ABSENT_SYM}():\n pass\n"}}
|
||||||
),
|
),
|
||||||
"scribe_sync_processes.sh": json.dumps({"source": "startup"}),
|
"scribe_sync_processes.sh": json.dumps({"source": "startup"}),
|
||||||
"scribe_session_context.sh": json.dumps({"source": "startup"}),
|
"scribe_session_context.sh": json.dumps({"source": "startup"}),
|
||||||
@@ -253,6 +265,48 @@ def check_fail_open() -> None:
|
|||||||
ok(f"{rel} [{label}]: exit 0, silent")
|
ok(f"{rel} [{label}]: exit 0, silent")
|
||||||
|
|
||||||
|
|
||||||
|
def check_local_prior_art_needs_no_instance() -> None:
|
||||||
|
"""The prior-art hook's local arm must answer with no credentials (#2280).
|
||||||
|
|
||||||
|
The other arms ask Scribe what was RECORDED. This one asks the repo what
|
||||||
|
EXISTS, which needs no instance — and that is the whole reason it catches
|
||||||
|
the case the recorded arms structurally cannot: a helper nobody thought to
|
||||||
|
record. If it ever silently starts depending on configuration, it stops
|
||||||
|
covering that case and nothing else would notice.
|
||||||
|
|
||||||
|
Paired with the silence assertion in check_fail_open, which uses a symbol
|
||||||
|
that cannot exist. Together they pin both halves: silent when there is
|
||||||
|
nothing to say, and speaking when there is — both with no instance at all.
|
||||||
|
"""
|
||||||
|
script = HOOKS_DIR / "scribe_prior_art.sh"
|
||||||
|
if not script.is_file() or not shutil.which("jq"):
|
||||||
|
skip("prior-art local arm: hook or jq missing")
|
||||||
|
return
|
||||||
|
|
||||||
|
# A definition this repo really does contain, written into a DIFFERENT file
|
||||||
|
# so the self-match exclusion doesn't suppress it.
|
||||||
|
event = json.dumps({
|
||||||
|
"session_id": "smoke", "cwd": ".", "tool_name": "Write",
|
||||||
|
"tool_input": {
|
||||||
|
"file_path": "scripts/_probe_not_real.py",
|
||||||
|
"content": "def check_local_prior_art_needs_no_instance():\n pass\n",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
proc = _run_hook(script, event, {}) # NO credentials, on purpose
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
fail("prior-art local arm: hung")
|
||||||
|
return
|
||||||
|
if proc.returncode != 0:
|
||||||
|
fail(f"prior-art local arm: exited {proc.returncode}, must be 0")
|
||||||
|
elif "already defined" not in proc.stdout:
|
||||||
|
fail("prior-art local arm: found nothing for a symbol this repo "
|
||||||
|
"defines, with no credentials — the arm that needs no instance "
|
||||||
|
"has stopped working, and the recorded arms cannot cover for it")
|
||||||
|
else:
|
||||||
|
ok("prior-art local arm: answers with no instance configured")
|
||||||
|
|
||||||
|
|
||||||
def _git(*args: str) -> tuple[int, str]:
|
def _git(*args: str) -> tuple[int, str]:
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
["git", *args], capture_output=True, text=True, cwd=ROOT
|
["git", *args], capture_output=True, text=True, cwd=ROOT
|
||||||
@@ -344,6 +398,7 @@ def main() -> int:
|
|||||||
check_patterns()
|
check_patterns()
|
||||||
check_shellcheck()
|
check_shellcheck()
|
||||||
check_fail_open()
|
check_fail_open()
|
||||||
|
check_local_prior_art_needs_no_instance()
|
||||||
if not args.no_version:
|
if not args.no_version:
|
||||||
check_version_bump(args.base)
|
check_version_bump(args.base)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user