fix(hooks): drop wing_ prefix from transcript-derived wings#9
Merged
Conversation
The fork-only _wing_from_transcript_path returned wing_<project> for hook-derived wings, but operator-mined content from `mempalace mine ~/Projects/X` lands in a bare-name wing (e.g. memorypalace, mempalace, projects). Result: every project with both manual-mined content AND hook-mined transcripts had its drawers split between "wing_X" and "X" — silently invisible to a search filtered by either name. Drop the prefix. _wing_from_transcript_path now returns the bare project name (lowercased, spaces → underscores), matching the operator-mine convention. Fallback "wing_sessions" → "sessions" (which already exists in JP's canonical palace with 2,132 drawers from earlier hook-derived ingest with hardcoded --wing sessions, so new fallback content converges with the older fallback content too). A separate one-shot script renames legacy wing_<x> drawers' metadata so they merge into <x> on the live palace. Tests: 9 wing-related assertions updated to expect bare-name shape; 1548 pass, 1 skipped, lint clean. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR aligns hook-derived transcript ingestion with operator-mined project wings by changing _wing_from_transcript_path() to return bare project wing names (and sessions as the fallback) instead of the wing_<project> / wing_sessions prefixed shape, preventing content from silently splitting across two wings for the same project.
Changes:
- Update
_wing_from_transcript_path()to drop thewing_prefix and rename the default fallback tosessions. - Update hook CLI tests to assert the new bare-name wing behavior in system messages and daemon routing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
mempalace/hooks_cli.py |
Changes transcript-path → wing derivation to return bare project names and sessions fallback. |
tests/test_hooks_cli.py |
Updates assertions to match the new wing naming behavior for transcript ingestion. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+525
to
+527
| Returns the project directory's basename, lowercased, with spaces | ||
| collapsed to underscores. Falls back to ``"sessions"`` for paths | ||
| that don't match the standard Claude Code projects layout. |
Comment on lines
539
to
+543
| if match: | ||
| encoded = match.group(1) | ||
| project = encoded.rsplit("-", 1)[-1] | ||
| if project: | ||
| return f"wing_{project.lower().replace(' ', '_')}" | ||
| return project.lower().replace(" ", "_") |
jphein
added a commit
that referenced
this pull request
May 6, 2026
…ing_name (#10) Two findings from Copilot review on #9 (already merged): 1. **Last-dash-token rule lost hyphenated project names.** A project directory named ``realm-watch`` is encoded by Claude Code as ``-home-jp-Projects-realm-watch``, and the previous primary regex's ``rsplit('-', 1)[-1]`` returned ``watch`` — collapsing the project name. Reorder the resolution: try the explicit ``-Projects-<name>`` segment FIRST (preserves dashes), fall back to the last-dash-token only when the path is in a non-Projects layout (``~/dev/<parent>/<project>``). 2. **Inconsistent normalization vs operator mines.** Hook used ``.lower().replace(' ', '_')`` (no hyphen handling) while ``mempalace mine`` runs the dirname through ``normalize_wing_name`` (lowercases, dashes/spaces → underscores). Same project mined two ways produced two different wings. Route the hook through ``normalize_wing_name`` for parity. Net behavior: ``-Projects-realm-watch`` → ``realm_watch`` (matches operator-mine output). Existing tests for non-dashed projects still pass; 4 new tests cover dashed-project + uppercase-mixed cases + explicit operator-mine convergence assertion. Tests: 1551 pass, 1 skipped. Ruff lint + format clean. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_wing_from_transcript_pathreturnedwing_<project>for hook-derived wings, while operator-mined content frommempalace mine ~/Projects/Xlands in a bare-name wing. Result: every project that has both kinds of content silently splits betweenwing_XandX— invisible to a filtered search by either name.This PR drops the prefix. The fallback
wing_sessions→sessions(which already exists with 2,132 drawers in JP's canonical palace, so future fallback content converges with older fallback content).A separate one-shot script handles renaming the existing 28K+
wing_*drawers on the live palace so legacy hook content merges into the corresponding bare-name wings.Why
Live palace state pre-fix:
memorypalacewing_realmwatchwing_techempowerSame project, two wings. Search either way and you miss the other.
Test plan
🤖 Generated with Claude Code