From e3adbf0462cbb3eef2eef88d67bdfb84c85bfa9b Mon Sep 17 00:00:00 2001 From: Danny Kim Date: Fri, 25 Sep 2026 12:40:17 +0900 Subject: [PATCH] Drop ids, staged writes and publish from the filesystem contract --- sdk/src/lib.rs | 2 +- sdk/wit/filesystem.wit | 35 ++++++++++------------------------- src/lib.rs | 12 ------------ src/listing.rs | 1 - 4 files changed, 11 insertions(+), 39 deletions(-) diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index cc09842..00ca18d 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -14,5 +14,5 @@ pub use exports::memona::filesystem::provider::{ }; pub use memona::filesystem::host::{ Exchange, Header, HostError, LogLevel, Method, Request, Response, Setting, - Tcp, Udp, bind, config, connect, http, invalidate_token, log, + Tcp, Udp, bind, config, connect, http, log, }; diff --git a/sdk/wit/filesystem.wit b/sdk/wit/filesystem.wit index 560695e..4529372 100644 --- a/sdk/wit/filesystem.wit +++ b/sdk/wit/filesystem.wit @@ -74,9 +74,6 @@ interface host { variant setting { text(string), secret(string), toggle(bool) } /// Reads configuration or a session-only credential for this connection. config: func(key: string) -> option; - /// Reports that the current access token was rejected. The host refreshes - /// it once; a second rejection surfaces to the caller as denied. - invalidate-token: func(); /// Emits a diagnostic event. Never include secrets or private document data. log: func(level: log-level, message: string); @@ -101,36 +98,28 @@ interface provider { /// An opaque version token, at most 4096 UTF-8 bytes. type revision = string; - /// An opaque backend identity, at most 4096 UTF-8 bytes. The host never - /// parses, orders, or shows one, and never keeps one past the connection, - /// because a backend may reuse it. - type resource-id = string; - /// How one resource is named. A provider that hands out ids must accept - /// them back; one that does not may reject every id as invalid-input. - variant locator { path(string), id(resource-id) } + /// How one resource is named: a path within the connection root. + variant locator { path(string) } /// Optional operations. False capabilities must return unsupported. - /// Conditional-write promises atomic create-only and revision comparisons, - /// and cannot be combined with staged-write, where nothing to compare - /// exists until a publish lands. Virtual-directories says a directory is - /// only ever a prefix of something stored, as in a flat object store: the - /// host then never offers to create an empty one, warns that removing the - /// last child removes the folder, and does not call a vanished folder an - /// error. Such a provider may still accept mkdir by writing a marker, and - /// must answer unsupported when asked to rename a directory. + /// Conditional-write promises atomic create-only and revision comparisons. + /// Virtual-directories says a directory is only ever a prefix of something + /// stored, as in a flat object store: the host then never offers to create + /// an empty one, warns that removing the last child removes the folder, + /// and does not call a vanished folder an error. Such a provider may still + /// accept mkdir by writing a marker, and must answer unsupported when + /// asked to rename a directory. record capabilities { write: bool, mkdir: bool, rename: bool, remove: bool, conditional-write: bool, watch: bool, - staged-write: bool, publishable: bool, virtual-directories: bool, } - /// Byte length, an opaque revision, and a backend identity, each if known. + /// Byte length and an opaque revision, each if known. record file-info { kind: entry-kind, size: u64, revision: option, - id: option, } /// One child name, without slashes, dot segments, or control characters. record entry { name: string, info: file-info } @@ -198,10 +187,6 @@ interface provider { /// Polls for a bounded change page if the watch capability is present. No /// background callback or persistent subscription is installed by the host. poll: func(cursor: option) -> result; - /// Makes every staged write visible as one new root, if the publishable - /// capability is present, and names it, for example as a content - /// identifier. A none result means the publish needs another call. - publish: func() -> result, error-code>; } /// Memona filesystem extension ABI 0.1.0, distributed as a WebAssembly component. diff --git a/src/lib.rs b/src/lib.rs index 76b3a2a..4fdffb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,6 @@ fn text(setting: Option<&Setting>) -> Option { fn route(target: &Locator) -> Result { match target { Locator::Path(path) => Ok(path.clone()), - Locator::Id(_) => Err(ErrorCode::InvalidInput), } } @@ -141,7 +140,6 @@ impl GuestWriter for FtpWriter { kind: EntryKind::File, size: 0, revision: None, - id: None, })) } } @@ -192,8 +190,6 @@ impl Guest for Ftp { // promised without simulating one, which the contract forbids. conditional_write: false, watch: false, - staged_write: false, - publishable: false, virtual_directories: false, }) } @@ -216,7 +212,6 @@ impl Guest for Ftp { kind: EntryKind::Directory, size: 0, revision: None, - id: None, }); } with_control(|control| { @@ -231,7 +226,6 @@ impl Guest for Ftp { kind: EntryKind::File, size, revision: None, - id: None, }); } let (code, _) = control.send(&format!("CWD {path}"))?; @@ -240,7 +234,6 @@ impl Guest for Ftp { kind: EntryKind::Directory, size: 0, revision: None, - id: None, }) }) } @@ -309,7 +302,6 @@ impl Guest for Ftp { kind: EntryKind::Directory, size: 0, revision: None, - id: None, }) } @@ -342,10 +334,6 @@ impl Guest for Ftp { fn poll(_cursor: Option) -> Result { Err(ErrorCode::Unsupported) } - - fn publish() -> Result, ErrorCode> { - Err(ErrorCode::Unsupported) - } } memona_plugin_sdk::export!(Ftp); diff --git a/src/listing.rs b/src/listing.rs index fe46573..cb0ba4f 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -35,7 +35,6 @@ pub fn machine_entry(line: &str) -> Option { kind, size, revision: None, - id: None, }, }) }