You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up from the retroactive 6-AI verify of #18 (master report). The three HIGH findings + two MEDIUM (F1 warn-bypass, F2 escape-hatch, F3 typo-message, F4 is_fable-lowercase, F6 wording) were fixed in 27cb144 (v1.12.1). This issue tracks the remaining, non-blocking findings — scope-expansion + theoretical + one pre-existing.
F5 (MEDIUM) — Agent side-door. A single turn can emit multiple parallel Agent tool-use blocks (a sanctioned pattern); none trip the fable gate, which only fires on tool_name == "Workflow". So up to MAX_IN_WINDOW concurrent fable-tier Agent dispatches can launch with no fable-aware protection (the per-bucket burst guard still counts them, so there is some backstop). pacing-guard.py:513(DA.) Options: extend fable-awareness to a fan-out of Agent blocks, or explicitly document that the burst guard is the intended backstop for parallel-Agent fable bursts. Decide which — right now it's an unstated gap.
F7 (LOW) — is_fable() prefix has no word boundary."claude-fablecraft-1".lower().startswith("claude-fable") → True. Purely theoretical given Anthropic's family-dash-version naming, but re.match(r"claude-fable(?:-|$)", model.lower()) would tighten without losing real variants (claude-fable-5, dated suffixes, bare claude-fable). pacing-guard.py:213-217(Logic + Codex.)
F8 (LOW) — is_fable() bakes in "fable ⇒ expensive" with no tier gate. The gate assumes every claude-fable* id is the expensive top tier. If Anthropic ever ships a cheap fable variant, it'd be wrongly denied. Theoretical; revisit if the fable line ever gains tiers. (DA.)
F10 (LOW, pre-existing — NOT a pacing-guard 應擋「Fable 5 session 開 Workflow」(fable5 + 寬 fan-out = 必炸;hook 機制已備、缺 fable 辨識 + deny 分支) #18 regression) — burst-deny message leaks the absolute data_dir path. The existing burst-deny context (pacing-guard.py, the count >= max_in_window branch) interpolates the real absolute data_dir / disabled / max-override paths, which include the local username. pacing-guard 應擋「Fable 5 session 開 Workflow」(fable5 + 寬 fan-out = 必炸;hook 機制已備、缺 fable 辨識 + deny 分支) #18's fable-deny was noted by the security reviewer as more conservative before this fix; the v1.12.1 fix now also interpolates the real path into the fable-deny escape-hatch instruction (deliberate — actionability requires a copy-pasteable path, and it's shown in the user's own terminal). If path-in-deny-message is judged a real concern, it should be addressed uniformly across all deny sites (or accepted as "shown only to the owning user"). (Security, incidental.)
Not in scope / accepted residue
The blanket-deny false positive (a fable5 workflow with every agent() already pinned to a cheap model is still denied) remains the acknowledged Residue from #18's diagnosis — a PreToolUse hook can't parse-and-prove every agent() is pinned reliably, so blanket-deny + the (now mid-session-actionable, per F2 fix) off/warn override is the intended approximation. The v1.12.1 fixes made the override work; they don't remove the residue.
Context
Follow-up from the retroactive 6-AI verify of #18 (master report). The three HIGH findings + two MEDIUM (F1 warn-bypass, F2 escape-hatch, F3 typo-message, F4 is_fable-lowercase, F6 wording) were fixed in
27cb144(v1.12.1). This issue tracks the remaining, non-blocking findings — scope-expansion + theoretical + one pre-existing.Findings (verify #18, deferred)
F5 (MEDIUM) — Agent side-door. A single turn can emit multiple parallel
Agenttool-use blocks (a sanctioned pattern); none trip the fable gate, which only fires ontool_name == "Workflow". So up toMAX_IN_WINDOWconcurrent fable-tierAgentdispatches can launch with no fable-aware protection (the per-bucket burst guard still counts them, so there is some backstop).pacing-guard.py:513(DA.) Options: extend fable-awareness to a fan-out ofAgentblocks, or explicitly document that the burst guard is the intended backstop for parallel-Agent fable bursts. Decide which — right now it's an unstated gap.F7 (LOW) —
is_fable()prefix has no word boundary."claude-fablecraft-1".lower().startswith("claude-fable")→ True. Purely theoretical given Anthropic'sfamily-dash-versionnaming, butre.match(r"claude-fable(?:-|$)", model.lower())would tighten without losing real variants (claude-fable-5, dated suffixes, bareclaude-fable).pacing-guard.py:213-217(Logic + Codex.)F8 (LOW) —
is_fable()bakes in "fable ⇒ expensive" with no tier gate. The gate assumes everyclaude-fable*id is the expensive top tier. If Anthropic ever ships a cheap fable variant, it'd be wrongly denied. Theoretical; revisit if the fable line ever gains tiers. (DA.)F10 (LOW, pre-existing — NOT a pacing-guard 應擋「Fable 5 session 開 Workflow」(fable5 + 寬 fan-out = 必炸;hook 機制已備、缺 fable 辨識 + deny 分支) #18 regression) — burst-deny message leaks the absolute
data_dirpath. The existing burst-deny context (pacing-guard.py, thecount >= max_in_windowbranch) interpolates the real absolutedata_dir/disabled/max-overridepaths, which include the local username. pacing-guard 應擋「Fable 5 session 開 Workflow」(fable5 + 寬 fan-out = 必炸;hook 機制已備、缺 fable 辨識 + deny 分支) #18's fable-deny was noted by the security reviewer as more conservative before this fix; the v1.12.1 fix now also interpolates the real path into the fable-deny escape-hatch instruction (deliberate — actionability requires a copy-pasteable path, and it's shown in the user's own terminal). If path-in-deny-message is judged a real concern, it should be addressed uniformly across all deny sites (or accepted as "shown only to the owning user"). (Security, incidental.)Not in scope / accepted residue
The blanket-deny false positive (a fable5 workflow with every
agent()already pinned to a cheap model is still denied) remains the acknowledged Residue from #18's diagnosis — a PreToolUse hook can't parse-and-prove everyagent()is pinned reliably, so blanket-deny + the (now mid-session-actionable, per F2 fix)off/warnoverride is the intended approximation. The v1.12.1 fixes made the override work; they don't remove the residue.