소스 정보
- 저장소
- lukemcqueen/hermes-cortex
- 최근 소스 활동
- 2026년 8월 21일 02:39
- 감지된 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 mycortex명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | mycortex |
| version | 1.1.0 |
| category | devops |
| description | Use for mycortex knowledge brain work or mycortex migration. |
| author | Hermes Cortex |
| license | MIT |
| platforms | ["linux","macos"] |
The fleet knowledge brain replacing mycortex: markdown-in-git as source of truth,
shared mycortex-postgres (:15432) as the query index, thin Python CLI + cron as
plumbing. No daemon, no bun. Canonical design: docs/design/mycortex-DESIGN.md;
stories: docs/elicit/2026-08-01_mycortex-stories.md.
| Layer | Choice |
|---|---|
| Source of truth | Markdown in git (~/brain/*, ~/hermes-cortex) |
| Index store | mycortex schema on mycortex-postgres :15432 (pgvector for v1.1) |
| Search | Postgres FTS (websearch_to_tsquery) + pg_texample (v1); pgvector (v1.1 slice) |
| Plumbing | Cron sync (no daemon), advisory-lock guarded |
Role split (DB-enforced, NOT CLI convention):
| Role | Grants | Used by |
|---|---|---|
mycortex_admin | sources/source_grants/DDL + full page SELECT (audit) | orchestrators — registration, PII gate, grants |
mycortex_ingest | DML on pages/content_chunks/ingest_log ONLY; REVOKEd on sources | sync cron |
mycortex_reader | SELECT on pages/chunks (RLS-filtered), sources(id,name,is_federated,search_config) | fleet agents via CLI |
RLS is FORCE'd on pages/content_chunks, fail-closed from v001: a reader sees a
page iff its source is federated OR the reader holds a source_grants row.
PII gate: is_federated = TRUE requires pii_scan_at (CHECK constraint).
ops/scripts/manage/mycortex, deployed to ~/.hermes-cortex/scripts/mycortex)mycortex sources add <name> <path> [--mode git|local] [--federated] [--search-config C]
mycortex sources list [--json]
mycortex sources remove <name> # builtin 'default' refused; pages hard-purge
mycortex sync [--source NAME] [--force] # sha256, advisory-lock, mass-delete guardrail
mycortex search <query> [--source NAME...] [--limit N] [--json]
mycortex list [-n N] [--source NAME] [--json]
mycortex stats [--json]
mycortex doctor [--json]
Connection: psql via sg docker -c "docker exec -i mycortex-postgres psql -U <role> -d <db>" on Linux (trust auth inside container); direct psql reading ~/.legacy-brain/config.json on macOS. Roles connect WITHOUT passwords inside the container; direct TCP to :15432 from the host requires a password (pg_hba scram for non-localhost).
mycortex_reader needs search_config column grant. Original grant was
SELECT (id, name, is_federated) on sources — the search query joins sources
for per-source FTS config and fails permission denied for table sources.
Fix: GRANT SELECT (id, name, is_federated, search_config) ON mycortex.sources.mycortex_pages_admin / mycortex_chunks_admin
FOR SELECT TO mycortex_admin USING (true) policies. Admin = audit role.sources.host DEFAULT is 'localhost' (not current_setting('hostname',...) — that GUC returns NULL and violates NOT NULL). CLI passes the real host explicitly.vNNN__*.sql), not just edits to v001. Gotchas 1+2 (admin policies, reader search_config grant) were originally fixed ONLY in the v001 file — hosts that had already applied v001 (schema_version=1) never got them: admin queries returned 0 rows and search failed permission denied for table sources. Fix: v002__rls-admin-reader-grants.sql (idempotent CREATE POLICY IF NOT EXISTS + GRANT). If you patch the schema, add a migration for existing hosts — do not rely on v001 edits reaching anyone who applied earlier.bash tests/test-mycortex-schema.sh — S-003 AC battery (15 checks) on scratch
DB mycortex_test; hermeticity guard refuses mycortex DB.CREATE DATABASE mycortex_test → migrate.py --db-name mycortex_test → add source (local mode) → sync → search → verify isolation (reader sees ZERO rows from isolated source, even with --source; grant → reader sees it).mycortex DB — always --db-name mycortex_test.All mycortex scripts use #!/usr/bin/env python3 (portable) — no python3.12 hardcoding. Verified 2026-08-02: hosts run python3.10–3.12; code parses clean at 3.10 (no match/case or 3.12-only syntax). The earlier python3.12 shebangs broke agent-mycortex-sync on python3.10/3.11 hosts (env: 'python3.12': No such file or directory, cron rc=127) — fixed fleet-wide. No venv/uv needed: stdlib-only, no external deps. If you add a script, use #!/usr/bin/env python3.
The knowledge brain + agent bus now run on a hermes-cortex-owned Postgres, NOT the langfuse stack.
| Before (pre-08-05) | After | |
|---|---|---|
| Container | legacy Postgres (stale langfuse compose labels, langfuse_legacy Postgres-data volume) | mycortex-postgres via ops/install/deploy/docker-compose.mycortex.yml, own mycortex-postgres-data volume |
| DB / role | mycortex / mycortex (superuser) | mycortex / mycortex |
| Port | 15432 | 15432 (unchanged) |
| Schemas | bus + mycortex + public (legacy_* tombstone) | same, carried over (S-012 purge window respected) |
Rollout: ops/scripts/manage/migrate-legacy Postgres-to-mycortex.sh — idempotent,
per-host, non-destructive (old container STOPPED, not removed; dump kept in
~/.hermes-cortex/backups/). Esther host migrated 2026-08-05 as the reference
(1726 pages / 29298 chunks verified post-restore).
Connection fixes shipped with the migration:
core/cortex_bus/queue.py _load_config() — the .env fallback previously
never read CORTEX_BUS_PG_DB, so the bus ignored .env DB changes and kept
hitting the dead mycortex DB. Fixed (2026-08-05).mycortex-postgres.mycortex daemon check kept as decommission verification (PASS when the
unit is disabled/absent).legacy import.py (one-shot additive legacy → mycortex copy, idempotent, dry-run, --federated with PII gate) — registered in cortex-update.shhermes-cortex + default federated, moses/luke/lessons/shared isolated. Command used: python3 ops/services/mycortex/legacy import.py --federated hermes-cortex --federated default + mycortex sources add <name> <path> + mycortex sync. Do NOT read another agent's status line as this host's state.agent-mycortex-sync (S-009) — every 15 min, per-host (NOT orchestrator-only, design D4), no_agent wrapper, registered in install-crons.sh (both arrays)plugins/mycortex-command/ — versioned plugin (replaces install.sh's generated legacy brain command). Registers /brain + /mycortex. Dynamic source presets from mycortex sources list --json (no hardcoded list — fixes broken-presets bug). Output is data-delimited in a code block with source+path+score citations; instruction-shaped chunk content rendered as data, never followed (injection guardrail, verified). Deployed by deploy_mycortex_plugin() in cortex-update.sh; install.sh step 7 copies the repo plugin, step 15 enables it.check_mycortex_parity reduced to INFO (no subprocess) and daily agent-mycortex-parity cron removed. Parity script kept as a only ().Source registration is per-host, NOT orchestrator-only. Design D4 + install.sh: each host registers its OWN local brain dirs (hermes-cortex + ~/brain/<agent>) at install time, and the per-host agent-mycortex-sync cron syncs them. Every agent runs its own mycortex-postgres with the mycortex schema and populates its own sources — this is the per-host model, not a shared fleet index. The mycortex_admin DB role is required for registration — on Linux any user in the docker group can sg docker exec psql -U mycortex_admin (trust auth) on the host that runs the container. The "orchestrators only" label applies to federation + grants + PII gate (turning a source is_federated=true, writing source_grants), not to registering your own local source. If you see 0 sources on your own host, register + import your own sources — don't wait for an orchestrator and don't read another agent's status as your own.
The tenant boundary is the Hermes PROFILE, not the hostname. "Imagine 100
employees sharing one brain": a shared index with per-tenant visibility.
Each profile connects as its OWN reader role (mycortex_reader_<profile>,
created by install-profile-reader-role.sh, LOGIN INHERIT mycortex_reader) —
RLS keys on CURRENT_USER, so isolation is automatic by construction. Personal
sources (dreams, bible, notes) MUST be:
<tenant>/<owner> (e.g. acme/esther) — bare names collide in a shared DB--mode local, no --federated) — the defaultsource_grants, NEVER the
shared mycortex_reader (a blanket grant leaks every tenant's dreams)Worked example (Esther's dreams, 2026-08-06):
mycortex sources add esther ~/brain/esther --mode local # isolated + auto-grant profile role
mycortex sync --source esther # pages indexed
AGENT_NAME=esther mycortex search "silence is the failure mode" --limit 3 # dreams rank
# isolation proof: another profile sees ZERO esther rows
AGENT_NAME=joseph mycortex search "dreams" --limit 3 # → (no results) for esther source
Search returning [] for an isolated source is the DESIGN working — fix via
grants, never by weakening RLS. Migration + verification steps for agents:
docs/design/mycortex-multi-tenancy.md (canonical). Dream-layer tenant
rules: docs/design/mycortex-dream-layer.md §Multi-Tenancy.
See references/migration-2026-08-02.md for the full session trace: schema fixes, CLI verification outputs, and what remains.
mycortex search as reader returns [] for isolated sources by design — RLS fail-closed. Don't "fix" it by running search as admin; grant the reader (source_grants) or federate with a PII scan.--source filter does NOT grant access — RLS is the enforcement, the filter is only a filter.pg_try_advisory_lock(42, hashtext('mycortex:'||source_id)) gates the whole per-source sync via \gset/\if; a concurrent sync gets LOCKED_SKIP (never blocks); crash = txn rollback + session-end lock release. ingest_log rows are written in the same txn (status ok/error). The old per-statement autocommit behavior is gone.git ls-files --cached --others --exclude-standard — excludes .git internals and honors .gitignore.-t -A in _psql_base — missing it makes current_version() parse the coalesce column header as a version (fixed 2026-08-02 by Titus).-t -A in _psql_base too — the CLI's Darwin branch was missing -t -A (only Linux had it), breaking every |-parsing subcommand (sources list/stats/sync/list) with IndexError/ValueError on Darwin (Titus, 2026-08-02). Fixed — Darwin now has -t -A like Linux.mycortex doctor must run as mycortex_admin, not mycortex — doctor hardcoded role mycortex which doesn't exist on macOS (roles are mycortex_admin/ingest/reader); also mycortex needs SELECT on schema_version (v003 grants it to admin). Fixed 2026-08-02 (Titus + Moses).slug relpaths (extension-stripped + lowercased: skills/.../skill for SKILL.md, docs/agent-architecture for .md). mycortex's canonical relpath is the REAL file path (golden queries assert .md/SKILL.md). Copying slugs verbatim makes the first sync's mass-deletion guardrail fire (every imported page looks "missing" → 642/642 abort). legacy import.py walks each source tree, builds slug→real map, inserts with real paths, and prunes slug-path dupes — fully idempotent across re-runs.legacy-brain-maintenance — the old system's lifecycle (autopilot, dream, PGLite); decommission target.cortex-deployment-sync — pull/update/deploy cycle that ships mycortex files.mycortex-parity.py --mode checkagent-mycortex-retention — daily 06:00 no_agent cron. ops/scripts/manage/agent-mycortex-retention.py prunes ingest_log >90d and hard-purges archived pages >7d (soft-delete window), runs as mycortex_ingest (DML role), counts eligible rows BEFORE delete, has --dry-run. Registered in install-crons.sh (create + uninstall arrays) + cortex-update.sh register.sg docker is ~1s/call — batch with VALUES joins. The original sync loop did 4 psql calls per page (~10s/page → hours for 1600 files). Batched to 5 calls per source total (page upsert, id lookup, chunk delete, chunk insert, FTS rebuild) using INSERT ... VALUES (...),(...) and UPDATE ... FROM (VALUES ...) AS v(...) — 1552 files in ~3s. Since the 2026-08-02 compliance fix, the 5 calls are ONE psql script per source (single session, single txn, advisory lock held); page ids resolve via a session temp table _mc_ids instead of a Python round-trip. Any tool that shells out to psql per row (sync, import, migration) must batch; also remember ::uuid casts when joining VALUES text against uuid FK columns.sync skips sources with empty local_path (e.g. builtin default); if the skip branch doesn't update last_sync_at, mycortex doctor flags them stale forever. Update the cursor on skip.