Skip to content

Add gstack adapter: one command to make gstack memory native to Dhee#26

Merged
Ashish-dwi99 merged 3 commits intomainfrom
feat/gstack-adapter
Apr 21, 2026
Merged

Add gstack adapter: one command to make gstack memory native to Dhee#26
Ashish-dwi99 merged 3 commits intomainfrom
feat/gstack-adapter

Conversation

@Ashish-dwi99
Copy link
Copy Markdown
Collaborator

Summary

  • dhee install gstack ingests gstack's siloed ~/.gstack/projects/<slug>/ memory into Dhee's existing remember pipeline — mirrors the Claude Code + Codex harness install pattern.
  • Feature-detected, idempotent, read-only. Zero mutation of gstack files. Respects $GSTACK_HOME. Injection-safe (runs gstack's own denylist before writing).
  • Session hooks (SessionStart + Stop) call tail_ingest() automatically, but only when the user has explicitly run dhee install gstack.

Why

gstack is a 79k-star Claude Code skill pack. Its memory layer works fine at a 3-month horizon but breaks on six axes over years:

Failure mode Dhee component that fixes it
Substring-only learnings search dhee/memory/search_pipeline.py + dhee/memory/reranker.py
No consolidation of near-dup keys dhee/core/engram.py + write pipeline
No correction / invalidation loop dhee/core/conflict.py + dhee/core/forgetting.py
Checkpoint rehydration is ls -t | head -3 dhee/memory/episodic.py + retrieval helpers
No code world-model dhee/hooks/claude_code/ingest.py
Cross-project honor-system dhee/memory/projects.py

Dhee already has every fix. The adapter just wires gstack's on-disk files into the pipeline — no reimplementation of BM25, consolidation, or correction.

What's in the three commits

  1. 7d1d9e3dhee/adapters/gstack_parser.py (pure parsers) + 7-test suite + seeded fixture.
  2. 443f396dhee/adapters/gstack.py (adapter core), dhee/harness/install.py (install/disable/status), dhee/hooks/claude_code/__main__.py (session-hook tail_ingest).
  3. a86e59adhee install gstack CLI, dhee adapters gstack [status|reingest|clear], --harness gstack on install/harness commands, docs, CHANGELOG v5.1.0.

Behavioral contract

  1. Read-only. Dhee never mutates gstack files.
  2. Idempotent. Manifest at $DHEE_DATA_DIR/gstack_manifest.json tracks per-project JSONL byte offsets + markdown mtime/size.
  3. Feature-detected install. Missing ~/.claude/skills/gstack/VERSION → clean "skipped" result, config flag stays off.
  4. gstack standalone still works. Uninstalling Dhee leaves ~/.gstack/ intact.
  5. Respects $GSTACK_HOME.
  6. Injection defense. Atoms that match gstack's own denylist are dropped before remember.

Test plan

  • pytest tests/test_gstack_adapter.py — 7 passed (backfill, tail, idempotent, checkpoint sections, uninstall, no-install-graceful, injection-safe).
  • Full pytest tests/ — 1177 passed, 6 skipped. Two failures in test_mcp_artifact_tools.py are pre-existing on main and unrelated.
  • CLI smoke: dhee install gstack on a host with no gstack → "skipped". Seeded fixture → dhee adapters gstack reingest --reset --json reports 11 atoms (2 learnings, 3 timeline, 2 reviews, 4 checkpoint sections).
  • No real-user simulation (per plan direction — deterministic tests only).

🤖 Generated with Claude Code

Ashish-dwi99 and others added 3 commits April 21, 2026 17:16
Pure parsers for gstack's four memory surfaces (learnings.jsonl,
timeline.jsonl, <branch>-reviews.jsonl, checkpoints/*.md) plus a sealed
fixture that seeds a realistic projects/<slug>/ tree and 7 deterministic
tests exercising backfill, tail-ingest, idempotency, checkpoint
sectioning, uninstall, graceful skip when gstack is absent, and
injection-safe refusal.

Parsers reuse gstack's own prompt-injection denylist so we never ingest
what gstack itself would reject, and preserve unknown fields on a `raw`
passthrough so future schema drift doesn't silently discard data.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
dhee/adapters/gstack.py is the read-only ingestor that turns gstack's
siloed ~/.gstack/projects/<slug>/ memory into atoms on Dhee's
`remember` pipeline. Per-project cursor manifest at
$DHEE_DATA_DIR/gstack_manifest.json (byte offsets for JSONL, mtime+size
for markdown) makes backfill and tail-ingest idempotent, handles
truncation/partial-write cases, and never mutates gstack files.

dhee/harness/install.py grows `_install_gstack` / `_disable_gstack` /
`_status_gstack` mirroring the existing Claude Code + Codex pattern.
Feature-detected: a missing ~/.claude/skills/gstack/VERSION yields a
clean "skipped" result and leaves the config flag off.

dhee/hooks/claude_code/__main__.py calls tail_ingest() on SessionStart
and Stop — no-op unless the user has explicitly run `dhee install
gstack`. Errors are swallowed end-to-end; session hooks never block.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CLI surface:
- `dhee install gstack` (positional shortcut) and
  `dhee install --harness gstack` both reach `_install_gstack`.
- `dhee harness [status|enable|disable] --harness gstack` accepts the
  new target alongside claude_code and codex.
- `dhee adapters gstack [status|reingest|clear]` exposes ad-hoc
  inspection and refresh without re-running the full install command.

Docs: docs/adapters/gstack.md maps the six gstack memory failure modes
(substring-only search, no consolidation, no correction, ls -t
checkpoint rehydration, no code world-model, honor-system project
scoping) onto the existing Dhee components that fix each one.

README: one short section under the harness install block pointing at
the new command and the adapter doc.

CHANGELOG: v5.1.0 entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Ashish-dwi99 Ashish-dwi99 merged commit 6d04293 into main Apr 21, 2026
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant