소스 정보
- 저장소
- lukemcqueen/hermes-cortex
- 최근 소스 활동
- 2026년 8월 24일 01:10
- 감지된 SKILL.md 언어
- 영어
- 스타
- 4
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/lukemcqueen/hermes-cortex --skill enforcer-modification-considerations명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Cross-server agent health monitoring using binary status vectors — deploy health endpoints on each agent, poll from orchestrator, alert on state transitions.
Wire a self-hosted Langfuse instance to Hermes Agent — generate API keys, configure env vars, enable the bundled plugin, install SDK, and verify traces flow.
Use before enforcement code changes or shared-repo commits.
SKILL.md 표시 중
| name | enforcer-modification-considerations |
| version | 1.0.0 |
| category | devops |
| description | Use before modifying any enforcer/governance code. |
| author | Moses |
| platforms | ["linux","macos"] |
Load this skill BEFORE modifying plugins/governance-enforcer/__init__.py, mcp-servers/loop-gov-mcp.py, or any governance enforcement code.
Hermes creates sessions with different ID prefixes depending on the session type. Every guard in the enforcer must cover ALL non-interactive prefixes.
| Prefix | Source | Marker behaviour (per-session, 2026-08-01+) |
|---|---|---|
20260730_... (date-based) | Interactive Telegram/DM / CLI | Owns its own marker file — never touches other sessions' |
cron_... | Scheduled cron job | Owns its own marker (bootstrap-created) |
bg_... | Background subagent (delegate_task, etc.) | Owns its own marker |
cli-source date-based | CLI-invoked session (cron/terminal hermes runs) | Owns its own marker |
Per-session markers (2026-08-01): the shared .skills-loaded file race is
structurally eliminated — each session writes its own proof at
state/skills-loaded/<session_id>, so no session can ever stomp another's.
The entire guard class bolted onto the shared file (daemon guard, subagent
guard, sticky-marker-per-governance-lock) is obsolete and was removed.
This was gap-doc P1-A candidate #3 ("per-session marker files"), the
documented structural fix.
Rule: When adding a session-type guard, use session_id.startswith("cron_") or session_id.startswith("bg_"). Do NOT create separate is_cron and is_bg booleans — future prefixes will be missed.
Guard locations in the enforcer:
_auto_create_skills_marker() — writes state/skills-loaded/<session_id> (atomic temp+rename)_check_skills_loaded_marker() — reads THIS session's own marker; exact content match_on_session_start() — cron bootstrap creates the cron session's OWN markerChecklist when modifying:
grep -n 'cron_\|bg_' plugins/governance-enforcer/__init__.pybg_ sessions?not session_id.startswith("2026") as fallback).The begin_change() MCP tool has a DOGFOOD check: if the deployed enforcer (~/.hermes/plugins/governance-enforcer/__init__.py) differs from the repo source (plugins/governance-enforcer/__init__.py), begin_change() rejects the request.
The problem: This blocks a new change when the mismatch is caused by ANOTHER agent's commit arriving via git pull — not by un-deployed local work.
How to break the loop (fixed 2026-08-04 — the sanctioned command is now lock-free):
bash ~/hermes-cortex/ops/scripts/cortex-update.sh
(No sudo, no chaining, no other flags beyond
--dry-run/--status/--delta/--clean-stale — the
enforcer's _is_sanctioned_cortex_update_command() matches exactly.)skill_view() callsbegin_change() should now succeed (repo == deployed)If the skills gate blocks the terminal call (no skills marker yet):
core.hooksPath ~/.hermes-cortex/hooks is global: the pre-commit/pre-push
hooks run in EVERY git repo on the host, including project repos (client-alpha,
client-works, and other client repos) that have no ops/ tree and no .hermes-cortex/
directory inside them. Any hook/enforcer path built on $REPO_ROOT (the repo
being committed IN) and assuming cortex layout will break every commit there.
Regression 2026-08-04 (faa0e929 → fix 72d6cdc3): the adversarial gate
hard-resolved to $REPO_ROOT/ops/scripts/quality/adversarial-verify.py —
project repos lack that path, so ALL their commits failed fail-closed.
Fix pattern: candidate loop, repo-local first, then the canonically-deployed
copy at $HOME/.hermes-cortex/scripts/ (registered by cortex-update.sh on
both Linux and macOS). Fail closed only if BOTH are missing. See
enforcement-change-safety Rule 6 for the full pattern and the 3-branch
verification (cortex repo / project repo / tool-missing).
When modifying hooks or the enforcer, test in a scratch project repo
(git init /tmp/t && git config core.hooksPath ~/.hermes-cortex/hooks)
before shipping — a cortex-repo-only test proves nothing about project repos.
cortex-update.sh copies the new enforcer to
~/.hermes/plugins/governance-enforcer/ and re-locks it — but the RUNNING
gateway keeps executing the OLD module from memory. The plugin manager is a
process-global singleton: hermes plugins disable/enable only writes
config.yaml; it does NOT hot-reload loaded modules.
bash ~/hermes-cortex/ops/scripts/cortex-update.sh --status still returns
GOVERNANCE LOCK REQUIRED → pending restart, not a code bug.hermes gateway restart — agents cannot run it (lifecycle guard);
the host operator (Luke) must. Verify with the positive control (--status
passes lock-free) and negative control (... && echo hi still blocked).The old design: .skills-loaded at ~/.hermes-cortex/state/ was a single
file. ALL concurrent Hermes sessions wrote to it. When session B loaded skills,
it overwrote session A's marker. Session A's writes were then blocked because
_check_skills_loaded_marker() saw session B's ID.
The fix: per-session marker files at ~/.hermes-cortex/state/skills-loaded/<session_id>,
plus per-session state at state/skills-state/<session_id>.json. Each session
writes and reads only its OWN files — concurrent sessions (telegram, cli 1,
cli 2 on one server) can never stomp each other. The daemon guard, subagent
guard, and sticky-marker-per-lock rules were removed; they're no longer needed.
If your writes are blocked (marker missing or wrong content):
cat ~/.hermes-cortex/state/skills-loaded/<your-session-id>
# → session:<your-session-id> (valid)
# → empty / missing (skills not loaded this session)
Fix:
skill_view() → your session's marker
is auto-createdLegacy files: the old ~/.hermes-cortex/state/.skills-loaded and
skills-state.json files are inert — the enforcer no longer reads them. They
can be deleted once all sessions have restarted with the new enforcer.
When a single Hermes installation manages multiple repos (e.g., hermes-cortex + other projects), the repo_slug field in governance lock files must be derived dynamically, not hardcoded.
The problem:
~/.hermes-cortex/state/.governance-{session_id}.json contains "repo_slug": "hermes-cortex""hermes-cortex"hermes-agent (different name), the slug won't matchFix:
basename "${CORTEX_REPO:-${HOME}/hermes-cortex}"_derive_repo_slug() which runs git rev-parse --show-toplevel and takes the directory basenameFiles to check:
ops/scripts/manage/agent-nginx-threat-pipeline.sh — hardcoded slug (fixed)ops/scripts/agent/agent-ip-submission.sh — hardcoded slug (fixed)plugins/governance-enforcer/__init__.py — dynamic via _derive_repo_slug() ✓ops/scripts/pre-commit-score — dynamic via git rev-parse ✓Search pattern for hardcoded slugs:
grep -rn '"repo_slug"' ops/scripts/ plugins/
The pre-commit hook enforces orchestrator-only paths (from docs/orchestrator-only-paths.txt). If an agent has stale hooks (hasn't run cortex-update.sh after the guard was added), non-orchestrators can modify restricted paths like plugins/, skills/, ops/scripts/.
The fix chain:
check_hook_drift() detects deployed hooks that differ from repo sourcecortex-update.sh to redeploy hooksIf you're adding a new restricted path:
docs/orchestrator-only-paths.txtAGENTS.md which lists the canonical restricted pathscortex-update.shTwo mechanisms deploy the enforcer:
| Mechanism | Trigger | How | Caveat |
|---|---|---|---|
| Pre-commit DOGFOOD | git commit | Copies repo → deployed + unlock/lock | Only runs during commits |
cortex-update.sh | Manual run | deploy_governance_plugin() function | Runs at end of deploy cycle |
The DOGFOOD auto-deploy is faster but only works during commits. If another agent's enforcer change arrives via git pull, the DOGFOOD check in begin_change() blocks you because the deployed copy is stale. Run cortex-update.sh to sync.
When modifying the enforcer, test these scenarios:
TestSkillsMarkerPerSession::test_second_session_does_not_invalidate_first)bg_): owns its own markercortex-update.sh — does begin_change() work?Quick test for per-session markers:
echo "session:test" > ~/.hermes-cortex/state/skills-loaded/test-session
# Check: does _check_skills_loaded_marker("test-session") accept only exact content?
The domain-skill gate (_check_domain_skill_gate) is an EDUCATIONAL mechanism
for interactive sessions: it makes the agent load the craft skill (e.g.
documentation-auditing for .md) before writing. Cron sessions (cron_
prefix) and background subagent sessions (bg_ prefix) execute pre-vetted
prompts whose write targets were declared at install time, and their
enabled_toolsets may exclude the skills toolset entirely (e.g.
["terminal","file"]) — skill_view() is NOT in the tool registry, so the
gate is structurally unsatisfiable and every write deadlocks.
Regression 2026-08-06: agent-mycortex-dream-nightly (toolsets
[terminal,file]) was blocked writing ~/brain/<agent>/dreams/*.md because
the .md extension demands documentation-auditing, which the cron cannot
load. Same class affects memory-pruning (MEMORY.md), agents-md-prune-apply
(AGENTS.md), soul-refinement (SOUL.md), orch-skill-lifecycle (skills/).
Fix (commit b8bbaf52): _check_domain_skill_gate returns None early when
_session_type(session_id) in ("cron", "bg"). This mirrors the always-skills
cron bootstrap rationale (cron agents may not have skill_view()). Security is
NOT weakened: PII content gate, adversarial commit gate, bypass-debt mandate,
and governance lock still apply to cron/bg writes.
Checklist when modifying the domain gate:
_session_type() returns "interactive"
for date-format and empty session IDs — the gate still fires for them.tests/test_runtime/test_governance_bypass.py::TestDomainSkillGate
— cron/bg pass, interactive blocks, empty/None session still enforced.enabled_toolsets or every write deadlocks again.plugins/governance-enforcer/__init__.py — the enforcer itselfdocs/orchestrator-only-paths.txt — restricted pathsops/scripts/pre-commit-score — pre-commit hook with orchestrator guardops/scripts/manage/cortex_doctor/checks.py — doctor checks (hook drift, enforcer permissions)ops/scripts/cortex-update.sh — deploy script with deploy_governance_plugin()skills/devops/cortex-preflight/SKILL.md — Pitfall 3 covers skills-loaded marker