refactor: rename metadata directory .hermes to .mam in backplane scripts and documents
This commit is contained in:
@@ -7,5 +7,5 @@
|
||||
- 브로커 PoC→운영 전환: [`mqtt-broker-setup.md`](./mqtt-broker-setup.md)
|
||||
- 레지스트리 포맷/동시성: [`registry.md`](./registry.md)
|
||||
- 참조 구현: [`tmux-agent-orchestrate-delegate-job`](./tmux-agent-orchestrate-delegate-job) (bash wrapper), [`scripts/publish_event.py`](./scripts/publish_event.py), [`scripts/job_subscriber.py`](./scripts/job_subscriber.py), [`scripts/registry.py`](./scripts/registry.py), [`scripts/mqtt_common.py`](./scripts/mqtt_common.py)
|
||||
- 영구 감사 로그: `.hermes/delegate_job_logs/<job_id>/` (`meta.json`·`events.ndjson`·`status.json`)
|
||||
- 영구 감사 로그: `.mam/delegate_job_logs/<job_id>/` (`meta.json`·`events.ndjson`·`status.json`)
|
||||
— `tmux-agent-orchestrate-delegate-job logs <id>` 또는 `tmux-agent-orchestrate-delegate-job logs --list`로 조회 (SKILL.md "Audit Logs" 참조)
|
||||
|
||||
@@ -27,7 +27,7 @@ canonical concrete instance.
|
||||
|
||||
The model is deliberately small. A **job** is one delegated task. An **agent**
|
||||
is a worker (a claude-code tmux session, a codex run, a human). The **registry**
|
||||
(`.hermes/jobs/<id>.json`) holds everything about a job so nothing important
|
||||
(`.mam/jobs/<id>.json`) holds everything about a job so nothing important
|
||||
lives in environment variables — which means one tmux session can process many
|
||||
jobs sequentially, and many sessions can fan out in parallel, with no env
|
||||
collisions. The **event channel** is one MQTT topic per job carrying JSON
|
||||
@@ -83,7 +83,7 @@ tmux-agent-orchestrate-delegate-job submit \
|
||||
# subscriber pid: …
|
||||
# agent launched in tmux session: demo
|
||||
# subscriber output: <one line per event>
|
||||
# /path/to/project/.hermes/delegate_job_logs/<JID> ← audit log dir
|
||||
# /path/to/project/.mam/delegate_job_logs/<JID> ← audit log dir
|
||||
|
||||
# 2) at any time, query the job or its audit log
|
||||
tmux-agent-orchestrate-delegate-job status --job <JID>
|
||||
@@ -148,9 +148,9 @@ One topic per job: `python/mqtt/jobs/<job_id>/events`. Payload (JSON, UTF-8,
|
||||
## Registry Format
|
||||
|
||||
```
|
||||
.hermes/jobs/<id>.json # metadata record (single source of truth)
|
||||
.hermes/jobs/<id>.events.log # append-only JSON-lines log (debug, optional)
|
||||
.hermes/jobs/.lock # fcntl advisory lock for the registry
|
||||
.mam/jobs/<id>.json # metadata record (single source of truth)
|
||||
.mam/jobs/<id>.events.log # append-only JSON-lines log (debug, optional)
|
||||
.mam/jobs/.lock # fcntl advisory lock for the registry
|
||||
```
|
||||
|
||||
The record holds `status`, `prompt`, `agent`, `agent_session`, a `broker` block,
|
||||
@@ -163,13 +163,13 @@ the atomic rename trick, and multi-session job claiming are in
|
||||
## Audit Logs
|
||||
|
||||
Every job's lifecycle is mirrored to a **persistent, append-only audit log**
|
||||
under `.hermes/delegate_job_logs/` (override with `DELEGATE_JOB_LOGS_DIR`;
|
||||
default `<cwd>/.hermes/delegate_job_logs`). Unlike the registry — live state
|
||||
under `.mam/delegate_job_logs/` (override with `DELEGATE_JOB_LOGS_DIR`;
|
||||
default `<cwd>/.mam/delegate_job_logs`). Unlike the registry — live state
|
||||
mutated in place and liable to be cleaned up — the audit log is durable
|
||||
history you can replay after the fact. It is git-ignored.
|
||||
|
||||
```
|
||||
.hermes/delegate_job_logs/<job_id>/
|
||||
.mam/delegate_job_logs/<job_id>/
|
||||
meta.json # registration snapshot: prompt, agent, broker, timeouts, …
|
||||
events.ndjson # append-only, one JSON event per line, in time order
|
||||
status.json # current status only (fast point-query)
|
||||
@@ -371,7 +371,7 @@ has been verified (2026-06-21, 6-batch refactoring sprint):
|
||||
- [ ] `publisher.py`/`subscriber.py`/`README.md` demo on `python/mqtt/sample`
|
||||
still works unchanged (regression).
|
||||
- [ ] **audit log integrity** — for a completed job,
|
||||
`.hermes/delegate_job_logs/<JID>/events.ndjson` contains `registered` →
|
||||
`.mam/delegate_job_logs/<JID>/events.ndjson` contains `registered` →
|
||||
`received started` → `published completed` (in that order), and
|
||||
`status.json.status == "completed"` matches the registry record. A
|
||||
logging failure (e.g. read-only log dir) does not break the publish or
|
||||
|
||||
@@ -15,13 +15,13 @@ Reference implementation: [`./scripts/registry.py`](./scripts/registry.py)
|
||||
## 1. Directory layout
|
||||
|
||||
```
|
||||
.hermes/jobs/
|
||||
.mam/jobs/
|
||||
<job_id>.json # job metadata record (schema below)
|
||||
<job_id>.events.log # append-only JSON-lines event log (debug, optional)
|
||||
.lock # shared advisory lock (fcntl) for the whole registry
|
||||
```
|
||||
|
||||
`registry_dir` defaults to `.hermes/jobs` and is overridable everywhere via
|
||||
`registry_dir` defaults to `.mam/jobs` and is overridable everywhere via
|
||||
`--registry-dir`.
|
||||
|
||||
---
|
||||
@@ -143,13 +143,13 @@ that session.
|
||||
## 7. Persistent audit log
|
||||
|
||||
Separate from the registry, every job is also mirrored to a durable append-only
|
||||
audit log at `.hermes/delegate_job_logs/<job_id>/` (override with
|
||||
`DELEGATE_JOB_LOGS_DIR`, default `<cwd>/.hermes/delegate_job_logs`). The registry
|
||||
audit log at `.mam/delegate_job_logs/<job_id>/` (override with
|
||||
`DELEGATE_JOB_LOGS_DIR`, default `<cwd>/.mam/delegate_job_logs`). The registry
|
||||
is **live state** mutated in place; the audit log is **history** that survives
|
||||
even after the registry dir is cleaned up. It is git-ignored.
|
||||
|
||||
```
|
||||
.hermes/delegate_job_logs/<job_id>/
|
||||
.mam/delegate_job_logs/<job_id>/
|
||||
meta.json # registration snapshot (the full job record at register time)
|
||||
events.ndjson # append-only, one JSON event per line, time-ordered
|
||||
status.json # current status only (fast point-query)
|
||||
|
||||
@@ -71,11 +71,11 @@ _load_dotenv()
|
||||
# Constants
|
||||
# --------------------------------------------------------------------------
|
||||
SCHEMA_VERSION = 1
|
||||
DEFAULT_REGISTRY_DIR = ".hermes/jobs"
|
||||
DEFAULT_REGISTRY_DIR = ".mam/jobs"
|
||||
DEFAULT_TOPIC_ROOT = "python/mqtt/jobs"
|
||||
LOCK_FILENAME = ".lock"
|
||||
|
||||
# Persistent audit-log layout: .hermes/delegate_job_logs/<job_id>/{meta,events,status}.
|
||||
# Persistent audit-log layout: .mam/delegate_job_logs/<job_id>/{meta,events,status}.
|
||||
# This is a *separate* artifact from the registry: the registry is the live job
|
||||
# record (mutated in place), the audit log is an append-only history that
|
||||
# survives even if the registry dir is cleaned up.
|
||||
@@ -86,15 +86,15 @@ STATUS_FILENAME = "status.json"
|
||||
|
||||
def _default_logs_dir() -> str:
|
||||
"""Audit-log root. Overridable with ``DELEGATE_JOB_LOGS_DIR``; otherwise
|
||||
``<cwd>/.hermes/delegate_job_logs`` — we keep audit logs next to the
|
||||
live registry (``.hermes/jobs/``) so the two runtime artifacts sit
|
||||
``<cwd>/.mam/delegate_job_logs`` — we keep audit logs next to the
|
||||
live registry (``.mam/jobs/``) so the two runtime artifacts sit
|
||||
under the same parent dir and follow the same ``.gitignore`` rule.
|
||||
The cwd of whichever process emits events (the bash wrapper and
|
||||
scripts) is used as the anchor."""
|
||||
env = os.environ.get("DELEGATE_JOB_LOGS_DIR")
|
||||
if env and env.strip():
|
||||
return env
|
||||
return os.path.join(os.getcwd(), ".hermes", "delegate_job_logs")
|
||||
return os.path.join(os.getcwd(), ".mam", "delegate_job_logs")
|
||||
|
||||
|
||||
LOGS_DIR = _default_logs_dir()
|
||||
@@ -376,7 +376,7 @@ def _utcnow_precise() -> str:
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Persistent audit log (.hermes/delegate_job_logs/<job_id>/...)
|
||||
# Persistent audit log (.mam/delegate_job_logs/<job_id>/...)
|
||||
#
|
||||
# Every function here is idempotent, concurrency-safe, and *best-effort*: a
|
||||
# logging failure is swallowed with a logger.warning and never propagated, so it
|
||||
|
||||
@@ -222,7 +222,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
help="summarise every job under the logs dir instead")
|
||||
p_logs.add_argument("--logs-dir", default=None,
|
||||
help="override the audit-log root (default: $DELEGATE_JOB_LOGS_DIR "
|
||||
"or <cwd>/.hermes/delegate_job_logs)")
|
||||
"or <cwd>/.mam/delegate_job_logs)")
|
||||
p_logs.add_argument("--tail", type=int, default=0,
|
||||
help="show only the last N events (0 = all)")
|
||||
p_logs.add_argument("--json", action="store_true",
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ pick_python() {
|
||||
echo "$py_bin"
|
||||
}
|
||||
|
||||
REGISTRY_DIR_DEFAULT=".hermes/jobs"
|
||||
REGISTRY_DIR_DEFAULT=".mam/jobs"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
|
||||
Reference in New Issue
Block a user