Commit Graph

13 Commits

Author SHA1 Message Date
Martin Vogel 3f54d7c7ea test(go): restore the publication concurrency tests for the single-file runtime
Same restoration as the pypi wrapper, same reasoning: serialization of
concurrent publishers, killed-publisher reconciliation via locked readiness,
the crash-phase matrix, and multiply-linked-leaf rejection are properties of
the LOCK design, not of how many files publish.

Adaptations for one file: the mid-publication pause hooks the binary rename
itself (the runtime lock is held until publish returns, so the serialization
property is exercised exactly as before); the "partial sidecar publish" crash
phase is gone with the sidecars; backup-member expectations drop to the single
member, including cleanup-interrupted leaving 0 rather than 1; and the
hardlink-rejection guard now targets the binary leaf.

go vet + gofmt clean; full Go suite ok including the restored
TestConcurrentRuntimePublishersAreSerialized,
TestKilledRuntimePublisherIsReconciledByLockedReadiness (5 crash phases),
TestRuntimePublicationCrashHelper and
TestRuntimeReadinessRejectsMultiplyLinkedLeaves.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 20:26:42 +02:00
Martin Vogel 6415f94fef fix(packages): put every wrapper and its tests on the same base
Restoring files from two different pre-revert commits left the package wrappers
internally inconsistent, and one of them did not compile. Found by actually
building and running them rather than by grepping for removed symbols.

pkg/npm — bin.js was never restored, so main's version was destructuring
runtimeSetReady/acquireRuntimeLock out of an install.js restored from an older
base that does not export them. `npx codebase-memory-mcp` would have died at
require time on Windows. install.js, bin.js and the launcher test now all sit on
the pre-externalization base, where installWindowsBinaryAtomically is the right
primitive for publishing exactly one file. The runtime-set locking that goes
away with it existed only to publish binary+sidecars atomically.

pkg/go — main.go kept the Windows lock work while main_test.go had been reverted
past it, so the package did not build at all:
  main.go:805: no new variables on left side of :=      (my edit dropped uiPack)
  main_test.go: undefined: windowsPayloadName           (reverted past its removal)
The test is back on main's base, keeping every lock-race test from #1495/#1496
(TestRuntimeSetLock*, TestExpiredLease*, TestStalledRuntimeLockCreator*,
TestRuntimeSetLockSerializesProcesses). Dropped 19 whose premise -- a multi-file
runtime set with content-addressed sidecars -- no longer exists, and reduced the
writeTestRuntimeSet/assertRuntimeTag helpers to the single file that now ships.

pkg/pypi — same base repair, keeping the lock and orphan-reconciliation tests.
The three archive-SAFETY tests (hardlink members, symlink metadata, unexpected
root member) were ADAPTED rather than dropped: they only named a removed file in
their fixtures, and they guard traversal properties that still matter.
test_release_archives_require_the_integrations_sidecar is inverted rather than
deleted -- asserting the sidecar is ABSENT is the stronger guard, since a
returning sidecar is exactly what broke `pip install` on Windows.

Verified: go vet + go build + go test ok; pypi 24 tests OK; npm 10/10;
Windows single-binary bundle contract still passes.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 17:29:56 +02:00
Martin Vogel a4336dc40a feat(release): ship one archive set and tolerate a single Microsoft !ml verdict
Completes the collapse to a single shipped composition and replaces the
zero-tolerance VirusTotal gate with a narrow, disclosed policy.

Packaging and installers
  - package-release.sh loses --variant; archives are codebase-memory-mcp-<os>-<arch>
    with exactly four members. install.sh/install.ps1 lose --ui/--standard.
  - The extractor drops CBMUIPK pack parsing and --archive-scope; its scan-set and
    association manifests (which the gate depends on) are unchanged otherwise.
  - npm/PyPI/Go wrappers: the runtime "set" is one file again. The Windows lock
    and race fixes from #1495/#1496 are kept; only multi-file set membership goes.
    This also fixes `pip install` on Windows, which rejected the fifth archive
    member against a hardcoded four-name allowlist.
  - The wrappers' post-download probe moves from --verify-runtime-assets (removed)
    to --version, which proves the same thing: the binary executes.

VirusTotal gate
  - Exactly ONE detection is tolerated, and only when the engine is Microsoft AND
    the label ends in `!ml`. Two or more engines, any non-`!ml` label, any other
    vendor, any suspicious verdict and every infrastructure error still block.
  - A tolerated object prints TOLERATED:, never OK:, and its counts are recorded
    in vt-results.tsv exactly as a blocked one would be.
  - append-vt-notes.sh mirrors the policy. It previously hard-failed on any
    malicious count, so loosening only the gate would have passed the scan and
    then died at note publication. The notes now DISCLOSE a tolerated detection
    and link to SECURITY.md rather than claiming "0 malicious" for everything.

Rationale for the tolerance is in the gate itself: the verdict is not a property
of our bytes. It inverts across architectures and link modes, moves between
sibling artifacts of one build, and lands in different variant buckets for the
same source. The same `!ml` family hits llama.cpp, GitHub's own `gh`, Microsoft's
own Go toolchain and Anthropic's Claude installer.

The zero-tolerance contract becomes test_vt_gate_policy_contract.sh, asserting
the full matrix: 1x Microsoft !ml passes and reports TOLERATED; a Microsoft
signature label, a non-Microsoft engine, two engines, a suspicious verdict and
every malformed-response case still block. Its tripwire is narrowed to the
reverted endpoint-verification mechanism rather than the words "false positive",
so it no longer fires on a deliberate in-gate policy branch.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 16:16:08 +02:00
Martin Vogel d58afe562d revert(release): re-embed runtime assets into the single shipped binary
Externalizing the integration templates (#1492/#1493) and the UI bundle
(#1501/#1503) was done to reduce the Microsoft `Wacatac.B!ml` surface. It did
not work: across dry runs the flagged artifact count stayed at ~3 and the
detections merely moved between artifacts.

Dissection of run 31286803592 shows there is no structural cause to fix. The
verdicts split across every axis at once — linux-amd64 (dynamic) flagged while
linux-amd64-portable (static) is clean, but linux-arm64 (dynamic) clean while
linux-arm64-portable (static) is flagged. The two macOS binaries have identical
segment structure and split clean/flagged. Siblings from one build landed in
different variant buckets (.B vs .C). Entropy is low everywhere
(code_vectors.bin 4.166, grammar tables 3.464 bits/byte, against 7.5-8.0 for
packed payloads), so the packed-payload hypothesis is excluded too.

So the complexity bought nothing, and installation goes back to being
self-contained: one binary that carries its own UI and agent integration
templates, with no adjacent data file that has to resolve before `install`
works. Only the UI-capable composition ships from now on, under the historical
unsuffixed archive name.

Removed: src/ui/asset_pack.{c,h}, asset_pack_stub.c, asset_manifest_stub.c,
scripts/pack-ui-assets.mjs, src/cli/integration_assets.{c,h},
assets/cbm-integrations.json, scripts/gen-integrations-hash.sh, the
--verify-runtime-assets probe (nothing adjacent left to verify), and the
composition gates A6/A7 whose property is now deliberately inverted.

Restored: scripts/embed-frontend.sh, src/ui/embedded_{assets.h,stub.c}, the
compiled-in hook/adapter template bodies, and the embed/EMBED_OBJS build path.

Kept from the reverted commits, re-applied by hand where a wholesale file
restore would have dropped them:
  - cbm_module_path_utf8() in both self-path sites. GetModuleFileNameA renders
    through the ANSI code page and mangles non-ASCII install paths.
  - the /__cbm/ui-readiness HMAC proof, secure_random and cbm_hmac_sha256, so
    `daemon start --open` still waits for a genuine CBM listener.
  - X-Content-Type-Options: nosniff on served assets.
  - the MinGW noexecstack gate, -lbcrypt, and the cppcheck/zip CI fixes.

Archives are now codebase-memory-mcp-<os>-<arch>[-portable] with exactly four
members (binary, LICENSE, installer, THIRD_PARTY_NOTICES.md). That restores the
names every static package manifest already points at — aur, chocolatey,
homebrew, scoop, winget and glama were all broken by the -ui- rename.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 13:06:42 +02:00
Martin Vogel a1a5b7fdb4 fix(packages): eliminate wrapper lock sharing races
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-08 21:45:33 +02:00
Martin Vogel 7a62a085cf fix(packages): make wrapper locks Windows-safe
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-08 20:53:14 +02:00
Martin Vogel 8018561cfe fix(release): externalize runtime assets and harden VT verification
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-08 17:35:05 +02:00
Martin Vogel 83c137d2a5 feat: complete shared daemon lifecycle
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-18 01:26:08 +02:00
Martin Vogel 0e00ef5702 feat: coordinate concurrent CBM sessions
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-16 19:20:46 +02:00
Martin Vogel eb748cb532 Bump the go-install shim to v0.8.1 2026-06-12 09:59:51 +02:00
Martin Vogel c1eb3dd2d1 Comprehensive security hardening across all installers
install.sh:
- Wrap entire body in main() to prevent partial execution from curl|bash
  (interrupted download would execute truncated script)

install.ps1:
- Enforce TLS 1.2+ (older PowerShell defaults to TLS 1.0)

PyPI (_cli.py):
- Add SHA256 checksum verification against checksums.txt (was the only
  installer without checksums)

npm (install.js):
- Add SHA256 checksum verification against checksums.txt
- Validate HTTPS on every redirect hop (max 5 redirects)
- Replace execSync string interpolation with execFileSync array args
  (eliminates shell injection vector in tar/PowerShell calls)
- Add path traversal check on extracted binary

npm (bin.js):
- Auto-download binary if missing (handles --ignore-scripts / pnpm)

Go wrapper (main.go):
- Custom HTTP client with CheckRedirect that rejects non-HTTPS redirects
  (Go's default http.Get follows redirects without scheme validation)
- Fix variable name bug in error message (url → rawURL)
2026-04-14 21:00:42 +02:00
Martin Vogel a89bf96382 Harden installers: remove Unblock-File, add HTTPS-only URL validation
install.ps1:
- Remove both Unblock-File calls (Defender ClickFix.R!ml signal)
- Remove ExecutionPolicy ByPass from usage comment (scanned by Defender)
- Add HTTPS-only URL scheme check on CBM_DOWNLOAD_URL

install.sh:
- Add HTTPS-only URL scheme check on CBM_DOWNLOAD_URL

pkg/go wrapper:
- Add validateURLScheme() to httpGet and fetchChecksums (defense-in-depth,
  matching Python wrapper's _validate_url_scheme from PR #248)

All installers now allow localhost/127.0.0.1 for testing but reject
http://, ftp://, file:// and other schemes.
2026-04-14 20:44:17 +02:00
DeusData 39901769fd Add pkg/go — Go module wrapper for go install distribution
Adds a thin Go wrapper at pkg/go/cmd/codebase-memory-mcp that detects
the current platform and architecture, downloads the matching pre-built
binary from GitHub Releases, verifies its SHA-256 checksum, caches it,
and replaces the current process via exec.

Install via:
  go install github.com/DeusData/codebase-memory-mcp/pkg/go/cmd/codebase-memory-mcp@latest

The Go module proxy indexes this automatically once live on main.
2026-04-12 18:28:29 +01:00