Skip to content

feat(kernel-platforms): vend fs as an exo - #1056

Draft
ci-belphegor wants to merge 1 commit into
grypez/narrowing-9a-fs-promises-onlyfrom
grypez/narrowing-9b-fs-exo
Draft

feat(kernel-platforms): vend fs as an exo#1056
ci-belphegor wants to merge 1 commit into
grypez/narrowing-9a-fs-promises-onlyfrom
grypez/narrowing-9b-fs-exo

Conversation

@ci-belphegor

Copy link
Copy Markdown

Explanation

Converts fs from a hardened record of caveated functions into an exo with explicit M.interface method guards, and flattens the nested promises: { readFile: true } config into a flat methods: ['readFile'] list, since exos have a flat method namespace.

A vat's global fs becomes the exo itself: await E(fs).readFile('/srv/x') rather than fs.promises.readFile(...).

There is exactly one thing to judge in this PR: is this the right exo shape, and are the guards right? Paths stay strings here; segment arrays are the next PR, deliberately, so that a reviewer is not simultaneously assessing path semantics and interface guards.

Notes for reviewers

The guards are written out per method rather than via makeDefaultExo, which departs from the repo convention on purpose: makeDefaultExo yields defaultGuards: 'passable' and an empty guard map, and narrowing conjoins a delta onto a per-argument guard, so there has to be one to conjoin onto. There is a comment at the interface saying so.

defaultGuards is omitted entirely, so the guard map is the sole authority — a method absent from the map is uncallable rather than falling back to "any passable args." That applies the design's "omission removes authority" default one level down.

A real surface reduction, flagged rather than buried. M.any() matches Passables only, so readFile(path, { signal: abortSignal }) is now rejected where the raw function accepted it. No caller in this repo does that, but it is a genuine narrowing of behavior, not just a reshaping. It is named in 9c's changelog entry.

An omitted methods yields an exo with zero methods; an unknown method name is rejected by the config struct.

No changelog here — the 9a/9b/9c chain squashes to one commit and the single **BREAKING:** entry lands in 9c.

Stack

PR 10 of 12. Base: #1055.

Replace the hardened record of caveated functions with an exo built from
explicit `M.interface` method guards, and flatten the `promises.readFile`
config nesting into a flat `methods` list to match the exo's flat method
namespace. Paths stay strings.

Guards are explicit rather than `makeDefaultExo`'s `defaultGuards: 'passable'`
because narrowing conjoins a delta onto a per-argument guard, so there has to
be one to conjoin onto. They are `M.callWhen` because narrowed methods forward
through `E()` and every derived guard is asyncified.

No changelog entry: 9a/9b/9c squash to a single commit on main, so the one
`**BREAKING:**` entry covering the whole shape change lands in 9c.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ci-belphegor
ci-belphegor force-pushed the grypez/narrowing-9b-fs-exo branch from 40ec599 to 55901ff Compare September 11, 2026 11:42
@ci-belphegor
ci-belphegor added this pull request to stack #1060 September 11, 2026 11:44
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.

1 participant