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.

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