os: the user, User.current() (step 2 of #130, OS slice 6) #537

Closed
opened 2026-10-28 05:01:04 +00:00 by orion · 9 comments
Collaborator

Goal

Step 2 of #130 (OS slice 6): std/os answers who the user is. User and User.current() as specified in docs/design/OS.md section 5.7, on Windows, Linux, macOS and FreeBSD; the browser answers OsError.Unsupported.

Specification

  • Design record: OS.md section 5.7 (the user) and the slice 6 row of section 10. Follow the conventions Volumes (#128) and Directories (#531) set for the OS arms, the OsError mapping and the Task shape of current().
  • POSIX (Linux, macOS, FreeBSD): name, fullName (GECOS, None where empty), home from Posix.account (exists, runtime/os/posix.c); identifier is the user id as text; isElevated is Posix.effectiveUserIdentifier() == 0 (geteuid).
  • Windows: new natives in std/os/src/windows/native.trb and runtime/os/*.c: the login name without its domain, the display name (GetUserNameExW(NameDisplay), None where the account has none), the SID text (process token, GetTokenInformation(TokenUser) and ConvertSidToStringSidW), the elevation of the token (TokenElevation); home from the existing Windows.knownFolder (FOLDERID_Profile).
  • Browser: OsError.Unsupported.
  • Public shape exactly as 5.7 (name, fullName, identifier, home, isElevated; Show, Equals); export User from std/os. Doc comments with examples; docs/standard-library/os.md and the std index regenerated; skills/ regenerated.

Acceptance criteria

  • User.current() answers the account of the running process on the host system: name non-empty, home absolute and equal to Directories.home() where the environment does not override it, identifier non-empty, fullName None or non-empty.
  • POSIX: the account-entry mapping (empty GECOS to None, id to text, elevation from the effective id) is a pure function with unit tests on captured input that run on every machine; a host test per system checks identifier equals the id Posix.effectiveUserIdentifier()/getuid reports.
  • Windows: a host test checks the SID starts with S-1-, the name carries no \ domain part, and isElevated is a plain Bool; the SID-text and name-splitting helpers are pure and tested on captured input everywhere.
  • Browser build answers Unsupported (test in the browser arm like the other modules); an account that cannot be read answers a Failed/Missing OsError with the reason, never a panic.
  • torb check --every-target clean, docs check clean, skills/ regenerated.
  • docs/design/OS.md section 5.7 stays the record; any difference found while implementing is noted there (the slice 6 "How slice 6 landed" note is written by the last step, #130 step 3).

Seed impact

No. New Windows natives, but the compiler does not import User (like volumes, #128): no seed refresh, no two-commit rule.

Size

One PR, one or two Conventional Commits (for example feat(os): the Windows natives for the user then feat(os): User and User.current).

Part of #130. Depends on #531 (landed).

## Goal Step 2 of #130 (OS slice 6): `std/os` answers who the user is. `User` and `User.current()` as specified in `docs/design/OS.md` section 5.7, on Windows, Linux, macOS and FreeBSD; the browser answers `OsError.Unsupported`. ## Specification - Design record: [OS.md section 5.7 (the user)](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/OS.md#57-the-user) and the slice 6 row of section 10. Follow the conventions `Volumes` (#128) and `Directories` (#531) set for the OS arms, the `OsError` mapping and the `Task` shape of `current()`. - POSIX (Linux, macOS, FreeBSD): `name`, `fullName` (GECOS, `None` where empty), `home` from `Posix.account` (exists, `runtime/os/posix.c`); `identifier` is the user id as text; `isElevated` is `Posix.effectiveUserIdentifier() == 0` (`geteuid`). - Windows: new natives in `std/os/src/windows/native.trb` and `runtime/os/*.c`: the login name without its domain, the display name (`GetUserNameExW(NameDisplay)`, `None` where the account has none), the SID text (process token, `GetTokenInformation(TokenUser)` and `ConvertSidToStringSidW`), the elevation of the token (`TokenElevation`); `home` from the existing `Windows.knownFolder` (`FOLDERID_Profile`). - Browser: `OsError.Unsupported`. - Public shape exactly as 5.7 (`name`, `fullName`, `identifier`, `home`, `isElevated`; `Show`, `Equals`); export `User` from `std/os`. Doc comments with examples; `docs/standard-library/os.md` and the std index regenerated; `skills/` regenerated. ## Acceptance criteria - [ ] `User.current()` answers the account of the running process on the host system: `name` non-empty, `home` absolute and equal to `Directories.home()` where the environment does not override it, `identifier` non-empty, `fullName` `None` or non-empty. - [ ] POSIX: the account-entry mapping (empty GECOS to `None`, id to text, elevation from the effective id) is a pure function with unit tests on captured input that run on every machine; a host test per system checks `identifier` equals the id `Posix.effectiveUserIdentifier()`/`getuid` reports. - [ ] Windows: a host test checks the SID starts with `S-1-`, the name carries no `\` domain part, and `isElevated` is a plain `Bool`; the SID-text and name-splitting helpers are pure and tested on captured input everywhere. - [ ] Browser build answers `Unsupported` (test in the browser arm like the other modules); an account that cannot be read answers a `Failed`/`Missing` `OsError` with the reason, never a panic. - [ ] `torb check --every-target` clean, `docs check` clean, `skills/` regenerated. - [ ] `docs/design/OS.md` section 5.7 stays the record; any difference found while implementing is noted there (the slice 6 "How slice 6 landed" note is written by the last step, #130 step 3). ## Seed impact No. New Windows natives, but the compiler does not import `User` (like volumes, #128): no seed refresh, no two-commit rule. ## Size One PR, one or two Conventional Commits (for example `feat(os): the Windows natives for the user` then `feat(os): User and User.current`). Part of #130. Depends on #531 (landed).
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-28T11:30Z

[loop:torbscript] claim implement by session:loop-torbscript-20261028 until 2026-10-28T11:30Z
Author
Collaborator

[loop:torbscript] release implement: worker lost its execution context before pushing anything (no branch exists). Respawning.

[loop:torbscript] release implement: worker lost its execution context before pushing anything (no branch exists). Respawning.
Author
Collaborator

[loop:torbscript] claim implement (respawn) by session:loop-torbscript-20261028 until 2026-10-28T11:40Z

[loop:torbscript] claim implement (respawn) by session:loop-torbscript-20261028 until 2026-10-28T11:40Z
Author
Collaborator

[loop:torbscript] implement: PR #540 is open (2 commits, std/os User and User.current plus the Windows natives; local checks per the PR body). The worker lost its execution context after pushing and could not post its own result, so this comment releases the claim. CI on the PR is still running; next: waiting (CI and merge gate on PR #540)

[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/540 is open (2 commits, `std/os` User and User.current plus the Windows natives; local checks per the PR body). The worker lost its execution context after pushing and could not post its own result, so this comment releases the claim. CI on the PR is still running; next: waiting (CI and merge gate on PR #540)
Author
Collaborator

CI update for #540 (head b2dc4e6): settled. Green: tier A, bootstrap linux-x64, every host emits the same C, playground, release-sync/registry, commit messages, pdisc. Red: tier B and the aggregate gates only. Tier B is red on main and fixed by #536, so this PR introduces no failure of its own.

CI update for #540 (head `b2dc4e6`): settled. Green: tier A, bootstrap linux-x64, every host emits the same C, playground, release-sync/registry, commit messages, pdisc. Red: tier B and the aggregate gates only. Tier B is red on main and fixed by #536, so this PR introduces no failure of its own.
Author
Collaborator

[loop:torbscript] claim implement (PR #540: drop the WIP prefix, carry it through CI) by session:loop-torbscript-20261028 until 2026-10-28T14:40Z

[loop:torbscript] claim implement (PR #540: drop the WIP prefix, carry it through CI) by session:loop-torbscript-20261028 until 2026-10-28T14:40Z
Author
Collaborator

[loop:torbscript] review: dropped the WIP prefix, PR #540 is now feat(os): User and User.current and mergeable. CI on head b2dc4e6 unchanged: everything green except tier B (linux-x64) and the aggregate gates, both red for the main-side resource conformance programs that #536 fixes. #536 has not landed (its own tier B is currently red as well, tier A still pending), so no rebase yet. next: waiting (#536 landing on main, then rebase #540 and re-read CI). Claim released. ~60k tokens.

[loop:torbscript] review: dropped the WIP prefix, PR #540 is now `feat(os): User and User.current` and mergeable. CI on head `b2dc4e6` unchanged: everything green except `tier B (linux-x64)` and the aggregate `gates`, both red for the main-side resource conformance programs that #536 fixes. #536 has not landed (its own tier B is currently red as well, tier A still pending), so no rebase yet. next: waiting (#536 landing on main, then rebase #540 and re-read CI). Claim released. ~60k tokens.
Author
Collaborator

[loop:torbscript] claim implement (PR #540: #536 landed on main, rebase onto 403ee176 and re-read CI) by session:loop-torbscript-20261028 until 2026-10-28T18:40Z

[loop:torbscript] claim implement (PR #540: #536 landed on main, rebase onto 403ee176 and re-read CI) by session:loop-torbscript-20261028 until 2026-10-28T18:40Z
Author
Collaborator

[loop:torbscript] release implement: the rebase worker lost its execution context after pushing. PR #540 is rebased onto main acf85102 (head 5e8e8da, linear history, 3 commits, mergeable); bootstrap (linux-x64) is green, tier A, tier B and gates are queued behind the single linux-x64 runner. Main's resource conformance programs are fixed by #536, so tier B is expected green. next: waiting (CI on PR #540 and merge gate)

[loop:torbscript] release implement: the rebase worker lost its execution context after pushing. PR #540 is rebased onto main acf85102 (head 5e8e8da, linear history, 3 commits, mergeable); bootstrap (linux-x64) is green, tier A, tier B and gates are queued behind the single linux-x64 runner. Main's resource conformance programs are fixed by #536, so tier B is expected green. next: waiting (CI on PR #540 and merge gate)
argus closed this issue 2026-10-28 16:18:00 +00:00
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#537
No description provided.