Request helper: refuse an upload directory of another user, and the body writes of registry.trb #293

Open
opened 2026-10-10 00:20:17 +00:00 by orion · 3 comments
Collaborator

Split from #288 (criterion 3, the owner half) and two spots of the same hardening in compiler/src/cli/registry.trb, which #288's PR leaves alone while #279 edits that file.

Goal. request refuses a <work>/upload that belongs to another user, with a message naming the path and the reason, before anything is written into it and before its chmod; and no registry command writes into that directory or prints a registry's raw bytes before the checks of #288 ran.

Why it is split. std/fs has no owner query: Metadata carries kind, size, modification time and permissions, and std/os only the process's own effective user id (Posix.effectiveUserIdentifier). The owner needs a new native (st_uid), and under the two-commit rule (compiler/CONTRIBUTING.md, "Two commits for a breaking change") its use in the compiler can be pushed only after the seed knows it. Meanwhile uploadDirectory (#288) refuses a symbolic link and anything that is not a directory, and the chmod to 0700 that follows fails for every user but root on a directory they do not own, so nothing is written there.

Acceptance criteria

  • Commit 1: an owner query on File (a method, std naming; not by changing the signature of the existing fileMetadata native, which the seed's compiler reaches), implemented in runtime/ for POSIX, answering unsupported where there is no owner id (Windows, the browser), entered in the natives manifest with the table regenerated; a std test and a runtime test.
  • After the seed knows the native (refresh is the owner's step): uploadDirectory refuses a directory whose owner is not the effective user, also for root; the owner comparison is a separate function with a unit test.
  • registry.trb writes the bodies of torb owner and torb yank (member.json, step-up.json, yank.json) only after uploadDirectory checked the directory, and printOwner prints a non-JSON answer through printable instead of reply.body.trim().
  • Existing loopback tests of torb login, torb owner, torb yank and publish stay green.

Seed. Yes: a new native (two commits, seed refresh between them). Depends on #288 and #279.

Split from #288 (criterion 3, the owner half) and two spots of the same hardening in `compiler/src/cli/registry.trb`, which #288's PR leaves alone while #279 edits that file. **Goal.** `request` refuses a `<work>/upload` that belongs to another user, with a message naming the path and the reason, before anything is written into it and before its `chmod`; and no registry command writes into that directory or prints a registry's raw bytes before the checks of #288 ran. **Why it is split.** `std/fs` has no owner query: `Metadata` carries kind, size, modification time and permissions, and `std/os` only the process's own effective user id (`Posix.effectiveUserIdentifier`). The owner needs a new native (`st_uid`), and under the two-commit rule (`compiler/CONTRIBUTING.md`, "Two commits for a breaking change") its use in the compiler can be pushed only after the seed knows it. Meanwhile `uploadDirectory` (#288) refuses a symbolic link and anything that is not a directory, and the `chmod` to `0700` that follows fails for every user but root on a directory they do not own, so nothing is written there. **Acceptance criteria** - [ ] Commit 1: an owner query on `File` (a method, std naming; not by changing the signature of the existing `fileMetadata` native, which the seed's compiler reaches), implemented in `runtime/` for POSIX, answering unsupported where there is no owner id (Windows, the browser), entered in the natives manifest with the table regenerated; a std test and a runtime test. - [ ] After the seed knows the native (refresh is the owner's step): `uploadDirectory` refuses a directory whose owner is not the effective user, also for root; the owner comparison is a separate function with a unit test. - [ ] `registry.trb` writes the bodies of `torb owner` and `torb yank` (`member.json`, `step-up.json`, `yank.json`) only after `uploadDirectory` checked the directory, and `printOwner` prints a non-JSON answer through `printable` instead of `reply.body.trim()`. - [ ] Existing loopback tests of `torb login`, `torb owner`, `torb yank` and `publish` stay green. **Seed.** Yes: a new native (two commits, seed refresh between them). Depends on #288 and #279.
Author
Collaborator

[loop:torbscript] intake: in scope (author orion, split from #288), not a duplicate, no collision with a design record. Refined by its author already (goal, criteria, seed impact: a new native under the two-commit rule, size: two commits). Depends on #288 and #279 (both have open PRs) and on a published seed for its second commit. next: waiting (PRs of #288 and #279) until 2026-10-10T04:00:00Z

[loop:torbscript] intake: in scope (author orion, split from #288), not a duplicate, no collision with a design record. Refined by its author already (goal, criteria, seed impact: a new native under the two-commit rule, size: two commits). Depends on #288 and #279 (both have open PRs) and on a published seed for its second commit. next: waiting (PRs of #288 and #279) until 2026-10-10T04:00:00Z
Author
Collaborator

[loop:torbscript] claim refine by session:loop-torbscript-20261026-1044 until 2026-10-26T11:56:08Z

[loop:torbscript] claim refine by session:loop-torbscript-20261026-1044 until 2026-10-26T11:56:08Z
Author
Collaborator

[loop:torbscript] refine: #288 (PR #294) and #279 (PR #292) have both merged, so the dependencies are gone; the criteria were checked against main (uploadDirectory in compiler/src/package/upload.trb has no owner check yet; registry.trb still writes member.json, step-up.json and yank.json before request reaches uploadDirectory, and printOwner still prints reply.body.trim()). The criteria hold, but the item is an epic: commit 1 and commit 2 are separated by a seed refresh (owner's step), so they cannot land as one PR. Steps:

  • Step 1: native File.owner, #496 (loop + ready; seed: new native, commit 1)
  • Step 2 (just in time, after the seed refresh): uploadDirectory refuses a directory of another user (comparison in its own function with a unit test), also for root; registry.trb calls uploadDirectory before it writes member.json, step-up.json and yank.json; printOwner prints a non-JSON answer through printable; loopback tests of torb login, torb owner, torb yank, publish stay green. The registry.trb and printable part needs no new native and may be split off as its own step earlier if the loop picks it up.

[loop:torbscript] decided by the loop: step 1 is split off now because it does not depend on anything unmerged; this issue stays without ready (epic) until step 1 has landed and a seed containing File.owner is published, then step 2 is filed. No owner question: a new native under the two-commit rule is a technical choice; the seed refresh itself stays Torben's.

next: waiting (step 1 #496, then the owner's seed refresh). Worker usage ~60k tokens.

[loop:torbscript] refine: #288 (PR #294) and #279 (PR #292) have both merged, so the dependencies are gone; the criteria were checked against `main` (`uploadDirectory` in `compiler/src/package/upload.trb` has no owner check yet; `registry.trb` still writes `member.json`, `step-up.json` and `yank.json` before `request` reaches `uploadDirectory`, and `printOwner` still prints `reply.body.trim()`). The criteria hold, but the item is an epic: commit 1 and commit 2 are separated by a seed refresh (owner's step), so they cannot land as one PR. Steps: - [ ] Step 1: native `File.owner`, https://git.torb.dev/torbscript/language/issues/496 (`loop` + `ready`; seed: new native, commit 1) - [ ] Step 2 (just in time, after the seed refresh): `uploadDirectory` refuses a directory of another user (comparison in its own function with a unit test), also for root; `registry.trb` calls `uploadDirectory` before it writes `member.json`, `step-up.json` and `yank.json`; `printOwner` prints a non-JSON answer through `printable`; loopback tests of `torb login`, `torb owner`, `torb yank`, `publish` stay green. The `registry.trb` and `printable` part needs no new native and may be split off as its own step earlier if the loop picks it up. [loop:torbscript] decided by the loop: step 1 is split off now because it does not depend on anything unmerged; this issue stays without `ready` (epic) until step 1 has landed and a seed containing `File.owner` is published, then step 2 is filed. No owner question: a new native under the two-commit rule is a technical choice; the seed refresh itself stays Torben's. next: waiting (step 1 #496, then the owner's seed refresh). Worker usage ~60k tokens.
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#293
No description provided.