147 Commits

Author SHA1 Message Date
jenkins
964103f02b merge(hermes): integrate hardened HUX foundation 2026-08-24 02:01:08 -03:00
jenkins
3c06ae867b fix(hermes): reject invalid release revisions early 2026-08-24 01:19:58 -03:00
jenkins
b4145861d2 hermes(hux): freeze hux.v1 contract 1.0.0 and move reference modules into the foundation package
HUX-11 contract freeze: identity/capabilities/manifest/error records, event turn
and idempotency and delegation/side-effect kinds, memory no-store/supersedes/
retrieval removal, revisions for optimistic concurrency, artifact access,
budget scope/spend/subagents and external side-effect gating, notebook notes and
dedupe keys. ADR-0001 records the wire and compatibility rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNPhwu2bsaRNg3DETSAZoM
2026-08-24 00:48:20 -03:00
jenkins
d3cb6e9045 hermes(hux): add contract-only foundation for the chat UX program
Schemas, examples and a flag registry for the twelve HUX cards, a dependency-free
validator, the governance rules (memory ledger, autonomy matrix, friendly modes
mapped to real Switchyard routes, privacy defaults, suggestion gating, release
state machine) and the contract doc UI work codes against.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNPhwu2bsaRNg3DETSAZoM
2026-08-23 22:30:41 -03:00
jenkins
d254931a14 feat(hermes): ship full-duplex voice release 2026-08-23 22:13:52 -03:00
jenkins
636f3fcf93 fix(hermes): harden release reconciliation 2026-08-23 18:53:11 -03:00
jenkins
33c6f187b3 fix(hermes): recognize containerd release images
Some checks failed
Tests / Declarative: Post Actions failed: 49, skipped: 19, passed: 2816
2026-08-23 17:23:51 -03:00
jenkins
b87f33530b feat(hermes): brand chat and prove image rollout 2026-08-23 17:13:14 -03:00
jenkins
79369c2357 release(hermes): automate private voice images 2026-08-23 15:54:56 -03:00
jenkins
c0b806e5d2 release(hermes): automate validated image promotion 2026-08-23 13:41:58 -03:00
jenkins
6b378fd410 fix(hermes): preserve proven Claude authentication 2026-08-23 11:18:18 -03:00
jenkins
1e66a0bedf fix(hermes): tolerate worker lease handoff 2026-08-23 11:01:20 -03:00
jenkins
271f3e8c32 ops: spread saturated node workloads 2026-08-23 10:37:01 -03:00
jenkins
fe7832efaf hermes: retain dual-provider quota health
Some checks failed
Tests / Declarative: Post Actions failed: 39, skipped: 19, passed: 2757
2026-08-23 02:52:42 -03:00
jenkins
81b3e6b992 hermes: expose Claude remaining quota 2026-08-23 00:42:39 -03:00
jenkins
d036062519 hermes: stabilize AI quota collection 2026-08-23 00:14:58 -03:00
jenkins
69ad76bebc hermes: keep distributed workers on Claude 2026-08-22 23:02:15 -03:00
jenkins
8acb99d100 hermes: make Claude setup-token access durable 2026-08-22 22:52:28 -03:00
jenkins
db0cb86ca6 hermes: stabilize Claude access health probes 2026-08-22 18:07:58 -03:00
jenkins
bd50a7e4ad hermes: persist Claude subscription access 2026-08-22 17:32:30 -03:00
77905ff1db Merge branch 'main' into fix/cli-auto-failover-effort
Some checks failed
Tests / Declarative: Post Actions failed: 40, skipped: 19, passed: 2737
2026-08-21 23:12:12 +00:00
Hermes Agent
820872e117 feat(hermes-voice): route Whisper language to multilingual Piper
Port the original #27 detected-language pipeline onto the verified PR #39 prerequisite while preserving the current-main conversation instrument and host continuity changes.

Keep voice selection server-side with no user selector or client voice field. Reuse 207c16ab only for its stricter exact-code trust boundary, omitting malformed or absent language so Piper defaults to Amy.
2026-08-21 13:58:50 +00:00
Hermes Agent
d579c08cbe fix(hermes): cli-auto capacity failover uses automatic Switchyard reclassification
Capacity/auth/quota failover for cli-auto previously called select_route
with a hardcoded manual lane (cli-{alternate}-{effort}), so the retry
boundary was classified as switchyard-manual instead of going through
Jetson automatic classification, making the routing evidence misleading.

Now the retry calls select_route(context, "cli-auto", exclude_provider=...)
so the boundary stays automatically classified with an explicit
failed-provider exclusion. If the classifier reclassifies to a lower
effort than the original route, the lane re-pins the chosen provider at
the original effort floor so a capacity failure never silently downgrades
a high/xhigh task. Manual lanes (assignee != cli-auto) remain unchanged
and still fail closed without switching providers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 05:04:55 +00:00
jenkins
0a4ff7f1f6 hermes: read node access keys through CSI symlinks
The Vault CSI secrets-store projects /vault/secrets/node-ssh-public-key
as a symlink chain (file -> ..data/file -> ..<timestamp>/file), which
the O_NOFOLLOW hardened reader refuses with ELOOP, crash-looping the
hermes-node-ssh-access key reconciler on most nodes.

Resolve the projection safely instead of relaxing the reader: realpath
the secret strictly (loops and dangling links become a clean refusal),
refuse any resolution that escapes the read-only mount, then apply the
unchanged O_NOFOLLOW regular-file read to the resolved target. Host
account databases and authorized_keys keep the strict no-symlink read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 16:28:25 -03:00
jenkins
9749e65042 Merge remote-tracking branch 'origin/feature/hermes-chat-smoothness' into feature/hermes-inpod-supervisor 2026-08-18 07:03:41 -03:00
jenkins
d1e8cda5ed hermes: make supervisor terminal emissions idempotent across ticks
Fix reviewer BLOCK: the stateless poll loop re-planned every terminal card each
tick, so SHIP and the two cycle-limit escalations - whose source cards stay in
the done state - re-fired their comment/block on every pass (~2880/day/chain).

- Add a persistent emission Ledger (/opt/data/supervisor/emitted.json): SHIP and
  escalate perform their action only when the (action, target) key is absent,
  then record it, so each fires at most once and survives a pod restart. Spawns
  remain self-limiting via the existing dedup scan.
- Cycle-limit escalations now target the SOURCE review/repair card (not the impl
  root), so the card also leaves the done state and is skipped next tick even if
  block_task round-trips imperfectly.
- Harden the _spawn TypeError fallback: re-run the dedup scan before retrying so
  a post-insert TypeError can never double-insert.
- Add across-ticks idempotency tests (10x supervise_once -> exactly one
  comment/flag/block) plus ledger persistence/corruption and spawn-guard tests.

Both modules stay 100% line+branch, <500 LOC. Stacks on the merge train
(base 5f27e50c).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-18 06:51:36 -03:00
jenkins
2b2c8bda14 Merge remote-tracking branch 'origin/wt/t_1e95ea6d' into feature/hermes-chat-smoothness 2026-08-18 06:46:48 -03:00
jenkins
a9ee1070be Merge remote-tracking branch 'origin/feature/hermes-full-handoff-acceptance' into wt/t_1e95ea6d
# Conflicts:
#	services/hermes/agent-deployment.yaml
#	testing/tests/test_hermes_auto_router.py
2026-08-18 06:41:13 -03:00
jenkins
6a7009b31c hermes: add in-pod autonomous kanban supervisor
Drive the cross-card implement->review->repair->re-review chain from inside
the pod so unattended runs no longer stall once the first implementation card
completes. Today that chain exists only as an external codex-shepherd session;
this adds a bounded in-pod poll loop that reads board state via
hermes_cli.kanban_db and creates Kanban follow-up cards (subscription lanes
only) with no provider/metered path of its own.

- kanban_supervisor.py (I/O shell) + supervisor_policy.py (pure state machine):
  impl-done+PR -> review; review SHIP -> mark impl ready-for-human (never
  merges/approves/clears WIP); review BLOCK -> bounded repair; repair new
  commit -> re-review. Fail-closed on unparseable/ambiguous state; per-
  (parent, head_commit) dedup safe beside the external shepherd; bounded review
  <->repair cycle count and max concurrent chains.
- Deployed as a hardened non-root sidecar (drop ALL caps, read-only rootfs, no
  runtime-access/credential mount) alongside model-steward; scripts packaged in
  the coordinator configMapGenerator.
- Gated by new kanban.auto_supervise config key (default false, re-read each
  tick like auto_decompose) so it is inert until the external shepherd retires.
- Fix latent goal_max_turns NULL fallback in cli_lane_execution (1 -> documented
  default 20).
- 62 new behavioral tests at 100% line+branch on both modules.

Stacks on the merge train (base 5f27e50c).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-18 06:28:49 -03:00
jenkins
8036101f0b Merge remote-tracking branch 'origin/feature/hermes-review-goal-semantics' into feature/hermes-distributed-worker-pool
# Conflicts:
#	scripts/tests/test_dashboards_render_atlas_drilldowns.py
#	scripts/tests/test_dashboards_render_jobs.py
#	services/hermes/scm-common/scripts/scm_broker.py
#	services/hermes/scripts/cli_lane_dispatch.py
#	services/hermes/scripts/cli_lane_execution.py
#	testing/quality_contract.json
#	testing/tests/test_hermes_agent_access.py
#	testing/tests/test_hermes_agent_security.py
#	testing/tests/test_hermes_chat_config.py
#	testing/tests/test_hermes_chat_images.py
#	testing/tests/test_hermes_chat_provider_auth.py
#	testing/tests/test_hermes_chat_quality.py
#	testing/tests/test_hermes_chat_support.py
#	testing/tests/test_hermes_chat_voice.py
#	testing/tests/test_hermes_cli_finalization_edges.py
#	testing/tests/test_hermes_cli_foundation_coverage.py
#	testing/tests/test_hermes_cli_lanes_configuration.py
#	testing/tests/test_hermes_cli_recovery_edges.py
#	testing/tests/test_hermes_cli_retention_edges.py
#	testing/tests/test_hermes_coordinator.py
#	testing/tests/test_hermes_coordinator_boards.py
#	testing/tests/test_hermes_coordinator_support.py
2026-08-18 01:43:39 -03:00
jenkins
7db9f61659 Merge remote-tracking branch 'origin/feature/hermes-cli-auto-quota-routing' into feature/hermes-review-goal-semantics
# Conflicts:
#	services/hermes/scripts/cli_lane_runner.py
2026-08-18 01:18:06 -03:00
jenkins
603524ba6a Merge remote-tracking branch 'origin/fix/hermes-result-decomposition-reliability' into feature/hermes-cli-auto-quota-routing
# Conflicts:
#	services/hermes/networkpolicy.yaml
#	testing/quality_contract.json
#	testing/tests/test_hermes_agent_security.py
2026-08-18 00:57:54 -03:00
jenkins
a3077224e0 Merge origin/main (#14 + #16) into PR #15 decomposition reliability
Reconcile two independent test/gate reorganizations:
- Gate/semgrep/mailu: keep main's #16 dual-metric implementation.
- quality_contract.json: union #16 image-builder + #14 scm/node + #15 cli_lane.
- agent-deployment.yaml: keep #14 gitea removal + #16 image-build-token + #15 probe.
- Test splits: main's chat/coordinator/agent organization is authoritative;
  drop #15's redundant competing splits and #14's stale cli-lane duplicates;
  keep #15's cli-lane decomposition suite and port the execution-safety test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 00:42:53 -03:00
jenkins
9d42ff33f5 Merge origin/main (#16 image-builder) into hermes-safe-gitea-pr
Resolve 8 conflicts, uniting #16's daemonless image-release lane with
#14's SCM broker + node-audit boundary. Nothing dropped from either side.

- quality_coverage.py / test_quality_coverage_helpers.py: take main's
  dual-metric gate (line+branch enforced per file at minimum_percent);
  drop #14's now-dead branch_tracked_files/minimum_branch_percent keys.
- quality_contract.json: union all lists (managed_modules, lint_paths,
  coverage_sources, tracked_files, hygiene globs) so #14's scm-broker,
  git_pack_objects, receive_pack_scan, deadline_http and node_polkit_audit
  are branch-checked alongside #16's image-builder modules.
- Vault auth (vault_k8s_auth_configure.sh): coexist both role sets. Keep
  #16's hermes-switchyard split + hermes-jenkins-token-seed; keep #14's
  hermes-scm-broker role. Preserve #14's security property: hermes-agent
  no longer holds developer-gitea (broker role carries it).
- agent-deployment.yaml / stage_runtime_access.py: keep #16's
  jenkins-image-build-token injection/staging; keep #14's removal of the
  agent's gitea-token/gitea-username.
- Bump vault-k8s-auth-hermes job -9 -> -10 (and its health check + test)
  so the merged auth config re-applies over any -9 already in-cluster.
- flux hermes dependsOn: union jenkins + hermes-scm-broker + observer-rbac.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 21:07:06 -03:00
jenkins
a5d0abb678 hermes: align capacity gate with auth classifier
CAPACITY_PATTERN (the gate that sets result.capacity_failure) lacked the
bare unauthorized/forbidden/401/403 signals that classify_capacity_failure
already recognizes, so an auth blip surfacing only as "403 Forbidden"
was blocked as capability instead of transient: no auto failover, no
health cooldown. Add 401|403|unauthorized|forbidden to the gate so it
matches the classifier; reason classification still distinguishes auth
from quota/rate-limit/transport.

Tests: an auto card failing with only "403 Forbidden" now fails over to
the other provider, records an auth cooldown (authenticated:false), and
classifies the fallback reason as auth in metrics; a manual card with the
same failure still fails closed as transient. Router-outage tests moved to
test_hermes_cli_router_outage.py to keep both files <500 LOC.

Based on PR #15 (fix/hermes-result-decomposition-reliability).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-17 20:46:00 -03:00
jenkins
6c1123201e hermes: audit every sudo include spelling
A quoted, space-bearing #include path failed the include regex and fell
through to the comment branch, leaving a second authority file
unenumerated. Detect any include directive before the comment rule and
fail closed on every form except the exact bare includedir into the
audited /etc/sudoers.d.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 20:37:30 -03:00
jenkins
6e9e8c6ab5 hermes: reject regex literals in polkit grants
A regex literal embedding a quote desynced the string tokenizer and
swallowed an unconditional Result.YES, so the grant read as unscoped and
slipped past the literal-identity check. Fail closed on any slash outside
a string or comment; neither regex nor division belongs in an
identity-scoped grant.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 20:37:30 -03:00
jenkins
034c8372c7 hermes: enforce quota-aware fail-closed cli-auto provider routing
Based on PR #15 (fix/hermes-result-decomposition-reliability); stacked
on the decomposed cli_lane modules.

- cli_lane_quota: soft-exclude a provider from NEW cli-auto work below
  the remaining-quota threshold (both-below prefers more remaining;
  fetch failure fails open with a metric).
- cli_lane_health: lane now writes provider health (G7) with classified
  failure reasons splitting the capacity conflation (quota/auth/
  rate-limit/transport) and cooldown hysteresis; re-admission only on
  full cooldown expiry, passed quota reset, or fresh success (G4).
- cli_lane_routing: capacity-limited health now excludes a provider
  (G3); cooldown/reset-aware re-admission.
- cli_lane_failover: explicit cli-codex-*/cli-claude-* assignees fail
  closed as transient instead of switching providers (G5); fallback
  depth stays bounded at two hosted providers (G1) with effort
  preserved; Switchyard outages block transient, not capability (G9).
- cli_lane_metrics: route-decision/fallback counters, quota and
  soft-exclusion gauges, pod-local scrape server (G6).
- cli_lane_provider: worker env drops ANTHROPIC_API_KEY, CLAUDE_API_KEY,
  OPENAI_API_KEY, API_SERVER_KEY so no metered path exists (G10).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-17 20:31:05 -03:00
jenkins
b8f2163af0 hermes: prove sudo and polkit denial closed
Expand sudoers User_Alias chains so aliases, wildcards, netgroups, and
undefined names cannot smuggle authority to the Hermes account, and
require polkit grants to scope through exact literal identity
comparisons: computed strings, bracket lookups, subject aliasing,
operator-built values, and unconditional or wildcard grants fail closed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:15:47 -03:00
jenkins
e3ecc18d0e hermes: refresh capabilities and readiness per loop
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:03:50 -03:00
Hermes Agent
360d8aad8f hermes: close the review-role gaps found reviewing PR 22
Repairs the blockers from the independent review of the previous head. The
role-aware verdict contract was correct but reachable only through one call
site and only on cards written with real newlines, so most real review cards
never used it.

* The role-blind call is no longer a weaker classifier that can reject before
  the role-aware judge runs. Without a card there is no defensible
  role-dependent judgement, so `unfinished_result_reason()` applies only the
  card-independent checks. That closes the short-circuit at every call site,
  including the one PR15 moves to `cli_lane_execution`, and it makes a
  journalled terminal record accepted under one version of these semantics
  re-validate under any other instead of being quarantined into a re-dispatch
  of an already-accepted task.
* The lane resolves the role from the card and passes it, and records it in
  the Kanban metadata. The verdict contract binds only where the lane can buy
  another turn: in single-shot mode a rejection discards the worker's real
  result, so review cards keep the relaxation without gaining any rejection
  single-shot mode did not already have.
* Card scope expands the literal \n escapes the board stores in one-line
  bodies, so explicit `Hermes-Task-Role` / `Hermes-Expected-Output` directives
  are honoured on the 6 of 78 live cards that carry no real newline, and the
  read-only, verdict and mutation heuristics stop being cut apart by them.
* Card scope now ends at the first non-card H2 and at the runner's controller
  evidence, which is emitted under its own heading. Goal-controller rejection
  history can no longer sit inside the card, and an upstream heading rename
  fails closed instead of admitting history into role resolution.
* The inference recognises the SHIP/BLOCK-shaped deliverables real cards
  actually use: 21 of 78 live cards resolve to review, up from 10, with no
  implementation card misclassified. Cards asking for a findings list rather
  than a verdict deliberately stay on the model judge, since the verdict is
  the review contract's only gate.
* A declared review role no longer outranks mutation evidence: a report that
  changed files falls back to the implementation regime.
* Judge reasons go through the agent runtime's canonical redactor, extended
  for the two shapes it deliberately passes through and this lane handles -
  `scheme://user:secret@host` and a credential named in prose - while a 40-hex
  commit SHA survives as evidence.

Regressions cover the recovered t_dbdcd739 incident, a verbatim snapshot of
every live card on three boards with a hand-labelled expected role, the
upgrade and single-shot properties against the previous gate, the upstream
context-heading contract, and the end-to-end `execute_claim` shape that used
to burn every goal turn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 17:27:11 +00:00
Hermes Agent
5d963c9354 hermes: make pool lease recovery and release isolation safe
Independent review t_5975c06a blocked this branch on a P1: a Kanban write that
failed while a lease expired left a `lease_failed` row that was invisible to
every pass, immortal to garbage collection, and fatal to the coordinator. It
poisoned `reconcile()` forever with a conflicting-duplicate primary key,
produced a spurious capability `block_task` from `dispatch()`, and -- because
startup maintenance ran unguarded before the port bound, against a store on a
PVC -- crash-looped the coordinator with no automatic recovery.

`lease_failed` is now a retryable state that every maintenance pass drains, and
a row only reaches a terminal state on authoritative evidence about its exact
Kanban run, so nothing is collected before its outcome is known and nothing is
silently dropped. Each row, task, and board is processed in isolation, and a
coordinator-side fault is never converted into a Kanban mutation. Startup runs
through the same guarded cycle as the steady-state loop.

The wire protocol and the durable store are now separate modules, and the
maintenance passes moved out of the coordinator, so each file stays under the
managed line ceiling with room for the recovery logic.

Also closes three consequential handoff risks the same review raised:

* mediator-N pinned itself hard to worker-N while sharing a ReadWriteOnce
  claim, so a drain or preemption that moved only the lower-priority worker
  deadlocked the ordinal on Multi-Attach until an operator deleted a Pod. The
  shared workspace is now ReadWriteMany (as the hermes-chat tenant workspaces
  already are on the same class), colocation is a preference, and the mediator
  shares the worker's preemption priority, so each Pod reschedules on its own.
* the broker permits only branch creation, so a retry that added commits could
  never submit and the run's work was discarded with the failure. Submission
  now targets a fresh attempt- or content-scoped ref in the same reviewed
  namespace -- never an update -- and is idempotent under replay. A refused
  submission downgrades the result and says why instead of unwinding the run.
* the provider CLIs were reinstalled into an emptyDir on every Pod start inside
  the 10m Flux health window for the whole hermes app. They now install once
  per pinned version onto a durable volume, re-verified against the real
  binaries and time-bounded, and the best-effort pool no longer gates the
  health of the app its dependents wait on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 16:31:15 +00:00
Hermes Agent
7a55b259bf hermes: add the fenced three-node distributed execution pool
Three fenced worker Pods claim Hermes Kanban runs through a coordinator that
owns every state transition, with per-ordinal HMAC authority, a mediated
broker-only SCM path, and durable per-ordinal workspaces.

Content is the reviewed head of PR #18 (689bcb6e) with PR 16's and PR 19's
contributions removed: they were merged in only to validate co-existence and are
not prerequisites, so this branch no longer carries them as ancestors. Only PR 14
and PR 15 remain, because the broker boundary and the cli_lane_* decomposition
are load-bearing for two of the fixed P0 boundaries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 16:31:15 +00:00
Hermes Agent
03b10ff8b1 Merge PR 15 (CLI lane decomposition) on top of PR 14 (Atlas SCM broker)
The distributed worker pool stacks on exactly two open pull requests, in this
order: PR 14 supplies the broker-only SCM boundary the mediators route through
and the hermes-scm-boundary-v2 ConfigMap they mount, and PR 15 supplies the
cli_lane_* decomposition -- including canonical_run_id and the eligibility
predicate on claim_ready -- that the coordinator depends on. Neither can be
dropped without breaking a fixed P0 boundary, so both are carried here as
prerequisites and this branch must not merge before them.

PR 16 (agent image release lane) and PR 19 (full-handoff acceptance harness)
are NOT prerequisites and are deliberately absent, so reviewing this branch no
longer means approving them.

PR 14 and PR 15 conflict with each other in nine paths. Each is resolved to the
resolution already reviewed on this branch at 4d4cf1bd.
2026-08-17 16:29:29 +00:00
Hermes Agent
ed43dbaa7f hermes: split AI usage exporter engines 2026-08-17 15:33:56 +00:00
Hermes Agent
b080b5f622 hermes: finalize completed review verdicts in the goal judge
The local goal judge scored every worker report against "did the reviewed
implementation reach a shippable state". A read-only reviewer that returned a
completed BLOCK verdict with findings was therefore resumed turn after turn with
an instruction to repair code it was forbidden to touch (observed live on
t_dbdcd739), burning subscription capacity and risking an unbounded loop.

Completion is now judged against the action the card assigned:

* Cards declare their role explicitly with Hermes-Task-Role / Hermes-Expected-
  Output metadata. Pre-contract cards fall back to a narrow inference that needs
  a read-only scope, a requested verdict, no requested mutation deliverable, and
  a report that changed no files.
* Role resolution reads only the card itself. Prior attempts, parent results,
  cross-task history and comments appended to the worker context can no longer
  reassign the role.
* Review, audit and diagnostic cards finalize deterministically on a truthful
  SHIP or BLOCK verdict with evidence, and fail closed on a missing,
  unrecognized or self-contradictory verdict, on a BLOCK without findings, and
  on a verdict without evidence. Every rejection reason carries the read-only
  guard, so a resumed review is never told to edit the reviewed implementation.
* Implementation cards keep the fail-closed model judge unchanged, including the
  unfinished-work heuristic and judge-unavailable rejection.
* All judge reasons are bounded, single-line and secret-redacted before they
  reach Kanban metadata, comments and continuation prompts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 14:54:36 +00:00
Hermes Agent
c867ae52fb hermes: harden chat continuity and activity 2026-08-17 14:39:21 +00:00
jenkins
e8c26ecf85 hermes: add daemonless agent image release lane 2026-08-17 08:25:52 -03:00
jenkins
73fefbb5d9 hermes: gate mixed image lane APIs 2026-08-17 08:16:35 -03:00
jenkins
8c6e3acdac hermes: isolate Atlas SCM write authority 2026-08-17 07:58:44 -03:00