Skip to content

Commit 6144da8

Browse files
Claudeclaude
authored andcommitted
chore: bump version to v1.4.4
fix: project drift on session resume — stored project now overrides agent-supplied project when resuming an existing session (hostname+PID match). fix: enforcement test aligned with create_thread removal from CONSEQUENTIAL_TOOLS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1f7274b commit 6144da8

5 files changed

Lines changed: 27 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.4.4] - 2026-03-31
11+
12+
### Fixed
13+
- **Project drift on session resume eliminated**: When resuming an existing session (same hostname+PID), the stored project now overrides whatever the agent passes. Previously, context compaction could cause agents to send the wrong project (e.g., `orchestra_dev` instead of `weekend_warrior`), creating a session under the wrong project with wrong threads and decisions. The active-sessions registry already stored the correct project — it just wasn't used on resume.
14+
- **`closing_reflection` array coercion**: Values passed as arrays in `closing_reflection` are now coerced to strings, preventing schema validation errors on session close.
15+
- **`create_thread` no longer triggers false enforcement warnings**: Removed from `CONSEQUENTIAL_TOOLS` list — creating threads is lightweight and shouldn't require prior recall.
16+
1017
## [1.4.3] - 2026-02-24
1118

1219
### Fixed

bin/gitmem.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,10 @@ async function cmdInit() {
154154
// Merge: skip scars that already exist by id
155155
const existingIds = new Set(existing.map((s) => s.id));
156156
let added = 0;
157+
const now = new Date().toISOString();
157158
for (const scar of starterScars) {
158159
if (!existingIds.has(scar.id)) {
159-
existing.push(scar);
160+
existing.push({ ...scar, created_at: now, source_date: now.slice(0, 10) });
160161
added++;
161162
console.log(` + ${scar.title}`);
162163
} else {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "gitmem-mcp",
3-
"version": "1.4.3",
3+
"version": "1.4.4",
44
"mcpName": "io.github.gitmem-dev/gitmem",
55
"description": "Persistent learning memory for AI coding agents. Memory that compounds.",
66
"type": "module",

src/tools/session-start.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ function readSessionFile(sessionId: string): Record<string, unknown> | null {
620620
function restoreSessionState(
621621
existing: Record<string, unknown>,
622622
fallbackAgent: AgentIdentity,
623-
): { sessionId: string; agent: AgentIdentity; linearIssue?: string; startedAt?: Date } {
623+
): { sessionId: string; agent: AgentIdentity; linearIssue?: string; startedAt?: Date; project?: Project } {
624624
const startedAt = existing.started_at ? new Date(existing.started_at as string) : undefined;
625625

626626
setCurrentSession({
@@ -640,6 +640,7 @@ function restoreSessionState(
640640
agent: (existing.agent as AgentIdentity) || fallbackAgent,
641641
linearIssue: existing.linear_issue as string | undefined,
642642
startedAt,
643+
project: existing.project as Project | undefined,
643644
};
644645
}
645646

@@ -653,7 +654,7 @@ function restoreSessionState(
653654
function checkExistingSession(
654655
agent: AgentIdentity,
655656
force?: boolean
656-
): { sessionId: string; agent: AgentIdentity; linearIssue?: string; startedAt?: Date } | null {
657+
): { sessionId: string; agent: AgentIdentity; linearIssue?: string; startedAt?: Date; project?: Project } | null {
657658
if (force) {
658659
console.error("[session_start] force=true, skipping active session guard");
659660
return null;
@@ -918,12 +919,23 @@ export async function sessionStart(
918919
// 1. Detect agent (or use provided)
919920
const env = detectAgent();
920921
const agent = params.agent_identity || env.agent;
921-
const project: Project = params.project || getConfigProject() || "default";
922+
let project: Project = params.project || getConfigProject() || "default";
922923

923924
// Check for existing active session — reuse session_id but still load full context
924925
const existingSession = checkExistingSession(agent, params.force);
925926
const isResuming = existingSession !== null;
926927

928+
// When resuming, prefer the stored project from the existing session.
929+
// This prevents project drift after context compaction — the agent may pass
930+
// the wrong project (e.g., from CLAUDE.md defaults) but the stored session
931+
// knows the real project.
932+
if (isResuming && existingSession?.project) {
933+
if (existingSession.project !== project) {
934+
console.error(`[session_start] Project override on resume: ${project}${existingSession.project} (from stored session)`);
935+
}
936+
project = existingSession.project;
937+
}
938+
927939
// t-f7c2fa01: When force:true kills an existing session, carry forward its startedAt
928940
// so session_close duration reflects the full conversation, not just the new session.
929941
// Also carry forward activity counts (recalls, observations) so standard close isn't rejected.

tests/unit/services/enforcement.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ describe("enforcement", () => {
110110
expect(result.warning).toContain("No recall()");
111111
});
112112

113-
it("warns when create_thread called without recall", () => {
113+
it("does not warn for create_thread (not consequential)", () => {
114114
const result = checkEnforcement("create_thread");
115-
expect(result.warning).toContain("No recall()");
115+
expect(result.warning).toBeNull();
116116
});
117117

118118
it("warns when session_close called without recall", () => {

0 commit comments

Comments
 (0)