fix(ingest): route raw claude-session dumps to non-indexed archive, not wiki
claudeSink wrote every raw transcript into brain/wiki/claude-sessions/facts/ (BM25-indexed), duplicating what ai-sessions' curated summaries already cover and out-ranking them in search (177,818 vs 45,335 BM25 weight on the same query, per ai-sessions#10 investigation). Raw dumps now land in brain/archive/claude-sessions/<host>/ — kept for deep lookups, never indexed, never deleted. Refs: ai-sessions#10
This commit is contained in:
@@ -36,10 +36,12 @@ import (
|
|||||||
"github.com/mathiasbq/hyperguild/ingestion/internal/watcher"
|
"github.com/mathiasbq/hyperguild/ingestion/internal/watcher"
|
||||||
)
|
)
|
||||||
|
|
||||||
// claudeSink converts each claudewatcher.Batch into one wiki note under
|
// claudeSink converts each claudewatcher.Batch into a raw session dump
|
||||||
// brain/wiki/claude-sessions/facts/. v1 emits one note per session
|
// under brain/archive/claude-sessions/<host>/. Deliberately NOT a wiki
|
||||||
// keyed by host + session id; classifier-driven hall routing is a
|
// note (api.WriteNote / brain/wiki/) — raw full transcripts out-ranked
|
||||||
// follow-up (hyperguild#27 v2).
|
// curated ai-sessions summaries in BM25 (177,818 vs 45,335 on the same
|
||||||
|
// query) and duplicated content already summarized elsewhere. Kept for
|
||||||
|
// deep lookups, never indexed. See ai-sessions#10.
|
||||||
type claudeSink struct {
|
type claudeSink struct {
|
||||||
brainDir string
|
brainDir string
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
@@ -67,17 +69,14 @@ func (s *claudeSink) Ingest(ctx context.Context, b claudewatcher.Batch) error {
|
|||||||
sb.WriteString("\n\n")
|
sb.WriteString("\n\n")
|
||||||
}
|
}
|
||||||
slug := "session-" + b.Host + "-" + b.SessionID
|
slug := "session-" + b.Host + "-" + b.SessionID
|
||||||
if _, err := api.WriteNote(s.brainDir, api.WriteNoteOptions{
|
dest := filepath.Join(s.brainDir, "archive", "claude-sessions", b.Host, slug+".md")
|
||||||
Filename: slug,
|
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
|
||||||
Wing: "claude-sessions",
|
return fmt.Errorf("create claude-sessions archive dir: %w", err)
|
||||||
Hall: "facts",
|
|
||||||
Type: "source",
|
|
||||||
Domain: b.ProjectID,
|
|
||||||
Content: sb.String(),
|
|
||||||
SourceType: "internal", // raw session transcript, not an external claim (brain-gardener#5)
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("write claude session note: %w", err)
|
|
||||||
}
|
}
|
||||||
|
if err := os.WriteFile(dest, []byte(sb.String()), 0o644); err != nil {
|
||||||
|
return fmt.Errorf("write claude session archive: %w", err)
|
||||||
|
}
|
||||||
|
s.logger.Debug("claude session archived (non-indexed)", "path", dest)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/mathiasbq/hyperguild/ingestion/internal/claudewatcher"
|
"github.com/mathiasbq/hyperguild/ingestion/internal/claudewatcher"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClaudeSink_IngestTagsSourceTypeInternal(t *testing.T) {
|
func TestClaudeSink_IngestWritesToNonIndexedArchiveNotWiki(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
sink := &claudeSink{brainDir: dir, logger: slog.New(slog.NewTextHandler(os.Stderr, nil))}
|
sink := &claudeSink{brainDir: dir, logger: slog.New(slog.NewTextHandler(os.Stderr, nil))}
|
||||||
|
|
||||||
@@ -29,8 +29,10 @@ func TestClaudeSink_IngestTagsSourceTypeInternal(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
got, err := os.ReadFile(filepath.Join(dir, "wiki", "claude-sessions", "facts", "session-koala-abc.md"))
|
got, err := os.ReadFile(filepath.Join(dir, "archive", "claude-sessions", "koala", "session-koala-abc.md"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err, "raw session dump must land in the non-indexed archive")
|
||||||
assert.Contains(t, string(got), "source_type: internal")
|
assert.Contains(t, string(got), "did a thing")
|
||||||
assert.Contains(t, string(got), "wing: claude-sessions")
|
|
||||||
|
_, err = os.Stat(filepath.Join(dir, "wiki", "claude-sessions"))
|
||||||
|
assert.True(t, os.IsNotExist(err), "raw transcripts must never land under wiki/ (ai-sessions#10 — BM25 pollution)")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user