Skip to content

Scrub the incidental operator names, and stop shipping the repo as the package - #89

Merged
Cipher208 merged 3 commits into
masterfrom
fix/scrub-incidental-names-and-packaging
Oct 7, 2026
Merged

Cipher208 merged 3 commits into
masterfrom
fix/scrub-incidental-names-and-packaging

Conversation

@Cipher208

Copy link
Copy Markdown
Owner

Second pass over the identifier class PR #88 started. That one cleaned fixtures and
data; this one cleans prose, then fixes the packaging that would have carried any
future slip straight to PyPI.

Names: 41 files → 4

Removed from CHANGELOG.md (two quoted utterances and the agent_id list),
AUDIT_REPORT_20260629.md, ARIEL_RULES.md, autohooks/examples/dsh.yaml, one
Alembic revision comment, scripts/purge_foreign_rows.py, a pyproject.toml comment,
and eleven test files where a name stood in for a role.

The four that remain are deliberate and must stay: config.yaml rag.ru_personas,
rag/synonyms.py, mcp_server/utils/privacy.py, tests/test_hooks/test_privacy_ru.py
and the graph_miners canon test. Those name lists are the anonymizer's input —
deleting them deletes the feature that hides names.

Also untracked six docs/compose/ files that had been force-added past .gitignore.
They stay on disk; three docstrings cite them and never read them.

Packaging: 445 files → 276

[tool.hatch.build.targets.wheel] was packages = ["."], which made the repository
root
the package root. The 1.9.0 wheel shipped tests/ (115 files), docs/,
.github/, uv.lock, the Dockerfile and the raw pytest logs.

only-include names the runtime trees. The risk was dropping something read at import,
and it was real: config.py loads config.yaml from its own directory, so the first
attempt installed cleanly and then failed on a missing default config. The in-repo test
suite cannot catch that — the file is always present. Installing into a fresh venv
did
; config.yaml is now included and the install loads all 23 top-level keys.
Runtime parity with 1.9.0 checked: autohooks/eval/scripts/embeddings_service.py
shipped in neither, and no runtime module imports them.

The sdist keeps tests and docs — that is what a source distribution is for.

A real bug the packaging work surfaced

uv build --sdist in the working tree read 5.5 GB and was minutes into writing a
multi-gigabyte archive: it was packing .venv-embeddings/ (5.6 GB of torch and CUDA).
/tmp here is a tmpfs where a full disk has already killed the test gate, so it was
killed rather than waited on.

Why git never showed it: a venv ships its own .gitignore containing *, and git
honours a nested ignore file — build backends read only the root one. Named in the root
file now, with .mypy_cache/, .ruff_cache/, .skylos/, .hypothesis/, .vscode/.
After: 1.7 seconds, 1.2 MB.

A 1-in-256 flake, found by this branch's own gate

test_saga_crypto_coverage asserted not data.startswith(b"{") to prove encryption.
The blob is nonce(24) || ciphertext, so byte one is a random nonce byte — { in 1
write out of 256. Measured: 14 of 4096 encrypt_json calls begin with {, and one
of them failed this suite. Both assertions now test behaviour (plain-JSON decode must
fail; read_state round-trips; a second read agrees without a rotation warning),
verified over 2048 fresh blobs including the 5 beginning with {, and over 60
consecutive runs.

Reported but not changed: the exported is_encrypted_blob still sniffs one byte and
so calls 4 of 256 real ciphertexts plain JSON (69/4096 = 1.68%). The saga read path
decrypts first and no longer consults it, so it is an API footgun for outside callers,
not a live defect — and altering a public helper's contract is your call.

Verification

  • ruff check / ruff format --check — clean
  • mypy over the CI scope (features/ shared/ mcp_server/ rag/ hooks/ wiki/ lifecycle/ graph/ core) — 230 files, no issues
  • Full suite 2087 passed — run by the pre-commit gate on every commit here
  • Clean venv install + entry point + all three console scripts
  • Name sweep with word-boundary matching, after an unanchored Лили pattern gave three false hits inside «отвалились» / «слились»

History is untouched: 927 commits and the archive fork preserve everything, so this is
tidy-tree work, not erasure. Rotation of what was exposed remains the honest reaction.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: Cipher208/a-memory/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a21348ac-b77b-4dc5-8847-498412c4c86b
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…, not the repo

Two changes in one pass, because the packaging fix decided where the first one
had to reach.

Tree — the names that WERE the privacy feature stay; the ones that were prose
are gone. CHANGELOG (two quoted utterances and the agent_id list),
AUDIT_REPORT_20260629, ARIEL_RULES, the autohooks DSH example, one Alembic
revision comment, purge_foreign_rows' docstring, pyproject's "handled by Lucy"
comment, and eleven test files where a name stood in for a role. Kept
deliberately: config.yaml `rag.ru_personas`, rag/synonyms.py, privacy.py,
test_privacy_ru.py and the graph_miners canon test — those name lists are the
anonymizer's input, and deleting them deletes the feature.

Six docs/compose/ files that had been force-added past .gitignore are untracked
again. They stay on disk; three docstrings cite them and never read them.

Wheel — packages = ["."] made the repository root the package root, so 1.9.0
shipped tests/ (115 files), docs/, .github/, uv.lock, the Dockerfile and the
raw pytest logs: 445 files against 276 now. only-include names the runtime
trees explicitly.

The real risk was dropping something read at import time, and it bit: config.py
loads config.yaml from its own directory, so the first cut installed cleanly and
then failed on a missing default config. The in-repo test run cannot see this —
the file is always there. Installing into a fresh venv caught it; config.yaml is
included now and the install loads all 23 top-level keys.

test_output.txt and full_test_output.txt joined .gitignore. They were never
tracked and still shipped, because hatch walked the filesystem rather than git.
…them

`uv build --sdist` in the working tree did not finish: it read 5.5 GB and was
minutes into writing a multi-gigabyte archive. It was walking
`.venv-embeddings/` (5.6 GB of torch and CUDA libraries) straight into the
source distribution. `/tmp` here is a tmpfs, where a full disk has already
killed the test gate once, so this was killed rather than waited on.

The reason git never showed it: a venv ships its own `.gitignore` containing
`*`, and git honours a nested ignore file. The build backend does not — it reads
the root `.gitignore` only. So a directory that `git status` correctly hides was
invisible to the packer and fully visible to the archive. `.venv-embeddings/`
is now named in the root file, alongside `.mypy_cache/`, `.ruff_cache/`,
`.skylos/`, `.hypothesis/` and `.vscode/`, which had the same exposure.

Measured after: 1.7 seconds, 732 files, 1.2 MB, no venv.

Checked separately, because the two distributions want different answers: the
wheel must not carry tests or docs, and does not; the sdist should carry both,
and does — a source distribution exists to be built and tested downstream.
…st flake

The five files: AUDIT_REPORT_20260629.md audits 18 of what are now 731 files.
ROADMAP.md opens by declaring itself legacy and frozen against reality
("no longer reflects reality", 2026-09-03). .ai-memory.toml and .codegraph/ are
local tool state. .compose/context/gates.md is a working note. Each was checked
for live references first — the only hit was `~/.compose` in docstrings and
fixtures, the operator's own directory, a different thing from this tree's
.compose/. Nothing in CI, code or docs reads any of the five. None are deleted;
all stay locally and are named in .gitignore. .codegraph/ moves off its nested
.codegraph/.gitignore because git honours a nested ignore file and build
backends do not — the same asymmetry that put a 5.6 GB venv into a source
distribution one commit earlier.

openwiki/ and the AGENTS.md / CLAUDE.md markers are deliberately untouched: a
scheduled workflow regenerates the first, and the second two are its anchors.

The flake, found by this commit's own pre-commit gate failing:

test_saga_crypto_coverage asserted `not data.startswith(b"{")` to prove a state
file had been encrypted. The blob is nonce(24) || ciphertext, so the first byte
is a random nonce byte — `{` in 1 write out of 256. Measured over 4096
encrypt_json calls, 14 began with `{` (0.34%); one of them failed the suite.
The two assertions now test behaviour instead of a byte: the file must fail a
plain-JSON decode, read_state must round-trip it, and a second
read_state_legacy_or_encrypted must agree without emitting a rotation warning.
Verified over 2048 fresh blobs including the 5 beginning with `{` — zero
failures — and over 60 consecutive runs of the file.

Neither the crypto code nor these tests were touched by the privacy or packaging
work; that was confirmed by running the test in isolation, where it passes. The
flake is pre-existing and load-bearing only in the sense that it can fail any
build at random.

Reported, not fixed: the exported helper is_encrypted_blob still sniffs one byte
and therefore classifies 4 of 256 real ciphertexts as plain JSON — measured
69/4096, 1.68%. The saga read path no longer consults it (it decrypts first), so
this is an API footgun for outside callers rather than a live defect, and
changing a public helper's contract is the owner's call.
@Cipher208
Cipher208 force-pushed the fix/scrub-incidental-names-and-packaging branch from 7596c2c to 0335d4f Compare October 7, 2026 23:18
@Cipher208
Cipher208 merged commit 14018df into master Oct 7, 2026
19 checks passed
@Cipher208
Cipher208 deleted the fix/scrub-incidental-names-and-packaging branch October 7, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant