Skip to content

Commit fd133ec

Browse files
committed
fix(test): unblock 1.0.10 publish
1 parent 5dbb457 commit fd133ec

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
1515
- **Agent Team wording tightened** -- Public docs now frame Agent Team as optional autonomous-agent/subagent coordination state rather than an IDE-window chat room. Existing `team_*` APIs and CLI namespaces are unchanged.
1616

1717
### Fixed
18+
- **Release publish blocker** -- `tests/integration/release-blockers.test.ts` now reserves an ephemeral local TCP port for the real `memorix serve-http` smoke test instead of assuming port `19879` is free. This removes a CI-only `EADDRINUSE` failure that blocked the npm publish workflow.
1819
- **Standalone dashboard embedding config (#46 follow-up)** -- `memorix dashboard` now loads project `.env` / project YAML before dashboard status routes initialize embedding provider state, matching `status`, `doctor`, and TUI behavior.
1920

2021
### Documentation

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ Additional deep references:
436436

437437
## What's New in 1.0.10
438438

439-
Version `1.0.10` tightens Memorix's low-intrusion operator story: privacy-safe handoff diagnostics, clearer cross-agent memory boundaries, optional session semantics in generated rules, independent TUI agent LLM config, a better fresh-project cold-start path, and safer update behavior.
439+
Version `1.0.10` tightens Memorix's low-intrusion operator story: privacy-safe handoff diagnostics, clearer cross-agent memory boundaries, optional session semantics in generated rules, independent TUI agent LLM config, a better fresh-project cold-start path, safer update behavior, and a release-gate fix so the real `serve-http` smoke test no longer depends on port `19879` being free on the runner.
440440

441441
- **Privacy-Safe Handoff Receipt**: `memorix receipt --json` and `memorix doctor --receipt` expose hashes/counts for project identity, writes, and optional probe results without leaking raw chat, memory text, queries, tool payloads, or local paths.
442442
- **Lower-Intrusion Agent Guidance**: Generated rules now treat `memorix_session_start` as optional and avoid repeating `memorix_search` in the same turn after a confirmed fresh-project cold start.

README.zh-CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ Memorix 不是一条单线流水线。它从多个入口接收记忆,把内容
433433

434434
## 1.0.10 更新亮点
435435

436-
`1.0.10` 继续把 Memorix 往更低侵入、更容易排障的 operator 体验上收紧:跨 agent 交接诊断更安全、共享记忆边界更清晰、生成规则更克制、TUI agent LLM 配置更独立,同时修复了 fresh project 和更新检查里的几个易误解路径
436+
`1.0.10` 继续把 Memorix 往更低侵入、更容易排障的 operator 体验上收紧:跨 agent 交接诊断更安全、共享记忆边界更清晰、生成规则更克制、TUI agent LLM 配置更独立,同时补上了一个发版阻断修复:真实 `serve-http` 冒烟测试改为运行时申请空闲本地端口,不再依赖 CI 机器上的 `19879` 端口必须空闲
437437

438438
- **隐私安全的交接 Receipt**`memorix receipt --json``memorix doctor --receipt` 提供项目身份哈希、写入/检索计数、最近 observation ID 哈希和可选 probe 结果计数,用于跨 agent memory 排障;不暴露原始 chat、记忆文本、查询、tool payload 或本地路径。
439439
- **更低侵入的 Agent 指南**:生成规则现在把 `memorix_session_start` 视为可选动作,只在 handoff、长任务、session 恢复、team 协调或 HTTP 项目绑定时推荐使用。

tests/integration/release-blockers.test.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import { describe, it, expect, beforeEach, afterEach, beforeAll, afterAll, vi } from 'vitest';
1313
import { writeFileSync, unlinkSync, mkdirSync, existsSync } from 'node:fs';
1414
import { spawn, type ChildProcess } from 'node:child_process';
15+
import { createServer as createNetServer } from 'node:net';
1516

1617
vi.mock('../../src/embedding/provider.js', () => ({
1718
getEmbeddingProvider: async () => null,
@@ -34,6 +35,26 @@ import { compactDetail } from '../../src/compact/engine.js';
3435
import { storeObservation, initObservations, getObservationCount } from '../../src/memory/observations.js';
3536
import { getLastSearchMode, resetDb, searchObservations } from '../../src/store/orama-store.js';
3637

38+
async function reserveEphemeralPort(): Promise<number> {
39+
const probe = createNetServer();
40+
await new Promise<void>((resolve, reject) => {
41+
probe.once('error', reject);
42+
probe.listen(0, '127.0.0.1', () => resolve());
43+
});
44+
const address = probe.address();
45+
if (!address || typeof address === 'string') {
46+
await new Promise<void>((resolve, reject) => {
47+
probe.close(err => (err ? reject(err) : resolve()));
48+
});
49+
throw new Error('Failed to reserve an ephemeral TCP port');
50+
}
51+
const { port } = address;
52+
await new Promise<void>((resolve, reject) => {
53+
probe.close(err => (err ? reject(err) : resolve()));
54+
});
55+
return port;
56+
}
57+
3758
// ================================================================
3859
// B2: /api/config startup project YAML leak via global fallback
3960
// ================================================================
@@ -259,6 +280,22 @@ describe('B5: search mode is project-scoped', () => {
259280
});
260281
});
261282

283+
describe('release-blocker test helpers', () => {
284+
it('allocates a reusable local TCP port', async () => {
285+
const port = await reserveEphemeralPort();
286+
expect(port).toBeGreaterThan(0);
287+
288+
const probe = createNetServer();
289+
await new Promise<void>((resolve, reject) => {
290+
probe.once('error', reject);
291+
probe.listen(port, '127.0.0.1', () => resolve());
292+
});
293+
await new Promise<void>((resolve, reject) => {
294+
probe.close(err => (err ? reject(err) : resolve()));
295+
});
296+
});
297+
});
298+
262299
// ================================================================
263300
// B1 + B2: Real embedded serve-http route tests
264301
//
@@ -269,8 +306,8 @@ describe('B5: search mode is project-scoped', () => {
269306
// Requires: `npm run build` must have been run first.
270307
// ================================================================
271308
describe('B1+B2: Real embedded serve-http route tests', () => {
272-
const REAL_PORT = 19879;
273-
const REAL_BASE = `http://127.0.0.1:${REAL_PORT}`;
309+
let REAL_PORT = 0;
310+
let REAL_BASE = '';
274311
const STARTUP_PROJECT_ID = 'test/real-http-blocker';
275312
const SECONDARY_PROJECT_ID = 'other/secondary';
276313
const originalHome = process.env.HOME;
@@ -284,6 +321,8 @@ describe('B1+B2: Real embedded serve-http route tests', () => {
284321
if (!existsSync(distCli)) {
285322
throw new Error(`dist/cli/index.js not found at ${distCli}. Run \`npm run build\` first.`);
286323
}
324+
REAL_PORT = await reserveEphemeralPort();
325+
REAL_BASE = `http://127.0.0.1:${REAL_PORT}`;
287326

288327
// Create temp dir with fake git repo + memorix.yml containing canary values
289328
startupDir = await fs.mkdtemp(path.join(os.tmpdir(), 'memorix-real-http-'));

0 commit comments

Comments
 (0)