Skip to content

P4: categorization + bucket routing (port FxFiles ShelfClassifier) #55

Description

@ehsan6sha

Phase 4 — categorization + bucket routing (fula-mcp)

Pure-logic phase (no network, no crypto). Port FxFiles file classifier + category->bucket mapping to Rust so AI-stored files get the EXACT same ShelfCategory and native v8 bucket as the FxFiles app, enabling later adoption.

Scope

  • category module in crates/fula-mcp/src/:
    • Category enum mirroring Dart ShelfCategory (link, note, screenshot, image, video, audio, document, file, other) with the same order.
    • classify(mime: Option<&str>, filename: &str, text: Option<&str>) -> Category porting ShelfClassifier.classify exactly: text/plain (or no-MIME) + non-empty payload short-circuits to link (single URL) or note; image/* -> screenshot (filename matches /screenshot/i) else image; video/* -> video; audio/* -> audio; application/pdf -> document; text/* -> note; application/* -> file; else other. When MIME absent, derive from the filename extension using the FxFiles isImage/isVideo/isAudio/isDocument lists (dependency-light; no mime crate) so behavior matches the app.
    • native_category_bucket(cat) -> Option<&'static str> returning the FxFiles native v8 content bucket (images->images-v8, videos->videos-v8, audio->audio-v8, documents->documents-v8; document maps to documents-v8). Categories with no native content bucket (link/note/screenshot/file/other) return None. Document the AI-workspace convention: AI writes to its OWN workspace; the category tells FxFiles where to adopt the file later.
  • Wire pub mod category; into lib.rs.

Source of truth (FxFiles, ported verbatim)

  • lib/core/services/shelf_classifier.dart
  • lib/core/models/shelf_item.dart (ShelfCategory enum + order)
  • lib/core/services/bucket_version_resolver.dart (category->bucket, -v8 routing)
  • lib/core/models/fula_object.dart (extension lists for the no-MIME fallback)

Tests

Table-driven (mime, filename, text) -> Category covering every ShelfClassifier branch (each case cites the Dart rule it pins) + native_category_bucket per category + extension-fallback (no-MIME) cases. Offline; cargo test -p fula-mcp green.

Out of scope

No MCP protocol, no network, no crypto, no actual bucket writes (that is P5 fula_store_file). This phase is the pure classifier + bucket-name resolver P5 will call.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions