summaryrefslogtreecommitdiff
path: root/spec/fake_ext.lua
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-08-17 23:35:36 -0600
committert <t@tjp.lol>2026-08-18 00:40:46 -0600
commit372ef8ff40991644ec2654c61328f31779f4ad21 (patch)
tree9bc69a578995e14f154202badcdbe0021a39c467 /spec/fake_ext.lua
parent7f8fdd8e868fb5fad71eacdf0c4fd0a97fe9c6ee (diff)
Validation-pass fixes; DESIGN.md describes the shipped seam
jobs: a child whose wake pipe cannot be armed is refused up front instead of started into a state nothing can wake (the luv-less drain loop survives only for hosts without a loop); a closing child keeps its concurrency slot and its id's exclusivity until the pump actually exits, so teardown can no longer over-admit new children or let two turns share one session file. Resume-metadata reads honor the plain-error contract on a malformed store. workflow: the built-in schema subset validator is the only validator — the jsonschema probe made behavior depend on an undeclared rock (see rockspec: that dependency is deliberately rejected); dead exports and the unreachable half of the structured-output guard are gone, keeping the empty-arguments provider case. DESIGN.md's seam sections now describe the shipped division: binding-level async jobs and tool control, host-level resolve_model/ExtHost/turn events/ component handles, rock-level policy; protocol bodies run to completion on the loop thread and cannot yield, cancellation is scoped to the stream that opened it, and a child's compaction leaves protocol sessions alone.
Diffstat (limited to 'spec/fake_ext.lua')
-rw-r--r--spec/fake_ext.lua35
1 files changed, 19 insertions, 16 deletions
diff --git a/spec/fake_ext.lua b/spec/fake_ext.lua
index 5ec4c06..dfdfdb3 100644
--- a/spec/fake_ext.lua
+++ b/spec/fake_ext.lua
@@ -32,11 +32,12 @@
--
-- Settling. There is no event loop here, so a fake job settles on the Nth call
-- to `job:result()`: `settle = N`, lowest first, which is the same ordering key
--- the previous fake used for "first" awaits. `uv.pipe()` fails in this harness
--- (see the stub below), so the job machinery takes its fd-less path and drains
--- its jobs in place; that is what turns those polls into progress and keeps the
--- specs plain assert scripts. `request_cancel` settles the next poll as
--- cancelled, exactly like the binding's pump.
+-- the previous fake used for "first" awaits. Real wake pipes are opened and
+-- polled (the job machinery refuses to start a child without one), but nothing
+-- ever runs the loop and nothing writes a wake byte; the specs call await from
+-- a plain script, which cannot park, so awaiting drains its jobs in place and
+-- those polls are what turn into progress. `request_cancel` settles the next
+-- poll as cancelled, exactly like the binding's pump.
--
-- Everything the host was asked to do is recorded on the returned handle:
-- `spawns` (one record per child agent, in creation order, carrying the
@@ -52,21 +53,17 @@ local M = {}
-- luv stand-in, installed once when this module loads
-- ---------------------------------------------------------------------------
--- The harness has no event loop, so it has no pipes: `uv.pipe()` fails and the
--- job machinery falls back to draining in place, which is the same path a host
--- without luv takes. `fs_mkdir` is recorded rather than performed, so a spec can
--- assert which directories a child store would need without touching the disk.
--- Everything else delegates to the real luv, so the filesystem cases are
--- unaffected. This has to happen at load time, not inside install(), because a
--- module that resolves luv once at load would otherwise capture the real one.
+-- `fs_mkdir` is recorded rather than performed, so a spec can assert which
+-- directories a child store would need without touching the disk. Everything
+-- else — pipes included — delegates to the real luv, so a spec exercises the
+-- same wake-pipe arming production does. This has to happen at load time, not
+-- inside install(), because a module that resolves luv once at load would
+-- otherwise capture the real one.
local made_dirs = {}
do
local ok, real = pcall(require, "luv")
if ok and type(real) == "table" then
package.loaded.luv = setmetatable({
- pipe = function()
- return nil, "the spec harness provides no pipes"
- end,
fs_mkdir = function(path)
made_dirs[#made_dirs + 1] = path
return true
@@ -162,7 +159,9 @@ conv_mt.__index = conv_mt
conv_mt.__name = "fake.conversation"
-- scripted = array of { role =, text = | blocks =, metadata = }. `record`, when
--- given, is the child record seeded system messages are mirrored onto.
+-- given, is the child record seeded system messages are mirrored onto. A
+-- scripted message may instead carry `metadata_error =`, which is how the
+-- binding reports a stored record it cannot decode: by raising.
local function new_conversation(scripted, record)
local messages = {}
for index, message in ipairs(scripted or {}) do
@@ -170,6 +169,7 @@ local function new_conversation(scripted, record)
role = message.role or "user",
blocks = message.blocks or { { type = "text", text = message.text or "" } },
metadata = message.metadata,
+ metadata_error = message.metadata_error,
}
end
return setmetatable({ _messages = messages, _record = record }, conv_mt)
@@ -194,6 +194,9 @@ function conv_mt:message_metadata(index)
if message == nil then
return nil
end
+ if message.metadata_error then
+ error("panto: " .. message.metadata_error, 2)
+ end
return message.metadata
end