5456 Commits

Author SHA1 Message Date
Hermes Agent
c36b2e688e Merge current PR 19 into distributed worker pool
# Conflicts:
#	testing/quality_contract.json
#	testing/quality_coverage.py
#	testing/tests/conftest.py
#	testing/tests/test_hermes_auto_router.py
#	testing/tests/test_quality_coverage_helpers.py
2026-08-17 13:33:46 +00:00
Hermes Agent
f0d8fc9588 Merge current PR 16 into distributed worker pool
# Conflicts:
#	clusters/atlas/flux-system/applications/hermes/kustomization.yaml
#	dockerfiles/Dockerfile.hermes-agent.dockerignore
#	services/hermes/agent-deployment.yaml
#	services/hermes/scripts/stage_runtime_access.py
#	services/vault/scripts/vault_k8s_auth_configure.sh
#	testing/quality_contract.json
#	testing/tests/test_hermes_runtime_access.py
2026-08-17 13:30:14 +00:00
Hermes Agent
56697358ac hermes: preserve exact CLI lane retirement semantics 2026-08-17 13:21:00 +00:00
Hermes Agent
c808baff40 docs(hermes): record repaired conflict graph 2026-08-17 13:12:36 +00:00
Hermes Agent
9d5214f809 fix(hermes): close full-handoff acceptance blockers 2026-08-17 13:11:34 +00:00
Hermes Agent
4d4cf1bd44 Merge current PR 15 into distributed worker pool
# Conflicts:
#	testing/quality_contract.json
2026-08-17 12:58:29 +00:00
Hermes Agent
7c87285940 Merge current PR 14 into distributed worker pool
# Conflicts:
#	testing/tests/test_hermes_chat_quality.py
#	testing/tests/test_hermes_cli_lanes.py
2026-08-17 12:55:52 +00:00
Hermes Agent
0fc97529c2 hermes: repair distributed pool integration boundaries 2026-08-17 12:52:23 +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
Hermes Agent
5dedb67ec6 Merge remote-tracking branch 'origin/pr/15' into feature/hermes-distributed-worker-pool
# Conflicts:
#	scripts/tests/test_dashboards_render_jobs.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_cli_lanes.py
#	testing/tests/test_hermes_coordinator_routing.py
#	testing/tests/test_hermes_coordinator_support.py
2026-08-17 10:59:32 +00:00
jenkins
8c6e3acdac hermes: isolate Atlas SCM write authority 2026-08-17 07:58:44 -03:00
Hermes Agent
2980a20e96 Merge remote-tracking branch 'origin/pr/14' into feature/hermes-distributed-worker-pool 2026-08-17 10:55:42 +00:00
Hermes Agent
1b5753341f Merge remote-tracking branch 'origin/main' into feature/hermes-distributed-worker-pool 2026-08-17 10:55:39 +00:00
jenkins
2c1d97e551 hermes: match canonical Forgejo PR URL 2026-08-17 07:22:26 -03:00
jenkins
cf3e46c2b6 hermes: harden Forgejo client boundary 2026-08-17 07:22:26 -03:00
jenkins
762784da6b hermes: bound Atlas pull request client 2026-08-17 07:22:26 -03:00
jenkins
1ba9f13959 hermes: bind terminal commit to journal inode 2026-08-17 07:19:10 -03:00
jenkins
8c71d55853 hermes: harden journal quarantine races 2026-08-17 07:15:31 -03:00
jenkins
c20bc263e0 hermes: close terminal replay edge cases 2026-08-17 07:15:31 -03:00
jenkins
64ea6d685c hermes: harden replay and decomposition races 2026-08-17 07:15:31 -03:00
jenkins
f04a524738 hermes: preserve terminal results and prevent duplicate fanout 2026-08-17 07:15:31 -03:00
8f00545828 hermes: add a fail-closed full-handoff acceptance harness
Decides whether the Hermes platform handoff is fit to release, and refuses
to round an absence of evidence up to a pass.

The harness is read-only by default and classifies 71 checks PASS / FAIL /
NOT_RUN / NOT_APPLICABLE. Any mandatory FAIL or NOT_RUN is NO_GO, and so is a
harness-level problem: an unreachable vantage, a catalog entry whose evidence
no longer exists, an expired deadline, or an evaluator that raised.

Evidence comes from two vantages that cannot cover for each other: an external
read-only operator kubeconfig, and the Hermes agent probing itself from inside
its own pod. Before any check runs, the harness asks each vantage who it is and
stops if they are the same principal, because dual-vantage evidence from one
identity is a restatement rather than a corroboration. `--as` is rejected for
every operator-side command and reachable only as the inner command of a
`kubectl exec`, so impersonation can never stand in for a real self-probe. A
deny check needs a live refused request, not only an authorization review.

Two safety properties are structural rather than conventional, enforced where
an argv becomes a subprocess: the default mode mutates nothing (mutating verbs
require a server dry run; there is deliberately no live TokenRequest probe,
because a successful one would mint a real credential), and no probe can pull a
credential value into a report (no vault/sops/curl, secrets readable only with
-o name, environment probes list names, shell only through frozen reviewed
templates). Captures are bounded before they are screened, and the rendered
report is re-screened before it is written.

Mutation lives behind a separate arming flag with an exact confirmation phrase,
a caller-supplied unique ref, a preflight that refuses a protected push target
before any network call, and a cleanup whose verification is itself mandatory.
A default run reports those four checks NOT_RUN.

The catalog is declarative so a reviewer reads what is asserted rather than how
it is plumbed, and so structural properties can be proven over every entry
before a run. Catalog drift surfaces as NOT_RUN, which stops the release.

docs/hermes_full_handoff_acceptance.md carries the merge order for PRs #14-#18
on top of the merged #13 baseline, the image build and Flux rollout, the
rollback point for each step, the go/no-go checklist, and the limits that are
asserted rather than exercised.

Validation: 295 handoff tests pass with 100% line coverage on all 15 new
modules; the full unit suite is 647 passed with two failures that reproduce
unchanged on origin/main; Ruff, py_compile, kustomize render, and a diff
credential screen are clean; a live read-only run against Atlas returns NO_GO
for the pre-merge cluster with no unscreened fields in the report.
2026-08-17 10:14:17 +00:00
flux-bot
d8f2d818b9 chore(bstein-dev-home): automated image update 2026-08-17 10:08:46 +00:00
flux-bot
30259b526b chore(bstein-dev-home): automated image update 2026-08-17 10:06:40 +00:00
Hermes Agent
2000252751 hermes: add fenced three-node execution pool 2026-08-17 09:55:55 +00:00
jenkins
3cd8a17e77 hermes: isolate Atlas SCM write authority 2026-08-17 06:36:24 -03:00
jenkins
0167e7068b hermes: match canonical Forgejo PR URL 2026-08-17 06:04:54 -03:00
jenkins
6c644d727e hermes: harden Forgejo client boundary 2026-08-17 06:04:54 -03:00
jenkins
da1e2ec03c hermes: bound Atlas pull request client 2026-08-17 06:04:54 -03:00
ab346f5550 Merge pull request 'hermes: harden worker isolation and blocked-task semantics' (#13) from wt/t_cca008de into main
Reviewed-on: atlas/titan-iac#13
2026-08-17 08:33:41 +00:00
flux-bot
d9a88713a7 chore(maintenance): automated image update 2026-08-17 05:31:09 +00:00
flux-bot
9ada3ba6d0 chore(maintenance): automated image update 2026-08-17 02:00:37 +00:00
flux-bot
b4f78a615b chore(maintenance): automated image update 2026-08-17 01:51:36 +00: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
flux-bot
9bf1ab8a9c chore(bstein-dev-home): automated image update 2026-08-16 22:08:05 +00:00
flux-bot
b53e4cda45 chore(bstein-dev-home): automated image update 2026-08-16 22:06:05 +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
0dd6ea0f02 hermes: add durable Telegram topics 2026-08-16 15:59:09 -03:00
jenkins
9eee5cb339 mailu: reserve capacity for spam filtering 2026-08-16 15:25:03 -03:00
jenkins
6118b4eb3e mailu: apply intended admin probe tolerances 2026-08-16 15:15:30 -03:00
jenkins
77360ee9d3 mailu: fail critical paths onto healthy capacity 2026-08-16 15:12:58 -03:00
jenkins
c5d6e91d45 mailu: reserve healthy failover capacity 2026-08-16 15:11:38 -03:00
jenkins
c0847b5c73 mailu: preserve capacity during recovery 2026-08-16 15:09:40 -03:00
jenkins
8c33dd199e mailu: contain recovery to healthy nodes 2026-08-16 15:05:06 -03:00
jenkins
5a9028f13d mailu: mirror admin image for reliable recovery 2026-08-16 14:56:07 -03:00
jenkins
3ef0265ea8 mailu: move admin auth off unhealthy node 2026-08-16 14:49:41 -03:00
flux-bot
3da65e4de8 chore(maintenance): automated image update 2026-08-16 17:31:23 +00:00
jenkins
ba590c2518 hermes: retain native auth failure health 2026-08-16 13:47:19 -03:00
jenkins
e8b4f0c57c hermes: widen local goal judge timeout 2026-08-16 13:29:10 -03:00