github yvgude/lean-ctx v3.8.10

latest release: v3.8.11
one day ago

Fixed

  • #462 / #474 — restricted shell mode no longer rejects for/while/if
    loops, case blocks and subshells.
    The allowlist checker now expands a
    compound command down to its leaf command segments and validates each segment
    against the allowlist, so legitimate constructs (for f in *.rs; do cat $f; done, if test -f x; then ls; fi, ( ls && pwd )) run under restricted mode
    while injection attempts smuggled through the same constructs stay blocked.
  • #476 / #477lean-ctx uninstall --help no longer performs a real
    uninstall.
    The --help/-h flag fell through to the uninstaller, which
    removed the installation instead of printing usage. The CLI now short-circuits
    uninstall --help/-h to print the usage text and exit without touching
    processes, configs, data or the binary.
  • #356 — the "lean-ctx wants to access your Documents folder" prompt is now
    closed even for brew upgrade-only installs.
    The path guards + LaunchAgent
    Seatbelt wrapper already made daemon/proxy boot promptless, and lean-ctx update/dev-install regenerate the plists with that wrapper. The remaining
    hole was a user who only runs brew upgrade (which bypasses lean-ctx's
    updater), so their pre-Seatbelt plists were never regenerated. New belt-and-
    suspenders: a launchd-standalone process (ppid 1) now re-execs itself
    under the deny-~/Documents Seatbelt at startup
    if it is not already
    wrapped (reexec_under_seatbelt_if_needed, called first thing in main). A
    sentinel env var baked into the plists (LEAN_CTX_SEATBELT) prevents any
    double-wrap for current-code plists; terminal/editor children (host TCC grant)
    and non-macOS are unaffected. Verified by the existing tcc_sandbox.sh
    SIGKILL-on-access boot test. This makes the daemon/proxy promptless
    independent of code signature, so no Apple Developer ID is required.
  • #451ctx_shell / lean-ctx -c no longer run agent commands in a
    non-POSIX interactive shell.
    $SHELL is the user's interactive shell; when
    it is Nushell, Fish, Elvish, xonsh or PowerShell, an agent's bash/POSIX command
    silently mis-executes. detect_shell now honors $SHELL only when it is
    POSIX-compatible (bash/zsh/sh/dash/ash/ksh/mksh) and otherwise falls back to a
    real POSIX shell. zsh/bash users are unaffected; LEAN_CTX_SHELL still forces a
    specific shell regardless of the gate.
  • Shell gotcha auto-learning now correlates fail→fix in CLI (lean-ctx -c)
    mode.
    pending_errors were #[serde(skip)] and cleared on load, so a fix
    spanning two separate lean-ctx -c processes never correlated (only the
    long-lived daemon could). They are now persisted (bounded by MAX_PENDING + a
    15-min TTL, pruned on load), so a later process loads the pending error and
    correlates the fix — the gotcha loop now works in the hybrid CLI-shell setup.

Added

  • #668 — FinOps showback: readable project names. The savings ledger stores
    only a truncated repo hash (never a path), so the finops export project
    column was opaque. An opt-in <config_dir>/finops-aliases.toml ([projects]
    <repo_hash> = "Team", also --aliases=FILE / $LEAN_CTX_FINOPS_ALIASES) now
    maps hashes to human-readable names at export time only — the ledger, the
    signed batch and the hash chain are never touched, so privacy guarantees and
    signatures stay intact. Unmapped hashes fall back to the hash, so an incomplete
    map never drops rows. New core/finops_export/aliases.rs; applies to all
    targets (FOCUS / CBF / Vantage).
  • #674 — central, signed org policy distribution + admin. lean-ctx policy org sign <pack.toml> --org <name> wraps a policy pack in an Ed25519-signed
    artifact; endpoints policy org trust <pubkey> (pin once, out-of-band) and
    policy org install <artifact>, after which the runtime folds the org pack in
    as an un-bypassable floor beneath the local .lean-ctx/policy.toml. The
    local pack can only ever tighten it: deny_tools union, allow_tools
    intersect, redaction union (org patterns win clashes), the stricter filter
    action, the tighter egress/max_context_tokens caps, the longer
    audit_retention_days. Two independent checks gate enforcement — the signature
    must verify and the signer key must be pinned — so a forged or untrusted
    artifact is ignored, never enforced, and never bricks the agent (fail-open);
    with no key pinned nothing is enforced (opt-in). --advisory distributes a
    policy for preview without enforcing it; policy org status shows the
    effective floor and policy org verify checks an artifact offline. Pluggable
    source (LEANCTX_ORG_POLICY / LEANCTX_ORG_TRUST_KEY for MDM). New
    core::policy::org + core::policy::floor; contract
    docs/contracts/org-policy-v1.md.
  • #677 — signed CISO compliance report. lean-ctx compliance report --from <rfc3339> --to <rfc3339> [--framework eu-ai-act|iso42001|soc2]... [--pack <name|path>] [--format json|csv|pdf|text] composes the engine's evidence
    surfaces into one Ed25519-signed artifact for a date range: OWASP
    Top-10-for-Agents alignment, framework coverage (verified live against the
    resolved pack), what enforcement blocked (ToolDenied) and redacted
    (SecretDetected) over the period (folded from the append-only audit chain,
    with the segment's head_hash bound into the signed payload), and the
    retention posture (pack audit_retention_days intent vs. plan entitlement).
    The signed JSON is always written and is offline-verifiable with lean-ctx compliance verify <report.json> (no audit trail, no LeanCTX needed); --format csv|pdf additionally emits that human rendering — the PDF is a real,
    dependency-free PDF 1.7. Honest by construction: a quiet period reports zero
    blocks, and a broken local chain is reported (chain_valid = false), never
    hidden. New core::compliance_report module; contract
    docs/contracts/compliance-report-v1.md.
  • #676 — egress / output DLP on agent writes & actions. A new [egress]
    policy-pack section governs what the agent emits (the output side of the
    Great Filter), checked before dispatch of ctx_edit writes and
    ctx_shell/ctx_execute actions — so a blocked write never touches disk and a
    blocked command never runs. forbidden_patterns are regexes that refuse a
    write/action on match (e.g. a prod-DB DSN or a destructive query);
    block_secrets refuses content carrying detected secrets (the pack's
    [redaction] patterns) or PII (the #675 checksum-validated detectors);
    max_writes_per_min is a per-process sliding-window rate limit on agent
    writes/actions. Blocked egress returns [POLICY BLOCKED] and is audited
    (ToolDenied) with a non-sensitive reason (forbidden-pattern:…, secret,
    pii:…, rate-limit) — never the matched content. Egress obeys the same
    opt-in / fail-open / Local-Free guarantees; forbidden_patterns accumulate and
    the scalars override down the extends chain. New core::egress module.
  • #675 — inbound content filters (PII / classification / prompt-injection).
    A new [filters] policy-pack section adds net-new detectors that run inside the
    enforcement pipeline before tool output reaches the agent (the input side of
    the Great Filter). Each detector takes an action — off / warn / redact /
    block: pii finds Swiss AHV (EAN-13), IBAN (mod-97), payment cards
    (Luhn) and email, each checksum-validated to keep false positives low;
    classification gates files marked confidential/secret (banner lines or
    a Classification: field, not prose mentions; blocked_labels is
    configurable); injection masks/blocks OWASP-LLM01 prompt-injection lines
    (reusing output_sanitizer::detect_injection). Decisions are audit-logged
    privacy-preservingly — only (class, count) pairs (e.g. pii:iban×2), never
    the matched value. Filters obey the same opt-in / fail-open / Local-Free
    guarantees as the rest of the pack; actions override and blocked_labels
    accumulate down the extends chain. New core::input_filters module.
  • #673 — context policy packs are now enforced at runtime. A project pack
    (.lean-ctx/policy.toml, authored from any built-in via lean-ctx policy show <name> --toml) is applied at the MCP hot path: deny_tools/allow_tools
    gate which tools the agent may call (denied calls return [POLICY DENIED] and
    are audited as ToolDenied), [redaction] patterns strip matches
    ([REDACTED:<name>]) from tool output before it reaches the model,
    default_read_mode sets the ctx_read fallback when the caller omits mode,
    and max_context_tokens tightens (never loosens) the session token ceiling.
    Enforcement is opt-in (no pack → unchanged behavior), fail-open on an invalid
    pack, and Local-Free — only the agent pipeline is constrained, never a human's
    own reads. The ctx/ctx_session/ctx_policy meta tools are never gated, so
    a pack can never lock the operator out.
  • #454prefer_native_editor config to opt out of lean-ctx edit operations.
    Set prefer_native_editor = true (or LEAN_CTX_PREFER_NATIVE_EDITOR=1) so the
    lean-ctx edit tool (ctx_edit) is neither advertised in list_tools nor
    dispatchable (direct or via ctx_call); the agent falls back to the host's
    built-in editor UI. Read / search / shell / memory tools are unaffected.
    Colorized diffs are intentionally left to host extensions rather than the MCP
    tool output, which must stay byte-stable for prompt caching (#498).

Upgrade

lean-ctx update                 # recommended (auto-downloads + refreshes shell hooks)
cargo install lean-ctx          # or
npm update -g lean-ctx-bin      # or
brew upgrade lean-ctx

Note: After upgrading via cargo/npm/brew, run lean-ctx setup to refresh shell aliases. lean-ctx update does this automatically.

Full Changelog: v3.8.10...v3.8.10

Don't miss a new lean-ctx release

NewReleases is sending notifications on new releases.