Skip to content

Implement openkal.terminal, and follow openkal 0.8 - #13

Merged
Sunrisepeak merged 6 commits into
mainfrom
feat/openkal-0.8
Aug 27, 2026
Merged

Implement openkal.terminal, and follow openkal 0.8#13
Sunrisepeak merged 6 commits into
mainfrom
feat/openkal-0.8

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

Paired with mcpplibs/openkal#13.

The console operations this environment offers map onto the interface directly: ENABLE_LINE_INPUT is what openkal.terminal calls line editing and ENABLE_ECHO_INPUT is what it calls echo. GetConsoleMode is already what kal_stream_props asks, so a stream that is not a console is reported as unsupported by the same test.

The mode is read, modified and written rather than written alone. The console mode carries processed input, mouse input, window input and virtual terminal processing, none of which the interface names; a word composed from the two positions alone would turn all of them off, and a program that asked only to stop echoing would find its console changed in ways it did not ask for.

kal_terminal_size reports the window and not the buffer. This environment's screen buffer may be taller than the window that shows it, and a program drawing a full screen against the buffer's height would scroll its own output away.

The other four interfaces version 0.8 adds are not provided, which clause 6.1 makes an absence at the link rather than a deviation.

`xim:glibc` 的 `latest` 从 `2.44` 移到了 `2.44.2`。载荷目录按请求**解析成**的版本
命名,而 RuntimeBinding 带的是**声明的**版本 —— 而一个已发布的 mcpp vendor 进自己
沙箱的那份 xlings 仍然声明 `2.44`。于是干净机器装出 `2.44.2`,工具链 fixup 要
`2.44`,构建在编译任何东西之前就停住:

    error: selected RuntimeBinding glibc@2.44 requires payload
           '.../xpkgs/xim-x-glibc/2.44', but it is not installed

⚠️ 在每一台**新**机器上出现,在任何已存在的机器上都不出现 —— 所以开发机看不见。
索引的 `pkgs/g/glibc.lua` 把这次失败逐字记着,并给出规则:
「The index is DATA and the client is a PROGRAM: the consumer ships first。」

## ⚠️ 我先试过 bump xlings,撤回了

把 `XLINGS_VERSION` 提到 2026.8.27.1 会让**沙箱里那份** xlings 被换掉
(mcpp 的 `acquire_xlings_binary` 在 pin 前移时更新它),绑定于是**前移**到
`glibc@2.44.2`,而已经装好的是 `2.44` —— 请求比已装的**更新**。那是更糟的一侧:
接受一个更旧的载荷去回答更新的请求,等于静默用上索引明说
「IT IS NOT THE ONE TO INSTALL」的那份(带 mcpp#484 的 preload 缺陷)。

⇒ 保持 xlings 不动,把缺的那个载荷直接装上。

⭐ 待 mcpp 2026.8.27.1(mcpp-community/mcpp#515)发布后移除:它接受
「版本精化了请求」的已装载荷,从它引导就不需要这一步。
The console operations this environment offers map onto the interface directly:
ENABLE_LINE_INPUT is what openkal.terminal calls line editing and
ENABLE_ECHO_INPUT is what it calls echo, which is the same division the interface
draws. GetConsoleMode is already what kal_stream_props asks, so a stream that is
not a console is reported as unsupported by the same test.

The mode is read, modified and written rather than written alone. The console
mode carries processed input, mouse input, window input and virtual terminal
processing, none of which the interface names; a word composed from the two
positions alone would turn all of them off, and a program that asked only to stop
echoing would find its console changed in ways it did not ask for.

kal_terminal_size reports the WINDOW and not the buffer. This environment's
screen buffer may be taller than the window that shows it, and a program drawing
a full screen against the buffer's height would scroll its own output away.

The other four interfaces version 0.8 adds are not provided, which clause 6.1
makes an absence at the link rather than a deviation.
ADDING TO AN EXISTING INTERFACE OBLIGES EVERY IMPLEMENTATION OF IT, and adding a
new interface obliges none. Clause 6.1 makes an interface a backend does not
provide absent at the link and not a deviation; it makes one provided IN PART a
deviation. The five interfaces version 0.8 adds are therefore free to decline,
and the three names added to openkal.process are not.

The specification's own surface checker said so before anything else noticed:

    openkal.process is provided in part: 3 of 8 names are not exported --
        kal_process_channel
        kal_process_channel_close
        kal_process_spawn_with

kal_process_channel is CreatePipe. THIS ENVIRONMENT DECIDES INHERITANCE PER
HANDLE AND NOT PER EXEC, which is the opposite of the other two: there every
handle is inherited unless marked otherwise, so those implementations mark both
ends close-on-exec and let the spawn place the far one. Here the default is not
to inherit, so the far end is created inheritable and the near end is withdrawn
afterwards --- otherwise the started program would hold both ends and the writer
would never observe the end of input.

kal_process_spawn_with refuses a non-empty set of grants, and the refusal is the
honest answer rather than a gap. A preopened directory is a handle a started
program reads back by NUMBER, and this environment has no numbering: a handle
crosses a spawn by being inheritable, and the started program learns of it
through a mechanism the parent arranges. There is no correspondence to descriptor
three.

Clause 6.2 is what makes that conforming: the operation exists, reports
kal_err_not_supported, and the property word does not claim
KAL_PROCESS_PROP_GRANT_DIR --- so a caller learns from the word what it would
otherwise learn from a failed call. A count of zero is still answered, by the
ordinary spawn, because a program with no preopens is what this environment
starts anyway.
`port/*.def` is an explicit list, and the import library generated from it
contains exactly those names. I added three declarations to `src/win32.h` for
openkal 0.8 and did not add the names, so the import library this package
generates for its consumers was missing them.

⚠️ AND THIS PACKAGE'S OWN CI STAYED GREEN, because this package does not link.
The failure appeared one repository away, in openkal-llvm-runtime's cross-build:

    ld.lld: error: undefined symbol: __declspec(dllimport) CreatePipe
    ld.lld: error: undefined symbol: __declspec(dllimport) GetConsoleScreenBufferInfo
    ld.lld: error: undefined symbol: __declspec(dllimport) SetConsoleMode

which reads as a defect in the consumer and is nothing of the kind.

⭐ IT WAS FOUND BY COMPARING IMPORT LIBRARIES, NOT BY READING THE ERROR. Every
copy of a vendor `libkernel32.a` on the machine had all three; the one generated
here had `GetConsoleMode` and not `SetConsoleMode`, which is not a shape a
vendor's library takes and pointed straight at the generated list.

The check added here is the one that would have caught it: every name
`src/win32.h` declares must be exported by some `.def`. It belongs in this
repository, where the two lists are, rather than in the consumer that trips over
the difference.

Measured both ways: removing `CreatePipe` from the list makes it red and names
the symbol; the lists as committed are 42 declared, 49 exported, none missing.
A denominator is asserted on both sides, since two empty lists have an empty
difference too.
Python opens a file with the platform's default encoding, which on the Windows
runner is cp1252, and these sources are UTF-8:

    UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 90

A check that reads source files must say what they are encoded in, or it reports
on the runner's locale rather than on the sources. The byte it stopped at is in a
comment marker, so the check would have passed on a repository whose comments
happened to be ASCII and failed on this one --- which is the least useful place
for a difference to appear.

Both reads name utf-8. Rehearsed locally under cp1252: 42 declared, 49 exported,
none missing.
openkal 0.8.0 is published, so the manifest names it by version rather than by
branch. A branch is how a change spanning these repositories is developed and is
not a form a published package may carry: a consumer resolving from the index
would be handed a reference that moves.

The engine pin moves to mcpp 2026.8.27.1 and the repository variable
MCPP_SOURCE_REF is cleared, so what this repository tests is the engine a user
installs.
@Sunrisepeak
Sunrisepeak merged commit d6fc05a into main Aug 27, 2026
7 of 8 checks passed
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.

2 participants