Skip to content
This repository was archived by the owner on Sep 5, 2026. It is now read-only.

harden: work through both code-review batches (provenance pinning, consolidation, guard, CI, docs) - #11

Merged
dcondrey merged 11 commits into
mainfrom
harden/review-batch
Jun 28, 2026
Merged

harden: work through both code-review batches (provenance pinning, consolidation, guard, CI, docs)#11
dcondrey merged 11 commits into
mainfrom
harden/review-batch

Conversation

@dcondrey

Copy link
Copy Markdown
Owner

Works through both review batches from the code review. 11 commits, each self-contained and verified; 73 tests pass (was 66), ruff clean, every engine module import-smoked.

Security / correctness (the high-value core)

  • d1d5cb9 Issuer pinning. Verification proved internal consistency, not authenticity: every verify path checked signatures against the key embedded in the artifact's own issuer field, so a vault-write attacker could forge a self-consistent chain under their own did:key and have it verify. Pin the agent DID on first use in $COGMEM_HOME/trust.json (outside vault/) and require issuer == pinned DID in verify_credential/verify_log/verify_sth. New forged-chain rejection test.
  • f553b43+8184bad Consolidation cliff. load_existing_knowledge concatenated every rule into one unbounded prompt → at scale the call exceeds the context window, fails, and strands candidates forever. Bound the corpus + batch candidates, then scope-prioritize it so the older same-scope rule a candidate may duplicate isn't evicted by newer out-of-scope ones. Test proves the oldest in-scope rule survives over 40 newer out-of-scope rules.
  • 236cd30 Guard ReDoS. Model-generated tripwire regexes ran via re.search on every Bash command. Cap inputs, fall back to literal for oversized patterns, bound total matching to 250ms via SIGALRM (fail-open). Regression test.
  • f2f322a Socket bound. 1 MiB ceiling on daemon/recall reads.

Quality / reach

  • 927e8cb Dedupe drifted api_call/parse_json_block (acquire → common); centralize all model IDs (incl. two out-of-sync embed-model copies) into config.
  • c332cc4 cogmem doctor — end-to-end loop health (daemon ping, API key, trust anchor, capture freshness, backlog).
  • 435c450 CI installs numpy, import-smokes every engine module, runs all three suites, adds a ruff job. (Previously only 2/3 suites, recall path never imported.)
  • 52becb8 Portable mtime in hooks — capture dedup + approval rate-limit were silently broken on Linux (stat -f is BSD-only).
  • 411baec Eval reports at live config thresholds (was hardcoded 0.62); circularity documented.
  • 015b35a Docs honesty: corrected "nothing is sent anywhere" (learning calls the Anthropic API; recall is local); documented the pinning trust model + residuals in THREAT-MODEL.

Honest seams

dcondrey added 11 commits June 28, 2026 12:38
Verification proved internal consistency, not authenticity: every verify path
checked signatures against the key embedded in the artifact's own issuer field,
so a vault-write attacker could forge a self-consistent chain under their own
did:key and have it verify. Pin the agent DID on first use in $COGMEM_HOME/trust.json
(outside vault/) and require issuer == pinned DID in verify_credential, verify_log,
and verify_sth. Adds the forged-chain rejection test.
load_existing_knowledge concatenated every rule + pending into one prompt with no
cap; as the vault grew the call would eventually exceed the context window, fail,
and strand candidates unconsolidated forever. Cap the corpus to a char budget
(curated files always included, newest rules fill the rest) and classify candidates
in batches so one failed batch no longer strands the whole backlog.
acquire.py carried its own drifted copies of api_call (60s vs common's 90s) and
parse_json_block; import them from common instead. Move every hardcoded model id
(per-role LLMs + the embed/rerank models, incl. the two out-of-sync copies in
daemon.py and index.py) into config with accessors, so upgrades and overrides no
longer need code edits.
guard.py ran model-generated regexes via re.search on every Bash command, so a
catastrophic-backtracking pattern (accidental or planted in a poisoned failure
note) could hang the PreToolUse hook. Cap command and pattern length, fall back to
literal search for oversized patterns, and bound total matching to 250ms via
SIGALRM, failing open on timeout.
Both _recv_line and the recall client looped until a newline with no size bound, so
a peer that never sends one could grow the buffer without limit. Add a 1 MiB ceiling.
The default eval reported at a hardcoded floor=0.62 while production runs the tuned
config value, so the published number wasn't the operating point. Read thresholds
from config (with --floor/--gap overrides) and document that auto-generated positives
are paraphrases of the rules themselves, so the number is an upper bound, not absolute.
A silently-broken learning loop looked identical to a working one. doctor reports
every link that can fail independently: daemon warm/cold (with a live ping), API key
presence, trust-anchor status, last capture time, candidate/approval backlog, recall
injections, feedback tallies, and the provenance-enforce flag.
CI installed only cryptography+cbor2 and ran two of three test files, so test_cogmem
and the entire recall/daemon import graph were never checked. Install numpy too, add
an import smoke over every engine module, run all three suites, and add a ruff lint
job (pyproject config) gating real defects (F-class: undefined names, unused imports).
Newest-first truncation could evict the older same-scope rule a candidate actually
duplicates, defeating the dedup it was meant to protect. Order the bounded corpus
in-scope-first then by recency, so a candidate's likely duplicate is always present.
Test proves the oldest in-scope rule survives eviction over 40 newer out-of-scope ones.
stat -f %m is BSD-only; on Linux it failed straight to 'echo 0', so the capture
dedup saw mtime 0 (skipping real captures) and lock-age math misfired. Fall back to
GNU 'stat -c %Y'. (A Linux daemon service is still tracked separately as issue #8.)
README claimed 'nothing is sent anywhere', but the learning pipeline (acquisition,
consolidation, feedback, project/user-model) sends session transcripts to the
Anthropic API; only recall is local. State the split honestly and soften the badge/
tagline. Update THREAT-MODEL T2 and §4.3 to reflect the new TOFU issuer pinning and
its precise residual (whole-home write still collapses to T6; STH still unwitnessed).
@dcondrey
dcondrey merged commit 86fc149 into main Jun 28, 2026
2 checks passed
@dcondrey
dcondrey deleted the harden/review-batch branch June 28, 2026 20:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant