Skip to content

feat(organizer): trust levels, audit attribution + export, guided setup#96

Merged
mohabbis merged 1 commit into
masterfrom
claude/rational-to-analysis-w2943q
Jul 4, 2026
Merged

feat(organizer): trust levels, audit attribution + export, guided setup#96
mohabbis merged 1 commit into
masterfrom
claude/rational-to-analysis-w2943q

Conversation

@mohabbis

@mohabbis mohabbis commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Adopts the product mechanics that make agentic automation trustworthy — inspired by cloud "agentic back-office" tools (Rational.to) but kept local-first — and surfaces them across the Ghost Organizer trust pipeline. Four SWE upgrades plus matching marketing. Ghost's architecture already embodied deny-by-default policy, audit, and undo; this makes those decisions legible and user-controllable.

Trust & safety

  • Touches files / filesystem mutation: yes — same Organizer move/rename surface; behavior only narrows or gates via trust levels, never widens (delete stays denied at every level).
  • Touches OS input: none
  • Touches screenshots / screen contents: none
  • Touches network: none — time-to-value milestones are local-only (timestamps, no paths/content).
  • Touches authentication / secrets: none
  • Touches app / window state: none

For mutating operations, the pipeline still holds (Intent → Plan → Policy → Approval → Execution → Audit → Undo):

  • Risky actions remain deny-by-default
  • Reversible mutations write undo data before executing
  • No silent delete or silent overwrite (delete denied even under automate)
  • New Tauri commands have a module and a risk class (documented in command-registry.md)
  • Experimental features stay gated or labeled (no experimental code touched)

Changes

Per-rule trust levels (automate / ask-first / never)

  • TrustLevel on FolderRule; serde + SQLite default ask_first, so rules created before this field keep their exact prior behavior. Migration V4 adds trust_level.
  • Policy engine maps the stricter covering rule's trust to allow / require-confirmation / deny. Reads stay allowed at every level (the read grant is the scope); folder creation refused only under never.
  • organizer_set_rule_trust command + in-place trust selector on rule chips and the add-folder row.

Audit rule attribution, provenance, and export

  • evaluate_with_attribution returns the rule that fired; PlanAction and AuditEvent carry rule_path (+ provenance: automated vs user-approved), all #[serde(default)] so old persisted plans/logs still deserialize.
  • organizer_export_audit returns a run's log as pretty JSON or RFC-4180 CSV; frontend shows per-row rule/provenance and adds Export (CSV/JSON) buttons.

Guided setup wizard

  • Generalized the client-filing preset into organizerRunWizard with three presets (client filing, bookkeeping inbox, downloads cleanup), composing existing create_zone / add_folder_rule — no new backend.

Local time-to-value instrumentation

  • storage/milestones records first zone/plan/run/undo timestamps locally; organizer_time_to_value exposes them for diagnostics. No network.

Marketing

  • Site copy names concrete failure modes and the trust trio; contrasts with cloud agents that hold your logins; Organizer demo shows rule attribution + provenance; roadmap reflects shipped features. New docs/gtm-organizer.md (beachhead persona, positioning, channels, gated time-to-value claim).

Docs updated: policy-engine.md, organizer-commands.md, organizer-executor.md, command-registry.md.

Validation

  • cargo fmt --manifest-path src-tauri/Cargo.toml -- --check
  • cargo check --manifest-path src-tauri/Cargo.toml --all-targets
  • cargo test --manifest-path src-tauri/Cargo.toml347 passed, 0 failed (incl. new trust-mapping, serde back-compat, migration V4, CSV escaping, provenance, and milestone tests)
  • cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings — clean
  • Frontend: node --check passes for src/main.js and public/main.js; site JSON-LD intact
  • Experimental leg — not touched, not run
  • cargo tauri build --no-bundle — not run locally (CI covers the macOS/Windows smoke build)

Risks / follow-up

  • No end-to-end GUI run in this environment (headless Linux CI backend only). Trust/audit/export logic is covered by unit tests; the wizard and export-download are frontend flows worth a manual make dev pass.
  • Only the Organizer demo tab on the marketing site was updated to show attribution; the client-filing demo tab is unchanged.
  • The "first safe cleanup in N minutes" site claim is intentionally not published — gated on real medians from the new local instrumentation.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Vy2Lt4hoeK6K4f8LfhWXWg


Generated by Claude Code

Adopt the trust mechanics that make agentic automation trustworthy —
inspired by cloud back-office agents, but kept local-first — and surface
them across the Organizer trust pipeline.

Per-rule trust levels (automate / ask-first / never):
- add TrustLevel on FolderRule (serde+SQLite default ask_first, so old
  rules keep their exact behavior); migration V4 adds trust_level.
- policy engine maps the stricter covering rule's trust to allow /
  require-confirmation / deny; reads stay allowed at every level; delete
  stays denied even under automate.
- organizer_set_rule_trust command + in-place trust selector on rule chips.

Audit rule attribution, provenance, and export:
- evaluate_with_attribution returns the rule that fired; PlanAction and
  AuditEvent carry rule_path (+ provenance: automated vs user-approved),
  all serde-defaulted so old logs/plans still deserialize.
- organizer_export_audit returns a run's log as JSON or CSV (RFC-4180);
  frontend adds per-row rule/provenance and Export buttons.

Guided setup wizard:
- generalize the client-filing preset into organizerRunWizard with three
  presets (client filing, bookkeeping inbox, downloads cleanup), composing
  existing create_zone / add_folder_rule commands.

Local time-to-value instrumentation:
- storage/milestones records first zone/plan/run/undo timestamps locally;
  organizer_time_to_value exposes them for diagnostics. No network.

Marketing: name concrete failure modes and the trust trio on the site,
contrast vs cloud agents that hold your logins, update the Organizer demo
to show rule attribution + provenance, and add docs/gtm-organizer.md.

Docs updated: policy-engine, organizer-commands, organizer-executor,
command-registry. Validation: cargo fmt --check, clippy -D warnings, and
347 backend tests all pass; both frontend JS files pass node --check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vy2Lt4hoeK6K4f8LfhWXWg
@netlify

netlify Bot commented Jul 4, 2026

Copy link
Copy Markdown

Deploy Preview for muhammadghost ready!

Name Link
🔨 Latest commit c89f96d
🔍 Latest deploy log https://app.netlify.com/projects/muhammadghost/deploys/6a495cb848c726000814d479
😎 Deploy Preview https://deploy-preview-96--muhammadghost.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ghost Ready Ready Preview, Comment Jul 4, 2026 7:19pm

@mohabbis mohabbis marked this pull request as ready for review July 4, 2026 19:20
@mohabbis mohabbis merged commit ff8cb57 into master Jul 4, 2026
19 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c89f96ded0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +105 to +106
let from_rule = covered_by(from, rules, granted);
let to_rule = covered_by(to, rules, granted);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor nested Never rules before broader grants

When a user has overlapping rules such as /Downloads set to automate and /Downloads/DoNotTouch set to never, list_folder_rules returns them ordered by path, so the broader parent is seen first. These new evaluations call covered_by once for each endpoint, and covered_by returns only the first matching grant; the stricter nested rule is never considered, so moves/renames inside the never subfolder can still be allowed through the parent rule. This violates the documented “stricter covering rule” behavior and can mutate files in a folder the user explicitly marked as Never.

Useful? React with 👍 / 👎.

Comment on lines +78 to +80
let provenance = if evaluation.decision.is_allowed() {
Provenance::Automated
} else {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Attribute AskFirst folder creation as user-approved

For default ask_first rules, the policy engine returns Allow for CreateFolder to preserve the old behavior, so this branch records those category-folder creations as Provenance::Automated. In a normal Organizer run that creates destination folders, the audit UI/export now says those changes were automated / from an automate rule even though they happened under the user-approved run and the rule was not automate, making the new provenance record inaccurate. Derive provenance from the governing rule trust and capability instead of PolicyDecision::Allow alone.

Useful? React with 👍 / 👎.

Comment on lines +191 to +195
fn csv_field(field: &str) -> String {
if field.contains([',', '"', '\n', '\r']) {
format!("\"{}\"", field.replace('"', "\"\""))
} else {
field.to_string()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Neutralize spreadsheet formulas in CSV exports

When a user exports the new audit CSV and opens it in Excel/Sheets, fields coming from local paths, targets, rule paths, or error text are written verbatim; filenames are user-controlled, so a file named with a leading =, +, -, or @ becomes a spreadsheet formula cell despite RFC quoting. In the audit-export flow this can trigger spreadsheet-side actions or network lookups when the user reviews the log, so csv_field should also neutralize formula-leading characters before returning the cell.

Useful? React with 👍 / 👎.

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.

2 participants