phase0 amendment: §3/§7/§10 close review-surfaced manifest gaps
Three additions to PHASE0.md, all surfaced by the Phase 5 review of
the Phase 0 implementation. No invariant changes; manifest now matches
implementation reality.
§3 — FFI loader fallback paragraph. ffi.load("name") needs the
unversioned `libname.so` symlink that comes with the -dev package.
Phase 0 loaders try unversioned first then versioned sonames so
runtime-only hosts (no -dev) work as-is. Documents the actual
behavior in ffi/readline.lua and ffi/curl.lua.
§7 — LuaJIT 2.1 popen-close caveat paragraph. The §7 sketch had been
showing Lua 5.2's three-return io.popen():close() shape; LuaJIT 2.1
follows the Lua 5.1 ABI and returns just `true`. Phase 0 recovers
the exit status with a sentinel echo (`echo __AISH_EXIT_<tag>__$?`).
Phase 1 PTY+waitpid replaces the hack and the sketch becomes
accurate. Sketch left as-is (it's the right shape conceptually);
caveat now explicit.
§10 — cwd-relative package.path note. Phase 0 prepends `./?.lua;
./vendor/?.lua`, so aish must run from the repo root. Cwd-independent
resolution is a later concern. Also clarifies that --config is strict
(no fallback if the path is unopenable) — matches main.lua post the
review-followup commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+27
-3
@@ -43,6 +43,13 @@ Phase 0 is the minimal working skeleton. It establishes the REPL loop, input dis
|
||||
| Config format | Lua table (plain `.lua` file sourced at startup) | No parser dependency; native types; easily extended |
|
||||
| JSON encode/decode | dkjson 2.8 vendored under `vendor/dkjson.lua` | Pure Lua (preserves §3 "no compiled extensions" invariant); single-file vendor avoids `luarocks`; sourced from Debian's `lua-dkjson` package, originally from dkolf.de |
|
||||
|
||||
**FFI loader fallback.** `ffi.load("readline")` and `ffi.load("curl")`
|
||||
look for the unversioned `lib<name>.so` symlink, which is only installed
|
||||
by the `-dev` package. Phase 0 loaders try the unversioned name first
|
||||
then fall back to versioned sonames (`readline.so.8`, `readline.so.7`,
|
||||
`curl.so.4`, `curl-gnutls.so.4`) so a runtime-only host (Debian/ALARM
|
||||
without `lib<name>-dev`) just works.
|
||||
|
||||
---
|
||||
|
||||
## 4. Target Directory Layout
|
||||
@@ -153,7 +160,7 @@ The `CMD:` prefix convention is the extraction contract between the model and `e
|
||||
## 7. Execution Model (Phase 0)
|
||||
|
||||
```lua
|
||||
-- executor.lua Phase 0
|
||||
-- executor.lua Phase 0 (illustrative — see note below)
|
||||
local function exec(cmd)
|
||||
local handle = io.popen(cmd .. " 2>&1", "r")
|
||||
local output = handle:read("*a")
|
||||
@@ -162,11 +169,21 @@ local function exec(cmd)
|
||||
end
|
||||
```
|
||||
|
||||
**LuaJIT 2.1 popen-close caveat.** The sketch above assumes Lua 5.2's
|
||||
three-return `io.popen():close()` shape. LuaJIT 2.1 follows the Lua 5.1
|
||||
ABI and returns just `true` — no exit status. The Phase 0 implementation
|
||||
recovers the exit code by appending a sentinel echo to the wrapped
|
||||
command (`(cmd) 2>&1; echo __AISH_EXIT_<tag>__$?`) and parsing it back
|
||||
out. Phase 1's PTY work replaces this with `waitpid` via libc FFI; the
|
||||
sketch becomes accurate at that point.
|
||||
|
||||
Output is captured and:
|
||||
1. Printed to the terminal
|
||||
2. Injected into `context.lua` as a `[exec output]` user turn
|
||||
|
||||
`cd` is intercepted before `popen` and handled via `posix.chdir` (libc FFI) so the working directory change persists across calls — `popen` forks a subprocess and `cd` inside it would otherwise be discarded.
|
||||
`cd` is intercepted before `popen` and handled via `libc.chdir` (FFI) so
|
||||
the working directory change persists across calls — `popen` forks a
|
||||
subprocess and `cd` inside it would otherwise be discarded.
|
||||
|
||||
---
|
||||
|
||||
@@ -270,11 +287,18 @@ return {
|
||||
```
|
||||
|
||||
Config path resolution order:
|
||||
1. `--config <path>` CLI argument
|
||||
1. `--config <path>` CLI argument (explicit; failure if not openable, no fallback)
|
||||
2. `$AISH_CONFIG` environment variable
|
||||
3. `~/.config/aish/config.lua`
|
||||
4. `./config.lua` (development fallback)
|
||||
|
||||
**Cwd-relative module resolution.** Phase 0 prepends `./?.lua;./vendor/?.lua`
|
||||
to `package.path`, so `luajit main.lua` must be invoked with the repo
|
||||
root as cwd. Cwd-independent resolution (relative to the script's own
|
||||
directory) lands later — likely Phase 1 alongside the install path
|
||||
work, or whenever the first user reports trying `luajit ~/aish/main.lua`
|
||||
from somewhere else.
|
||||
|
||||
---
|
||||
|
||||
## 11. Planned Phase Sequence
|
||||
|
||||
Reference in New Issue
Block a user