The synthetic example 'sk-synthetic-litellm-' in hermes-key-enforcement.prose.md:217
was flagged by the secret-assign rule as a credential-shaped assignment. The
existing allowlist entry only covered openai-key, so secret-assign still failed.
Fix: Change the rule from openai-key to * (matches any rule) and update the
reason to explain why (2026-10-03: secret-assign also matches the credential-shaped
assignment).
This restores prose-lint on master, which was RED and blocking every open PR's
lint job (including PR #149's lint job 2160).
Chose option (b) (allowlist) over option (a) (restructure) because:
- The existing entry already documented the synthetic example
- Changing the rule to * is the minimal, honest fix
- Restructuring the command would risk weakening the enforcement check
Correlation: corr=7c202734ec6c452a
- Replace grep-based timeout control with sleep 5s command that cannot
finish in time, guaranteeing exit=124 (timeout)
- Run the control TWICE to prove determinism (exit=124 both times)
- Remove stale 0.9 s figure that was wrong by 13x
- Keep exit-status interpretation (124 vs 255) and probe-failed rendering
unchanged
Correlation: corr=bf05539bfb04f1ff
- State the COLD figure (5.7s), not the warm one (0.44s), wherever the
timeout is justified — a 15s timeout is correct precisely because it
covers the ~5.7s cold scan, not because the scan costs 0.44s
- Do NOT assert a proven cause for the original failure: the contract had
no documented timeout and no failure-kind rendering, so the honest
wording is that a slow/cold scan exceeded whatever bound that run used
and was rendered as a host-down verdict
- Keep the exit-status interpretation (124 vs 255) and the negative
control exactly as they are — those are the real fix
Correlation: corr=9531ff9ce03ba876
DEFECT 1: Step 2 had TWO commands as separate ssh arguments (second grep
never ran). Fixed by combining into ONE quoted remote command separated
by ';'.
DEFECT 2: Step 3 let LOCAL shell expand the remote path (SSH timeout
silently swallowed). Fixed by single-quoting remote command so
expands on the REMOTE host.
DEFECT 3: Timing figures understated (0.91s vs actual 0.451s over SSH).
Re-measured with method stated: 'over SSH, cold cache, 2026-10-02'.
VERIFIED:
- All 3 commands run against koby (192.168.68.129) verbatim
- Negative control (0.2s timeout) returns exit 124 (timeout), not 255
- Bounded scan excludes state-snapshots/ (exit 1 vs full scan exit 0)
- Step 3 now shows probe-failed error instead of silently swallowed
Correlation: corr=cc8d8ac2d5065818
Problem: koby's 16 GB .hermes tree made the grep scan take 5.7s, exceeding
the leg's timeout. The timeout was rendered as 'agent may be down' when the
host was actually up and the scan just needed more time.
Changes:
1. Bounded scan: --exclude-dir=state-snapshots (0.44s vs 0.91s on koby)
2. Timeout policy: 15s scan timeout, 10s SSH connect timeout (documented)
3. Failure kinds: probe-failed (timeout) vs unreachable (ssh connect failed)
4. Negative control: 1s timeout proves probe-failed not down
Measured cost (2026-10-02): koby full scan 0.91s, bounded 0.44s.
Timeout set to 15s for headroom.
Correlation: corr=69683f073322b46c
@@ -186,30 +186,60 @@ Agent keys live in `.env` or `.env.vault` files with 600 permissions (koonimo's
## Detection Query
Run on any Hermes host to detect violations:
Run on any Hermes host to detect violations.
**Timeout policy (2026-10-02):** The scan timeout is **15 seconds**, set from measured cost on the largest target (koby, 16 GB `.hermes` tree; full scan: **cold ≈ 5.7 s**, warm ≈ 0.44 s; bounded scan: warm ≈ 0.37 s, over SSH, measured 2026-10-02). The 15 s bound is justified by the COLD cost, not the warm cost — a 13× cold/warm spread means the warm figure alone would understate the real worst case by an order of magnitude. The SSH connection timeout is **10 seconds** (separate from the scan timeout). A scan timeout renders as `probe-failed: <agent> <ip> (timeout after 15s)` — **never** as "unreachable" or "may be down". An SSH connection failure (exit status 255) renders as `unreachable: <agent> <ip> (ssh connect failed)`. The original failure (2026-10-02 koby) was a slow/cold scan that exceeded whatever bound the prior run used and was rendered as a host-down verdict; the exact prior timeout was never reproduced, so this is the only proven fix: honest failure-kind rendering plus the bounded scan.
**Bounded scan (2026-10-02):** Do NOT recurse the entire `/root/.hermes/` tree. Use `--exclude-dir=state-snapshots` to skip dated snapshot directories. Rationale: a superseded config will always carry a superseded key and will report forever with zero signal content (the koby state-snapshot line has repeated on consecutive days). If you deliberately want to include snapshots, say so in the contract and the report.
# example is always an explicit exception, never a pattern-level exemption.
* hermes-key-enforcement.prose.md sk-synthetic-external-example Rule 15 illustration of a hardcoded external key that is tolerated; fabricated, never a live key.
* hermes-key-enforcement.prose.md sk-synthetic-example-12345 Rule 15 illustration of a forbidden hardcoded key; fabricated, never a live key.
openai-key hermes-key-enforcement.prose.md sk-synthetic-litellm- Fabricated key name inside a `grep 'LITELLM_API_KEY=...'` example; not a live key.
* hermes-key-enforcement.prose.md sk-synthetic-litellm- Fabricated key name inside a `grep 'LITELLM_API_KEY=...'` example; not a live key. (2026-10-03: changed rule from openai-key to * because secret-assign also matches the credential-shaped assignment)
secret-assign hermes-key-enforcement.prose.md sk-NEW_KEY Placeholder standing for the rotated key in an `infisical secrets set` command; not a literal key.
openrouter-key agent-zero-openrouter-key.prose.md sk-or-v1-synthetic Synthetic key prefix in the contract's example response; the real key is read from the vault.
openai-key litellm-api-keys.prose.md sk-synthetic-tanko-example Fabricated key name in migration history prose; not a live key.
Can't render this file because it contains an unexpected character in line 23 and column 25.
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.