So neither config is broken. What the audit actually detected is that both agents route to a provider other than the internal harness - a policy question for the captain, not a fault. Two distinct errors were being committed at once: mislabelling policy as breakage, and asserting a credential/base_url fault that live evidence contradicts.
A third error of the same family: Koonimo's config names api_key_env: LITELLM_API_KEY at top level while her runtime resolves provider: deepseek to her DeepSeek key and succeeds - the audit inferred credential resolution from config text and got it wrong.
Changes
Each of hermes-key-enforcement, hermes-config-template and hermes-agent-baseline gains a Violation Classification section (20 lines each) that requires:
POLICY (observation only, never phrased as breakage): the agent uses a non-harness provider, or a config field looks unusual while its calls succeed - e.g. POLICY: Koonimo uses deepseek directly; calls succeeding in the last hour.
FAULT (needs request-level evidence): calls failing with an observed auth error, or a missing key together with failing calls - e.g. FAULT: Koby's key expired; 401 observed at <timestamp>.
Explicit rules: do not infer the runtime's credential resolution from config text; require an observed auth failure or the absence of successful calls before calling anything a fault; state what was OBSERVED, not what a field implies.
Verification
Three-dot diff against master (71ceda0, the #89 merge): 3 files, +60/-0, contracts only.
No assertion about either agent's compliance is made by this PR - it changes what the contracts are allowed to claim. The two agents above remain as they are, reported as POLICY with the log lines that prove their calls succeed.
Reviewers: confirm no contract can still print a provider difference under a fault label, and that each FAULT example names an observable (a 401, or an empty success window) rather than a config reading. The policy question itself (should every agent route through the harness?) is with the captain and deliberately left undecided in the contracts.
Follow-up to #89. That fix made the audit's reachability verdict trustworthy; this one fixes what the audit *says* about what it finds.
## The defect (measured today)
Minutes after #89 merged, the same contracts reported two further "violations":
- **Mumuni (192.168.68.14)** - "empty base_url/api_key in multiple places"
- **Koonimo (192.168.68.114)** - "wrong base_url: https://api.deepseek.com/v1"
Both agents are working. Their own logs, read at the authority:
```
kagentz .14 2026-09-14 12:11:49 API call #40: model=glm-5.3-flash provider=custom in=58423 out=190 total=58613
baggy .114 2026-09-14 06:05:37 API call #10: model=deepseek-v4-pro provider=deepseek in=83375 out=4509
```
So neither config is broken. What the audit actually detected is that both agents route to a provider **other than the internal harness** - a policy question for the captain, not a fault. Two distinct errors were being committed at once: mislabelling policy as breakage, and asserting a credential/base_url fault that live evidence contradicts.
A third error of the same family: Koonimo's config names `api_key_env: LITELLM_API_KEY` at top level while her runtime resolves `provider: deepseek` to her DeepSeek key and succeeds - the audit inferred credential resolution from config text and got it wrong.
## Changes
Each of `hermes-key-enforcement`, `hermes-config-template` and `hermes-agent-baseline` gains a **Violation Classification** section (20 lines each) that requires:
- **POLICY** (observation only, never phrased as breakage): the agent uses a non-harness provider, or a config field looks unusual while its calls succeed - e.g. `POLICY: Koonimo uses deepseek directly; calls succeeding in the last hour`.
- **FAULT** (needs request-level evidence): calls failing with an observed auth error, or a missing key **together with** failing calls - e.g. `FAULT: Koby's key expired; 401 observed at <timestamp>`.
- Explicit rules: do not infer the runtime's credential resolution from config text; require an observed auth failure or the absence of successful calls before calling anything a fault; state what was OBSERVED, not what a field implies.
## Verification
- Three-dot diff against `master` (`71ceda0`, the #89 merge): 3 files, +60/-0, contracts only.
- No assertion about either agent's compliance is made by this PR - it changes what the contracts are allowed to claim. The two agents above remain as they are, reported as POLICY with the log lines that prove their calls succeed.
- Reviewers: confirm no contract can still print a provider difference under a fault label, and that each FAULT example names an observable (a 401, or an empty success window) rather than a config reading. The policy question itself (should every agent route through the harness?) is with the captain and deliberately left undecided in the contracts.
Contract design defect: 'uses a non-harness provider' (POLICY) and
'cannot authenticate' (FAULT) were printed as the same violation class.
A policy observation must never be phrased as if the agent were broken.
Changes:
1. Added 'Violation Classification' section to all three contracts
2. Separated POLICY (observation only) from FAULT (requires request-level evidence)
3. Rules:
- Do NOT infer runtime credential resolution from config text alone
- Require request-level evidence before calling a FAULT: observed auth failure
or absence of successful calls
- If calls are succeeding, output is 'POLICY: uses <provider> directly; calls
succeeding' - not a violation
- State what you OBSERVED, not what the field implies
Files changed (3):
- hermes-key-enforcement.prose.md
- hermes-config-template.prose.md
- hermes-agent-baseline.prose.md
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.
Follow-up to #89. That fix made the audit's reachability verdict trustworthy; this one fixes what the audit says about what it finds.
The defect (measured today)
Minutes after #89 merged, the same contracts reported two further "violations":
Both agents are working. Their own logs, read at the authority:
So neither config is broken. What the audit actually detected is that both agents route to a provider other than the internal harness - a policy question for the captain, not a fault. Two distinct errors were being committed at once: mislabelling policy as breakage, and asserting a credential/base_url fault that live evidence contradicts.
A third error of the same family: Koonimo's config names
api_key_env: LITELLM_API_KEYat top level while her runtime resolvesprovider: deepseekto her DeepSeek key and succeeds - the audit inferred credential resolution from config text and got it wrong.Changes
Each of
hermes-key-enforcement,hermes-config-templateandhermes-agent-baselinegains a Violation Classification section (20 lines each) that requires:POLICY: Koonimo uses deepseek directly; calls succeeding in the last hour.FAULT: Koby's key expired; 401 observed at <timestamp>.Verification
master(71ceda0, the #89 merge): 3 files, +60/-0, contracts only.Contract design defect: 'uses a non-harness provider' (POLICY) and 'cannot authenticate' (FAULT) were printed as the same violation class. A policy observation must never be phrased as if the agent were broken. Changes: 1. Added 'Violation Classification' section to all three contracts 2. Separated POLICY (observation only) from FAULT (requires request-level evidence) 3. Rules: - Do NOT infer runtime credential resolution from config text alone - Require request-level evidence before calling a FAULT: observed auth failure or absence of successful calls - If calls are succeeding, output is 'POLICY: uses <provider> directly; calls succeeding' - not a violation - State what you OBSERVED, not what the field implies Files changed (3): - hermes-key-enforcement.prose.md - hermes-config-template.prose.md - hermes-agent-baseline.prose.md