Skip to content

Learning/debug mode, trust-duration dashboard, P1 security fixes + coverage#36

Merged
blackaxgit merged 16 commits into
mainfrom
feat/learning-mode-and-hardening
Jun 10, 2026
Merged

Learning/debug mode, trust-duration dashboard, P1 security fixes + coverage#36
blackaxgit merged 16 commits into
mainfrom
feat/learning-mode-and-hardening

Conversation

@blackaxgit

Copy link
Copy Markdown
Owner

Summary

Accumulated work on top of v0.11.1 (16 commits), in four groups. Full suite green: 2610 passed / 0 failed; clippy -D warnings clean; fmt clean; gitleaks clean.

Security fixes (P1, were live in v0.11.1)

  • Redirection on the allow path — a whitelisted read carrying an output file-redirection (echo x > ~/.bashrc) no longer auto-allows; falls to Ask. fd-dups and /dev/* targets excluded.
  • Snapshot redactioncreate_snapshot and the auto-summary sink now redact summary/key_facts (secrets no longer reach the recall store).
  • Strict learned RuleType read — a corrupt/unknown rule_type row is dropped, not silently materialized as Allow (closes a fail-open into L0).
  • Canonicalizing Bash-write guard — resolves symlinks/../~ before the protected-dir check (symlink-alias bypass closed); shared path_resolves_into_protected_dir helper (dedup with the FileEdit guard).
  • FileEdit guard matches the write target, not file content; on_validator_unavailable knob (default ask).

Feature: learning/debug mode (opt-in, observe-only)

  • validator.learning_mode (+ CLX_LEARNING_MODE), off by default, trust-gated. When on, captures every PreToolUse decision + rationale + a divergence flag + errors/degraded events into a new learning_events table (schema v10), redacted at the sink, with COUNT-guard retention.
  • New clx learning CLI: report (decision/divergence/kind counts + deterministic rule/config suggestions), list, export --json, clear.

Feature: trust-duration in the dashboard

  • trust_mode_default_duration / trust_mode_max_duration editable in the dashboard Validator settings (config + CLI already honored them), with cross-field default ≤ max validation.

Test coverage (honest ceiling, no theater)

  • Behavior tests across all four crates; worst hook files raised (66→89, 72→91, 73→88); clx learning 68→99%; F-4 real-guard wiring test added.
  • Suite is now fully green — the stale l1_deny e2e was aligned with the documented Issue-9 contract (automated denials never learn).
  • Workspace ~90.3% lines (the documented honest ceiling); critical modules mutation-spot-checked.

Notes

  • Codex independent review was rate-limited during this work; an in-house adversarial reviewer substituted at each gate (noted in docs/).
  • No new released version is cut here.

Test plan

  • scripts/test.sh all (lint + nextest + insta + coverage gate) — green locally.

blackaxgit added 16 commits June 8, 2026 14:01
Opt-in {ask|deny|honordefault} governing the validator-UNREACHABLE case
separately from default_decision; default ask preserves current fail-closed
behavior. Stripped from untrusted repo config via the existing validator subtree.
… honor unavailable knob

- fileedit_candidate_paths only treats single-line non-content-key values as
  whole paths (keeps key-agnostic patch-header extraction incl. apply_patch's
  command field), so a file whose body mentions a protected path is no longer denied.
- The four L1-unavailable arms resolve via on_validator_unavailable instead of
  always forcing ask; default ask is unchanged.
…l '>' or reads

Replace the over-broad redirect/copy globs with a token-based destination check:
flags only real redirection targets (excludes fd-dups and input '<') and
cp/mv/tee/dd-of destinations by path component, so '->' arrows, '2>&1', and
cp/mv reading FROM a protected dir are no longer false-denied.
…e-dest extractor

- A whitelisted read carrying an output file-redirection no longer auto-allows
  (falls to Ask); fd-dups and /dev device targets are excluded so `cat x 2>/dev/null`
  and `cat x 2>&1` still allow (F-1).
- Expose pure `bash_write_destinations` for the hook's canonicalizing guard (F-4).
…uleType read

- create_snapshot and create_snapshot_if_no_recent_auto_summary redact summary
  and key_facts via redact_secrets before INSERT (single chokepoint) (F-2).
- row_to_learned_rule strict-parses rule_type; unknown rows are dropped (warn,
  redacted) instead of defaulting to Allow; get_rule_by_pattern unknown→None (F-3).
…g tests

- New Bash-write-destination guard resolves symlinks/~/relative (via the shared
  path_resolves_into_protected_dir helper, also used by the FileEdit guard) and
  denies writes into protected config dirs before L0 — closes the symlink bypass (F-4).
- Test run helper also scrubs CLX_HOOK_HOST so the envelope-sniff tests are
  deterministic regardless of ambient env (F-7).
…flag, divergence

- schema v10 learning_events table + redaction-choke-point record API + COUNT-guard
  retention; LearningEvent/DecisionOrigin/EffectiveConfig types + classify_divergence.
- validator.learning_mode flag (default off) + CLX_LEARNING_MODE env override (trust-gated).
- relocate NEVER_AUTO_WHITELIST to clx-core so the CLI suggestion filter can reuse it.
- Best-effort capture beside every decision emit (22 sites), gated by a single
  bool so the off-path opens no DB and writes nothing; never alters a decision.
- Site-assigned DecisionOrigin drives the divergence flag; errors/degraded arms
  recorded as such. Redaction happens at the clx-core sink.
…suggestions

- report shows decision/divergence/kind counts + deterministic rule suggestions
  (diverged-ask patterns), excluding never-auto-whitelist/secret-bearing/compound;
  unavailable-event count keys off the authoritative Error/Degraded kind.
- Expose validator.trust_mode_default_duration and trust_mode_max_duration as
  NumberU64 fields (section 0), mirroring layer1_timeout_ms; config + CLI already
  honored them, only the dashboard UI was missing.
- Cross-field validation on save: default must not exceed max (both directions).
…earn)

The test asserted the pre-Issue-9 contract (L1 deny increments denial_count);
Issue 9 deliberately made automated denials early-return before learning, so
the test now pins the documented behavior: no learned rule is created.
…, recall substring fallback, and StorageBackend wiring
…/credentials tools

Also tightens clx-core query/recall behavior tests. Removed one ineffective FTS-sabotage test (DROP from a 2nd connection didn't break the server FTS); the degraded substring-fallback path is covered at the engine level.
@blackaxgit blackaxgit merged commit ea442f5 into main Jun 10, 2026
7 of 8 checks passed
@blackaxgit blackaxgit deleted the feat/learning-mode-and-hardening branch June 10, 2026 19:14
blackaxgit added a commit that referenced this pull request Jun 10, 2026
Bumps the workspace to **0.12.0** (Cargo.toml + Cargo.lock + CHANGELOG).

This is the release-trigger that was missed: the v0.12.0 bump was pushed
to PR #36 *after* it had already been squash-merged, so the bump never
reached `main` and `release-plz` never tagged. The feature/security
content from #36 is already on `main`; this PR adds only the version
bump.

On merge: `release-plz` reads `0.12.0` from `Cargo.toml`, creates+pushes
tag `v0.12.0`, which triggers `release.yml` to build the arm64 macOS
binary and publish the GitHub Release + Homebrew.

Pre-merge gates: cargo-deny advisories ok; secret scan clean; workspace
at 0.12.0.

Co-authored-by: blackax <blackaxgit@users.noreply.github.com>
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