Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

## 2.1.1

Read-only diagnostic safety patch.

### Fixes & Improvements

1. **Strict diagnostic mode.** `run-once --diagnostic` inspects a stable private SQLite
snapshot without constructing the pipeline, changing HEGI state or queues, creating
dead letters, or calling Telegram, LLM, Memory Forest, archive, or run logging paths.
2. **Public CLI isolation.** Plugin registration starts the embedded worker only inside a
Hermes gateway process, and writable state initialization occurs later inside the
worker lock, so `hermes hegi ... --diagnostic` remains read-only before its handler.
A gateway blocked by a migration-held worker lock retries initialization once per
second instead of leaving approval state uninitialized for a full polling interval.
3. **Fail-closed snapshots.** Streaming snapshots preserve bounded memory, use no-atime
reads on Linux/WSL, pin config and state through directory descriptors, reject pathname
rebinding and unsafe artifacts, and distinguish concurrent changes from invalid state.
4. **Schema verification.** Diagnostics require schema version 8, required table/column
definitions, indexes (including partial idempotency indexes), and foreign keys.
5. **Migration quiescence and post-check.** The migration script stops the selected
gateway and holds both the gateway runtime lock and worker lock before its rollback
snapshot, launches foreground-capable restarts detached, verifies gateway lock
reacquisition, and runs the diagnostic while retaining the worker lock. Documentation
now distinguishes this mode from the legacy stateful `--dry-run` pipeline rehearsal.

## 2.1.0

First standalone HEGI release.
Expand Down
44 changes: 27 additions & 17 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,29 @@ scripts/migrate-existing-install.sh --apply \

The script performs these changes:

1. Creates `<runtime-home>/hegi/migration-backups/<UTC timestamp>/` with mode `0700`.
2. Copies the HEGI config.
3. Uses SQLite `.backup` for the state database, when present.
4. Copies the legacy `plugins/hegi-telegram` directory, when present.
5. Records whether `hegi.service` was enabled.
6. Seals the backup with a version marker and SHA-256 manifest covering every artifact.
7. Installs `icerain-cmd/hermes-hegi` through the Hermes plugin manager with `--force`.
8. Enables `hegi-telegram` without a built-in tool override grant.
9. Runs the additive HEGI state migration, creating another config/state checkpoint.
10. Disables the legacy service unless `--keep-old-service` was supplied.
11. Restarts the Hermes gateway.
12. Runs `hermes hegi doctor`.
13. Runs `hermes hegi run-once --dry-run`.
1. Acquires the worker lock, stops the selected profile's Hermes gateway, and holds its
runtime lock, quiescing both worker and legacy hook writes before the rollback snapshot.
2. Creates `<runtime-home>/hegi/migration-backups/<UTC timestamp>/` with mode `0700`.
3. Copies the HEGI config.
4. Uses SQLite `.backup` for the state database, when present.
5. Copies the legacy `plugins/hegi-telegram` directory, when present.
6. Records whether `hegi.service` was enabled.
7. Seals the backup with a version marker and SHA-256 manifest covering every artifact.
8. Installs `icerain-cmd/hermes-hegi` through the Hermes plugin manager with `--force`.
9. Enables `hegi-telegram` without a built-in tool override grant.
10. Runs the additive HEGI state migration, creating another config/state checkpoint.
11. Disables the legacy service unless `--keep-old-service` was supplied.
12. Releases the gateway runtime lock, launches gateway restart detached (including on
foreground-only WSL installations), and verifies that the gateway reacquired it.
13. Runs `hermes hegi doctor`.
14. Runs the no-state-write post-check `hermes hegi run-once --diagnostic` while the
migration still owns the worker lock.

If backup creation fails before plugin installation or schema migration begins, the
script makes a best-effort restart of the original gateway. Once an install or schema
mutation has started, a failure deliberately leaves the gateway stopped so an operator
can inspect the completed rollback backup instead of loading a potentially partial
deployment.

Save the printed backup directory and rollback command. If a later step fails, the backup
from an earlier step still exists. Do not delete it while diagnosing the partial
Expand All @@ -166,7 +176,7 @@ hermes plugins list --enabled --json
hermes gateway status
hermes hegi doctor --json
hermes hegi status
hermes hegi run-once --dry-run
hermes hegi run-once --diagnostic
```

Confirm:
Expand All @@ -178,7 +188,7 @@ Confirm:
- the config still points to the intended source databases and local archive;
- existing episode and delivery counts remain present;
- no second standalone worker is active; and
- dead-letter count did not grow unexpectedly.
- dead-letter count did not change during the diagnostic.

Inspect the script-created state backup too:

Expand All @@ -188,8 +198,8 @@ sqlite3 /path/to/migration-backup/state.db "PRAGMA quick_check;"

## 7. Telegram report smoke test

Choose a known, non-sensitive quiet episode and check dry-run output before allowing a
real report:
After the read-only migration verification is complete, choose a known, non-sensitive
quiet episode for an explicitly stateful pipeline rehearsal before allowing a real report:

```bash
hermes hegi run-once --dry-run
Expand Down
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# HEGI 2.1.0: AI Research Secretary for Hermes
# HEGI 2.1.1: AI Research Secretary for Hermes

[한국어 문서](docs/README.ko.md)

Expand All @@ -7,7 +7,7 @@ structured minutes, action items, revision-safe archives, Telegram reports, and
Forest recommendations. It is distributed as `hermes-hegi`, imported as `hegi`, and
registered with Hermes under the plugin key `hegi-telegram`.

HEGI 2.1.0 is a standalone plugin. It does not patch Hermes, copy code into the Hermes
HEGI 2.1.1 is a standalone plugin. It does not patch Hermes, copy code into the Hermes
installation, or depend on private Hermes modules. The package uses the public plugin
context for CLI registration, `pre_gateway_dispatch`, LLM access, and tool dispatch. It
calls the Telegram Bot API through its own adapter.
Expand Down Expand Up @@ -133,14 +133,14 @@ Install a tagged source tree or a downloaded release wheel into the same Python
environment as Hermes, then enable the discovered entry point:

```bash
python -m pip install "git+https://github.com/icerain-cmd/hermes-hegi.git@v2.1.0"
python -m pip install "git+https://github.com/icerain-cmd/hermes-hegi.git@v2.1.1"
hermes plugins enable hegi-telegram --no-allow-tool-override
```

or:

```bash
python -m pip install ./hermes_hegi-2.1.0-py3-none-any.whl
python -m pip install ./hermes_hegi-2.1.1-py3-none-any.whl
hermes plugins enable hegi-telegram --no-allow-tool-override
```

Expand Down Expand Up @@ -190,13 +190,24 @@ hermes gateway restart
hermes hegi doctor
hermes hegi doctor --json
hermes hegi status
hermes hegi run-once --diagnostic
hermes hegi run-once --dry-run
```

`run-once` defaults to dry-run behavior. It may use the configured LLM and Memory Forest
search tools and may update HEGI's local state, but it does not write an archive, send a
Telegram report, consume the source range, approve a Draft, or commit a memory. Use
`--send` only when you intend to archive and deliver a real report:
`run-once --diagnostic` streams a stable raw SQLite snapshot into private temporary
storage, checks configuration, the supported schema version and required invariants,
integrity, and aggregate queue
counts there, and verifies that the operating database and sidecars did not change. It
never constructs the pipeline or calls the LLM, Memory Forest, Telegram, archive, or run
logger. On Linux and WSL it opens SQLite artifacts with `O_NOATIME`; configuration and env
files are read, so their filesystem access timestamps are outside this logical no-write
guarantee.

The existing `run-once --dry-run` remains a stateful pipeline simulation for backward
compatibility. It may use the configured LLM and Memory Forest search tools and may
update HEGI's local state, retries, dead letters, cursors, buffers, and run log. It does
not write an archive, send a Telegram report, consume the source range, approve a Draft,
or commit a memory. Use `--send` only when you intend to archive and deliver a real report:

```bash
hermes hegi run-once --send
Expand All @@ -213,7 +224,8 @@ The CLI surface is:
| `hermes hegi setup [--dry-run|--apply]` | Discover and write HEGI configuration |
| `hermes hegi doctor [--json]` | Check Hermes APIs, configuration, tools, token, paths, and schema |
| `hermes hegi status` | Print episode, queue, notification, and dead-letter counts |
| `hermes hegi run-once [--dry-run|--send]` | Run one pipeline cycle; dry-run is the default |
| `hermes hegi run-once --diagnostic` | Inspect a stable private state snapshot with no HEGI data writes or external calls |
| `hermes hegi run-once [--dry-run|--send]` | Run a stateful pipeline cycle; dry-run is the default |
| `hermes hegi migrate [--dry-run|--apply]` | Back up config and state, then apply additive schema changes |
| `hermes hegi export-diagnostics [--output FILE]` | Write a redacted diagnostic JSON file with mode `0600` |
| `hermes hegi uninstall --keep-data` | Disable HEGI while retaining config, state, and archives |
Expand All @@ -233,11 +245,11 @@ hermes hegi migrate --dry-run
hermes hegi migrate --apply
hermes gateway restart
hermes hegi doctor
hermes hegi run-once --dry-run
hermes hegi run-once --diagnostic
```

For a Python installation, install the intended wheel or tag with `python -m pip install
--upgrade ...`, then run the same migrate, restart, doctor, and dry-run sequence. Schema
--upgrade ...`, then run the same migrate, restart, doctor, and diagnostic sequence. Schema
migrations are additive. Do not downgrade or restore `state.db` without a migration-specific
rollback plan.

Expand Down
29 changes: 19 additions & 10 deletions docs/README.ko.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# HEGI 2.1.0: Hermes용 AI 연구비서
# HEGI 2.1.1: Hermes용 AI 연구비서

[English README](../README.md)

HEGI는 여러 Hermes 연구 에이전트의 대화를 회의 Episode, 구조화 회의록, Action Item,
revision-safe archive, Telegram 보고, Memory Forest 권고로 변환한다. Python 배포명은
`hermes-hegi`, import package는 `hegi`, Hermes 플러그인 키는 `hegi-telegram`이다.

HEGI 2.1.0은 독립 플러그인이다. Hermes를 패치하거나 Hermes 설치 디렉터리에 코드를
HEGI 2.1.1은 독립 플러그인이다. Hermes를 패치하거나 Hermes 설치 디렉터리에 코드를
복사하지 않으며 Hermes private module에 의존하지 않는다. 이 패키지는 CLI 등록,
`pre_gateway_dispatch`, LLM 접근, tool dispatch에 public plugin context를 사용한다.
Telegram Bot API는 HEGI 자체 adapter로 호출한다.
Expand Down Expand Up @@ -133,14 +133,14 @@ tag가 지정된 source tree나 다운로드한 release wheel을 Hermes와 같
environment에 설치한 다음 발견된 entry point를 활성화한다.

```bash
python -m pip install "git+https://github.com/icerain-cmd/hermes-hegi.git@v2.1.0"
python -m pip install "git+https://github.com/icerain-cmd/hermes-hegi.git@v2.1.1"
hermes plugins enable hegi-telegram --no-allow-tool-override
```

또는 다음을 실행한다.

```bash
python -m pip install ./hermes_hegi-2.1.0-py3-none-any.whl
python -m pip install ./hermes_hegi-2.1.1-py3-none-any.whl
hermes plugins enable hegi-telegram --no-allow-tool-override
```

Expand Down Expand Up @@ -190,13 +190,21 @@ hermes gateway restart
hermes hegi doctor
hermes hegi doctor --json
hermes hegi status
hermes hegi run-once --diagnostic
hermes hegi run-once --dry-run
```

`run-once`는 기본적으로 dry-run으로 동작한다. 설정된 LLM과 Memory Forest search tool을
사용하고 HEGI local state를 갱신할 수 있지만 archive를 쓰거나 Telegram 보고를 보내지
않고, source range를 consumed로 전환하지 않으며, Draft approve나 memory commit을
수행하지 않는다. 실제 archive와 보고 전송을 의도할 때만 `--send`를 사용한다.
`run-once --diagnostic`은 운영 SQLite를 private 임시 공간으로 streaming snapshot한 뒤
지원 schema, 무결성, aggregate queue count를 검사한다. HEGI state나 queue를 쓰지 않고
pipeline, LLM, Memory Forest, Telegram, archive, run logger를 호출하지 않는다. Linux와
WSL에서는 SQLite artifact를 `O_NOATIME`으로 연다. config와 env 파일은 읽으므로 그
파일들의 filesystem access timestamp는 논리적 무쓰기 보장 범위에 포함하지 않는다.

기존 `run-once --dry-run`은 호환성을 위해 남겨 둔 stateful pipeline simulation이다.
설정된 LLM과 Memory Forest search tool을 사용하고 retry, dead letter, cursor, buffer 등
HEGI local state를 갱신할 수 있다. archive를 쓰거나 Telegram 보고를 보내지 않고,
source range를 consumed로 전환하지 않으며, Draft approve나 memory commit을 수행하지
않는다. 실제 archive와 보고 전송을 의도할 때만 `--send`를 사용한다.

```bash
hermes hegi run-once --send
Expand All @@ -213,6 +221,7 @@ CLI surface는 다음과 같다.
| `hermes hegi setup [--dry-run|--apply]` | HEGI config 탐지 및 작성 |
| `hermes hegi doctor [--json]` | Hermes API, config, tool, token, path, schema 점검 |
| `hermes hegi status` | episode, queue, notification, dead-letter count 출력 |
| `hermes hegi run-once --diagnostic` | HEGI data write와 external call 없이 private state snapshot 점검 |
| `hermes hegi run-once [--dry-run|--send]` | pipeline cycle 한 번 실행. 기본값은 dry-run |
| `hermes hegi migrate [--dry-run|--apply]` | config와 state를 백업하고 additive schema 변경 적용 |
| `hermes hegi export-diagnostics [--output FILE]` | mode `0600`인 redacted diagnostic JSON 작성 |
Expand All @@ -233,11 +242,11 @@ hermes hegi migrate --dry-run
hermes hegi migrate --apply
hermes gateway restart
hermes hegi doctor
hermes hegi run-once --dry-run
hermes hegi run-once --diagnostic
```

Python 설치에서는 의도한 wheel 또는 tag를 `python -m pip install --upgrade ...`로
설치한 다음 같은 migrate, restart, doctor, dry-run 순서를 실행한다. schema migration은
설치한 다음 같은 migrate, restart, doctor, diagnostic 순서를 실행한다. schema migration은
additive 방식이다. migration별 rollback 계획 없이 `state.db`를 downgrade하거나
복원하지 않는다.

Expand Down
32 changes: 26 additions & 6 deletions docs/operations.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Operations

This guide covers a new HEGI 2.1.0 installation. Operators moving an in-tree or standalone
This guide covers a new HEGI 2.1.1 installation. Operators moving an in-tree or standalone
daemon deployment should use [MIGRATION.md](../MIGRATION.md) first.

## Prerequisites
Expand Down Expand Up @@ -33,7 +33,7 @@ For a wheel installation, install into the Python environment that provides `her
enable the package entry point:

```bash
python -m pip install ./hermes_hegi-2.1.0-py3-none-any.whl
python -m pip install ./hermes_hegi-2.1.1-py3-none-any.whl
hermes plugins enable hegi-telegram --no-allow-tool-override
```

Expand Down Expand Up @@ -144,15 +144,35 @@ and must be disabled before the embedded worker handles production data.

## One-cycle checks

Run a dry cycle after setup, upgrade, gateway restart, or state migration:
Run the strict read-only diagnostic after setup, upgrade, gateway restart, or state
migration:

```bash
hermes hegi run-once --diagnostic
```

The diagnostic streams a stable raw main/WAL snapshot into a private temporary directory.
It reads configuration, the supported schema version and required invariants, integrity,
and aggregate queue state
from that copy, then verifies that the operating database and its sidecars are unchanged.
On Linux and WSL, SQLite artifacts are opened with `O_NOATIME`; config and env access
timestamps are outside the logical no-write guarantee. It does not construct the
pipeline, call the LLM or Memory Forest, contact Telegram, write an archive, or append the
run log. If another worker changes SQLite files during the check, it exits with
`hegi-state-changing`; an unsafe or unreadable artifact instead exits with
`hegi-state-unsafe`. Stop a concurrent worker before retrying a changing state; do not
treat an unsafe artifact as transient.

Use the older stateful simulation only when retry, cursor, buffer, episode, dead-letter,
and run-log updates are acceptable:

```bash
hermes hegi run-once --dry-run
```

Dry-run may read source databases, call the configured LLM, search Memory Forest, and
write HEGI state needed for diagnostics. It does not write the meeting archive, deliver a
Telegram report, consume the source range, approve a Draft, or commit a memory.
write HEGI state. It does not write the meeting archive, deliver a Telegram report,
consume the source range, approve a Draft, or commit a memory.

Send a real report only after the dry-run result and target chat are confirmed:

Expand Down Expand Up @@ -271,7 +291,7 @@ hermes hegi migrate --dry-run
hermes hegi migrate --apply
hermes gateway restart
hermes hegi doctor
hermes hegi run-once --dry-run
hermes hegi run-once --diagnostic
```

For a package installation, upgrade to an explicit tag or wheel and continue with the
Expand Down
2 changes: 1 addition & 1 deletion hegi/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Single source of truth for the HEGI package version."""

__version__ = "2.1.0"
__version__ = "2.1.1"
Loading