sigmap 8.8.0 → 8.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,18 @@ Format: [Semantic Versioning](https://semver.org/)
10
10
 
11
11
  ---
12
12
 
13
+ ## [8.8.1] — 2026-07-05
14
+
15
+ Patch release — **byte-stable context, reproducible benchmark.** Closes the determinism residual tracked in #440: `gen-context` output is now byte-identical run-to-run across all 43 benchmark repos, and the retrieval benchmark reproduces a single hit@5 (87.8%) instead of flapping 85.6–87.8%. Plus a test-count derivation fix, docs/CI serving fixes, and repo hygiene.
16
+
17
+ ### Fixed
18
+ - **gen-context determinism residual — token-budget recency boost (#440, PR #444):** the recency boost stamped `mtime = Date.now()` on every recently-committed file. On repos where nearly every file is "recently changed", consecutive files often landed on the *same millisecond* — so which equal-priority files shared a millisecond (and thus fell through to the `filePath` tie-break instead of sorting by a distinct mtime) shifted run to run, swapping which files survived at the budget cutoff and making the output non-byte-stable. The `Date.now()` value wasn't just a boost: it encoded the alphabetical walk order that the budget's best-first sort relied on; the nondeterminism was only the millisecond *collisions*. Replaced it with a deterministic monotonic counter (`nextRecentMtime`) that reproduces the exact same processing-order ranking without collisions. Result: all 43 benchmark repos are byte-identical across two clean runs (excluding the `Updated:` timestamp), and retrieval hit@5 reproduces at **87.8%** with identical per-repo results. Adds an integration regression guard (`test/integration/gen-context-determinism.test.js`) that runs gen-context twice on a committed fixture and asserts byte-equality — verified to fail on the old `Date.now()` behaviour.
19
+ - **Derived test count after test relocation (503a6e5):** the test-count derivation globbed `tests/**/*.py`; after relocating `test_python_ast_extractor.py` into `test/` it matched neither pattern and dropped the count, failing `check:metrics` in CI. Now counts `test/**/test_*.py` (unittest-named), which matches the relocated test and excludes the fixture.
20
+ - **Docs / CI serving (b236e08):** serve the OG banner image and the Google Search Console verification file; run the Python extractor tests in CI.
21
+
22
+ ### Changed
23
+ - **Repo hygiene (a49e9c5):** dropped orphaned demo GIFs and a dead script; relocated a stray test from `tests/` into `test/`.
24
+
13
25
  ## [8.8.0] — 2026-07-05
14
26
 
15
27
  Minor release — **the squeeze engine, exposed mid-session (D6).** The always-on squeeze engine (`src/squeeze/`) that powers `sigmap squeeze` was reachable only from the CLI on pasted input. This release exposes it as an MCP tool an agent can call *mid-session*, and adds a named CLI entry point for compressing an agent/tool *response*. Zero-dependency, offline, deterministic — the last A+ ceiling item (Machine 9→10): the engine already shipped, this just exposes it.
package/gen-context.js CHANGED
@@ -13566,7 +13566,7 @@ __factories["./src/mcp/server"] = function(module, exports) {
13566
13566
 
13567
13567
  const SERVER_INFO = {
13568
13568
  name: 'sigmap',
13569
- version: '8.8.0',
13569
+ version: '8.8.1',
13570
13570
  description: 'SigMap MCP server — code signatures on demand',
13571
13571
  };
13572
13572
 
@@ -18158,7 +18158,7 @@ function __tryGit(args, opts = {}) {
18158
18158
  catch (_) { return ''; }
18159
18159
  }
18160
18160
 
18161
- const VERSION = '8.8.0';
18161
+ const VERSION = '8.8.1';
18162
18162
  const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
18163
18163
 
18164
18164
  function requireSourceOrBundled(key) {
@@ -18368,6 +18368,26 @@ function annotateCoverage(sigs, testIndex, enabled) {
18368
18368
  // ---------------------------------------------------------------------------
18369
18369
  // Token budget enforcement
18370
18370
  // ---------------------------------------------------------------------------
18371
+ // Deterministic recency boost for recently-committed files so the token budget
18372
+ // doesn't drop them first. Previously this used `Date.now()`, which encoded the
18373
+ // (alphabetical) processing order as a monotonically increasing mtime — but on
18374
+ // repos where nearly every file is "recently changed", consecutive files often
18375
+ // landed on the *same* millisecond. Which files shared a millisecond (and so
18376
+ // fell through to the filePath tie-break instead of sorting by a distinct
18377
+ // mtime) shifted run to run, swapping which files survived at the budget cutoff
18378
+ // and making the output non-byte-stable. A monotonic integer counter preserves
18379
+ // the exact processing-order ranking Date.now() produced — recent files stay
18380
+ // ahead of non-recent ones, ordered among themselves by walk order — but is
18381
+ // collision-free and reproducible. RECENT_MTIME_BASE sits far above any real
18382
+ // filesystem mtime (ms since epoch ≈ 1.7e12) so boosted files always out-rank
18383
+ // non-boosted ones, and far below MAX_SAFE_INTEGER so the counter never
18384
+ // overflows. Call nextRecentMtime() once per boosted file, in walk order. (#440)
18385
+ const RECENT_MTIME_BASE = 1e15;
18386
+ let _recentMtimeSeq = 0;
18387
+ function nextRecentMtime() {
18388
+ return RECENT_MTIME_BASE + (_recentMtimeSeq++);
18389
+ }
18390
+
18371
18391
  function estimateTokens(str) {
18372
18392
  return Math.ceil(str.length / 4);
18373
18393
  }
@@ -19348,7 +19368,7 @@ function runDiff(cwd, config, stagedOnly, baseRef) {
19348
19368
 
19349
19369
  sigs = annotateCoverage(sigs, testIndex, !!config.testCoverage);
19350
19370
 
19351
- fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime: Date.now() });
19371
+ fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime: nextRecentMtime() });
19352
19372
  }
19353
19373
 
19354
19374
  if (fileEntries.length === 0) {
@@ -19496,8 +19516,11 @@ function runGenerate(cwd, config, reportMode, reportJson = false) {
19496
19516
  mtime = fs.statSync(filePath).mtimeMs;
19497
19517
  } catch (_) {}
19498
19518
 
19499
- // Boost recently committed files (give them max mtime so they aren't dropped first)
19500
- if (recentFiles.has(filePath)) mtime = Date.now();
19519
+ // Boost recently committed files (give them a max mtime so they aren't
19520
+ // dropped first). A deterministic monotonic counter — not Date.now() — keeps
19521
+ // the budget selection byte-stable when many files are recent, while
19522
+ // preserving the original processing-order ranking (see nextRecentMtime, #440).
19523
+ if (recentFiles.has(filePath)) mtime = nextRecentMtime();
19501
19524
 
19502
19525
  fileEntries.push({ filePath, sigs, deps: extractFileDeps(filePath, content, config), content, mtime });
19503
19526
  }
package/llms-full.txt CHANGED
@@ -11,7 +11,7 @@ ranking keeps the relevant context in scope (cutting tokens ~97% as a side
11
11
  effect), with no LLM calls, embeddings, or vector database. Works with Claude,
12
12
  Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
13
13
 
14
- # Version: 8.8.0 | Benchmark: sigmap-v8.8-main (2026-07-05)
14
+ # Version: 8.8.1 | Benchmark: sigmap-v8.8-main (2026-07-05)
15
15
  # Source: auto-generated from package.json, version.json, benchmarks/latest.json, src/mcp/tools.js, src/config/defaults.js
16
16
  # Regenerate: npm run generate:llms | Validate: npm run validate:llms
17
17
 
package/llms.txt CHANGED
@@ -11,7 +11,7 @@ ranking keeps the relevant context in scope (cutting tokens ~97% as a side
11
11
  effect), with no LLM calls, embeddings, or vector database. Works with Claude,
12
12
  Cursor, GitHub Copilot, Aider, Windsurf, local LLMs, and MCP.
13
13
 
14
- # Version: 8.8.0 | Benchmark: sigmap-v8.8-main (2026-07-05)
14
+ # Version: 8.8.1 | Benchmark: sigmap-v8.8-main (2026-07-05)
15
15
  # Source: auto-generated from package.json, version.json, benchmarks/latest.json, src/mcp/tools.js, src/config/defaults.js
16
16
  # Regenerate: npm run generate:llms | Validate: npm run validate:llms
17
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap",
3
- "version": "8.8.0",
3
+ "version": "8.8.1",
4
4
  "description": "97% token reduction for AI coding. Extracts function & class signatures with TF-IDF ranking to feed only the right files to Claude, Cursor, Copilot, Aider, Windsurf, local LLMs & MCP. Zero dependencies, runs offline via npx.",
5
5
  "main": "packages/core/index.js",
6
6
  "exports": {
@@ -17,6 +17,7 @@
17
17
  "test": "node test/run.js && node test/r-language.test.js",
18
18
  "test:integration": "node test/integration/strategy.test.js && node test/integration/secret-scan.test.js && node test/integration/token-budget.test.js && node test/integration/auto-budget.test.js && node test/integration/mcp/server.test.js && node test/integration/verify-ai-output.test.js && node test/integration/memory-tools.test.js && node test/integration/squeeze.test.js && node test/integration/context-consistency.test.js && node test/integration/features/llms-current.test.js",
19
19
  "test:integration:all": "node test/integration/all.js",
20
+ "test:python": "python3 test/test_python_ast_extractor.py",
20
21
  "test:all": "node test/run.js && node test/r-language.test.js && node test/integration/strategy.test.js && node test/integration/secret-scan.test.js",
21
22
  "generate": "node gen-context.js",
22
23
  "watch": "node gen-context.js --watch",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-cli",
3
- "version": "8.8.0",
3
+ "version": "8.8.1",
4
4
  "description": "SigMap CLI wrapper — thin adapter for programmatic CLI invocation",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigmap-core",
3
- "version": "8.8.0",
3
+ "version": "8.8.1",
4
4
  "description": "SigMap core library — zero-dependency code signature extraction, retrieval, and security scanning",
5
5
  "main": "index.js",
6
6
  "keywords": [
package/src/mcp/server.js CHANGED
@@ -18,7 +18,7 @@ const { readContext, searchSignatures, getMap, createCheckpoint, getRouting, exp
18
18
 
19
19
  const SERVER_INFO = {
20
20
  name: 'sigmap',
21
- version: '8.8.0',
21
+ version: '8.8.1',
22
22
  description: 'SigMap MCP server — code signatures on demand',
23
23
  };
24
24