33 Commits

Author SHA1 Message Date
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
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
1ba9f13959 hermes: bind terminal commit to journal inode 2026-08-17 07:19:10 -03:00
jenkins
f04a524738 hermes: preserve terminal results and prevent duplicate fanout 2026-08-17 07:15:31 -03:00
Hermes Agent
750dfa241f hermes: fail closed on kanban created-event producer drift
The sticky-block gate added in the previous commit classifies a task from
the `created` event payload that upstream `create_task` writes. That
producer is code we do not own, so trusting it silently was the gap: if
upstream renamed the key, dropped it, or stopped deriving it from
`initial_status`, the image would still build and ship a consumer that
mis-classifies every task it reads.

Anchor the producer contract at build time, before the regression suite
runs, with three assert-only preconditions: the `initial_status="blocked"`
park resolves `task_status` to `"blocked"`, every non-park creation
resolves it to something else, and the `created` event carries that same
variable under `"status"`. None of them rewrite the producer.

Textual anchors cannot see dataflow, so add the runtime net the reviewer
asked for. The suite now drives the real API: create + claim an ordinary
task, trip the circuit breaker once at failure_limit=1 so it parks with a
`gave_up` event (leaving its own `created` event as the most recent
create/block/unblock row), then recompute at failure_limit=2 and require
promotion to ready. That case is red under an unconditional-true created
predicate and red under producer drift that labels every created event
blocked, while the explicit block/unblock, dependency-promotion and
circuit-breaker-at-current-limit cases stay green. Non-blocked and
malformed created payloads are pinned as controls, and the gate now
rejects non-dict payloads rather than trusting `.get`.

Also make the live placement correction durable: titan-04 is cordoned
after repeated kernel undervoltage and kubelet failure and titan-19 was
probe/Longhorn unstable under worker load, so both join the hard NotIn
list; titan-05 is healthy but sits at 3592m/3600m requested CPU, so the
main hermes container gives back 50m (350m -> 300m) to schedule there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 22:42:18 +00:00
Hermes Agent
4f8dcfbbf7 hermes: harden worker isolation and blocked-task semantics
Three narrowly scoped Hermes reliability fixes backed by live evidence
from the Cassandra/titan-iac proof run.

Worker concurrency. Three simultaneous direct CLI workers on the 4-core
hermes-agent node drove load to ~45 and made the hermes and oauth2-proxy
containers fail their probes, leaving the pod 8/10 Ready; two workers
stayed at 10/10. Cap HERMES_CLI_LANE_CONCURRENCY at 2 and lower the
cli-lane-runner CPU limit from 3 to 2 so the dashboard and auth sidecars
keep a guaranteed share of the node. Requests are unchanged: the pod
still asks for 745m total, so placement does not move.

Service links. Kubernetes injects a service-link variable pair for every
service in the namespace, and hermes-claude-broker produces
HERMES_CLAUDE_BROKER_PORT=tcp://10.43.31.76:9006 — a value the broker
parses as an int. That contaminated worker and test environments even
though the deployment already addresses every service by DNS name. Set
enableServiceLinks: false on the hermes-agent pod spec.

Blocked-task scheduling. create_task(initial_status="blocked") records a
created event carrying status=blocked but never a blocked event, while
_has_sticky_block() only inspects blocked/unblocked events. recompute_ready()
considers blocked tasks, so an explicitly parked task with no incomplete
parent auto-promoted on the next dispatcher cycle. Teach _has_sticky_block()
to also recognize a created event whose payload status is blocked, which
covers tasks created before this image patch without adding a persisted
field. Dependency-driven promotion and the circuit-breaker failure-limit
guard are untouched; unblock_task() still releases either kind of block.

hermes-kanban-blocked-regression.py runs against the real upstream
kanban_db API during the image build, so the build fails if any of these
semantics regress.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 20:53:22 +00:00
jenkins
4bab6130bc hermes: close parked kanban tasks atomically 2026-08-16 04:31:00 -03:00
jenkins
7d284871e8 hermes: show activity during dashboard bootstrap 2026-08-16 03:33:41 -03:00
jenkins
9bc47f9ce3 hermes: keep durable worker activity visible 2026-08-16 01:20:08 -03:00
jenkins
1d2d386aeb hermes: pin ARM64 runtime images 2026-08-15 22:32:08 -03:00
jenkins
8c73906e6e hermes: preserve exact routes and accept Telegram images 2026-08-15 22:15:40 -03:00
jenkins
d27a9649cf hermes: secure node access and expose live workers 2026-08-15 13:58:42 -03:00
jenkins
9fa7612cd4 hermes: restore terminal rendering and worker lineage 2026-08-13 02:49:41 -03:00
jenkins
65b0e7f0c5 hermes: distinguish Claude subscription auth 2026-08-13 00:12:02 -03:00
jenkins
422f001a93 hermes: make Switchyard the routing authority 2026-08-11 20:22:26 -03:00
jenkins
9f21f66fcb hermes: route turns by service priority 2026-08-11 16:22:19 -03:00
jenkins
00e67b1482 hermes(agent): preflight protected socket auth 2026-08-11 04:05:46 -03:00
jenkins
c411018853 hermes(agent): recover stale dashboard sockets 2026-08-11 03:50:13 -03:00
jenkins
47ee53fd48 hermes: recover expired dashboard sessions 2026-08-11 02:23:15 -03:00
jenkins
f48ac926ec hermes(agent): retry dashboard ticket acquisition 2026-08-10 23:57:32 -03:00
jenkins
6169b2c802 hermes(agent): reconnect stock dashboard feeds 2026-08-10 23:44:56 -03:00
jenkins
f2a3616476 hermes: grant owner agent union access 2026-08-10 17:05:14 -03:00
jenkins
dee4ee8ab8 fix(hermes): put stock TUI in foreground 2026-08-10 05:45:36 -03:00
jenkins
aa8f97e3f0 fix(hermes): route delegated work independently 2026-08-10 05:16:30 -03:00
jenkins
c0b5af8621 fix(hermes): route every agent loop through Jetson 2026-08-10 04:31:41 -03:00
jenkins
379d2ea52e fix(hermes): run coding workers unattended 2026-08-10 02:15:34 -03:00
jenkins
9bdcddad7c feat(hermes): add Jetson-assisted auto routing 2026-08-09 02:42:30 -03:00
jenkins
432466156b fix(hermes): discover chat extraction backend 2026-08-08 23:59:05 -03:00
jenkins
639ac031a8 feat(hermes): strengthen isolated chat reasoning 2026-08-08 23:25:16 -03:00
jenkins
b315e02821 fix(hermes): report consumer access denial 2026-08-02 17:00:40 -03:00
jenkins
723a789ddf fix(hermes): isolate consumer sessions 2026-08-02 16:46:21 -03:00
jenkins
5c55735c89 fix(hermes): prevent stale dashboard sockets 2026-08-02 15:53:30 -03:00