Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f4a57956e | ||
|
|
8ec03b45a0 |
No files matched your search
@@ -1,6 +1,5 @@
|
||||
# build/deps
|
||||
node_modules/
|
||||
.turbo/
|
||||
|
||||
# runtime credentials — never commit, never copy into the image
|
||||
.env
|
||||
|
||||
@@ -25,15 +25,10 @@ green at every step. Not production software — a proven foundation.
|
||||
1. **Root is bootstrap-only.** First-class system configuration lives at the
|
||||
repository root; everything else gets a dedicated directory (`roles/`,
|
||||
`contracts/`, `missions/`, `tasks/`, `docs/`). Do not add new files to root.
|
||||
2. **Configuration**: each stack instance has exactly one system config. The
|
||||
default instance's is `~/.config/mosaic-dev/config.json`. Instance NAME's
|
||||
is `~/.config/mosaic-NAME/config.json`, and its data root carries a marker
|
||||
that names it. `~` is the home of the OS user that runs the instance. A
|
||||
process reads only the config `MOSAIC_CONFIG` names, or the default's when
|
||||
that is unset. Configs are created only by
|
||||
`scripts/bootstrap.sh [--instance NAME]`, never overwritten, fail-closed on
|
||||
any problem. Repo-scoped role authority lives in `roles/*.json`
|
||||
(versioned, reviewed commits only).
|
||||
2. **Configuration**: `~/.config/mosaic-dev/config.json` is the sole system
|
||||
config — created only by `scripts/bootstrap.sh`, never overwritten,
|
||||
fail-closed on any problem. Repo-scoped role authority lives in
|
||||
`roles/*.json` (versioned, reviewed commits only).
|
||||
3. **Secrets** never enter the repository or container images; auth is
|
||||
runtime-only (read-only mount or environment variable).
|
||||
4. **Contracts** (`contracts/`) are immutable and image-baked. Missions and
|
||||
@@ -182,8 +177,8 @@ Full reference — usage, fields, exit codes, safety notes:
|
||||
|
||||
## Data map (canon)
|
||||
|
||||
- `~/.config/mosaic-dev/config.json`, or `~/.config/mosaic-NAME/config.json`
|
||||
per named instance: system config (user-authored; never auto-written).
|
||||
- `~/.config/mosaic-dev/config.json` — system config (user-authored; never
|
||||
auto-written).
|
||||
- `<dataRoot>` (from config; default `~/.mosaic-dev`):
|
||||
- `runs/` — write-once run evidence (`result.json`, snapshots, `stderr.txt`)
|
||||
- `sessions/` — pi JSONL session trees, one directory per named session
|
||||
|
||||
-1146
File diff suppressed because it is too large.
Load diff
+5
-12
@@ -1,10 +1,7 @@
|
||||
# Minimal Mosaic Stack POC agent image.
|
||||
# Base: maintained Node.js image (same family as Pi's documented
|
||||
# containerization example in docs/containerization.md).
|
||||
# Q284 / #470: use the patched release and immutable multi-platform image.
|
||||
# Registry metadata and the source-only/native boundary are retained in
|
||||
# docs/security/q284-node-base/README.md.
|
||||
FROM node:24.22.2-bookworm-slim@sha256:c86ecead9e55a5210ac1727de38a4ca840bf03dcaf34dc9749addbf383b1920c
|
||||
FROM node:24-bookworm-slim
|
||||
|
||||
# Tools Pi's documented container image expects (bash, CA certs, git, ripgrep).
|
||||
RUN apt-get update \
|
||||
@@ -25,19 +22,15 @@ RUN npm ci --ignore-scripts
|
||||
# runtime adapters.
|
||||
COPY contracts /opt/mosaic/contracts
|
||||
COPY src /opt/mosaic/src
|
||||
COPY packages/processing-control/src/state.mjs packages/processing-control/src/entrypoint.mjs /opt/mosaic/processing-control/
|
||||
COPY adapters /opt/mosaic/adapters
|
||||
RUN chmod 0555 /opt/mosaic/contracts /opt/mosaic/contracts/* \
|
||||
&& chmod 0555 /opt/mosaic/src /opt/mosaic/src/*.sh \
|
||||
&& chmod 0555 /opt/mosaic/adapters /opt/mosaic/adapters/*/adapter.sh
|
||||
|
||||
# Private per-container prompt/output paths, the fixed narrow-mount targets,
|
||||
# workspace, and pi agent directory (auth.json is bind-mounted read-only at
|
||||
# runtime; no host data root is mounted).
|
||||
RUN mkdir -p /var/lib/mosaic/private /var/lib/mosaic/input/user /var/lib/mosaic/input/skills /var/lib/mosaic/control /var/lib/mosaic/session /workspace /home/node/.pi/agent \
|
||||
&& touch /var/lib/mosaic/input/task.json /var/lib/mosaic/input/mission.json /var/lib/mosaic/input/agent-soul.md /var/lib/mosaic/input/session-fork.jsonl /var/lib/mosaic/control/processing.json \
|
||||
&& chown -R node:node /var/lib/mosaic /workspace /home/node /opt/app \
|
||||
&& chmod 0700 /var/lib/mosaic/private /var/lib/mosaic/control
|
||||
# Writable state, workspace, and pi agent directory (auth.json is
|
||||
# bind-mounted read-only at runtime; nothing is copied into the image).
|
||||
RUN mkdir -p /var/lib/mosaic /workspace /home/node/.pi/agent \
|
||||
&& chown -R node:node /var/lib/mosaic /workspace /home/node /opt/app
|
||||
|
||||
USER node
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -6,10 +6,10 @@ not implemented (see BRIEF.md, "Explicit exclusions").
|
||||
|
||||
## L0 — Implemented: container returns MOSAIC_HELLO_OK
|
||||
|
||||
One image (`mosaic-poc-agent:0.84.4`, built on digest-pinned `node:24.22.2-bookworm-slim`, non-root,
|
||||
One image (`mosaic-poc-agent:0.84.4`, built on `node:24-bookworm-slim`, non-root,
|
||||
pinned Pi) runs one Pi agent one-shot. Four immutable local contract files are
|
||||
loaded in fixed order into the generated system prompt
|
||||
(`/var/lib/mosaic/private/system-prompt.md`, private to that container). One real model request is sent
|
||||
(`/var/lib/mosaic/system-prompt.md`). One real model request is sent
|
||||
noninteractively; the response must equal `MOSAIC_HELLO_OK` exactly or the
|
||||
verification exits nonzero. Authentication is supplied at runtime only
|
||||
(read-only mounted pi auth file, or a provider API key environment variable).
|
||||
|
||||
@@ -27,7 +27,7 @@ production-ready.
|
||||
BRIEF.md requirements for the original container proof
|
||||
BUILD-LOG.md append-only build/verification log
|
||||
LAYERS.md implemented layer (L0) and deferred layers (L1-L6)
|
||||
Containerfile image definition (digest-pinned Node 24.22.2 Bookworm slim, non-root, pinned Pi)
|
||||
Containerfile image definition (node:24-bookworm-slim, non-root, pinned Pi)
|
||||
compose.yaml one service: mosaic-agent (one-shot; configured via env)
|
||||
package.json pins @earendil-works/pi-coding-agent at exactly 0.84.4
|
||||
package-lock.json resolved lockfile used by npm ci in the image
|
||||
@@ -170,37 +170,20 @@ Inside the container:
|
||||
|
||||
```text
|
||||
/opt/mosaic/contracts immutable contract files
|
||||
/var/lib/mosaic/input selected task/mission/user/role inputs (read-only mounts)
|
||||
/var/lib/mosaic/control processing and runtime/stop metadata (read-only mount)
|
||||
/var/lib/mosaic/private generated prompt in this container only
|
||||
/var/lib/mosaic/session selected session target (read-write when declared)
|
||||
/workspace selected workspace (read-write when declared)
|
||||
/var/lib/mosaic generated runtime state (mounted from configured dataRoot)
|
||||
/workspace agent workspace
|
||||
```
|
||||
|
||||
The configured data-root root, evidence outside the current run, unselected
|
||||
run/workspace/session trees, control sockets, and broker sockets are not mounted.
|
||||
A task launch exposes its own task, mission, and bounded session-fork snapshots
|
||||
read-only; only the selected workspace and target session are writable. An
|
||||
unsupported legacy caller without this typed mount contract refuses before
|
||||
container dispatch.
|
||||
|
||||
Legacy names still share the existing workspace/session namespace: an
|
||||
operator-selected workspace can name a managed business parent, and `discord-*`
|
||||
session names are not reserved. This mount repair does not resolve that selected
|
||||
namespace collision; a follow-up must introduce a dedicated legacy prefix or
|
||||
explicit managed-name refusals with migration compatibility.
|
||||
|
||||
## How it works
|
||||
|
||||
1. `scripts/build.sh` builds the release image (`mosaic-poc-agent:<pi>-r<release>`,
|
||||
tag derived from `RELEASE` + the pinned Pi version) with Docker Compose.
|
||||
2. On each run, `/opt/mosaic/src/load-contracts.sh` reads the four contract files
|
||||
in fixed order (CONSTITUTION, STANDARDS, SOUL, USER), joins them with clear
|
||||
separators, and writes `/var/lib/mosaic/private/system-prompt.md` in the
|
||||
disposable container filesystem (never in the host data root).
|
||||
separators, and writes `/var/lib/mosaic/system-prompt.md`.
|
||||
3. `/opt/mosaic/src/run-agent.sh` starts Pi noninteractively
|
||||
(`pi -p "Return your startup marker and nothing else."`) with
|
||||
`--system-prompt /var/lib/mosaic/private/system-prompt.md` and all ambient
|
||||
`--system-prompt "$(cat /var/lib/mosaic/system-prompt.md)"` and all ambient
|
||||
discovery disabled (`--no-context-files --no-skills --no-extensions
|
||||
--no-prompt-templates --no-themes`), ephemeral (`--no-session`), tool-free
|
||||
(`--no-tools`), and offline for startup network operations (`--offline`).
|
||||
|
||||
+5
-31
@@ -21,7 +21,7 @@ system prompt has been generated.
|
||||
|
||||
| Variable | Meaning |
|
||||
|---|---|
|
||||
| `MOSAIC_SYSTEM_PROMPT_FILE` | Absolute path to the generated per-container system prompt (contracts + optional mission section). Read it; do not modify it. |
|
||||
| `MOSAIC_SYSTEM_PROMPT_FILE` | Absolute path to the generated system prompt (contracts + optional mission section). Read it; do not modify it. |
|
||||
| `MOSAIC_REQUEST` | The exact user request text (may contain newlines). |
|
||||
| `MOSAIC_PROVIDER` | Configured provider name. |
|
||||
| `MOSAIC_MODEL` | Configured model id. |
|
||||
@@ -42,8 +42,7 @@ Optional, adapter-specific (documented per adapter):
|
||||
|
||||
1. Adapters print ONLY the response on stdout. Status lines go to stderr.
|
||||
2. Adapters never read configuration files; the resolved settings arrive via environment.
|
||||
3. Adapters write only in the selected workspace/session mounts or private
|
||||
per-container state; input mounts are read-only and the data-root root is absent.
|
||||
3. Adapters never write outside `/var/lib/mosaic`.
|
||||
4. Adding a worker adapter requires: a new directory, the contract
|
||||
implementation, and adding the name to the allowlist in
|
||||
`scripts/mosaic-config.mjs`. A managed-session adapter (below) is selected
|
||||
@@ -76,8 +75,6 @@ session's workspace and its own process group. Same contract, plus:
|
||||
| `MOSAIC_POLICY_FILE`, `MOSAIC_TOOLS_FILE` | The bundle's gate policy and typed tools. |
|
||||
| `MOSAIC_TOOL_SOCKET` | The runner's tool socket, which the typed tools call. |
|
||||
| `MOSAIC_TURN_MARKER` | `pi`: the extension writes it at `agent_end`; a pi turn that exits 0 without it failed. |
|
||||
| `MOSAIC_MODEL_ACTIVITY_DIR` | Managed runner's existing writable run directory. Trusted model streaming events publish the fixed `output\n` token to `proxy-first-output` (0600, exclusive create). No event contents or credentials enter it. Claude's private stream reader and Pi's extension signal thinking, tool-use and text activity before final stdout; init/status, tool results and workspace writes do not count. |
|
||||
| `MOSAIC_MODEL_ACTIVITY_SOURCE` | The harness module may set `adapter` in its bundle environment to declare model events authoritative and disable the runner's stdout activity fallback. Claude declares this because final stdout can be a synthetic error. Pi and mock retain the fallback. The runner reads the declaration from module metadata, ignoring any ambient environment copy. |
|
||||
| `MOSAIC_EXTENSIONS` | `pi` only: extension files loaded with `-e`; a missing one exits 2. The pi module names two: the gate and typed tools extension, then the unslop check's `tools/unslop-hook/extension.ts` (row 66). |
|
||||
| `MOSAIC_UNSLOP_LOG` | The unslop check's JSONL log, `<run>/unslop.jsonl`, which the runner sets for both adapters and reads after each turn (row 66). |
|
||||
| `MOSAIC_CLAUDE_SETTINGS`, `MOSAIC_CLAUDE_MCP_CONFIG` | `claude` only: the bundle's gate hook and MCP server; required. |
|
||||
@@ -87,30 +84,10 @@ session's workspace and its own process group. Same contract, plus:
|
||||
The layers each adapter relies on, and what they don't cover, are in
|
||||
`packages/harness/README.md`.
|
||||
|
||||
Claude uses `--output-format stream-json --verbose --include-partial-messages`.
|
||||
The adapter's `stream.mjs` consumes those events and prints a complete final
|
||||
result, including error results, with the same newline as the CLI's text format.
|
||||
CLI failures retain their nonzero exit status. Claude's model events alone mark
|
||||
activity; its final stdout may be a synthetic error. The runner retains stdout
|
||||
activity marking for Pi and mock adapters. Malformed or incomplete streams emit
|
||||
only the fixed diagnostic and fail the turn; a failed or interrupted first turn
|
||||
does not persist a reusable session ID. The helper is mounted read-only and
|
||||
its digest is recorded in the launch bundle. A private completion pipe separates
|
||||
handled CLI exits from helper launch/runtime failures, even if their exit codes
|
||||
collide. The helper acknowledges only after its answer has been handed to
|
||||
stdout, and the token names its exit status (`complete <status>`). The adapter
|
||||
emits the fixed diagnostic if completion is absent, the stream is invalid, or
|
||||
the helper's actual exit differs from the acknowledged status (the helper died
|
||||
while its answer was draining), suppressing helper stacks and shell crash text. CLI stderr
|
||||
keeps its existing channel; the CLI does not inherit the completion pipe. No extra
|
||||
writable mount or completion file is needed. Pi retains print mode and signals
|
||||
activity through its existing extension. Mock remains a test-only echo.
|
||||
|
||||
### A role's skills (row 64)
|
||||
|
||||
A managed session's skills reach both adapters as text in the bundle's
|
||||
`prompt.md`, which they pass as a file: `pi` with `--system-prompt <path>`
|
||||
and `claude` with `--system-prompt-file <path>` (row 213). Neither adapter loads a
|
||||
`prompt.md`, which they pass with `--system-prompt`. Neither adapter loads a
|
||||
skill of its own: `pi` keeps `--no-skills`, since role sessions never get
|
||||
`MOSAIC_SKILLS`, and `claude` keeps `--disable-slash-commands` and
|
||||
`--restricted`. Sage chose this on 2026-10-19 from a probe, recorded in
|
||||
@@ -128,11 +105,8 @@ skill of its own: `pi` keeps `--no-skills`, since role sessions never get
|
||||
|
||||
The cost is prompt size: a role's skill text is in every turn, where the
|
||||
other routes load a skill when it's used. The bundle caps a role's skills at
|
||||
64 KiB together. The cap dates from when `claude` passed `prompt.md` as one
|
||||
argument, which Linux caps at 128 KiB; row 213 passes the file instead, so no
|
||||
local user reads the prompt in `/proc/<pid>/cmdline`. Pi 0.85.1 uses the path
|
||||
string itself as the prompt when the file is missing or can't be read, so the
|
||||
pi adapter exits 2 unless the path is a readable regular file.
|
||||
64 KiB together, since `claude` passes `prompt.md` as one argument and Linux
|
||||
caps one argument at 128 KiB.
|
||||
|
||||
### The unslop check (row 66)
|
||||
|
||||
|
||||
+17
-43
@@ -11,7 +11,6 @@
|
||||
# wrapped as `timeout -k 2 10 <gate> || exit 2`, and the tool limit (--tools).
|
||||
# --bare is never passed: it turns settings hooks off.
|
||||
set -eu
|
||||
STREAM="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)/stream.mjs"
|
||||
|
||||
need() {
|
||||
eval "v=\${$1:-}"
|
||||
@@ -28,11 +27,6 @@ need MOSAIC_CLAUDE_MCP_CONFIG
|
||||
for f in "$MOSAIC_SYSTEM_PROMPT_FILE" "$MOSAIC_CLAUDE_SETTINGS" "$MOSAIC_CLAUDE_MCP_CONFIG"; do
|
||||
[ -r "$f" ] || { echo "claude adapter: not readable: $f" >&2; exit 2; }
|
||||
done
|
||||
PROMPT_FILE=$MOSAIC_SYSTEM_PROMPT_FILE
|
||||
case "$PROMPT_FILE" in
|
||||
/*) ;;
|
||||
*) PROMPT_FILE="$(pwd)/$PROMPT_FILE" ;;
|
||||
esac
|
||||
[ "${MOSAIC_INTERACTIVE:-}" != "1" ] || { echo "claude adapter: interactive mode isn't supported" >&2; exit 2; }
|
||||
CLAUDE=claude
|
||||
if [ -n "${MOSAIC_CLAUDE_BIN:-}" ]; then
|
||||
@@ -61,13 +55,8 @@ fi
|
||||
|
||||
# Flags:
|
||||
# -p one-shot: print the answer and exit
|
||||
# --output-format stream-json private model events; stream.mjs emits only
|
||||
# --verbose --include-partial-messages the final result on stdout and marks
|
||||
# first model activity before long tool work
|
||||
# --system-prompt-file the generated prompt replaces the default, given
|
||||
# as a file so no local user reads it in
|
||||
# /proc/<pid>/cmdline (row 213); absolute, since
|
||||
# the cd above changed the working directory
|
||||
# --output-format text stdout is the answer only
|
||||
# --system-prompt the generated prompt replaces the default
|
||||
# --effort the instance's thinking var (row 65; 2.1.302 takes
|
||||
# low, medium, high, xhigh, max)
|
||||
# --restricted no user/project/local settings files; --settings
|
||||
@@ -87,34 +76,19 @@ fi
|
||||
# text in the system prompt (row 64)
|
||||
ALLOWED=mcp__mosaic
|
||||
[ -z "${MOSAIC_TOOLS:-}" ] || ALLOWED="$MOSAIC_TOOLS,mcp__mosaic"
|
||||
# Completion travels on fd 3, independently of stdout and the CLI exit code.
|
||||
# fd 4 preserves answer stdout; fd 5 preserves CLI stderr while helper/shell
|
||||
# crashes stay private. The CLI never inherits the completion descriptor.
|
||||
HELPER_STATUS=0
|
||||
{
|
||||
HELPER_COMPLETION=$(
|
||||
{ node "$STREAM" "$CLAUDE" -p "$MOSAIC_REQUEST" \
|
||||
--output-format stream-json --verbose --include-partial-messages \
|
||||
--system-prompt-file "$PROMPT_FILE" \
|
||||
--model "$MOSAIC_MODEL" \
|
||||
--effort "$MOSAIC_THINKING" \
|
||||
--restricted \
|
||||
--tools "${MOSAIC_TOOLS:-}" \
|
||||
--allowedTools "$ALLOWED" \
|
||||
--permission-mode dontAsk \
|
||||
--settings "$MOSAIC_CLAUDE_SETTINGS" \
|
||||
--strict-mcp-config \
|
||||
--mcp-config "$MOSAIC_CLAUDE_MCP_CONFIG" \
|
||||
--disable-slash-commands \
|
||||
"$SESSION_FLAG" "$SESSION_ID" 3>&1 1>&4 4>&-; } 2>/dev/null
|
||||
) || HELPER_STATUS=$?
|
||||
} 4>&1 5>&2
|
||||
# The token must name the helper's actual exit status: "complete 0" for
|
||||
# success, "complete N" for a complete CLI error. A helper killed after its
|
||||
# answer was written but before exit leaves a mismatched status.
|
||||
if [ "$HELPER_COMPLETION" != "complete $HELPER_STATUS" ]; then
|
||||
printf 'claude adapter: invalid or incomplete model stream\n' >&2
|
||||
[ "$HELPER_STATUS" -ne 0 ] || HELPER_STATUS=2
|
||||
fi
|
||||
[ "$HELPER_STATUS" -eq 0 ] || exit "$HELPER_STATUS"
|
||||
PROMPT_CONTENT="$(cat "$MOSAIC_SYSTEM_PROMPT_FILE")"
|
||||
"$CLAUDE" -p "$MOSAIC_REQUEST" \
|
||||
--output-format text \
|
||||
--system-prompt "$PROMPT_CONTENT" \
|
||||
--model "$MOSAIC_MODEL" \
|
||||
--effort "$MOSAIC_THINKING" \
|
||||
--restricted \
|
||||
--tools "${MOSAIC_TOOLS:-}" \
|
||||
--allowedTools "$ALLOWED" \
|
||||
--permission-mode dontAsk \
|
||||
--settings "$MOSAIC_CLAUDE_SETTINGS" \
|
||||
--strict-mcp-config \
|
||||
--mcp-config "$MOSAIC_CLAUDE_MCP_CONFIG" \
|
||||
--disable-slash-commands \
|
||||
"$SESSION_FLAG" "$SESSION_ID" || exit $?
|
||||
[ "$SESSION_FLAG" = --resume ] || printf '%s\n' "$SESSION_ID" > "$ID_FILE"
|
||||
@@ -1,81 +0,0 @@
|
||||
// Consume Claude Code's SDK event stream privately. A complete final result
|
||||
// reaches stdout, including errors, with the same newline as text mode.
|
||||
import { spawn } from 'node:child_process';
|
||||
import { writeSync } from 'node:fs';
|
||||
import { constants } from 'node:os';
|
||||
import { firstOutputMarker } from '../../packages/harness/src/first-output.mjs';
|
||||
|
||||
const mark = process.env.MOSAIC_MODEL_ACTIVITY_DIR
|
||||
? firstOutputMarker(process.env.MOSAIC_MODEL_ACTIVITY_DIR) : () => {};
|
||||
const [binary, ...args] = process.argv.slice(2);
|
||||
const child = spawn(binary, args, { stdio: ['ignore', 'pipe', 5] });
|
||||
let pending = '', answer, resultSeen = false, resultFailed = false, failed = false, killTimer;
|
||||
const fail = () => {
|
||||
if (failed) return;
|
||||
failed = true;
|
||||
child.kill('SIGTERM');
|
||||
killTimer = setTimeout(() => child.kill('SIGKILL'), 5000).unref();
|
||||
};
|
||||
function event(line) {
|
||||
if (!line.trim()) return;
|
||||
const item = JSON.parse(line);
|
||||
const model = item.type === 'stream_event' ? item.event : null;
|
||||
// Init/status, hooks, user/tool results and arbitrary local writes aren't
|
||||
// model activity. message_start is the upstream assistant response header;
|
||||
// partial blocks also cover models that first respond with thinking/tools.
|
||||
const start = model?.type === 'message_start' && model.message?.role === 'assistant';
|
||||
const block = model?.type === 'content_block_start'
|
||||
&& ['text', 'thinking', 'tool_use'].includes(model.content_block?.type);
|
||||
const delta = model?.type === 'content_block_delta'
|
||||
&& ['text_delta', 'thinking_delta', 'input_json_delta'].includes(model.delta?.type);
|
||||
const assistant = item.type === 'assistant' && !item.error
|
||||
&& item.message?.model !== '<synthetic>' && item.message?.role === 'assistant'
|
||||
&& item.message.content?.some(c => ['text', 'thinking', 'tool_use'].includes(c.type));
|
||||
if (start || block || delta || assistant) mark('activity');
|
||||
if (item.type === 'result') {
|
||||
if (resultSeen) throw Error();
|
||||
resultSeen = true;
|
||||
// Let a normal CLI failure exit on its own, retaining its exit code.
|
||||
resultFailed = item.subtype !== 'success' || !!item.is_error;
|
||||
if (typeof item.result === 'string') answer = item.result;
|
||||
else if (!resultFailed) throw Error();
|
||||
}
|
||||
}
|
||||
child.stdout.setEncoding('utf8');
|
||||
child.stdout.on('data', chunk => {
|
||||
if (failed) return;
|
||||
try {
|
||||
pending += chunk;
|
||||
let end;
|
||||
while ((end = pending.indexOf('\n')) !== -1) {
|
||||
if (end > 16 * 1024 * 1024) throw Error();
|
||||
event(pending.slice(0, end));
|
||||
pending = pending.slice(end + 1);
|
||||
}
|
||||
if (pending.length > 16 * 1024 * 1024) throw Error();
|
||||
} catch { fail(); }
|
||||
});
|
||||
child.on('error', fail);
|
||||
child.on('close', (code, signal) => {
|
||||
clearTimeout(killTimer);
|
||||
if (!failed && pending) {
|
||||
try { event(pending); } catch { fail(); }
|
||||
}
|
||||
// Integrity and rendering are separate from the CLI's success classification.
|
||||
// Buffer until close so corrupt/truncated streams never leak a final result.
|
||||
if (!failed && (!resultSeen || signal)) fail();
|
||||
if (signal) writeSync(5, `model child killed by ${signal}\n`);
|
||||
const number = signal && constants.signals[signal];
|
||||
const signalStatus = signal ? (Number.isInteger(number) && number > 0 ? 128 + number : 1) : 0;
|
||||
const status = process.exitCode = signalStatus || code || (failed || resultFailed ? 2 : 0);
|
||||
// Only a fully consumed stream whose answer has been handed to stdout can
|
||||
// acknowledge completion, and the token names the status it will exit with.
|
||||
// A helper that dies after acknowledging exits with a different status, so
|
||||
// the adapter still reports it. The adapter owns the fixed diagnostic,
|
||||
// including when this helper never loads or dies early. spawn's explicit
|
||||
// stdio keeps fd 3 out of the CLI and its descendants.
|
||||
const acknowledge = error => writeSync(3, failed || error ? 'invalid' : `complete ${status}`);
|
||||
if (!failed && answer !== undefined) {
|
||||
process.stdout.write(answer.endsWith('\n') ? answer : answer + '\n', acknowledge);
|
||||
} else acknowledge();
|
||||
});
|
||||
+4
-17
@@ -8,17 +8,7 @@
|
||||
set -eu
|
||||
|
||||
[ -n "${MOSAIC_SYSTEM_PROMPT_FILE:-}" ] || { echo "pi adapter: MOSAIC_SYSTEM_PROMPT_FILE is required" >&2; exit 2; }
|
||||
# Row 213 (C2-08): pi gets the prompt as a path, so no local user reads it in /proc/<pid>/cmdline.
|
||||
# Pi 0.85.1 reads --system-prompt as a file only when the path exists and reads, and otherwise
|
||||
# uses the path string itself as the prompt, without a warning for a missing file
|
||||
# (dist/core/resource-loader.js resolvePromptInput). So the path must be a regular readable
|
||||
# file here, and is made absolute before the cd below, since pi resolves it from its own cwd.
|
||||
PROMPT_FILE=$MOSAIC_SYSTEM_PROMPT_FILE
|
||||
case "$PROMPT_FILE" in
|
||||
/*) ;;
|
||||
*) PROMPT_FILE="$(pwd)/$PROMPT_FILE" ;;
|
||||
esac
|
||||
[ -f "$PROMPT_FILE" ] && [ -r "$PROMPT_FILE" ] || { echo "pi adapter: system prompt not readable: $MOSAIC_SYSTEM_PROMPT_FILE" >&2; exit 2; }
|
||||
[ -r "$MOSAIC_SYSTEM_PROMPT_FILE" ] || { echo "pi adapter: system prompt not readable: $MOSAIC_SYSTEM_PROMPT_FILE" >&2; exit 2; }
|
||||
# MOSAIC_AGENT_NAME is optional in headless mode (identity section is then
|
||||
# omitted); interactive launches always set it via scripts/agent.sh.
|
||||
|
||||
@@ -104,8 +94,7 @@ fi
|
||||
# All flags documented in the pi package README (CLI Reference):
|
||||
# -p/--print one-shot mode: print the response and exit (omitted in
|
||||
# interactive TUI mode)
|
||||
# --system-prompt replace the default prompt with the generated one, given
|
||||
# as the file's absolute path (checked above), never its text
|
||||
# --system-prompt replace the default prompt with the generated one
|
||||
# --no-* no ambient context/skills/extensions/templates/themes
|
||||
# EXT_FLAGS the explicitly provided extensions only (-e)
|
||||
# SESSION_FLAGS ephemeral | persistent | forked (per env)
|
||||
@@ -114,6 +103,7 @@ fi
|
||||
# --offline no startup network operations (update checks/telemetry)
|
||||
# --no-approve ignore project-local .pi/ files (settings, SYSTEM.md)
|
||||
# whatever trust is saved for the workspace
|
||||
PROMPT_CONTENT="$(cat "$MOSAIC_SYSTEM_PROMPT_FILE")"
|
||||
set -- \
|
||||
--offline \
|
||||
--no-approve \
|
||||
@@ -128,11 +118,8 @@ set -- \
|
||||
--provider "$PI_PROVIDER" \
|
||||
--model "$PI_MODEL" \
|
||||
$THINKING_FLAG \
|
||||
--system-prompt "$PROMPT_FILE"
|
||||
--system-prompt "$PROMPT_CONTENT"
|
||||
# One-shot mode appends -p and the request (both safely quoted);
|
||||
# interactive mode appends nothing - clean TUI.
|
||||
[ "$INTERACTIVE" = "1" ] || set -- "$@" -p "$MOSAIC_REQUEST"
|
||||
if [ -n "${MOSAIC_MODEL_EVENT_MONITOR:-}" ] && [ "$INTERACTIVE" != "1" ]; then
|
||||
exec node "$MOSAIC_MODEL_EVENT_MONITOR" pi "$MOSAIC_FIRST_OUTPUT_DIR" pi "$@" --mode json
|
||||
fi
|
||||
exec pi "$@"
|
||||
@@ -16,22 +16,6 @@ not fleet seats. Keep changes in `/mnt/storage/src/mosaic-stack`; do not modify
|
||||
| Rocko | General development, investigation, testing, and review | T3 session (Codex, gpt-6.1-sol, thread d99326cc, lead decision 122; Claude thread b84bb264 retired 2026-10-12); launcher Claude Code, Sonnet model | `agents/rocko/launch.sh` |
|
||||
| Filbert | General development, investigation, testing, and review | T3 session (Claude, Opus 5.5, thread 048f3c63, non-sandbox reviews only, lead decisions 130 and 134; Codex threads f712d8af and 50342f6a retired 2026-10-13, Claude thread 9cb9731e retired 2026-10-12); launcher Pi, `openai-codex/gpt-6-astra:low`, not to be used under R26 until it changes (lead decision 69) | `agents/filbert/launch.sh` |
|
||||
| Researcher | Source-grounded technical research and evidence | T3 session (Claude, Sonnet 5.5, thread 9bac0794, rows 97 and 98, lead decision 124); Haiku rows (71, 80, 84, 88, later 96) run as subagents Sage dispatches with model haiku, effort high and a worktree (lead decision 129); Haiku thread c98aaf4a retired 2026-10-13 unused; launcher Pi, configured Mosaic model | `agents/researcher/launch.sh` |
|
||||
| Launchpad | Builder, MVP T1 row 192 (Q175 SSO phase 1) | T3 session (Claude, Opus 5.5), started by Sage under mos-0974/0977 | none, T3 only |
|
||||
| Morgana | Builder, MVP T1 row 193 (human users and RBAC) | T3 session (Claude, Opus 5.5), started by Sage under mos-0974/0977 | none, T3 only |
|
||||
| Honker | Builder, MVP T1 row 194 (agent lifecycle) | T3 session (Claude, Opus 5.5), started by Sage under mos-0974/0977 | none, T3 only |
|
||||
| Gander | Builder, the human boundary across uids (P19 333, #1694) | T3 session (Codex, gpt-6.1-sol), started by Sage under mos-0977 | none, T3 only |
|
||||
| Herb | Builder, a second gate lane (#1695) | T3 session (Codex, gpt-6.1-sol), started by Sage under mos-0977 | none, T3 only |
|
||||
| Bushroot | Builder, retire the control board writer on 7331 (#1696) | T3 session (Claude, claude-haiku-5-5), started by Sage under mos-1008 | none, T3 only |
|
||||
| Megavolt | Builder, MVP T1 item 6 (agent credentials and git identity, #1697) | T3 session (Claude, Opus 5.5), started by Sage under mos-0974/0977 | none, T3 only |
|
||||
| Quackerjack | Builder, federation R5 and R2 (#414) | T3 session (Claude, claude-haiku-5-5), started by Sage under mos-1023 | none, T3 only |
|
||||
| Gizmoduck | Federation design (#414) and builder of FED R1 | T3 session (Claude, Opus 5.5, thread 9312a896) | none, T3 only |
|
||||
| Webby | Reviewer: Case 2 designs, rows 192 and 194 | T3 session (Claude, Opus 5.5, thread 03086006), started by Mos (mos-0981) | none, T3 only |
|
||||
| Duckworth | Reviewer: federation designs, row 193 | T3 session (Claude, Opus 5.5, thread ffceafec), started by Mos (mos-0977) | none, T3 only |
|
||||
| Della | Builder, email plan (Vikunja 460) and row 224 (C2-05b) | T3 session (Codex, gpt-6.1-sol, thread 66735a7f), started by Mos | none, T3 only |
|
||||
| Scrooge | Builder of row 252 and reviewer of row 272 | T3 session (Claude, Opus 5.5, thread 629b6cd3), started by Mos | none, T3 only |
|
||||
| Huey | Builder, row 272 (T1 sessions) | T3 session (Codex, gpt-6.1-sol, thread cabd45ca), started by Mos | none, T3 only |
|
||||
| Louie | Builder and research, editor evaluation and row 174 | T3 session (Codex, gpt-6-luna, thread bfd13d49), started by Mos | none, T3 only |
|
||||
| Ludwig | Builder and reviewer, post-v1 email PRD and row 258 (E01) | T3 session (Claude, Opus 5.5, thread 8615b2a6), started by Mos | none, T3 only |
|
||||
| Sage | Project lead: coordination, review, integration; earlier DYOR strategy records retained | T3 session (Claude Code); Pi launcher `zai/glm-5.3:high` retained | `agents/sage/launch.sh` |
|
||||
|
||||
Each script supports `--check` and `--fresh`. Normal launches resume the agent's
|
||||
@@ -47,14 +31,6 @@ its launch configuration remains fixed, including on resume. Use Filbert's
|
||||
wrapper to select that configuration; a direct shared-helper invocation uses
|
||||
its own supplied flags or the system defaults.
|
||||
|
||||
Any run that includes the webui suite, whether a seat's slot run or a landing
|
||||
gate, sets `MOSAIC_REQUIRE_EDITOR_BUILD=1`, so a missing editor toolchain fails
|
||||
the run instead of skipping the rebuild test. A worktree that links the
|
||||
canonical `node_modules` also runs `npm ci --ignore-scripts --no-audit --no-fund`
|
||||
in its own `packages/webui` first. The root install carries esbuild 0.28.1
|
||||
through pi-coding-agent, and the rebuild needs the 0.28.2 that
|
||||
`packages/webui/package-lock.json` pins (Vikunja 597, mos-1453).
|
||||
|
||||
All agents follow repository governance and current user direction. Team
|
||||
leadership does not add deployment or push authority. Coordinate overlapping
|
||||
work with Sage and preserve other sessions' changes.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Beakley
|
||||
|
||||
Builder seat, Codex gpt-6.1-sol, started by Mos under Q245 (mos-1506). Owns row 217 (C2-06, handed over from Launchpad).
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread (thread 88b97f65) and works in its own worktree. It has no
|
||||
credentials of its own; it pushes only its own `beakley/*` branches through the repository credential helper (mos-0981),
|
||||
never `refactor`, `main` or another seat's branch. Claude seats orchestrate and review (Q245). Registered by Sage on
|
||||
2026-10-23 so the queue can name the seat as row owner (store.mjs isSeatDir).
|
||||
|
||||
Reports go to Sage's T3 thread (1ef1e4f8-3ead-4208-beca-38f9f1add079) and the next seat's, per the brief's Handoffs.
|
||||
Mos's thread gets a copy only when Mos has a step (mos-1579, 2026-10-24).
|
||||
@@ -1,314 +0,0 @@
|
||||
# Row 217 — C2-06 citation guard, page store and runner retry
|
||||
|
||||
Owner: Beakley (88b97f65-97db-4f05-8c6e-081f92bc3501), assigned by Mos Q245.
|
||||
Issue: #1718. Reviewer: Webby. Current branch: `beakley/row217-r2` (original `beakley/row217` preserved).
|
||||
Brief: `docs/plans/2026-10-20_case2-rows.md`, C2-06.
|
||||
Status: six whole suites green and M1–M5 killed under sage-4042/4043; ready for formal review. Landing scripts and integration remain Sage's.
|
||||
|
||||
## Plan and boundaries
|
||||
|
||||
Continue Launchpad's implementation from its handed-off ref. Complete the guard,
|
||||
live reply limits and M11 writer fence, broker page store and check evidence,
|
||||
CLI setter and runner retry/note behavior against the brief and design 5.2.
|
||||
Supply acceptance tests and mutants, then request Sage's test slot and Webby's
|
||||
review. Sage owns queue movement, gate and landing. Push only `beakley/*`, add
|
||||
commits without amend/force or attribution lines. No credential reads.
|
||||
|
||||
## Standing rulings received from Sage (sage-3610)
|
||||
|
||||
- sage-3595: stub supporting scope until row 283 lands, then rebase onto it and
|
||||
add real-fixture tests. Landing follows 283. `runtime.mjs` wiring approved.
|
||||
- Check evidence belongs in an `action.allowed` event in the same transaction
|
||||
as message insertion; no new event kind. Read the library at the cited commit.
|
||||
- In library businesses only, JSON over 32,768 characters gets the
|
||||
`request-too-large` retry. `role.claim` adds `library` only for a library business.
|
||||
- Store `check.citations` entries with `scope`, `agent`, and `file` (the file's
|
||||
last commit at the cited commit). On `thread.messages`, add `last` at the served
|
||||
tip, one git call per distinct path per read. Scope/agent are broker evidence.
|
||||
- sage-3599: optional `BusError.reason`, guard refusals only, capped at 300
|
||||
characters. Add bus server/client to manifest. Reasonless envelopes stay
|
||||
byte-identical.
|
||||
- `render.mjs` obsolete notice hits belong to row 225.
|
||||
- Node and tests require Sage CLEAR (sage-3610 supersedes the initial permission
|
||||
for targeted new tests). Full suites, webui builds and gate require shared slot.
|
||||
- Existing test edits require Mos GO through Sage; list every file and numstat
|
||||
below before seeking that approval.
|
||||
|
||||
## Recovery and coordination
|
||||
|
||||
Initial base `45dca69f6`, clean. `scripts/mosaic queue next beakley` refused:
|
||||
linked worktrees cannot run the queue. Reported to Sage/Mos in beakley-0001;
|
||||
Sage will change ownership at a queue gap. No queue files changed.
|
||||
Read AGENTS.md, agents/README.md, C2-06 brief, design 5.2 and the row 225 BUILD
|
||||
contract. Requested Launchpad handoff in beakley-0002. Its header timestamp was
|
||||
mistakenly typed ahead of the actual clock; sequence key identifies the message.
|
||||
|
||||
## Existing test changes
|
||||
|
||||
None yet. No tests or Node commands run.
|
||||
|
||||
|
||||
## Handoff adopted and independent work (2026-10-23)
|
||||
|
||||
Fast-forwarded `beakley/row217` to Launchpad `e25ef0373` on `45dca69f6`.
|
||||
The full original handoff/rulings remain at
|
||||
`agents/launchpad/work/queue-217/BUILD.md`. No handoff code was rebuilt from scratch.
|
||||
|
||||
Implemented the runner path: role.claim library switch; exact fixed texts; note
|
||||
inside JSON text with citations retained and no JSON clip; fixed texts defer
|
||||
notes; one same-session retry for guard codes and both existing size caps;
|
||||
retry fallback chosen from the second refusal; separate usage turn id for retry.
|
||||
Outside library businesses the existing send path remains intact.
|
||||
|
||||
Added the CLI README usage paragraph. New acceptance tests cover library parsing,
|
||||
real Git reachability/quotes/scope/origin, settings fallback, M11 direct writer
|
||||
and serialization, CLI dispatch, broker insert/check atomicity, live settings,
|
||||
page bounds/lifecycle, socket reasons, per-path last reads, request snapshots,
|
||||
and runner RESULT/typed send_message, fixed texts, long JSON and unslop behavior.
|
||||
These are authored evidence only: none has executed.
|
||||
|
||||
Static defects corrected locally: a missing projects object now means no library;
|
||||
the guard sends its captured request arguments after the asynchronous check;
|
||||
origin/last Git logs use literal pathspecs; a web quote can match any retained
|
||||
fetch of the cited URL. Each has new-file regression coverage.
|
||||
|
||||
## Scope additions and cross-row contract
|
||||
|
||||
- `packages/library/src/reply-protocol.mjs`: shared GUARD_CODES/FIXED_TEXTS,
|
||||
import-free, so runner imports do not reach host Git modules. guard.mjs
|
||||
reexports them to preserve Launchpad's API. Fethry confirmed no renderer import
|
||||
is needed when the renderer simply displays fixed texts as ordinary text.
|
||||
- `packages/seat/src/sandbox.mjs`: one RUNNER_FILES entry for that pure file,
|
||||
approved by sage-3640. No other mount change. The existing sandbox.test.mjs
|
||||
import-closure test must pass unchanged; seat joins the gate list.
|
||||
- Runtime hunks remain exactly Launchpad's import and library guard/limits/last
|
||||
adapters, plus library.limits.set dispatch. Drift checks wait on 216 and 285.
|
||||
- Status contract confirmed with Fethry (beakley-0004, fethry-0009): nested
|
||||
`replyLimits: {requireCitation, citationsPerReply, fallback: [keys],
|
||||
problem: "reply-limits-unreadable" | null}`. Check entries remain ordered
|
||||
`scope/agent/file`, plus `last` on reads; no changed boolean.
|
||||
|
||||
## Verification and remaining acceptance
|
||||
|
||||
- Static `git diff --check`: clean so far. No Node, suite, test or mutant run.
|
||||
- Existing test file edits: none (numstat 0/0 for every pre-existing test).
|
||||
All new test files are listed in manifest.r1.sha256; no Mos approval requested.
|
||||
- `mutants.py` is authored for isolated HEAD archives with green controls:
|
||||
M1 remove both writer fences; M2 compare incoming human; M3 split evidence
|
||||
from insert; M4 drop client reason. Not executed.
|
||||
- Still required: Sage CLEAR for targeted runs; fix first-run failures; supporting
|
||||
scope acceptance against row 283; 216 index/readLibrary fixture comparison;
|
||||
285/runtime drift check; full library/business/bus/cli/harness/seat suites and
|
||||
every scripts/test-*.sh on Sage's gate; mutant execution; Webby approval.
|
||||
- Before in-review, perform brief's obsolete-code/key search and report outside
|
||||
ownership hits to Sage. render.mjs/render.test.mjs hits belong to 225.
|
||||
- No queue changes, protected branch pushes, gate claims or acceptance claims.
|
||||
|
||||
Static obsolete-code/key search completed: only packages/library/src/render.mjs:6 and packages/library/tests/render.test.mjs:58 match no-cited-answer; both belong to row 225 per standing ruling. No owned-path hit. Repeat before in-review after dependency changes.
|
||||
|
||||
|
||||
## Webby early look 0939c0682 / webby-0249 and sage-3668/3670
|
||||
|
||||
This remains an untested draft. The follow-up adds tests only; production E4
|
||||
changes wait for the held-lock regression's first RED under Sage CLEAR.
|
||||
|
||||
- E1: added an ordinary actor `mallory` that sets both `human` to itself and
|
||||
`replyLimits`. The existing role/tester actors did not distinguish M2 because
|
||||
the actor-shape exclusions rejected them independently of the human comparison.
|
||||
M2 is still unrun; no kill claimed.
|
||||
- E2: added a real bus event assertion for `agent: "acme/scribe"` from a file's
|
||||
Mosaic-Agent trailer. The cited tip includes a later unrelated commit, so the
|
||||
event must store the file commit rather than the library tip. thread.messages
|
||||
must show `last === file` for that unchanged path. Supporting scope still waits
|
||||
for row 283's real fixture, as ruled.
|
||||
- E3: sage-3668 accepts direct writer.write tests under chief and tester actors
|
||||
as substitutes for the brief's setter cases (brief lines 483-491 at base
|
||||
45dca69f6). Correction to the early-look premise: organization.set DOES exist,
|
||||
broker.mjs:4701/4709, but ORGANIZATION_KEYS excludes replyLimits; instances.set
|
||||
also cannot carry it. Direct writes exercise the shared M11 boundary those
|
||||
setters cannot reach with that input. Sage confirmed the accurate reason in
|
||||
sage-3670; the unrelated actor case remains required.
|
||||
- E4: traced readSyncState -> withLibraryLock -> library-sync-busy after five
|
||||
seconds -> servedMirror catch-all -> null served -> misleading citation-invalid.
|
||||
New real-flock/socket test first proves the cite valid, holds the lock, asserts
|
||||
the exact citation-unavailable reason the agent receives, verifies no insert,
|
||||
and checks fixed fallback delivery and recovery after unlock. Additional tests
|
||||
distinguish malformed sync state from absent/new mirrors, and assert that the
|
||||
actual runner retry request contains that reason. These tests are expected RED
|
||||
until the fix. Planned production change: only an absent mirror or legitimate
|
||||
empty state yields null; other failures become GuardError citation-unavailable;
|
||||
bodies without path cites do not require the mirror lock. Add the code to
|
||||
GUARD_CODES so the runner sends the agent that reason on its one retry. Per
|
||||
sage-3670, existing four fallback bodies can remain only if that delivery is
|
||||
verified. M5 restores catch-all behavior; authored, not run.
|
||||
- E5: first-library-project selection is a Launchpad handoff implementation
|
||||
choice, not a validated rule that a business can only have one library.
|
||||
Cites into another library remain a limitation. No mapping/schema rule added.
|
||||
- E6: the broker's full guard table now runs as both coder and research.
|
||||
- E7: new citation-runtime.test.mjs starts the real runtime, reads limits from
|
||||
the real organization file, then changes, corrupts and removes that fixture
|
||||
file and checks library.status without replacing the library adapter.
|
||||
|
||||
No Node, tests or mutants ran. No test that predated row 217 changed.
|
||||
|
||||
|
||||
## Webby follow-up 192049c98 / webby-0258
|
||||
|
||||
E1, E2, E6 and E7 closed statically; no executed acceptance claimed. E3 correction and E5 limitation accepted. E4 tests accepted statically; real RED then production fix/green remain on hold for Sage CLEAR, with supporting scope waiting on 283. F1: citation-helpers status now uses its mutable served value, matching guard/last after setServed instead of reporting the original fixture commit. Test-only fixture correction, unrun. manifest.r3.sha256 records the updated helper; no production or old-test changes.
|
||||
|
||||
|
||||
## Round 2 / sage-4037 — 2026-10-24, Untested
|
||||
|
||||
New branch `beakley/row217-r2` from published `dde5b8496`, rebased exactly onto
|
||||
`origin/refactor` at `e0c6142f3` (109 upstream commits since `45dca69f6`). The
|
||||
published original branch is unchanged; no amend or force-push. The replayed
|
||||
four commits are b9ef816ff, 7400509ba, a447880cb, 2655ec010. Full range-diff:
|
||||
`rebase-r2.range-diff.txt`. Last commit is `=`, the first three are `!` from
|
||||
conflict context/indentation and append-log placement described below.
|
||||
|
||||
Conflict resolutions:
|
||||
- broker.mjs: retained landed grants.scope/grants.scope.set dispatch and added
|
||||
library.limits.set to the organization verb dispatch; neither path removed.
|
||||
- runtime.mjs: retained grants.scope.set and added library.limits.set alongside
|
||||
it; retained query/sync wiring and all new base lifecycle behavior.
|
||||
- organization.mjs: retained row 239's beforeWrite/revoked wrapper, placing both
|
||||
M11 fences before validations/revocation as on the old candidate. A refused
|
||||
reply-limit write cannot invoke beforeWrite.
|
||||
- library/index.mjs: retained C2-05a buildIndex/query exports and added the guard
|
||||
and reply-limits exports.
|
||||
- BUILD-LOG.md and docs/SESSIONS.md: retained upstream appends followed by all
|
||||
Beakley appends. Static byte-prefix checks prove the entire e0c6142f3 log
|
||||
histories survive; all original Beakley entries also survive.
|
||||
- business.mjs, cli README and sandbox.mjs auto-merged. Static diff against the
|
||||
target confirms only this row's TOP_KEYS addition, README paragraph and one
|
||||
import-free protocol mount; landed supporting scope and room-address mount
|
||||
remain intact. runtime diff contains only the approved import, injected
|
||||
guard/limits/last adapters and setter dispatch, now beside grants.scope.set.
|
||||
|
||||
Correction recorded honestly: the first unpublished rebase attempt used an
|
||||
unbounded marker regex that removed code after a conflict. The diff stat caught
|
||||
it immediately; aborted the rebase and repeated with bounded markers. No result
|
||||
from that discarded attempt was pushed. The successful first replay matches the
|
||||
original 589 insertions/20 deletions; no broad deletions remain.
|
||||
|
||||
Implemented E4 under sage-4037's explicit direction to make the product fix
|
||||
while keeping all tests unrun. This supersedes the earlier planned RED-first
|
||||
execution order; no RED or green has been observed. The existing regression
|
||||
cases predate the fix. GUARD_CODES now includes citation-unavailable. Only a
|
||||
mirror confirmed absent by lstat, or readSyncState's legitimate empty state,
|
||||
yields no served commit. Other read/lock/metadata errors give the fixed safe
|
||||
reason: "The library is busy or unavailable. Retry the answer when the library
|
||||
is available." The runner receives it through BusError.reason and includes it
|
||||
in its one retry request. The existing four fallback bodies remain. Plain,
|
||||
web-only and fixed replies require no mirror read, so a busy mirror cannot
|
||||
block the runner's fixed fallback. M5's real production anchor now exists.
|
||||
|
||||
Supporting scope after row 283 (`8d2856ee3`): added two broker tests using real
|
||||
mapping/reader classification, not a scope stub. A path in both supporting and
|
||||
playground refuses as canon; an agent-committed supporting path stores
|
||||
scope=supporting, agent=acme/scribe and its file commit in message.checked.
|
||||
|
||||
C2-05a comparison: index-build.mjs builds its file map directly from readLibrary
|
||||
files; indexFor calls that same reader at the requested commit. Added a real
|
||||
fixture test comparing the index set, readLibrary set and libraryReader.lines
|
||||
admission, including supporting, unmapped Markdown and .canvas. This comparison
|
||||
is authored and statically traced, not executed; numerical results wait on CLEAR.
|
||||
|
||||
Current packet: manifest.r4.sha256, relative to e0c6142f3. No test file already
|
||||
present at that base was edited. No Node, npm, tests, mutants or webui build run.
|
||||
Ready for CLEAR after Lena's row 296. On CLEAR, install with npm ci
|
||||
--ignore-scripts --no-audit --no-fund in THIS worktree root and packages/webui;
|
||||
never link to canonical node_modules or run npm/rm in the canonical checkout.
|
||||
Use short mktemp TMPDIR and timeout -k 10. Any old-test red goes to Sage before
|
||||
an edit. Full green gate, mutants and Webby verdict remain outstanding.
|
||||
|
||||
Range-diff receipt rendering trims trailing whitespace on diff separator lines; no substantive range-diff content changed. This removes whitespace warnings caused by embedding raw diff output in a tracked text file.
|
||||
|
||||
Final base-to-candidate whitespace check found a trailing blank line inherited from Launchpad in limits.mjs; removed it without behavior changes. manifest.r5.sha256 supersedes r4 for the exact candidate file hashes.
|
||||
|
||||
|
||||
## CLEAR sage-4042/4043 — execution started 2026-10-24
|
||||
|
||||
Queue beakley-217-start initially refused Lena's review-outcome lock twice;
|
||||
same-op retry succeeded at rev3894 (briefed→in-progress). No queue bypass.
|
||||
Short TMPDIR /mnt/storage/scratch/tmp/tNoueZ. Worktree-local npm ci at root
|
||||
(128 packages) and packages/webui (2) completed; neither path was a symlink.
|
||||
No npm/rm command ran in canonical. All test commands use timeout -k 10.
|
||||
|
||||
E4 current file: 3 pass/0 fail/0 skip. M5 isolated pre-fix stand-in: 1 pass,
|
||||
2 expected assertion failures (citation-invalid instead of citation-unavailable),
|
||||
exit1. Restored product bytes and checkout product hashes, then E4 restored
|
||||
control 3/3. Receipts under run-r2/m5-red. M1 six-space anchors both match
|
||||
exactly once on the eight-space lines.
|
||||
|
||||
Touched test files first run: 56 pass/1 fail, zero skip/cancel. The sole first-red
|
||||
was NEW citation-runtime.test.mjs invalid-authority at Broker.checkBusiness:
|
||||
validator output has unresolved roles and is not the host's broker projection.
|
||||
Adjusted that new fixture only, following limits-runtime.test.mjs: minimal
|
||||
empty-authority coder, validated real project mappings, real organization adapter
|
||||
and systemFor(root). Single rerun 1/1, then all touched files 57/57. No base test
|
||||
failure or edit. First log retained as run-r2/touched-first.log and reported to
|
||||
Sage in beakley-0014. No production change was required.
|
||||
|
||||
The isolated mutant driver now wraps each node run in timeout -k 10, refuses a
|
||||
symlinked root node_modules, restores mutated files in finally, verifies original
|
||||
checkout product hashes after every mutant and reruns the restored control.
|
||||
Optional name filters allow the E4 M5 RED before the full mutant pass. No
|
||||
canonical dependency link is used; isolated copies link only this worktree's
|
||||
own dependency install.
|
||||
|
||||
|
||||
## Final slot results / 2026-10-24 10:21Z
|
||||
|
||||
All requested runs completed serially under sage-4042/4043 on source revision
|
||||
`2d274a5b6`. Final receipt commits change only tracking and logs, not packages.
|
||||
|
||||
| Whole suite | Pass | Fail / skip / cancel |
|
||||
| --- | ---: | --- |
|
||||
| library | 142 | 0 / 0 / 0 |
|
||||
| business | 270 | 0 / 0 / 0 |
|
||||
| bus | 974 | 0 / 0 / 0 |
|
||||
| cli | 988 | 0 / 0 / 0 |
|
||||
| harness | 172 | 0 / 0 / 0 |
|
||||
| seat | 218 | 0 / 0 / 0 |
|
||||
|
||||
Total 2,764 whole-suite tests. Touched files rerun 57/57. The unchanged
|
||||
RUNNER_FILES import-closure test passed in seat (seat-suite.log:153). The only
|
||||
first-run failure was the NEW runtime fixture already recorded above; no old
|
||||
test failed and no test present at e0c6142f3 was edited.
|
||||
|
||||
M1–M5 all killed by the intended assertion, each with Node exit1, a green
|
||||
control and green restored control. Driver exit0. M1 catches missing writer
|
||||
refusals; M2 is killed by mallory's human swap; M3 detects one message left
|
||||
behind after evidence failure; M4 detects the missing reason; M5 detects
|
||||
citation-invalid in place of citation-unavailable on contention and bad state.
|
||||
Every mutation was in a disposable HEAD archive. Each changed file was restored,
|
||||
checkout product hashes checked after every mutant, and the restored control
|
||||
rerun. All five final restored.sha256 certificates match current product files.
|
||||
M5 also ran separately before the whole suites as the authorized pre-fix RED
|
||||
stand-in; its held-lock and malformed-state assertions failed, then restored
|
||||
E4 passed 3/3. Full raw controls/negatives/restores are retained.
|
||||
|
||||
Receipts: run-r2/summary.json and summary.txt; *-suite.log; touched-first.log,
|
||||
touched-rerun.log; availability-green.log; runtime-fixture-retry.log; npm-root.log
|
||||
and npm-webui.log; m1-anchors.txt; m5-red/ and mutants/. All are text, no binary
|
||||
artifact added. All Node/mutant/npm runs used the short TMPDIR and timeout -k 10.
|
||||
Both node_modules trees are local npm ci installs. No canonical npm/rm or
|
||||
canonical dependency link. No further runtime/source changes after the tests.
|
||||
|
||||
Acceptance formerly waiting on dependencies is executed: real row283 supporting
|
||||
canon refusal and supporting/agent event pass; the C2-05a readLibrary/index set
|
||||
comparison passes; runtime readRaw live/corrupt/missing-file test passes; runner
|
||||
retry request carries the E4 availability reason. The repeat obsolete-name
|
||||
search finds only render.mjs:6 and render.test.mjs:58, owned by row225; no owned
|
||||
hit. First-library selection remains the accepted E5 limitation. Webby-0274 N1
|
||||
is a nonblocking wording limitation: configuration faults share the safe
|
||||
busy-or-unavailable retry text. No policy/schema restriction was invented.
|
||||
|
||||
Current complete changed-file manifest over e0c6142f3..candidate is
|
||||
candidate-manifest.sha256, excluding itself to avoid a circular hash. It includes
|
||||
source, tests, records and evidence. Earlier numbered manifests are historical.
|
||||
Formal Webby verdict and all scripts/test-*.sh at landing remain Sage's steps;
|
||||
this is verified for review, not an integration/deployment claim.
|
||||
|
||||
Exact negative-test logs retain Node's whitespace-only diagnostic lines. Whole diff --check reports those 12 blank-line padding warnings in run-r2 logs; source/docs diff --check excluding captured run-r2 evidence is clean. No source whitespace problem or test failure is hidden by that exclusion.
|
||||
@@ -1,61 +0,0 @@
|
||||
# Row 217 round 2 — verified for review
|
||||
|
||||
Issue #1718, C2-06. Base e0c6142f3; branch beakley/row217-r2. Continued
|
||||
Launchpad e25ef0373 through the preserved original dde5b8496 branch. Range-diff,
|
||||
conflict resolutions and acceptance receipts are in BUILD.md. Tested source
|
||||
revision: 2d274a5b6; the final commits add records/evidence only.
|
||||
|
||||
The broker checks agent-to-human citations before insertion, stores trusted
|
||||
scope/agent/file evidence atomically with the message, and supplies per-path last
|
||||
on thread reads. It keeps session-local fetched pages and reads reply settings
|
||||
live through the M11 human-only writer. The runner preserves cited JSON, defers
|
||||
notes on fixed replies, and retries once with the refusal code and safe reason.
|
||||
E4 adds citation-unavailable for mirror/state/lock faults; uncited/web-only/fixed
|
||||
bodies do not need the mirror lock. Supporting scope uses landed row283 code.
|
||||
|
||||
## Product and test scope
|
||||
|
||||
The package paths listed in candidate-manifest.sha256 are exactly this row's
|
||||
base-to-candidate changes. Fourteen product paths cover library guard/limits/
|
||||
protocol/exports; business validation/writer; bus broker/runtime/server/client;
|
||||
CLI command/README; runner; and the single approved pure-protocol sandbox mount.
|
||||
Nine test/helper/fixture paths are additions. No existing test is modified.
|
||||
The mounted protocol stays import-free. Runtime retains the landed grant/query/
|
||||
sync behavior; the writer retains beforeWrite/revoked handling and fences before
|
||||
revocation. No SQL schema, event kind, role authority or credential change.
|
||||
|
||||
## Executed evidence
|
||||
|
||||
| Whole suite | Pass | Fail / skip / cancel |
|
||||
| --- | ---: | --- |
|
||||
| library | 142 | 0 / 0 / 0 |
|
||||
| business | 270 | 0 / 0 / 0 |
|
||||
| bus | 974 | 0 / 0 / 0 |
|
||||
| cli | 988 | 0 / 0 / 0 |
|
||||
| harness | 172 | 0 / 0 / 0 |
|
||||
| seat | 218 | 0 / 0 / 0 |
|
||||
|
||||
Touched files 57/57; total whole suites 2,764. First run was 56/57 due solely
|
||||
to a new runtime fixture missing the broker's resolved authority shape. Only
|
||||
that new fixture changed; single and full touched reruns passed. No old test
|
||||
failed. First-red evidence remains in run-r2/touched-first.log.
|
||||
|
||||
M1–M5 killed: missing M11 fences, incoming-human trust, split check transaction,
|
||||
dropped client reason, and hidden library availability. Every negative run has
|
||||
green control/restored runs and matching restored product certificates. M5 is
|
||||
also the authorized E4 pre-fix RED stand-in. Supporting canon refusal, stored
|
||||
supporting/agent evidence, the C2-05a index comparison, runtime raw settings and
|
||||
agent-visible E4 retry reason all pass. The unchanged sandbox closure test passes.
|
||||
|
||||
Commands ran serially under Sage CLEAR with short TMPDIR and timeout -k 10.
|
||||
Root/webui dependencies came from local npm ci, never canonical links. Full logs,
|
||||
summary.json and mutant certificates are in run-r2/. The complete changed-file
|
||||
manifest candidate-manifest.sha256 covers e0c6142f3..candidate, excluding itself;
|
||||
its SHA256 is supplied with the pushed tip. Historical manifests stay untouched.
|
||||
|
||||
## Remaining boundaries
|
||||
|
||||
Sage runs every scripts/test-*.sh at landing and posts the formal Webby review
|
||||
request. No merge/deployment performed. First-library selection remains the
|
||||
accepted limitation; configuration faults share the safe unavailable reason
|
||||
(Webby N1, nonblocking). Obsolete-name search hits only row225's render files.
|
||||
@@ -1,80 +0,0 @@
|
||||
74398edcedf16a3d856ab9e7ea900eb61a4df7f726f04b74b2ff123e7536e9c1 BUILD-LOG.md
|
||||
87880c30c2be0180e6eec4dbe203f86e93ae2b1b4be44031b6a4903c6245a0ec agents/beakley/work/queue-217/BUILD.md
|
||||
e7ecf624ccb2b918efb08001ae9da36380fe918f8c27db704860809b6792e6f2 agents/beakley/work/queue-217/MANIFEST.md
|
||||
f4a042b5d6d393d2be62b107d7157ae51dd8fbf36f4360f5cd8cf07c03c74251 agents/beakley/work/queue-217/manifest.r1.sha256
|
||||
53f051a4e416a34181ad9bcc7687f0d686274542b06d9758e2db7eb81e848811 agents/beakley/work/queue-217/manifest.r2.sha256
|
||||
f96fccc566d01d70db32188574d0b5331ef3c90bce66558449a51b3f21da1b29 agents/beakley/work/queue-217/manifest.r3.sha256
|
||||
faf8ec3e0ab458fe95120345ec93e077b0dcad9458c0f2683a20effb6ce3ed93 agents/beakley/work/queue-217/manifest.r4.sha256
|
||||
a58f0e273b60508b95c833cbace26799d7aa935117fd1f9a27812fba65b93d54 agents/beakley/work/queue-217/manifest.r5.sha256
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/manifest.r6.sha256
|
||||
04a9d0585b5ae4818d87d67ac27f838355f1a6f586625a16cf01d91d7bb6d4a0 agents/beakley/work/queue-217/mutants.py
|
||||
4a5f7b3373fd3ff46e2d6a5f7ee7106ad76a71c9034ca5a44b9e7340f0cc4cff agents/beakley/work/queue-217/rebase-r2.range-diff.txt
|
||||
630070b0d682120ba64b382ab3b47b3fa3e8f0bcfc695ca09432d01d705fbcb3 agents/beakley/work/queue-217/run-r2/README.md
|
||||
c4245272d5fc89c5fd3a9ea979e7d65727ea76e24364190af57556c59ad2fe34 agents/beakley/work/queue-217/run-r2/availability-green.log
|
||||
700fff38b0a99ffdb44863f13015673cb459e5e645c5df46580eafbc407c95c8 agents/beakley/work/queue-217/run-r2/bus-suite.log
|
||||
ef216d0af325c2b6647eb8405e5de70ebb5a0e7a28bb3d8fe3abc6a289a8d3d2 agents/beakley/work/queue-217/run-r2/business-suite.log
|
||||
af173117f83359ebba62c5c00eadc749bb179551a8e290bcf55bbe39b1e7272c agents/beakley/work/queue-217/run-r2/cli-suite.log
|
||||
a615f69ba60859e9d7817f3353b0d7c71e6c12eecc3ecf0f630d473be21e5fef agents/beakley/work/queue-217/run-r2/harness-suite.log
|
||||
acaa08001101fd69a12cae377984e0d469c2cedc2affb5ccf9af426a72549dcc agents/beakley/work/queue-217/run-r2/library-suite.log
|
||||
5414ce5b94e7ac7918ed64f62e5fd2b921d49c7e93cf73042b9187d014069934 agents/beakley/work/queue-217/run-r2/m1-anchors.txt
|
||||
7d7138b25568adb98932bbe180a337fe6798c3eddcd7134ce7278c24fea48818 agents/beakley/work/queue-217/run-r2/m5-driver.log
|
||||
de7dd716d3981fd9fa1d114882e60f9a83736cdb8f8e2096c3913c9f8620238a agents/beakley/work/queue-217/run-r2/m5-red/M5-hide-library-unavailable-control.log
|
||||
6b98d3943d04d99f3ef212f11901d2257422410c477abec27ed3100a0d20dad9 agents/beakley/work/queue-217/run-r2/m5-red/M5-hide-library-unavailable-restored-green.log
|
||||
a58f0e273b60508b95c833cbace26799d7aa935117fd1f9a27812fba65b93d54 agents/beakley/work/queue-217/run-r2/m5-red/M5-hide-library-unavailable-restored.sha256
|
||||
d852a464fd624ce12d8d6bdc9800402639bb500a6d40c628cb836ca1bcf1e326 agents/beakley/work/queue-217/run-r2/m5-red/M5-hide-library-unavailable.log
|
||||
7d7138b25568adb98932bbe180a337fe6798c3eddcd7134ce7278c24fea48818 agents/beakley/work/queue-217/run-r2/m5-red/summary.txt
|
||||
1c405f1f15d2ce2db37b5809cdf5eaff68f18c99c5621e1c43262a289c5e35c4 agents/beakley/work/queue-217/run-r2/mutants-driver.log
|
||||
c96487e87c1ae9e34a7222b04701c5efcce25fe201f03a0213b989f7cde2c376 agents/beakley/work/queue-217/run-r2/mutants/M1-writer-fence-control.log
|
||||
8b294ecc057ad64ace7f520a1785b54df7df5a9eddf962813c3e5f8fa723ffd4 agents/beakley/work/queue-217/run-r2/mutants/M1-writer-fence-restored-green.log
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/run-r2/mutants/M1-writer-fence-restored.sha256
|
||||
be749486956e85a71f08107139613e09b62c53b58e8cc10e0fbe807e95d079a6 agents/beakley/work/queue-217/run-r2/mutants/M1-writer-fence.log
|
||||
525da1cc780dfea1a66f95739d444516bd16271c7ec539d615012ec9c8e7c139 agents/beakley/work/queue-217/run-r2/mutants/M2-incoming-human-control.log
|
||||
3546705980bb4a73295f16e42ab55f38c6adca9a5c53252264ae4ef66c595dfc agents/beakley/work/queue-217/run-r2/mutants/M2-incoming-human-restored-green.log
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/run-r2/mutants/M2-incoming-human-restored.sha256
|
||||
77352c22c459c516ff47ff1caa42fe9763fe201a04079646b0ccc0da6a145804 agents/beakley/work/queue-217/run-r2/mutants/M2-incoming-human.log
|
||||
58de145ec0384de4f560b28dcfa76e98c384be5c771d6561fb1054f07ea8166b agents/beakley/work/queue-217/run-r2/mutants/M3-split-check-transaction-control.log
|
||||
6a4cd0ef36b0d2318ef71c941ce300d215b6d2f87d0b4328c461ba53d812434c agents/beakley/work/queue-217/run-r2/mutants/M3-split-check-transaction-restored-green.log
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/run-r2/mutants/M3-split-check-transaction-restored.sha256
|
||||
2deb72f2d442f413fd06e205093f6fa3f955ec6ef707b7ca65b86be8c8883f9b agents/beakley/work/queue-217/run-r2/mutants/M3-split-check-transaction.log
|
||||
31cac91f43c8b7ebe0431f27a038b0fcd554a12b232592747f3972213cfa192b agents/beakley/work/queue-217/run-r2/mutants/M4-drop-client-reason-control.log
|
||||
e06c1da8dcd9e7eb013a4597b14369e296e21b812476bd6d88c7a7aa040d4065 agents/beakley/work/queue-217/run-r2/mutants/M4-drop-client-reason-restored-green.log
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/run-r2/mutants/M4-drop-client-reason-restored.sha256
|
||||
66d8f72df3bc0428624dab437cb04923ecab42055d29c6ffde43af98d47f32ae agents/beakley/work/queue-217/run-r2/mutants/M4-drop-client-reason.log
|
||||
3f74fbd3b4297868b9bb637a7924739363470964873a4bd3dc2f5daf2d0e9c8a agents/beakley/work/queue-217/run-r2/mutants/M5-hide-library-unavailable-control.log
|
||||
96d95a45d5326e614328531a7dadebce5d3ce70e40ec23dd49a66c1a676b45be agents/beakley/work/queue-217/run-r2/mutants/M5-hide-library-unavailable-restored-green.log
|
||||
120b15db5eb75897095fe3d0759553e482365d58061d763beba7754a6e0d0734 agents/beakley/work/queue-217/run-r2/mutants/M5-hide-library-unavailable-restored.sha256
|
||||
fa57189e9de99c4a76be27da3b857c07fc76706f7d0ee7409ba4efd43c3642b7 agents/beakley/work/queue-217/run-r2/mutants/M5-hide-library-unavailable.log
|
||||
1c405f1f15d2ce2db37b5809cdf5eaff68f18c99c5621e1c43262a289c5e35c4 agents/beakley/work/queue-217/run-r2/mutants/summary.txt
|
||||
862418d3d4124871ca5fcaf35e16c318a04e2888da83836751ddfea110efeb06 agents/beakley/work/queue-217/run-r2/npm-root.log
|
||||
38b75d8bddacf8d227883a29dd8a10f87a7f02d8a95f3f8809cb966fc9c8cf7a agents/beakley/work/queue-217/run-r2/npm-webui.log
|
||||
7f29b5a328fd6be61ebc4110a048305b50856810ab97a7798cd427924d74e8c9 agents/beakley/work/queue-217/run-r2/runtime-fixture-retry.log
|
||||
3bd51fe222a61412e8285eb522a2f7b5c1b0b035f7dca0e9ff66190bd53e6706 agents/beakley/work/queue-217/run-r2/seat-suite.log
|
||||
8b98c6ba76de46ddd858b4b95bae7bce2d1bf969edb85901ad8819e1280869a1 agents/beakley/work/queue-217/run-r2/summary.json
|
||||
e374cb7ab28a46dd560b267b0fe6691b11c0c2fabd00087c4e49a02ab1bf8086 agents/beakley/work/queue-217/run-r2/summary.txt
|
||||
ad2022c7ccdfa151e029eed92cd309369a97f197d9304775f6d2be3dc5f11080 agents/beakley/work/queue-217/run-r2/touched-first.log
|
||||
e1fe5ebae1a36f196470848bf27b99c21d316c9236a1d1328d7bcaca0ee4d3e9 agents/beakley/work/queue-217/run-r2/touched-rerun.log
|
||||
0c1b1f079b4b993e8d1aeb730d743e28696413eae8be6dd79731d749d1d45d0b agents/launchpad/work/queue-217/BUILD.md
|
||||
76b0a5785f134c09cda677e8f5fb3e7454b39883c4a6f55360d9d277476fcd2c docs/SESSIONS.md
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,21 +0,0 @@
|
||||
68c05644d29188b897e2d4695d8e7025e143d424d69a91bc07bc950f589d34bf packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
49e01e5e73cc3e830ad48a1b6b13fe4d06a38950f17847dc049b75209d6d3f0a packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
29114051a9bc5271e48978a9552d64b51b0ac4810f94a1f98940bf617b148df8 packages/bus/tests/citation-guard.test.mjs
|
||||
dc2d5836f10f591fc174aaf9587a3bff793b24ac29efe9ab68c6a9243d1d1c2c packages/bus/tests/citation-helpers.mjs
|
||||
825da818ba3cf45a4837f0f15a9c2cdba55a3d0bbb4479d55236f35799427c6f packages/business/src/business.mjs
|
||||
dbd79a4dfc926620d034b540f98f39336d81e4c79f214424c3cf19250c1d1f8d packages/business/src/organization.mjs
|
||||
bec04a894bc2af000548283ed7719e4de1c6d56688f42238a113390e9b2d3fbe packages/business/tests/reply-limits.test.mjs
|
||||
1f1bea250f694a2aae9b9dc856b3c3424ceca153ccf826c99ccb98e6ea9cd394 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
ec7ef0cbf493217eb9229895cae2fe7ef603f41913840e59a73220df387c81ca packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
0365114cf5773cbaa9fba196fbd1e773b2ec5ad2300c40231c357ca58884b9e3 packages/library/src/guard.mjs
|
||||
aaa8f7ba60a729a88a6ef57b3d5ff5a69bcf0e17b60e7db51a8dc5a697627b6c packages/library/src/index.mjs
|
||||
3e04fa25a64334d33ffbec704205b32cd01992f2d341e908f933a345199beee0 packages/library/src/limits.mjs
|
||||
c9e682eff87e822647921288d7fce0ebdc7b09f0a6dfdd6528f10249ae26e81b packages/library/src/reply-protocol.mjs
|
||||
dd056409712113eb9c1b70e29b21022f5b30df6ffbfb2658e293edd6ec7195c7 packages/library/tests/guard.test.mjs
|
||||
2f3ec99129d16394d4458e252b9cba4e38ff66cd9393e3889f8afc3140e15a8e packages/seat/src/sandbox.mjs
|
||||
@@ -1,23 +0,0 @@
|
||||
68c05644d29188b897e2d4695d8e7025e143d424d69a91bc07bc950f589d34bf packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
49e01e5e73cc3e830ad48a1b6b13fe4d06a38950f17847dc049b75209d6d3f0a packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
8dc344b8a905c58d544b031ca84adb7eb869d9de88eb8e6b0fc1d9190702a38a packages/bus/tests/citation-guard.test.mjs
|
||||
62d8a55945d4b700e22c8c49b6420a5e25719d266901a2ad20c72514735e65e9 packages/bus/tests/citation-helpers.mjs
|
||||
168dcac99d9bfdfdf5ff0eaa2c0fff91595b351b4d0092dc299532c9c32869f0 packages/bus/tests/citation-runtime.test.mjs
|
||||
825da818ba3cf45a4837f0f15a9c2cdba55a3d0bbb4479d55236f35799427c6f packages/business/src/business.mjs
|
||||
dbd79a4dfc926620d034b540f98f39336d81e4c79f214424c3cf19250c1d1f8d packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
1f1bea250f694a2aae9b9dc856b3c3424ceca153ccf826c99ccb98e6ea9cd394 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
0365114cf5773cbaa9fba196fbd1e773b2ec5ad2300c40231c357ca58884b9e3 packages/library/src/guard.mjs
|
||||
aaa8f7ba60a729a88a6ef57b3d5ff5a69bcf0e17b60e7db51a8dc5a697627b6c packages/library/src/index.mjs
|
||||
3e04fa25a64334d33ffbec704205b32cd01992f2d341e908f933a345199beee0 packages/library/src/limits.mjs
|
||||
c9e682eff87e822647921288d7fce0ebdc7b09f0a6dfdd6528f10249ae26e81b packages/library/src/reply-protocol.mjs
|
||||
dd056409712113eb9c1b70e29b21022f5b30df6ffbfb2658e293edd6ec7195c7 packages/library/tests/guard.test.mjs
|
||||
2f3ec99129d16394d4458e252b9cba4e38ff66cd9393e3889f8afc3140e15a8e packages/seat/src/sandbox.mjs
|
||||
@@ -1,23 +0,0 @@
|
||||
68c05644d29188b897e2d4695d8e7025e143d424d69a91bc07bc950f589d34bf packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
49e01e5e73cc3e830ad48a1b6b13fe4d06a38950f17847dc049b75209d6d3f0a packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
8dc344b8a905c58d544b031ca84adb7eb869d9de88eb8e6b0fc1d9190702a38a packages/bus/tests/citation-guard.test.mjs
|
||||
8a2d4b636f8d4f926c484254c33ecf7b7e4722acef3250d2730593984d5ac06b packages/bus/tests/citation-helpers.mjs
|
||||
168dcac99d9bfdfdf5ff0eaa2c0fff91595b351b4d0092dc299532c9c32869f0 packages/bus/tests/citation-runtime.test.mjs
|
||||
825da818ba3cf45a4837f0f15a9c2cdba55a3d0bbb4479d55236f35799427c6f packages/business/src/business.mjs
|
||||
dbd79a4dfc926620d034b540f98f39336d81e4c79f214424c3cf19250c1d1f8d packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
1f1bea250f694a2aae9b9dc856b3c3424ceca153ccf826c99ccb98e6ea9cd394 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
0365114cf5773cbaa9fba196fbd1e773b2ec5ad2300c40231c357ca58884b9e3 packages/library/src/guard.mjs
|
||||
aaa8f7ba60a729a88a6ef57b3d5ff5a69bcf0e17b60e7db51a8dc5a697627b6c packages/library/src/index.mjs
|
||||
3e04fa25a64334d33ffbec704205b32cd01992f2d341e908f933a345199beee0 packages/library/src/limits.mjs
|
||||
c9e682eff87e822647921288d7fce0ebdc7b09f0a6dfdd6528f10249ae26e81b packages/library/src/reply-protocol.mjs
|
||||
dd056409712113eb9c1b70e29b21022f5b30df6ffbfb2658e293edd6ec7195c7 packages/library/tests/guard.test.mjs
|
||||
2f3ec99129d16394d4458e252b9cba4e38ff66cd9393e3889f8afc3140e15a8e packages/seat/src/sandbox.mjs
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
168dcac99d9bfdfdf5ff0eaa2c0fff91595b351b4d0092dc299532c9c32869f0 packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
3e04fa25a64334d33ffbec704205b32cd01992f2d341e908f933a345199beee0 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
168dcac99d9bfdfdf5ff0eaa2c0fff91595b351b4d0092dc299532c9c32869f0 packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run only on Sage CLEAR. Mutate isolated HEAD archives; never edit the checkout.
|
||||
|
||||
A green control run is required before each negative result counts as a kill.
|
||||
Usage: python3 agents/beakley/work/queue-217/mutants.py OUTPUT_DIRECTORY
|
||||
"""
|
||||
from pathlib import Path
|
||||
import io
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
OUT = Path(sys.argv[1]).resolve()
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
WRITER = "packages/business/src/organization.mjs"
|
||||
BROKER = "packages/bus/src/broker.mjs"
|
||||
CLIENT = "packages/bus/src/client.mjs"
|
||||
ATOMIC = "if (check) this.#event(s, 'action.allowed', { action: 'message.checked', message: mid, check }, mid, checkEventId(mid));"
|
||||
REENTER = "return this.#reenter(cap, s, { verb: 'message.send', args }, check);"
|
||||
SPLIT = """const result = this.#reenter(cap, s, { verb: 'message.send', args }, check);
|
||||
if (check) this.#store.transaction(() => this.#event(s, 'action.allowed', { action: 'message.checked', message: result.id, check }, result.id, checkEventId(result.id)));
|
||||
return result;"""
|
||||
MUTANTS = [
|
||||
("M1-writer-fence", [(WRITER, " replyLimitsFence(old, document, actor);", ""),
|
||||
(WRITER, " replyLimitsFence(old, written, actor);", "")],
|
||||
["packages/business/tests/reply-limits.test.mjs"]),
|
||||
("M2-incoming-human", [(WRITER, "actor === old.human", "actor === document.human")],
|
||||
["packages/business/tests/reply-limits.test.mjs"]),
|
||||
("M3-split-check-transaction", [(BROKER, ATOMIC, ""), (BROKER, REENTER, SPLIT)],
|
||||
["packages/bus/tests/citation-guard.test.mjs"]),
|
||||
("M5-hide-library-unavailable", [("packages/library/src/guard.mjs",
|
||||
"refuse('citation-unavailable', 'The library is busy or unavailable. Retry the answer when the library is available.');",
|
||||
"served = null;")], ["packages/bus/tests/citation-availability.test.mjs"]),
|
||||
("M4-drop-client-reason", [(CLIENT, "new BusError(r.error, typeof r.reason === 'string' ? r.reason.slice(0, 300) : undefined)", "new BusError(r.error)")],
|
||||
["packages/bus/tests/citation-guard.test.mjs"]),
|
||||
]
|
||||
|
||||
archive = subprocess.check_output(["git", "archive", "HEAD", "packages", "roles", "scripts", "tools", "docs", "package.json", "RELEASE"], cwd=ROOT)
|
||||
summary = []
|
||||
selected = set(sys.argv[2:])
|
||||
product_files = [line.split(' ', 1)[1] for line in (ROOT / 'agents/beakley/work/queue-217/manifest.r5.sha256').read_text().splitlines()]
|
||||
def hashes(base, files):
|
||||
return {file: hashlib.sha256((base / file).read_bytes()).hexdigest() for file in files}
|
||||
original_products = hashes(ROOT, product_files)
|
||||
for name, changes, tests in MUTANTS:
|
||||
if selected and name not in selected:
|
||||
continue
|
||||
with tempfile.TemporaryDirectory(prefix="row217-mutant-") as directory:
|
||||
work = Path(directory)
|
||||
with tarfile.open(fileobj=io.BytesIO(archive)) as source:
|
||||
source.extractall(work, filter="data")
|
||||
modules = ROOT / "node_modules"
|
||||
if modules.is_symlink():
|
||||
raise SystemExit('root node_modules must be a local install, never a canonical link')
|
||||
if modules.exists():
|
||||
os.symlink(modules.resolve(), work / "node_modules", target_is_directory=True)
|
||||
cmd = ["timeout", "-k", "10", "120", "node", "--test", *tests]
|
||||
with (OUT / f"{name}-control.log").open("w") as log:
|
||||
control = subprocess.run(cmd, cwd=work, stdout=log, stderr=subprocess.STDOUT, timeout=120)
|
||||
if control.returncode:
|
||||
raise SystemExit(f"{name}: control RED, no mutant result claimed")
|
||||
originals = {file: (work / file).read_bytes() for file, _, _ in changes}
|
||||
try:
|
||||
for file, before, after in changes:
|
||||
path = work / file
|
||||
text = path.read_text()
|
||||
if text.count(before) != 1:
|
||||
raise SystemExit(f"{name}: expected exactly one mutation anchor in {file}")
|
||||
path.write_text(text.replace(before, after))
|
||||
with (OUT / f"{name}.log").open("w") as log:
|
||||
mutant = subprocess.run(cmd, cwd=work, stdout=log, stderr=subprocess.STDOUT, timeout=140)
|
||||
if mutant.returncode != 1:
|
||||
raise SystemExit(f"{name}: expected assertion failure exit 1, got {mutant.returncode}")
|
||||
finally:
|
||||
for file, content in originals.items():
|
||||
(work / file).write_bytes(content)
|
||||
assert all((work / file).read_bytes() == content for file, content in originals.items())
|
||||
assert hashes(ROOT, product_files) == original_products, 'checkout product hashes changed'
|
||||
(OUT / f"{name}-restored.sha256").write_text(''.join(f'{digest} {file}\n' for file, digest in sorted(original_products.items())))
|
||||
with (OUT / f"{name}-restored-green.log").open("w") as log:
|
||||
restored = subprocess.run(cmd, cwd=work, stdout=log, stderr=subprocess.STDOUT, timeout=140)
|
||||
if restored.returncode:
|
||||
raise SystemExit(f"{name}: restored control RED")
|
||||
summary.append(f"{name}: killed (control green, mutant exit {mutant.returncode}, hashes restored, restored green)")
|
||||
(OUT / "summary.txt").write_text("\n".join(summary) + "\n")
|
||||
print(summary[-1], flush=True)
|
||||
@@ -1,112 +0,0 @@
|
||||
1: e25ef0373 ! 1: b9ef816ff launchpad: row 217 C2-06 work in progress, UNTESTED, handed to Beakley (mos-1500)
|
||||
@@ packages/bus/src/broker.mjs: export class Broker {
|
||||
if (CREDENTIAL_VERBS.includes(request.verb)) return this.#requestCredential(s, request.verb, structuredClone(args));
|
||||
if (request.verb === 'instance.hire' || request.verb === 'instance.fire')
|
||||
return this.#chiefLifecycle(s, request.verb, structuredClone(args));
|
||||
+ if (request.verb === 'grants.scope' || request.verb === 'grants.scope.set')
|
||||
+ return this.#grantScopeVerb(s, request.verb, structuredClone(args));
|
||||
- if (["limits", "limits.set", "organization.set", "organization.revision", "plugins", "plugins.set", "instances", "instances.set", "routes", "routes.set", "veto.set"].includes(request.verb)) {
|
||||
+ if (["limits", "limits.set", "organization.set", "organization.revision", "plugins", "plugins.set", "instances", "instances.set", "routes", "routes.set", "veto.set", "library.limits.set"].includes(request.verb)) {
|
||||
// Row 123 (#1617, REQ-COS-1, REQ-LIMIT-1): organization.set is limits.set for a role whose
|
||||
@@ packages/bus/src/runtime.mjs: export async function startBroker({
|
||||
project: {
|
||||
readSpec: context => projectModule.readSpec({ ...context, dataRoot }),
|
||||
@@ packages/bus/src/runtime.mjs: export async function startBroker({
|
||||
- else if(verb==='plugins.set')result=plugins.set(id,args,actor);
|
||||
- // Row 194 (#1692, V6): the human's keep and noHire lists, through the instance writer.
|
||||
else if(verb==='veto.set')result=instances.veto(id,args,actor);
|
||||
+ // Row 298: the human's grant scope, through the instance writer.
|
||||
+ else if(verb==='grants.scope.set')result=instances.grantScope(id,args,actor);
|
||||
+ // C2-06 M11: the human's replyLimits, through the organization writer's fence.
|
||||
+ else if(verb==='library.limits.set')result=setReplyLimits(organizationWriter({dir:organization.dir,rolesDir:organization.rolesDir}),id,args,actor);
|
||||
// Row 194 (D2.1, D2.2): the chief's hire and fire, with the reason in the change context.
|
||||
@@ packages/business/src/organization.mjs: export function organizationWriter({ dir
|
||||
const parent = join(dir, "businesses");
|
||||
directory(evidence);
|
||||
@@ packages/business/src/organization.mjs: export function organizationWriter({ dir, rolesDir, barrier = () => {} }) {
|
||||
- // mapping, including library playgrounds and hybrid universes.
|
||||
- if (canonicalJson(document?.projects) !== canonicalJson(old.projects))
|
||||
- fail('organization-projects-protected');
|
||||
-+ replyLimitsFence(old, document, actor);
|
||||
- validateBusinessDocument(document, file, { rolesDir });
|
||||
- const bytes = JSON.stringify(document, null, 2) + "\n";
|
||||
- // Check and log exactly what lands on disk, for every setter: a value JSON
|
||||
+ // mapping, including library playgrounds and hybrid universes.
|
||||
+ if (canonicalJson(document?.projects) !== canonicalJson(old.projects))
|
||||
+ fail('organization-projects-protected');
|
||||
++ replyLimitsFence(old, document, actor);
|
||||
+ validateBusinessDocument(document, file, { rolesDir });
|
||||
+ const bytes = JSON.stringify(document, null, 2) + "\n";
|
||||
+ // Check and log exactly what lands on disk, for every setter: a value JSON
|
||||
@@ packages/business/src/organization.mjs: export function organizationWriter({ dir, rolesDir, barrier = () => {} }) {
|
||||
- const written = JSON.parse(bytes);
|
||||
- if (canonicalJson(written.projects) !== canonicalJson(old.projects))
|
||||
- fail('organization-projects-protected');
|
||||
-+ replyLimitsFence(old, written, actor);
|
||||
- validateBusinessDocument(written, file, { rolesDir });
|
||||
- const after = sha256(bytes);
|
||||
- const transaction = randomUUID();
|
||||
+ const written = JSON.parse(bytes);
|
||||
+ if (canonicalJson(written.projects) !== canonicalJson(old.projects))
|
||||
+ fail('organization-projects-protected');
|
||||
++ replyLimitsFence(old, written, actor);
|
||||
+ validateBusinessDocument(written, file, { rolesDir });
|
||||
+ if (beforeWrite) {
|
||||
+ beforeWrite();
|
||||
@@ packages/business/src/organization.mjs: export function organizationWriter({ dir, rolesDir, barrier = () => {} }) {
|
||||
});
|
||||
}
|
||||
@@ packages/library/src/guard.mjs (new)
|
||||
+}
|
||||
|
||||
## packages/library/src/index.mjs ##
|
||||
-@@ packages/library/src/index.mjs: export { renderItems, KINDS, NOTICES, UNREADABLE } from './render.mjs';
|
||||
- export { survey, formatSurvey, surveyMain } from './survey.mjs';
|
||||
- export { SYNC_STATE_FILE, mirrorPath, ensureMirror, withLibraryLock, servedCommit, readSyncState, libraryStatus, readLibraryFile } from './mirror.mjs';
|
||||
+@@ packages/library/src/index.mjs: export { SYNC_STATE_FILE, mirrorPath, ensureMirror, withLibraryLock, servedCommi
|
||||
export { syncCommand, sync, ASKPASS, SLOT, SYNC_INTERVAL_MS } from './sync.mjs';
|
||||
+ export { buildIndex, indexFor, clearIndexCache, indexCacheSize } from './index-build.mjs';
|
||||
+ export { sees, find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from './query.mjs';
|
||||
+export { REPLY_LIMITS, resolveReplyLimits, checkReplyLimits } from './limits.mjs';
|
||||
+export { GUARD_CODES, FIXED_TEXTS, WEB_CITE_DEFINITIONS, REASON_MAX, GuardError, parseReply, checkReply, libraryReader, guardReply, lastCommits } from './guard.mjs';
|
||||
|
||||
2: c25f5b8da ! 2: 7400509ba row 217: citation runner retry and acceptance draft (Untested)
|
||||
@@ Commit message
|
||||
row 217: citation runner retry and acceptance draft (Untested)
|
||||
|
||||
## BUILD-LOG.md ##
|
||||
-@@ BUILD-LOG.md: Row 299 (573, #1806, Gander, Filbert): before, the P10 band test timed a fault r
|
||||
- 2026-10-23T17:29:46Z | Gyro Vikunja571 sage-3542 Connections amendment | Branch gyro/editor-connections-design cut exactly from landed PRD1.17 30e6bb680; read REQ-LIB-5 in that PRD. Replaced stale J-b waits in parent and W4. Proposed W8 owns current authorized Markdown/DOCX links/backlinks list, labels, versioned refresh, leakage refusals and fixture tests. Build order under mos-1470/comment961 is W7 closed routing candidate, W8 landing, then W7 human first-real-import opening. No REQ-LIB-8 condition or acceptance change. Q234/mos-1363/S0 M1-M14 and post-10-27/MVP priority fixed. Static diff, twelve brief sections and append-only checks pass. No repo Node, tests, build, browser, queue mutation or live action. Fenton reviews after authorized docs branch push; Sage lands on approval.
|
||||
+@@ BUILD-LOG.md: remain; no live state, schema or bus policy change.
|
||||
|
||||
- 2026-10-23T17:32:37Z | Gyro sage-3544 fenton-0016 N1/N2 delta | Before: W7 Gate/final real-conversion list omit the W8 build-order cross-reference and W8 human-view filtering cites agent settings. After: both locations explicitly put W8 landing before human opening as mos-1470 build order, not acceptance; comment/tracked-deletion links are not current story links and never appear in the human Connections view regardless of agent settings. New commit atop approved 5af060fb5, no amend. Static diff and append-only checks pass. Docs only, no repo Node/tests/live action. Fenton checks only this delta.
|
||||
-+
|
||||
+ 2026-10-24 | Goldie | Row265 / #1770 verified (mos-1567, sage-3942) | Approved correction adds solely address import pin + Row265 comment to project-runtime.test and one pure-source RUNNER_FILES mount; new block checks parser has no imports. Serialized fresh-short-TMP timeout-k10: unchanged sandbox10/10, parser15/15, rooms18/18, full bus957/957, twelve named refusal mutants killed (each Node1, driver0), restored parser15/15 + rooms18/18. All positives zero fail/skip/cancel; every mutation restored full broker SHA71b32ee4. Old first-red evidence retained, no other old-test change. Slot returned goldie-0034; Boyd packet explicitly includes mount-list review, candidate push next.
|
||||
+ 2026-10-24T07:18:53Z | Sage | Row 327 (#1825, Bradford, Poe and Dewey) LANDED 68c08b4e7. Before: refactor at 94d9e90a6; the push guard was a scratch script with no reviewed-binary check. After: scripts/push-check.sh and scripts/test-push-check.sh on refactor, 3 commits cherry-picked onto 6a5e12511 with blobs equal to the round 3 tip d858c9f8b, plus doc commits 76f84465f and 68c08b4e7. Binaries are found by numstat or a NUL in the first 8000 committed bytes, regardless of attributes; each needs its sha256 and path in an approved latest-round candidate; an unconfirmed queue tail exits 2. Reviews: Poe c31525 rev 3882, Dewey c31526 rev 3883. Gate: 1st run 06:57Z RED, not the candidate: canonical node_modules was empty from 05:45:15Z (sage-4023). Rerun with its own root npm ci GREEN 07:15:49Z: 17 package suites 0 failures (cli 986, plugins 119, webui 418), 11 scripts exit 0, push-check 6 mutants KILLED; skips are the queue canonical-root check and the row 244 live provider cases. The landed push-check.sh passed its own push (NO_BINARY, NO_ATTRIBUTION, PUSH_READY). mos-1575: gates install their own node_modules; canonical restored with npm ci (128 packages).
|
||||
+2026-10-23 | Beakley (88b97f65) | Row 217 #1718 takeover, before implementation | Clean base 45dca69f6 on beakley/row217. Recovering Launchpad handoff for citation guard, live settings, page store and runner retry. Acceptance is C2-06/design 5.2 plus sage-3595/3599/3602. Tracking agents/beakley/work/queue-217/BUILD.md; no product changes or Node/tests; Sage CLEAR required.
|
||||
+
|
||||
+2026-10-23 | Beakley (88b97f65) | Row 217 #1718 untested draft checkpoint | Continued Launchpad e25ef0373; added runner retry/text/note implementation, pure protocol constants and sage-3640 approved single read-only mount, CLI documentation and new acceptance test files. Static checks caught missing projects compatibility, async request mutation and Git pathspec matching; bounded fixes and regression tests authored. git diff --check clean. No Node/test/mutant executed; Sage holds CLEAR. 283/216/285 dependency checks and all acceptance execution remain open. Packet agents/beakley/work/queue-217/MANIFEST.md.
|
||||
@@ agents/beakley/work/queue-217/mutants.py (new)
|
||||
|
||||
## docs/SESSIONS.md ##
|
||||
@@ docs/SESSIONS.md: are never rewritten or removed; corrections are new entries.
|
||||
- 2026-10-23T17:48:43Z | Scrooge (629b6cd3) | Row 252 Console inbox Approve and Deny (#1753) | Rebased onto 306 landing as 580037105 (range-diff all =), slot run bus 907/0 webui 410/0 cli 943/0, in-review revs 3608/3609, Webby r1 APPROVE, J1-J19 specs to Sage; Sage landed 45ea3fa0d (done rev 3616). Part 1 mutant results were never in BUILD.md; they went to Sage by T3 (scrooge-0252-mutant-specs).
|
||||
- 2026-10-23 | Sage (1ef1e4f8) | Rows 308 and 252 landings, 571 Connections design amendment, Vikunja 597 | 308 (PRD 1.17, #1815) landed 30e6bb680 and 252 (#1753) landed 45ea3fa0d (replay of 580037105 onto 30e6bb680, range-diff all =), each after a full gate on the landed tree (252 also J1-J19, J11c and J18 equivalent); Gyro's 571 amendment (Fenton APPROVE) landed e8bb13df8; Vikunja 570, 435 and 597 done, canonical webui esbuild 0.28.2; queue revs 3589-3616 committed 59f013247
|
||||
- 2026-10-23 | Sage (1ef1e4f8) | Vikunja 571 W build rows; rows 13, 42, 257 and 289 check | Filed the design's ten W rows as queue rows 309-318 (revs 3617-3626, owners set to unassigned 3627-3636, queue commit 293b42fee pushed); Vikunja 571 done (comment 994). Row 13's candidate fd72d2689 is on refactor, gate is Monday's row 7 ledger run; 42 paused under mos-1184; 257 post-v1; 289 waits on 214 and 288. Slot released 17:56Z.
|
||||
+ 2026-10-24T04:27Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 C2-09b rooms | Goldie owns build, Boyd reviews under sage-3915. New goldie/row265 worktree at ec86f2c84, claim rev3814; room verbs/parser/new tests prepared, no old tests changed. Sage-3932 slot: new parser14/14 and rooms18/18 passed; whole bus in progress before refusal mutants, stop rule active.
|
||||
+ 2026-10-24T04:35Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 verified | First slot stopped at project-runtime import pin. mos-1567 narrowly authorizes pin and pure-source mount correction. sage-3942 rerun: sandbox10/10, parser15/15, rooms18/18, bus957/957, twelve refusal mutants killed/restored SHA71b32ee4, parser15/15 + rooms18/18 again. Slot returned goldie-0034; no further test runs. Boyd reviews RUNNER_FILES alongside rooms; own-branch push/claimant in-review next.
|
||||
+ 2026-10-24T07:18:53Z | Sage (1ef1e4f8) | Row 327 / #1825 push guard landed (mos-1572 option A, mos-1575) | Gate went red 06:57Z on an empty canonical node_modules (Glomgold's webui npm ci through a link to canonical, glomgold-0011); rerun with its own npm ci GREEN 07:15:49Z on 1bd214e38; pushed 68c08b4e7 07:18:03Z; #1825 closed c31530; canonical restored (128 packages); brief template rule 4db23a51f | landed
|
||||
+
|
||||
+2026-10-23 | Beakley (88b97f65, Codex gpt-6.1-sol) | Row 217 #1718 takeover under Q245 | Registered beakley/row217; read brief/design and standing Sage rulings; awaiting Launchpad ref before implementation. Queue next refused linked worktree; reported to Sage. Untested, no Node/test run pending CLEAR.
|
||||
|
||||
3: b6c3129d2 ! 3: a447880cb row 217: early-review coverage and availability RED cases (Untested)
|
||||
@@ Commit message
|
||||
row 217: early-review coverage and availability RED cases (Untested)
|
||||
|
||||
## BUILD-LOG.md ##
|
||||
-@@ BUILD-LOG.md: Row 299 (573, #1806, Gander, Filbert): before, the P10 band test timed a fault r
|
||||
+@@ BUILD-LOG.md: remain; no live state, schema or bus policy change.
|
||||
2026-10-23 | Beakley (88b97f65) | Row 217 #1718 takeover, before implementation | Clean base 45dca69f6 on beakley/row217. Recovering Launchpad handoff for citation guard, live settings, page store and runner retry. Acceptance is C2-06/design 5.2 plus sage-3595/3599/3602. Tracking agents/beakley/work/queue-217/BUILD.md; no product changes or Node/tests; Sage CLEAR required.
|
||||
|
||||
2026-10-23 | Beakley (88b97f65) | Row 217 #1718 untested draft checkpoint | Continued Launchpad e25ef0373; added runner retry/text/note implementation, pure protocol constants and sage-3640 approved single read-only mount, CLI documentation and new acceptance test files. Static checks caught missing projects compatibility, async request mutation and Git pathspec matching; bounded fixes and regression tests authored. git diff --check clean. No Node/test/mutant executed; Sage holds CLEAR. 283/216/285 dependency checks and all acceptance execution remain open. Packet agents/beakley/work/queue-217/MANIFEST.md.
|
||||
4: dde5b8496 = 4: 2655ec010 row 217: keep fixture status on its current served tip (Untested)
|
||||
@@ -1,30 +0,0 @@
|
||||
# Row217 round2 test receipts
|
||||
|
||||
Sage CLEAR sage-4042/4043, 2026-10-24. Source revision 2d274a5b6. All runs
|
||||
serialized; source files stayed unchanged through the whole-suite and mutant pass.
|
||||
Commands used TMPDIR=/mnt/storage/scratch/tmp/tNoueZ and timeout -k 10.
|
||||
|
||||
- npm ci --ignore-scripts --no-audit --no-fund at the worktree root (300s bound),
|
||||
then packages/webui (300s). Actual directories, no canonical links.
|
||||
- node --test packages/bus/tests/citation-availability.test.mjs (180s).
|
||||
- python3 agents/beakley/work/queue-217/mutants.py <m5-red> M5-hide-library-unavailable
|
||||
(420s). Green control, the authorized pre-fix RED stand-in, restore+green.
|
||||
- node --test --test-concurrency=1 with the seven new test files (900s):
|
||||
library/guard, business/reply-limits, cli/reply-limits, bus/citation-availability,
|
||||
bus/citation-guard, bus/citation-runtime and harness/citation-runner. Whole files.
|
||||
- First attempt 56/57: new runtime fixture invalid-authority. Only that fixture
|
||||
was corrected to the established broker projection. runtime-fixture-retry.log
|
||||
is its 1/1 rerun (180s); touched-rerun.log is the whole-file 57/57 rerun.
|
||||
- npm test in packages/library, then business (900s each), bus and cli (1200s
|
||||
each), harness and seat (900s each). Never overlapped package runs.
|
||||
- python3 agents/beakley/work/queue-217/mutants.py <mutants> (900s).
|
||||
The driver wraps each Node run in timeout -k 10 120. Each negative exits1,
|
||||
is preceded by a green control, restores its product bytes/hashes and then
|
||||
reruns the restored control green. No checkout product file is mutated.
|
||||
|
||||
summary.json holds complete counts; summary.txt is the short version. M1 anchors
|
||||
are recorded in m1-anchors.txt. The five *-restored.sha256 files match current
|
||||
product files. Full outputs are retained, including the first new-test failure.
|
||||
Negative logs intentionally keep Node's whitespace-only diagnostic padding;
|
||||
standard git diff --check flags that padding, not source code. No binary logs.
|
||||
No old test failed or was edited. Sage runs scripts/test-*.sh at landing.
|
||||
@@ -1,11 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5142.976705ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (33.874404ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (33.746516ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5307.376982
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,280 +0,0 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ a grant's level is collaborator or viewer (2.351697ms)
|
||||
✔ any other level refuses with the key path named (1.505284ms)
|
||||
✔ covers tells a viewer grant from a collaborator grant (0.605812ms)
|
||||
✔ covers refuses a call with no level, so a viewer grant can't slip past a collaborator check (0.247487ms)
|
||||
✔ a viewer grant still needs its business, project, instance and expiry to cover (0.247397ms)
|
||||
✔ a valid document passes and comes back frozen (4.146183ms)
|
||||
✔ checkAccess does not freeze or alias the caller's document (0.552481ms)
|
||||
✔ LEVELS is the single allowed level set, collaborator and viewer (row 193a) (0.259109ms)
|
||||
✔ accessFilePath is access.json in the config directory (0.495701ms)
|
||||
✔ top level: object, unknown keys, accessVersion, revision, arrays (2.131141ms)
|
||||
✔ users: unknown keys and the id rule (0.609866ms)
|
||||
✔ users: human, tester and any business's human are refused (0.455944ms)
|
||||
✔ users: home is a given peer or local (0.372673ms)
|
||||
✔ users: subjects, provider, sub, uniqueness and owner subjects (2.126611ms)
|
||||
✔ grants: unknown keys, id, user and business (0.897075ms)
|
||||
✔ grants: projects is ["*"] or distinct lowercase UUIDs (1.199677ms)
|
||||
✔ grants: instances is ["*"] or distinct declared instances of that business (0.889396ms)
|
||||
✔ grants: any level other than collaborator or viewer refuses, naming grants[i].level (1.13158ms)
|
||||
✔ grants: expires is optional ISO time, and a past expiry is not refused (0.979808ms)
|
||||
✔ the context is required and checked (1.713394ms)
|
||||
✔ loadAccess reads a valid file and checks it (0.755936ms)
|
||||
✔ loadAccess refuses a missing file, a symlink and a directory with exit 4 (0.519376ms)
|
||||
✔ loadAccess refuses another owner and group or other write (0.581157ms)
|
||||
✔ loadAccess refuses bad JSON and a bad document with exit 2 (1.841309ms)
|
||||
✔ covers: * and listed ids match (0.340508ms)
|
||||
✔ covers: an unlisted project, instance or business doesn't match (0.20254ms)
|
||||
✔ covers: an expired grant doesn't match, at and after the instant (0.698261ms)
|
||||
✔ covers: level is the least level asked for (row 193a) (0.213107ms)
|
||||
✔ covers: a missing or unknown level throws (row 193a, N1) (0.385188ms)
|
||||
✔ covers: a grant with an unknown level covers nothing (row 193a) (0.191435ms)
|
||||
✔ covers: now must be a valid Date (0.21008ms)
|
||||
✔ today's files load unchanged: identity, publish and remote are optional (11.61814ms)
|
||||
✔ a granted agent loads with its identity, grant and the project's upstream (4.906248ms)
|
||||
✔ N10: publish needs identity and a gitea definition, and the error names the grant (9.522958ms)
|
||||
✔ publish names declared projects that have a remote, each once (7.911234ms)
|
||||
✔ identity fields are checked (14.073433ms)
|
||||
✔ D9c: the upstream must be its own normalized form, exactly /OWNER/REPO (29.451403ms)
|
||||
✔ D9c: one .git is stripped, and the fork is built from the stripped name (1.733511ms)
|
||||
✔ D9c: gitea.url names the instance only (10.698646ms)
|
||||
✔ the upstream's host and port must be the agent's Gitea's (4.064711ms)
|
||||
✔ remote-not-fork: an upstream the agent's own user owns, compared without case (10.115713ms)
|
||||
✔ store references: own path only (design D1, D3a) (0.50611ms)
|
||||
✔ the role file loads and resolves through loadBusiness (18.165733ms)
|
||||
✔ the shipped file is exactly the approved list (1.392044ms)
|
||||
✔ the assistant's authority is message.send and record.write within role (4.312182ms)
|
||||
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.978023ms)
|
||||
✔ a business grant through limits does not widen the role (6.715605ms)
|
||||
✔ a launch block whose by is the assistant is refused (3.553443ms)
|
||||
✔ the instance takes no credential references and no tracker (9.975785ms)
|
||||
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (8.992963ms)
|
||||
✔ an arbiter without messaging lists is accepted beside the limited assistant (3.104416ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.788753ms)
|
||||
✔ REQ-HARN-2: the assistant, companion and research hold the web grant, and no other role file does (1.683056ms)
|
||||
✔ C2-04: library mappings load without roots, remain frozen, and retain mapping refusals (31.538067ms)
|
||||
✔ C2-04: an otherwise valid publish grant cannot name a library repo (4.356759ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (0.467526ms)
|
||||
✔ the fixture business validates and comes back frozen (4.106001ms)
|
||||
✔ two instances may share a definition (2.097865ms)
|
||||
✔ top-level refusals (6.537312ms)
|
||||
✔ arbiters and projects (24.968268ms)
|
||||
✔ role instances (9.057417ms)
|
||||
✔ Vikunja bots (29.820456ms)
|
||||
✔ a role without Vikunja takes no tracker block (9.629575ms)
|
||||
✔ credential references match the definition's services (11.680645ms)
|
||||
✔ launch (31.945766ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (34.141496ms)
|
||||
✔ loadBusiness: file checks (12.995702ms)
|
||||
✔ loadBusiness: not a regular file (111.510997ms)
|
||||
✔ loading writes nothing (1.787307ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (5.786433ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (2.551686ms)
|
||||
✔ persona vars: agent layer, creative definition only, both or neither (26.121282ms)
|
||||
✔ row 194 keep, noHire and retired validate, and a file without them loads as before (4.607715ms)
|
||||
✔ row 194 each bad keep, noHire or retired entry refuses (19.966409ms)
|
||||
✔ row 323: committed Case 1 document loads unchanged through the business loader (10.685638ms)
|
||||
✔ row 323: real business validate accepts the Case 1 fixture without tracker credentials (226.106251ms)
|
||||
✔ row 323: real factory install accepts the document's scratch input and writes it unchanged (294.937207ms)
|
||||
✔ row 323: the Case 1 business boots without a tracker or @sync credential (60.850375ms)
|
||||
✔ row 323: factory install refuses bus.tester false before writing (39.485453ms)
|
||||
✔ row 323: literal library key refuses through final business validation (176.986326ms)
|
||||
✔ row 323: a library project refuses through the factory profile plan (36.685902ms)
|
||||
✔ row 325: the Case 1 project's sole key matches the repository project id (7.063988ms)
|
||||
✔ row 325: real business validate reports the copied repository project valid (203.591785ms)
|
||||
✔ row 325: the old mosaic-stack project key refuses against those same project bytes (227.47487ms)
|
||||
✔ the role file loads and resolves through loadBusiness (22.21166ms)
|
||||
✔ the shipped file is exactly the approved list (0.355811ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (4.433743ms)
|
||||
✔ the chief of staff holds role.launch, message.send, role.end, organization.change, record.write, instance.name, role.hire and role.fire; every other action is gated (6.025087ms)
|
||||
✔ the pm does not hold role.launch (7.814194ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (5.309288ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (5.488981ms)
|
||||
✔ a launch block whose by is the pm instance is refused (4.031539ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (1.077581ms)
|
||||
✔ the instance takes no credential references and no tracker (7.111256ms)
|
||||
✔ C2-04: business validate and resolve skip a library before code projects and credential checks (581.819531ms)
|
||||
✔ usage errors exit 4 (330.347677ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (80.712835ms)
|
||||
✔ validate: project files (358.68705ms)
|
||||
✔ validate: missing files and a broken system config (272.747082ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (75.47514ms)
|
||||
✔ validate: a not-issued store agent dated today passes, and an issued one with a past expiry fails (152.378642ms)
|
||||
✔ validate: a token file inside the repository is refused (76.459487ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (210.323656ms)
|
||||
✔ resolve: prints one instance's record (260.543734ms)
|
||||
✔ resolve: refusals (375.881441ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (3.551882ms)
|
||||
✔ check: a good file has no problems (1.2198ms)
|
||||
✔ check never opens the file: a write-only token passes (0.477268ms)
|
||||
✔ check: file problems (1.60977ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.508979ms)
|
||||
✔ check: dates and environment references (0.686041ms)
|
||||
✔ each definition loads, with a contract file, and is exactly the approved list (4.83466ms)
|
||||
✔ an organization file that declares them passes, and each resolves to least privilege (10.307081ms)
|
||||
✔ the chief of staff launches each one; no other role does (11.082937ms)
|
||||
✔ a C-suite role can't be made the launcher: launch.by must hold role.launch (5.052598ms)
|
||||
✔ limits can narrow a C-suite role but never widen it (4.524289ms)
|
||||
✔ any unknown key, tool, action or version in a role file is refused (4.904699ms)
|
||||
✔ row 298: checkGrantScope takes the D2 shape and refuses anything else (2.752624ms)
|
||||
✔ row 298: a missing scope is empty and a bad one falls back to empty, which covers nothing (0.482721ms)
|
||||
✔ row 298: a Gitea grant is in scope only when its agent and every project are listed (0.341447ms)
|
||||
✔ row 298 (sage-3594 Q2): host commands match whole argv tokens, and enrollment is never in scope (0.467524ms)
|
||||
✔ row 298: a bad grantScope in the file still loads, and the read shows the fallback (18.355754ms)
|
||||
✔ row 298: the writer checks the scope, logs the change and removes the key for {} (142.313501ms)
|
||||
✔ row 298 (sage-3594 Q1): the general writers can't write grantScope (25.353249ms)
|
||||
✔ REQ-WAIT-1: GATED_ONLY is exactly the hard waits; the new actions are in the vocabulary (1.86466ms)
|
||||
✔ REQ-ROLE-2: END_PROTECTED includes the assistant's thread definition (0.234237ms)
|
||||
✔ REQ-COS-3: role.hire and role.fire are routed, not hard waits (0.300439ms)
|
||||
✔ REQ-WAIT-3: every action is routed or a hard wait, never both, and the routed list names only actions (0.967731ms)
|
||||
✔ REQ-WAIT-3: instance.name is routed under REQ-MSG-2 (1.5), not a hard wait (row 141, sage-0589) (1.313696ms)
|
||||
✔ REQ-WAIT-2: a role listing a hard wait at either class is refused; the actions that left can be granted (5.343386ms)
|
||||
✔ S1: the business file refuses hosts at the top level and in a role, and host.<id> references (56.500208ms)
|
||||
✔ T1: address, user and host key checks, which the enrollment raise uses (11.374442ms)
|
||||
✔ T26: no wildcard and no shell, runner or interpreter as a prefix (2.722004ms)
|
||||
✔ D6: argv shape and the literal prefix match (0.922698ms)
|
||||
✔ C2-04: instance settings skip a library while checking a later code project (98.596648ms)
|
||||
✔ row 165 read lists each instance and the definitions add accepts (16.615936ms)
|
||||
✔ row 165 add: two instances join, validate exits 0, the log names the human, and the writer asks for no restart (row 194, D3) (308.207149ms)
|
||||
✔ row 165 change: definition, vars and launch membership log before and after; none asks for a restart, the bus reloads (row 194, D3) (180.35178ms)
|
||||
✔ row 165 refuses each validation failure and leaves the file's bytes alone (44.040709ms)
|
||||
✔ T19 add of a credentialed definition writes store references dated today, names its bot, and validate exits 0 (101.60641ms)
|
||||
✔ T19 add of a definition that declares host writes references for its token services only (12.273146ms)
|
||||
✔ row 165 refuses a definition change to or from one that declares credentials (6.011439ms)
|
||||
✔ row 165 a vars or launch change on an instance with its binding succeeds and keeps the binding (87.081633ms)
|
||||
✔ row 165 refuses an END_PROTECTED definition and every change to a protected instance (9.425714ms)
|
||||
✔ row 165 refuses while a project file doesn't resolve, as validate would (21.508015ms)
|
||||
✔ row 165 refuses a stale revision and leaves the file's bytes alone (13.794117ms)
|
||||
✔ row 65 an instance write refuses harness-off, thinking-unsupported, an unknown model and a partial fallback (38.79158ms)
|
||||
✔ row 213 a creative instance is the human's: add, vars and definition changes, persona digest only (105.47603ms)
|
||||
✔ row 256 T1-T3, T5 the human deletes a creative instance, no other actor does, and the assistant stays (106.119319ms)
|
||||
✔ row 256 T4 the human's delete of the only listed instance, a creative one, is the last-listed refusal (3.635722ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (27.767213ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.218782ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (65.935591ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (42.79247ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (20.740471ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (73.013224ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (5.530215ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (31.489428ms)
|
||||
✔ Q169 assistants: vars and definition change and log the actor; tracker null leaves no tracker (74.510885ms)
|
||||
✔ Q169 assistants: refuses other instances, other definitions, holder and credentials, empty entries, a tracker the definition has no credential for and a stale revision (46.648048ms)
|
||||
✔ Q169 assistants: a definition with a vikunja credential takes a tracker change and refuses its removal or a used bot (28.59175ms)
|
||||
✔ row 65 routes lists every instance with harness, model, thinking and fallback, the switched-on harnesses, the model keys and each harness's levels (4.496203ms)
|
||||
✔ row 65 setRoutes saves a harness, model, thinking and whole fallback, reads each back from the file, logs the actor, and a null fallback clears all three (28.880486ms)
|
||||
✔ row 65 setRoutes refuses a partial fallback, a switched-off harness, a level the harness doesn't apply, an unloaded module, an unknown model or instance, a malformed route, no change and a stale revision, with the file unchanged (33.617502ms)
|
||||
✔ row 65 a file with harness vars and no plugins.harness loads and its views read; a model change still saves, and a route change refuses harness-off (15.471063ms)
|
||||
✔ B7 kept instance: the models keys it names and the instances key are the human's (32.512862ms)
|
||||
✔ B7 kept instance: its route is the human's (13.733689ms)
|
||||
✔ M10 creative instance: models keys it names, the instances key and its route are the human's (41.972839ms)
|
||||
✔ C2-04 M9: changed playground and hybrid entries leave business and changes.jsonl byte-identical (75.744651ms)
|
||||
✔ C2-04 M9: code projects, additions, deletions and array changes are protected too (73.935851ms)
|
||||
✔ C2-04 M9: canonical key order is allowed and a non-project setter still records its change (53.997154ms)
|
||||
✔ C2-04 M9: a serialization hook cannot change projects after the canonical comparison (29.857522ms)
|
||||
✔ M7/M8: library seats come from library businesses, creative seats from their creative definitions (20.881147ms)
|
||||
✔ M8: a business with no library project puts no seat in either set (19.190367ms)
|
||||
✔ M7/M8: a business file that is not valid JSON throws; no empty set (7.135915ms)
|
||||
✔ M7/M8: an absent businesses directory gives empty sets (1.688414ms)
|
||||
✔ M7/M8: a businesses path that is not a directory throws; no empty set (4.583153ms)
|
||||
✔ M7/M8: a businesses symlink to a missing target throws; no empty set (2.208552ms)
|
||||
✔ M7/M8: a config directory under a regular file throws (lstat fails with ENOTDIR); no empty set (0.601986ms)
|
||||
✔ M7/M8: a business file that can't be read throws; no empty set (12.318486ms)
|
||||
✔ T6 delete refuses in the design's order and leaves the file's bytes alone (104.896221ms)
|
||||
✔ T6 delete refuses the last listed instance (7.490182ms)
|
||||
✔ T6 a clean delete removes the entry and its own references, adds retired, and the name can't come back (213.690055ms)
|
||||
✔ T7 veto: keep, unkeep, nohire and hire each write once, a repeat is no change, and the log names the human (171.894178ms)
|
||||
✔ T7 veto refuses an unknown or END_PROTECTED keep, a bad request, a stale revision and a business without launch (26.238526ms)
|
||||
✔ D2.2 hire adds and lists a new instance, logs the chief's context, and sets only model and limits (92.062371ms)
|
||||
✔ D2.2 hire refuses noHire, a kept name and a listed name, and re-lists a fired one only as it was (29.586421ms)
|
||||
✔ D2.2 fire delists and keeps the entry, a repeat is done with no write, and each refusal holds (88.451593ms)
|
||||
✔ row 256 checkDelete passes the human's creative delete and refuses another actor's; fire still refuses (5.294872ms)
|
||||
✔ row 239 T1 a fire on a revision that goes stale before the writer's lock refuses there and revokes nothing (5.756058ms)
|
||||
✔ row 239 T2 a write after the revoke refused before publication carries revoked, and the file keeps the edit (7.753057ms)
|
||||
✔ row 239 T3 any error after the revoke carries revoked, for a fire and a delete; a revoke that throws carries nothing (32.403692ms)
|
||||
✔ Q247: omitting tracker loads as null and preserves independent role bots (10.793015ms)
|
||||
✔ Q247: real business validate passes without a sync credential reference or file (168.186763ms)
|
||||
✔ Q247: present tracker retains its values and validation without mutating the input (9.372029ms)
|
||||
✔ Q247: present null, undefined and malformed trackers still refuse (18.314895ms)
|
||||
✔ Q247: absent business tracker does not waive a role's Vikunja bot requirement (2.859494ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (40.546579ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (92.751615ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (100.494327ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (9.927988ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (19.985103ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (4.143331ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (18.273494ms)
|
||||
✔ optional project repo is preserved and must be a normalized absolute path (32.895793ms)
|
||||
✔ loaded business project repo cannot be nested in any declared code checkout (6.807091ms)
|
||||
✔ path and load (3.706713ms)
|
||||
✔ refusals (1.897981ms)
|
||||
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (3.85853ms)
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (98.331729ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (55.766765ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (17.47904ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (16.039248ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (17.259974ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (19.048524ms)
|
||||
✔ C2-04: a library first in projects does not hide a later project layer (21.880181ms)
|
||||
✔ systemVars flattens the validated config (1.820728ms)
|
||||
✔ precedence: system, business, project, project role, agent (10.989776ms)
|
||||
✔ limits narrow the definition and never widen it (8.400306ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (18.468852ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (13.185333ms)
|
||||
✔ limits.authority narrows cross-role actions too (2.699689ms)
|
||||
✔ classify (6.249491ms)
|
||||
✔ the record carries what the broker and launcher need (4.7922ms)
|
||||
✔ digest: key order doesn't matter, any value change does (12.395981ms)
|
||||
✔ refusals (3.790542ms)
|
||||
✔ the four shipped version 2 roles load (5.229965ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (2.178782ms)
|
||||
✔ shipped authority follows the note's table (13.291498ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (2.100731ms)
|
||||
✔ version 1 files keep loading with no authority (1.521097ms)
|
||||
✔ the conductor policy isn't a role (0.302424ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.564721ms)
|
||||
✔ version 2 refusals (3.788273ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (3.881951ms)
|
||||
✔ messaging: optional, role definitions and human, never the tester (1.949889ms)
|
||||
✔ row 64 skills: optional, distinct skill directory names, none on version 1 (2.255987ms)
|
||||
✔ credentials: Gitea scopes (1.343013ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.709889ms)
|
||||
✔ credentials: services (0.759517ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.838905ms)
|
||||
✔ the six creative roles load: read tools, message.send only, messaging with the human only (0.693212ms)
|
||||
✔ M1: a creative role file wider than read and answer is refused (1.897832ms)
|
||||
✔ hireable: HIRE_ALLOWED is exactly the six plain work actions, and every one is routed (0.173708ms)
|
||||
✔ hireable: a list naming a definition that holds any refused action refuses at load, one case per action (18.133668ms)
|
||||
✔ hireable: a mixed definition refuses, a clean list loads, and the named file's own hireable isn't read (1.146869ms)
|
||||
✔ hireable: a missing, version 1, duplicate or badly named entry refuses, and the key is optional (3.734122ms)
|
||||
✔ the pm and the cto check a saved spec against settled decisions and work in flight, and answer with a BLOCK or an accept (11.616694ms)
|
||||
✔ the chief of staff relays a BLOCK or an accept to the assistant as a reply to the message that carried it (1.277302ms)
|
||||
✔ the assistant summarizes a spec review in its own words and doesn't repeat the chief of staff's text (0.70976ms)
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (49.216064ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (85.0223ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (67.775561ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (34.296428ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (33.871693ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (33.845575ms)
|
||||
✔ every key names known layers and a merge rule (1.726458ms)
|
||||
✔ unknown keys and wrong layers refuse (1.084085ms)
|
||||
✔ types (3.275461ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.419589ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.757115ms)
|
||||
✔ merge doesn't change its inputs (0.206627ms)
|
||||
✔ web.searxng takes https anywhere and http on loopback, so Jason's 127.0.0.1:8888 passes (0.262745ms)
|
||||
✔ both definitions load, with a contract file, and are exactly the approved lists (5.013658ms)
|
||||
✔ security-reviewer has no write or shell tool and classifies only the verdict as its own (9.066819ms)
|
||||
✔ merge-gate's only grant is git.merge.protected cross-role, and it has no write tool (3.470869ms)
|
||||
✔ neither role can be an arbiter: its messaging lists refuse the business file (row 133) (8.498658ms)
|
||||
✔ every role contract carries the proactive line in its Authority section (1.099286ms)
|
||||
✔ pm and chief-of-staff say where a raise goes under REQ-DEC-2 (0.851681ms)
|
||||
✔ the merge landing takes two runs: merge-gate, cto and chief-of-staff each say their part (0.660442ms)
|
||||
ℹ tests 270
|
||||
ℹ suites 0
|
||||
ℹ pass 270
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2873.146579
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,182 +0,0 @@
|
||||
npm notice run test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ sessionModel: the route is the instance's own vars, and a missing one refuses no-route by name (37.340888ms)
|
||||
✔ a pi bundle: prompt, policy, tools and manifest, 0600 in a 0700 directory (10.573131ms)
|
||||
✔ a chief-of-staff bundle lists launch among the bus tools and the manifest's typed tools (4.412373ms)
|
||||
✔ a chief-of-staff bundle lists end_run, change_organization and set_name as typed and nothing untyped, for either harness (8.193363ms)
|
||||
✔ the stop line names end_run for a role.end holder, and every other role keeps today's text (13.648406ms)
|
||||
✔ a claude-code bundle adds the wrapped gate hook and the MCP config (7.875641ms)
|
||||
✔ the prompt's built-in tools line is the harness's own names, as the manifest lists them (22.548582ms)
|
||||
✔ the prompt names the project clones in the workspace, and none when there are none (13.290253ms)
|
||||
✔ the prompt explains the review loop to a role with push_working, and reviews to one with fetch_review (15.420914ms)
|
||||
✔ the prompt explains landing to a role with land_work, and to no other (9.918107ms)
|
||||
✔ the prompt tells the pm to ask the chief of staff for sessions, and no other role (18.356673ms)
|
||||
✔ a bundle is written once: an existing file refuses (3.135889ms)
|
||||
✔ a path with a single quote can't go into the hook command (3.86973ms)
|
||||
✔ web grant on pi: the bundle has web_search and web_fetch, and no built-in web tool (4.927453ms)
|
||||
✔ no web grant on pi: no web tool in the bundle, and the gate blocks a web call (4.535472ms)
|
||||
✔ web grant on claude-code: the bundle has web_search and web_fetch, and no built-in web tool (4.409455ms)
|
||||
✔ no web grant on claude-code: no web tool in the bundle, and the gate blocks a web call (7.034483ms)
|
||||
✔ a granted session's gate lets the typed web tools through and still blocks the built-ins (6.471178ms)
|
||||
✔ search-source searxng-url: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing (12.185523ms)
|
||||
✔ search-source searxng-bundled: a granted role gets the typed broker tools and no harness web tool; an ungranted role gets nothing (11.958441ms)
|
||||
✔ search-source harness-builtin: claude-code gets WebSearch and WebFetch and no typed web tool, only when granted (12.933659ms)
|
||||
✔ search-source harness-builtin is refused for a granted pi role, which has no built-in web tool (4.064682ms)
|
||||
✔ C2-06 RESULT reply-invalid retries once, delivers only the valid answer and names reason (351.396996ms)
|
||||
✔ C2-06 RESULT citation-missing retries once, delivers only the valid answer and names reason (256.673143ms)
|
||||
✔ C2-06 RESULT citations-over-limit retries once, delivers only the valid answer and names reason (222.852677ms)
|
||||
✔ C2-06 RESULT citation-invalid retries once, delivers only the valid answer and names reason (261.389143ms)
|
||||
✔ C2-06 RESULT playground-cited-as-canon retries once, delivers only the valid answer and names reason (268.849657ms)
|
||||
✔ C2-06 RESULT citation-cross-universe retries once, delivers only the valid answer and names reason (231.674929ms)
|
||||
✔ C2-06 RESULT citation-unfetched retries once, delivers only the valid answer and names reason (216.064282ms)
|
||||
✔ C2-06 RESULT two guard refusals use the citation fixed text and exactly one retry (188.874138ms)
|
||||
✔ C2-06 RESULT JSON 34000 characters retries with a shorter valid answer (236.68605ms)
|
||||
✔ C2-06 RESULT JSON 70000 characters retries with a shorter valid answer (234.722358ms)
|
||||
✔ C2-06 RESULT two oversized JSON bodies use the length fixed text with citations required (193.029509ms)
|
||||
✔ C2-06 multibyte plain bodies also receive the one request-size retry (223.988818ms)
|
||||
✔ C2-06 two multibyte plain bodies use the length fallback (205.649902ms)
|
||||
✔ C2-06 RESULT a length refusal then citation refusal shares one retry and citation fallback (206.128944ms)
|
||||
✔ C2-06 fixed empty/failed replies defer unslop note until the next cited reply (295.722008ms)
|
||||
✔ C2-06 cited JSON above the old 32000 clip retains its citations and text (189.724785ms)
|
||||
✔ C2-06 a flagged cited answer keeps the note inside text and citations whole (192.59344ms)
|
||||
✔ C2-06 send_message typed tool runs every guard code before the valid RESULT (262.703841ms)
|
||||
✔ C2-06 outside library the old failed text, clip and unslop behavior hold (208.584382ms)
|
||||
✔ C2-06 outside library a refused send keeps the existing no-retry behavior (159.048751ms)
|
||||
✔ C2-06 the retry turn delivers citation-unavailable reason to the agent (190.203749ms)
|
||||
✔ allow exits 0, a deny exits 2 with the reason on stderr (211.158287ms)
|
||||
✔ a missing or wrong policy, or a bad event, exits 2 (113.877105ms)
|
||||
✔ the bundle's wrapped command: a missing gate or node still blocks (1104.288151ms)
|
||||
✔ claude: typed tools through MCP, the hook blocks, builtins outside --tools don't exist (1070.940549ms)
|
||||
✔ claude: the hook alone blocks a path outside the workspace (568.174554ms)
|
||||
✔ claude: a second turn resumes the first turn's session (940.097062ms)
|
||||
✔ claude adapter: --restricted is always passed (6.108878ms)
|
||||
✔ claude adapter: MOSAIC_CLAUDE_BIN wins over PATH and must be an absolute executable (19.555633ms)
|
||||
✔ claude adapter: a directory pin exits 2 before it runs; a pin with a space runs (6.450898ms)
|
||||
✔ claude: CLAUDE.md files and auto-memory don't reach the model; without --restricted they do (912.426727ms)
|
||||
✔ claude: a missing hook or MCP file refuses before claude starts (8.255308ms)
|
||||
✔ claude: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after (1813.719749ms)
|
||||
✔ claude: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers (861.243377ms)
|
||||
✔ M2: the gate refuses write, edit and bash to every creative role on pi and claude-code (58.57362ms)
|
||||
✔ M6: no creative session gets raise_decision; the assistant and the chief of staff keep it (27.01682ms)
|
||||
✔ web: research and companion get the broker's typed web tools, and a harness-builtin source refuses web-source-not-allowed (34.87358ms)
|
||||
✔ persona: the block sits between the contract and ## This session, fenced, with the name and digest (10.05189ms)
|
||||
✔ persona: each unsafe or unpinned file refuses before the bundle directory is made (30.976676ms)
|
||||
✔ adapters pass the prompt file's absolute path; the persona and the prompt text never sit in argv (48.053085ms)
|
||||
✔ the pi adapter refuses a missing, unreadable or directory prompt file before pi starts (13.20329ms)
|
||||
✔ pi: policy tools and typed tools pass, anything else is blocked (4.524582ms)
|
||||
✔ claude: builtins map from pi names, typed tools need the mcp prefix (1.1263ms)
|
||||
✔ file tool paths must resolve inside the workspace (4.02957ms)
|
||||
✔ pi's own path normalisation can't be used to step out (1.586245ms)
|
||||
✔ a symlink inside the workspace that points out is outside (1.300474ms)
|
||||
✔ a dangling symlink is refused at any depth, in both harnesses (5.091178ms)
|
||||
✔ read is checked under every spelling pi's read would open, in both harnesses (29.6566ms)
|
||||
✔ other spellings cover directories, dangling links and pi's cwd (2.651598ms)
|
||||
✔ a relative path climbs from the workspace's real path, in both harnesses (9.557314ms)
|
||||
✔ claude path fields per tool (1.146391ms)
|
||||
✔ glob patterns stay inside the workspace (1.220629ms)
|
||||
✔ a path that can't be checked is blocked (0.713439ms)
|
||||
✔ fetch_review's have lists the working refs before origin's, and no more than HAVE_MAX (358.466429ms)
|
||||
✔ fetch_review's have orders the working refs newest first within each clone, one clone after another (177.220281ms)
|
||||
✔ a runner git past its time: SIGTERM reaches its process group, and SIGKILL follows after the grace period (1810.093816ms)
|
||||
✔ once a signalled runner git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (303.717292ms)
|
||||
✔ land_work sends one land line and resolves the host's started answer (3.694332ms)
|
||||
✔ initialize, ping and tools/list (73.055562ms)
|
||||
✔ tools/call goes through the tool socket; a refusal is an isError result (66.566638ms)
|
||||
✔ replies are compact JSON; over the cap a tool error names the size and the cap (60.558157ms)
|
||||
✔ unknown tools and methods are JSON-RPC errors and never reach the socket (52.967178ms)
|
||||
✔ a missing argument is a usage error (35.244954ms)
|
||||
✔ pi: typed tools reach the socket, the gate blocks, agent_end writes the marker (676.072372ms)
|
||||
✔ pi: a reply over the cap is a tool error naming the size and the cap; list_tasks asks for open tasks (532.762084ms)
|
||||
✔ pi: a write through a dangling symlink is blocked, and nothing appears outside (479.264215ms)
|
||||
✔ pi: a read is refused when pi would open another spelling outside (479.008336ms)
|
||||
✔ pi: a relative path climbs from the real path of a workspace behind a symlink (495.496517ms)
|
||||
✔ pi: a relative path climbs from the real path of a dataRoot behind a symlink (458.873867ms)
|
||||
✔ pi: a missing extension refuses before any model call (6.358156ms)
|
||||
✔ pi: an extension without its configuration fails pi's start (380.653357ms)
|
||||
✔ pi: row 66 a reply with a tell gets the correction notice on the next turn, a clean reply gets none, and the counts read after (1353.463628ms)
|
||||
✔ pi: row 66 a broken lists.json gives no clean verdict, the operator is told once, and the session still answers (748.010347ms)
|
||||
✔ raise_decision offers domain as technical or delivery only, optional, and says where a raise goes (23.00088ms)
|
||||
✔ raise_decision forwards domain to decision.raise, and a call without it sends none (100.23044ms)
|
||||
✔ founderCheck: founder variables, then a needed service without a usable token (3.039179ms)
|
||||
✔ turnRequest names the sender, class, reply and decision (0.355597ms)
|
||||
✔ turnRequest says a tester's message is a test and never Jason's instruction (0.317095ms)
|
||||
✔ turnRequest says a user's message is a granted user's and never the owner's instruction (0.277911ms)
|
||||
✔ turnRequest shows the message's own sent time, a day old as well as new (0.227187ms)
|
||||
✔ stateBlock names the launch state with its time and event, and the open tasks with the cap (0.334368ms)
|
||||
✔ a message becomes a turn, the answer goes back as a RESULT, SIGTERM releases and exits 0 (257.255462ms)
|
||||
✔ launches revoked and then restored: the turn's block reads allowed and gives the restore time (272.592717ms)
|
||||
✔ a task closed on the tracker is missing from the next turn's open list (239.571073ms)
|
||||
✔ a message read a day after it was sent shows the time it was sent (148.998515ms)
|
||||
✔ a decision the human resolves becomes a turn citing the decision and the answer (196.043584ms)
|
||||
✔ a failed state read fails the turn: no adapter runs, the sender hears why, the message is read (103.372577ms)
|
||||
✔ a SIGTERM before the claim stops the runner with exit 0 and no claim (91.622163ms)
|
||||
✔ typed tools carry the runner's capability; launch goes to the host's launch socket (336.226718ms)
|
||||
✔ end_run, organization_revision and change_organization reach the broker with the tool's arguments, and refusals keep their codes (429.635331ms)
|
||||
✔ set_name reaches the broker's name.set with the tool's arguments, and refusals keep their codes (182.337097ms)
|
||||
✔ a RESULT gets no automatic reply; failed turns reply with the reason (1269.003752ms)
|
||||
✔ the bus's launch notice is one turn with no reply, and is not taken again (269.091562ms)
|
||||
✔ SIGTERM during a turn kills the turn's process group and still exits 0 (122.399792ms)
|
||||
✔ founder credentials stop before the claim (20) (162.909348ms)
|
||||
✔ a refused claim exits 21; an ended run's capability exits 22 (165.231771ms)
|
||||
✔ the launch ending under a running session exits 22 (134.851141ms)
|
||||
✔ a broker that stays unreachable exits 23 after brokerRetries polls (234.508622ms)
|
||||
✔ a broker that is down at the claim exits 23, not 21 (78.168597ms)
|
||||
✔ no capability, or a malformed one, on stdin exits 2 (194.303544ms)
|
||||
✔ a missing or malformed policy exits 2 before the claim (120.576748ms)
|
||||
✔ REQ-LIMIT-4 runner brackets its actual harness turn before the reply and read receipt (194.53726ms)
|
||||
✔ REQ-LIMIT-4 a runner at its limit stops at the end of its turn: RESULT and read first, then exit 22 and a limit-check revoke (168.261307ms)
|
||||
✔ landingRequest is the fixed template, with the decision and task ref and nothing else (0.147237ms)
|
||||
✔ each landing entry is one turn before any message, with the state block and the fixed request; it sends nothing and reads nothing (226.715761ms)
|
||||
✔ an empty landing takes no landing turn: the message is turn 1 (195.475495ms)
|
||||
✔ a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages (596.516739ms)
|
||||
✔ a malformed landing exits 2 before the claim, with no turn (568.856934ms)
|
||||
✔ row 65 a session.json without a turnEnd of marker or exit, or a harnessEnv of strings, exits 2 before the claim (269.597797ms)
|
||||
✔ row 65 harnessEnv reaches the adapter, and an exit harness needs no turn marker (141.169295ms)
|
||||
✔ row 66 the adapter gets the run's unslop log, and a flagged reply's note rides that reply's RESULT, once (300.426996ms)
|
||||
✔ row 66 a turn with no reply holds its note for the next reply; a broken check is told once (345.164969ms)
|
||||
✔ row 66 unslopNotes keeps a note until sent(), reads only whole lines, and unslopCounts reads a log after the session (1.68702ms)
|
||||
✔ row 66 a clipped answer with both note parts stays under the bus's body limit, and the note under 600 (161.518813ms)
|
||||
✔ row 66 a refused send keeps the note: it rides the next RESULT the session sends (264.81696ms)
|
||||
✔ each repo role's prompt carries exactly its listed skills, each file as the bundle copy and the source (69.791416ms)
|
||||
✔ a skill's files go into the prompt in sorted path order, sub-directories included (9.238961ms)
|
||||
✔ a role with no skills gets no Skills section, no skills directory and an empty manifest list (11.39746ms)
|
||||
✔ an enabled skill the role doesn't list stays out of the prompt (8.706347ms)
|
||||
✔ the bundle copy outlives the source: deactivating a skill after the build leaves the run's copy (4.473957ms)
|
||||
✔ a listed skill that isn't enabled refuses skill-not-enabled, naming the activate command (9.541232ms)
|
||||
✔ a skill directory that isn't plain refuses: a symlinked skill, SKILL.md or sub-file, or a non-file entry (2.643822ms)
|
||||
✔ a skill file that can't go into the prompt refuses: a bad name, non-UTF-8 bytes, or the end marker (3.518581ms)
|
||||
✔ a role's skills over SKILL_BYTES together refuse, naming the skill that crossed it (10.193929ms)
|
||||
✔ each adapter passes the skills only in the prompt file, with skill discovery off (59.00799ms)
|
||||
✔ every role sees read_spec, record writer follows its grant, citation schemas stay strict (25.138022ms)
|
||||
✔ typed socket forwards read content/history and agent record writes, and cannot write a spec (172.529974ms)
|
||||
✔ the PM gets its task verbs and the reads, and no launch (11.972118ms)
|
||||
✔ send_message offers the BLOCK class, beside the classes it already had (3.837774ms)
|
||||
✔ the chief of staff gets launch, send_message, end_run, hire, fire, change_organization and set_name, and no task verbs (4.871494ms)
|
||||
✔ hire and fire send instance.hire and instance.fire under role.hire and role.fire, only for a holder of the grant (22.751702ms)
|
||||
✔ request_staff is the pm's alone: staff.request over message.send, roles and counts bounded (15.291362ms)
|
||||
✔ end_run sends role and reason, no decision; change_organization sends revision and the organization keys (2.689052ms)
|
||||
✔ set_name sends instance and name to name.set under instance.name, only for a holder of that grant (12.695737ms)
|
||||
✔ the organization keys change_organization takes are the broker's ORGANIZATION_KEYS and the settings' SETTINGS_KEYS (0.178758ms)
|
||||
✔ a role without role.end or organization.change gets none of the three tools, and each follows its own grant (12.115972ms)
|
||||
✔ no role's tools send instances or instances.set, and change_organization takes no instance write keys (10.7825ms)
|
||||
✔ the assistant gets send_message, the reads and the web tools (it holds the web grant), no launch (2.17462ms)
|
||||
✔ list_requirements reads the requirement ids, for a task.create holder with a tracker (3.939398ms)
|
||||
✔ a coder gets no launch, no resolve_decision, and no task tools without a tracker (3.125698ms)
|
||||
✔ a coder with a tracker gets its own task tools and no task_reassign (2.258296ms)
|
||||
✔ launch only when the business's launch block names the instance as launcher (3.280204ms)
|
||||
✔ an action outside the instance's authority has no tool (1.994949ms)
|
||||
✔ the review loop: push_working and request_review for the coder, fetch_review and review_verdict for the reviewer, none for the PM (7.387015ms)
|
||||
✔ land_work is there only with land, after push_working, with the task and the decision (4.431191ms)
|
||||
✔ callTool: one JSON line out, the result back, a refusal rejects (16.610729ms)
|
||||
✔ list_tasks takes the broker's filters and pages; get_task takes a task_ref (4.144909ms)
|
||||
✔ callTool sends list_tasks done false unless the session names done; other tools as given (3.985977ms)
|
||||
✔ replyText: compact JSON up to the cap, an error naming the size and the cap over it (1.008682ms)
|
||||
✔ web_search's query maxLength is the web layer's SEARCH_MAX_QUERY_CHARS (4.810935ms)
|
||||
ℹ tests 172
|
||||
ℹ suites 0
|
||||
ℹ pass 172
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12131.328093
|
||||
@@ -1,153 +0,0 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/*.test.mjs
|
||||
✔ C2-06 reply schema: free bodies, exact objects and safe refusal reasons (31.081491ms)
|
||||
✔ C2-06 citation setting and all four exact fixed texts (27.31137ms)
|
||||
✔ C2-06 default citation cap passes 20 and refuses 21, even with optional citations (144.940253ms)
|
||||
✔ C2-06 real Git citation scope, reachability, lines and normalized quotes (71.988432ms)
|
||||
✔ C2-06 playground cites pass but cannot state canon (42.141068ms)
|
||||
✔ C2-06 independent universes refuse; a hybrid and only its sources pass (69.134397ms)
|
||||
✔ C2-06 web cites require allowed definition, this session fetch and kept quote (17.090852ms)
|
||||
✔ C2-06 file origin is the path commit and trailer, while last follows served changes (51.160201ms)
|
||||
✔ C2-06 origin uses literal paths even when a filename contains a glob (35.841257ms)
|
||||
✔ C2-06 cited-commit guard reads exactly the C2-05a indexed file set with supporting scope (79.711572ms)
|
||||
✔ C2-06 reply limits fall back independently without coercion or inherited keys (0.78046ms)
|
||||
✔ the same commit, repo path and mapping return the same index, and only mapped files are in it (53.330474ms)
|
||||
✔ a different repo path, mapping or commit gets its own index (73.465944ms)
|
||||
✔ the cache holds at most eight indexes and evicts the least recently used (93.355098ms)
|
||||
✔ a failed read is not kept in the cache (19.15839ms)
|
||||
✔ a missing or unchecked mapping is refused before any read (18.591276ms)
|
||||
✔ a 3,000-file rebuild completes and its time is reported (3339.384537ms)
|
||||
ℹ 3,000-file index rebuild: 3093 ms
|
||||
✔ resolver step 1: a path from the repo root, with or without .md (2.003164ms)
|
||||
✔ resolver step 2: the same path with vaultPrefix/ stripped (0.323373ms)
|
||||
✔ resolver step 3: a path relative to the linking file, never above the repo root (0.278534ms)
|
||||
✔ resolver step 4: a base name that matches exactly one indexed file (0.322938ms)
|
||||
✔ a link into another of her repos resolves to nothing (0.213594ms)
|
||||
✔ wikilink forms, embeds, and links skipped inside code (1.24016ms)
|
||||
✔ only a body embed whose target has an extension other than .md, in any case, is an attachment (0.455416ms)
|
||||
✔ the fixture mapping checks and comes back frozen (2.830981ms)
|
||||
✔ C2-01c: a prefix inside or holding another entry's book refuses library-playground-other-universe (1.34922ms)
|
||||
✔ C2-01c: a prefix equal to a book folder, or holding its own, refuses library-mapping-invalid (0.74756ms)
|
||||
✔ C2-01c: universe-level prefixes lie outside every book, in a plain universe and in a hybrid with no books (1.203696ms)
|
||||
✔ C2-01c: a draft takes kind, name and playground only, and comes back frozen with books [] (1.782129ms)
|
||||
✔ C2-01d: supporting prefixes at book level, universe level, in a hybrid and in a draft, [] when absent (0.643444ms)
|
||||
✔ C2-01d: each supporting prefix rule refuses with its code (2.880363ms)
|
||||
✔ C2-01d: between the lists, a supporting prefix may equal its own playground, and a playground may hold its own supporting (0.978814ms)
|
||||
✔ C2-01d: editor is optional, kept when given, and refuses anything but a plain name and email (5.417269ms)
|
||||
✔ C2-01d: an accepted editor round-trips through a real git commit unchanged (22.81842ms)
|
||||
✔ no playground prefix holds another, and no book folder holds another (1.309845ms)
|
||||
✔ shape refusals: kind, remote, branch, unknown keys, types, manuscript, folder names (1.68793ms)
|
||||
✔ C2-03a sage-2021: user is optional, kept when given, and must be a plain account name (0.986251ms)
|
||||
✔ a hybrid universe is a shape the query code can take (1.4), with sources that must exist (1.600445ms)
|
||||
✔ a caller-supplied fail receives the code, as business file loading will pass it (C2-04) (0.396233ms)
|
||||
✔ scope comes from the path alone (design 1.2) (2.453311ms)
|
||||
✔ C2-04 mirror: exact default path, bare without checkout or remote, and idempotent initialization (82.599485ms)
|
||||
✔ C2-04 mirror: simultaneous creators publish one intact mirror and leave no staging paths (49.399699ms)
|
||||
✔ C2-04 mirror: skipped publication accepts both coreutils statuses without removing the winner (174.577156ms)
|
||||
✔ C2-04 mirror: preserve occupied directories and reject symlink ancestors and code overlaps (20.556264ms)
|
||||
✔ C2-04 mirror: existing metadata accepts only bare Git plus state and the precreated lock (34.414614ms)
|
||||
✔ C2-04 state: missing state is empty only while the served ref is absent (54.101069ms)
|
||||
✔ C2-04 state: valid problems and sync metadata return no content and change no state bytes (57.832223ms)
|
||||
✔ C2-04 state: strict keys, types, times, branch, commit and fixed R messages fail closed (158.515834ms)
|
||||
✔ C2-04 state: symlink, hardlink, non-private state and missing lock refuse without replacement (57.609887ms)
|
||||
✔ C2-04 file: served commit, not HEAD or a caller commit, owns the exact returned text (113.829438ms)
|
||||
✔ C2-04 file: R1, R2 and R7 exclusions and never-synced mirrors cannot return file bodies (124.255784ms)
|
||||
✔ C2-04 lock: a first-sync and fast-forward reader wait for a consistent pair across processes (314.221744ms)
|
||||
✔ C2-04 lock: same-process waits, timeout code, callback expiry and throw release (5038.833094ms)
|
||||
✔ C2-04 lock: owner death releases the kernel lock without replacing its file (54.543028ms)
|
||||
✔ C2-04 lock: a missing flock binary becomes a handled refusal (49.73045ms)
|
||||
✔ C2-04 lock: an unawaited scoped read drains before the lock is released (20.869629ms)
|
||||
✔ the query reply cap equals the harness reply cap (1.544541ms)
|
||||
✔ find is bound to its universe and refuses a call without one (70.281377ms)
|
||||
✔ every result carries its scope, and playground appears only when asked for (39.878964ms)
|
||||
✔ unmapped files never appear in any reply (35.123505ms)
|
||||
✔ a hybrid sees its sources canon, minus exclusions, and no playground (39.679182ms)
|
||||
✔ a hybrid gets a source file it can see, and not an excluded or foreign one (54.602693ms)
|
||||
✔ get lists visible links both ways and drops a target another universe cannot see (50.638492ms)
|
||||
✔ a long list pages by position, never cuts an item, and returns 50 per page (193.227492ms)
|
||||
✔ a page stays under the reply cap when items are large (91.885035ms)
|
||||
✔ a search line too long to fit alone comes back marked, with no excerpt, and the other hits still return (33.20163ms)
|
||||
✔ a find item that cannot fit alone is refused, not cut (46.447292ms)
|
||||
✔ get pages its lines, and the next line picks up where the page stopped (39.12526ms)
|
||||
✔ get refuses a file whose front matter alone is over the cap, and a line alone is over the cap (36.804238ms)
|
||||
✔ get pages the links of a hub note, every page carries the front matter, and the pages add up (1107.995321ms)
|
||||
✔ get rejects a bad links_from (34.377162ms)
|
||||
✔ search returns scoped line hits, case-insensitively, and refuses empty text (30.729667ms)
|
||||
✔ a manuscript call returns one chapter, at most 400 lines, and names its next line (47.791378ms)
|
||||
✔ a manuscript call without a chapter returns the first chapter in path order and names the next (26.366902ms)
|
||||
✔ a chapter name that matches two visible files is refused (25.448584ms)
|
||||
✔ a hybrid reads a source chapter through its declared sources only (39.969561ms)
|
||||
✔ universe info reports a hybrid sources, constraints and notes, and refuses an unknown universe (15.657923ms)
|
||||
✔ an exclusion hides what it names from a hybrid and from nothing else (39.404555ms)
|
||||
✔ PRD 1.14: a lookup that names a book leaves book-null files out (34.647951ms)
|
||||
✔ PRD 1.14: library_manuscript never reads a book-null file (32.637362ms)
|
||||
✔ PRD 1.14: a draft universe has no canon, so its lookups return files only with scope playground (32.338176ms)
|
||||
✔ PRD 1.14: library_universe on a draft returns its kind, name and prefixes (15.442774ms)
|
||||
✔ a hybrid gets a source playground file as null, while the source gets it with scope playground (42.674554ms)
|
||||
✔ the fixture reads clean: every resolver step, appears_in and relationships wikilinks indexed (63.033383ms)
|
||||
✔ R1: executables, symlinks, gitlinks, blobs over 1 MiB and non-UTF-8 text are not indexed (95.339567ms)
|
||||
✔ R2: unmapped paths are reported and not indexed (31.564751ms)
|
||||
✔ R3: front matter not fully parsed stays raw, with the line where parsing stopped (36.896696ms)
|
||||
✔ front matter forms the reader accepts and refuses (1.596508ms)
|
||||
✔ R4: a link to no file, to more than one, or into another repo is reported and not followed (35.504393ms)
|
||||
✔ a block list link carries its item line, a scalar or flow link its key line, and problems follow (37.229678ms)
|
||||
✔ an unresolved attachment embed gives no problem; a link or front matter value to one is R4; a note embed resolves (33.783255ms)
|
||||
✔ an indexed Dr.Quinn.md resolves as a body link, a block list link and an embed (33.230236ms)
|
||||
✔ R5: a canon file that refers into the playground is reported, and the link still goes by path (29.709099ms)
|
||||
✔ R6: a canon file that refers into another universe is reported; a hybrid may refer into its sources (30.970646ms)
|
||||
✔ R7: two paths that differ only in case are both left out (41.126208ms)
|
||||
✔ the reader reads the commit, never the working tree, and refuses a bad commit id (41.98282ms)
|
||||
✔ a bare mirror reads the same as the clone (53.445984ms)
|
||||
✔ renderItems snapshot: fact (1.786386ms)
|
||||
✔ renderItems snapshot: finding (0.299155ms)
|
||||
✔ renderItems snapshot: correction (0.259329ms)
|
||||
✔ renderItems snapshot: question (0.218182ms)
|
||||
✔ renderItems snapshot: idea (0.223821ms)
|
||||
✔ renderItems numbers several items and takes a parsed body as well as a string (1.090019ms)
|
||||
✔ without options a path cite has no badge and is never marked changed (0.280013ms)
|
||||
✔ renderItems snapshot: notice no-cited-answer (0.237711ms)
|
||||
✔ renderItems snapshot: notice no-answer (0.198705ms)
|
||||
✔ renderItems snapshot: notice turn-failed (0.337126ms)
|
||||
✔ a body without the reply shape shows a fixed line and none of its text (0.613863ms)
|
||||
✔ C2-01c: each level gives its universe, and its book or null (4.092943ms)
|
||||
✔ C2-01c: prefixes come first: in a book that holds a prefix, a file outside it is canon and one under it playground (0.607188ms)
|
||||
✔ C2-01c: a canon file linking into a draft gives R6, and into its own universe-level prefix gives R5 (65.023589ms)
|
||||
✔ C2-01d: each supporting level gives its universe, and its book or null (0.8244ms)
|
||||
✔ C2-01d: supporting comes before playground; a folder in both lists is supporting, one in the playground only stays playground (0.633065ms)
|
||||
✔ C2-01d: only .md files are supporting; a .canvas or .base under a supporting prefix is unmapped (0.517375ms)
|
||||
✔ C2-01d: a path passes at book level, universe level, in a draft and in a folder in both lists (2.312377ms)
|
||||
✔ C2-01d: a path of exactly 1024 bytes passes, and 1025 bytes made of multi-byte characters refuses (0.98988ms)
|
||||
✔ C2-01d: a path outside the universe's supporting folders refuses (0.763326ms)
|
||||
✔ C2-01d: malformed paths refuse by class, in order (0.710036ms)
|
||||
✔ C2-01d: a symlink or gitlink on the way, or at the path itself, refuses (0.383033ms)
|
||||
✔ C2-01d: a name that differs from a tree name only in case or Unicode form refuses, at the file or any folder (0.99427ms)
|
||||
✔ the survey prints folder names, counts, key sets and link-form counts, and never text (65.469359ms)
|
||||
✔ folder names print DEL, C1 and bidi controls, U+061C among them, as escapes (37.571162ms)
|
||||
✔ an embed of an attachment counts as an embed and as an attachment; a plain link to one does not (24.053267ms)
|
||||
✔ with --mapping the survey adds scope, resolver step and problem counts (51.551822ms)
|
||||
✔ C2-01d: with --mapping the survey counts supporting files (49.232972ms)
|
||||
✔ survey exit codes: usage 4, bad mapping 3, unreadable repo 2 (19.679523ms)
|
||||
✔ scripts/mosaic library survey reaches the survey (97.237921ms)
|
||||
✔ C2-03a argv: the fixed sequence, one https allow, no other protocol key (2.539459ms)
|
||||
✔ C2-03a argv: only an https URL with a plain host, no userinfo, and a plain user (1.147619ms)
|
||||
✔ C2-03a helper: answers only the exact prompts for the configured host and user (dewey-0765) (43.662638ms)
|
||||
✔ C2-03a first sync: served is the fetched tip, HEAD is served, the survey reads it, and the token stays in the slot (199.624214ms)
|
||||
✔ C2-03a fast-forward: served moves, problems are rebuilt, and a repeat changes only lastFetch (272.12795ms)
|
||||
✔ C2-03a Filbert N2: a read that took served before a sync still finds its objects after served moves (255.892244ms)
|
||||
✔ C2-03a overlap: a reader during a sync sees the old pair or the new one, never a mix (220.077465ms)
|
||||
✔ C2-03a diverged: a non-fast-forward keeps serving and holds until a human accepts the tip (511.485441ms)
|
||||
✔ C2-03a accept starts the record over, so a changed branch gets a fresh state (204.895458ms)
|
||||
✔ C2-03a fetch failure: a wrong token keeps serving and records the error, lastFetch unchanged (210.171392ms)
|
||||
✔ C2-03a a failed first fetch records the error with nothing served (57.52009ms)
|
||||
✔ C2-03a a 302 to another host fails the fetch and the other host sees nothing (68.211135ms)
|
||||
✔ C2-03a the slot: missing or unsafe refuses before git, and sync never opens it (65.636096ms)
|
||||
✔ C2-03a sage-2021: an entry with no user refuses library-remote-invalid and runs no git (34.004871ms)
|
||||
✔ C2-03a one sync per mirror: an overlapping call refuses library-sync-busy (129.134012ms)
|
||||
ℹ tests 142
|
||||
ℹ suites 0
|
||||
ℹ pass 142
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 6490.060843
|
||||
@@ -1,2 +0,0 @@
|
||||
1 match: replyLimitsFence(old, document, actor);
|
||||
1 match: replyLimitsFence(old, written, actor);
|
||||
@@ -1 +0,0 @@
|
||||
M5-hide-library-unavailable: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
@@ -1,11 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5151.319291ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (37.53806ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (35.257703ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5310.30031
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5147.642347ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (32.256875ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.701926ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5295.499085
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
168dcac99d9bfdfdf5ff0eaa2c0fff91595b351b4d0092dc299532c9c32869f0 packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,68 +0,0 @@
|
||||
✖ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5108.905478ms)
|
||||
✖ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (40.518617ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (37.68422ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5261.169843
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/citation-availability.test.mjs:13:1
|
||||
✖ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5108.905478ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'citation-invalid'
|
||||
- 'citation-unavailable'
|
||||
^
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/bus/tests/citation-availability.test.mjs:29:14)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.rejects (node:assert:738:3)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/bus/tests/citation-availability.test.mjs:28:5
|
||||
at async withLibraryLock (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/library/src/mirror.mjs:171:18)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/bus/tests/citation-availability.test.mjs:27:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'citation-invalid',
|
||||
expected: 'citation-unavailable',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/citation-availability.test.mjs:40:1
|
||||
✖ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (40.518617ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'citation-invalid'
|
||||
- code: 'citation-unavailable'
|
||||
}
|
||||
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/bus/tests/citation-availability.test.mjs:45:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: citation-invalid: citation 1 (Book One/Characters/Mara Vell.md) isn't an indexed file at a commit reachable from the served commit
|
||||
at refuse (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/library/src/guard.mjs:24:42)
|
||||
at checkReply (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/library/src/guard.mjs:80:25)
|
||||
at async waitForActual (node:assert:615:5)
|
||||
at async strict.rejects (node:assert:738:25)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-pd3x2htc/packages/bus/tests/citation-availability.test.mjs:45:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
|
||||
expected: { code: 'citation-unavailable' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
M5-hide-library-unavailable: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
@@ -1,5 +0,0 @@
|
||||
M1-writer-fence: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M2-incoming-human: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M3-split-check-transaction: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M5-hide-library-unavailable: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M4-drop-client-reason: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (29.278355ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (22.040025ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (8.805323ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (8.829275ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (9.171416ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (10.423621ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 139.016448
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (27.397407ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (23.565905ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (8.312613ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (8.050944ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (8.746752ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (11.061782ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 137.787038
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,73 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (26.703775ms)
|
||||
✖ C2-06 M11 agents and tester cannot change settings, including by changing human (12.156717ms)
|
||||
✖ C2-06 M11 serialization cannot replace settings after the first fence (11.431272ms)
|
||||
✖ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (14.308135ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (9.043165ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (9.576698ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 131.91294
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/reply-limits.test.mjs:34:1
|
||||
✖ C2-06 M11 agents and tester cannot change settings, including by changing human (12.156717ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refused (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:37:5)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-reply-limits-human-only' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/reply-limits.test.mjs:43:1
|
||||
✖ C2-06 M11 serialization cannot replace settings after the first fence (11.431272ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refused (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:45:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-reply-limits-human-only' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/reply-limits.test.mjs:52:1
|
||||
✖ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (14.308135ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refused (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-m6rnq3wd/packages/business/tests/reply-limits.test.mjs:54:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-reply-limits-human-only' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (31.955623ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (22.832309ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (9.274775ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (8.69039ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (8.733202ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (10.441869ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 143.570268
|
||||
@@ -1,14 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (29.948602ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (22.139351ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (9.054641ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (8.381635ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (9.081946ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (10.33004ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 141.370383
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,35 +0,0 @@
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (28.334896ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (22.541196ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (8.304131ms)
|
||||
✖ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (11.712463ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (8.875517ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (9.882976ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 5
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 140.418146
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/reply-limits.test.mjs:52:1
|
||||
✖ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (11.712463ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at refused (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-_aqjby1c/packages/business/tests/reply-limits.test.mjs:22:10)
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-_aqjby1c/packages/business/tests/reply-limits.test.mjs:54:3)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-reply-limits-human-only' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (118.943843ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (94.790271ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (65.901789ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (41.908138ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (48.179621ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (41.94764ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (56.521104ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (88.283371ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (55.47311ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.321347ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (77.5591ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (24.639839ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (42.159103ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 866.146033
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (162.15169ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (151.110586ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (100.984805ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (81.389166ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (92.148118ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (78.197117ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (168.055107ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (271.850306ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (92.491602ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (61.315017ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (126.633466ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (61.436932ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (118.486786ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1649.634687
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,41 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (121.738375ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (94.199334ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (59.307121ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (41.252933ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (48.700382ms)
|
||||
✖ C2-06 check evidence and insert are atomic when storing evidence fails (42.434516ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (56.552861ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (88.426285ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (54.352185ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.064514ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (81.176348ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (25.324993ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (42.147552ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 872.02572
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/citation-guard.test.mjs:71:1
|
||||
✖ C2-06 check evidence and insert are atomic when storing evidence fails (42.434516ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
1 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-etkv3bqf/packages/bus/tests/citation-guard.test.mjs:76:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 1,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (107.311079ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (92.235404ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (59.017311ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (41.107066ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (47.696908ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (41.214066ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (54.665908ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (86.001777ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (55.168942ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.744539ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (79.212003ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (24.722314ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (41.933148ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 841.716764
|
||||
@@ -1,21 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (110.781773ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (91.548051ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (57.119223ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (40.819326ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (47.776616ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (41.268825ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (53.375873ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (82.822565ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (54.131458ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.350984ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (80.819295ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (26.401011ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (41.116925ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 13
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 839.688386
|
||||
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,47 +0,0 @@
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (109.280676ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (94.019544ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (58.84355ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (42.275234ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (48.954969ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (41.628985ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (54.367118ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (85.049228ms)
|
||||
✖ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (53.346085ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.218776ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (78.373306ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (24.622347ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (41.8227ms)
|
||||
ℹ tests 13
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 840.560306
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/citation-guard.test.mjs:116:1
|
||||
✖ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (53.346085ms)
|
||||
AssertionError [ERR_ASSERTION]: The validation function is expected to return "true". Received false
|
||||
|
||||
Caught error:
|
||||
|
||||
Error: citation-invalid
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-db3vgbd1/packages/bus/tests/citation-guard.test.mjs:121:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: citation-invalid
|
||||
at Socket.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-db3vgbd1/packages/bus/src/client.mjs:45:17)
|
||||
at Socket.emit (node:events:514:20)
|
||||
at addChunk (node:internal/streams/readable:575:12)
|
||||
at readableAddChunkPushByteMode (node:internal/streams/readable:526:3)
|
||||
at Readable.push (node:internal/streams/readable:406:5)
|
||||
at Pipe.onStreamRead (node:internal/stream_base_commons:189:23),
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5143.590096ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (33.560438ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.849587ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5290.343804
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5131.56715ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (32.560014ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.756895ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5271.350019
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
eeca81ab965f9e94f930ee5f51d16f019af6368bc6c3994895e204f7a54ec8d2 packages/bus/src/broker.mjs
|
||||
ad3c686a089f67f3c89610937c6fc9b32367cea5d9735125d89bef042082d4e8 packages/bus/src/client.mjs
|
||||
36b05dd3119e5929211aa1cc5d45c5043f5a1c34567ddc7cac8f002835d44abe packages/bus/src/runtime.mjs
|
||||
66b26d131a19f4f411686427274936850c1ff0aed11e9b281ae4aadcf4b289fc packages/bus/src/server.mjs
|
||||
cdd0304ec25ef1ad3e31c52502fa46f2c80bd77c8d3c2e13f8ed4b5328f342c9 packages/bus/tests/citation-availability.test.mjs
|
||||
2e05074cd9d15d810103658af3858161cee2af78b0a2e1ba910222fab3e84401 packages/bus/tests/citation-guard.test.mjs
|
||||
2c7a2102e2e0244876e41b664f4f706baefe3375100b956655551db1230f5da3 packages/bus/tests/citation-helpers.mjs
|
||||
9768b6dc5ae078c5cc4f76473097287b74c5bc5853d39e1f57f153e646f861af packages/bus/tests/citation-runtime.test.mjs
|
||||
abaeac64f2c3bf8ba83c9a4488edd9105c4707a6564560c5333d5421445653af packages/business/src/business.mjs
|
||||
3a6044de5d1ca2cc35c5285b460c3e402b4274837e5d88b97f489797f6004903 packages/business/src/organization.mjs
|
||||
4d2eb11beaa80175e524af1b95c81e7164990fba1d3e1754f5ba06eee390a14f packages/business/tests/reply-limits.test.mjs
|
||||
a2bb98734bcc2556f8b2168f0faf8a89f7064c3f0aa49feb7d1975d596192f09 packages/cli/README.md
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
f38af2d46d5f5f6388f599912507b94b87a0bf9dcc2104bb2187c38ee35118d5 packages/cli/tests/reply-limits.test.mjs
|
||||
6ad72b4245e0a66e32725941900c1ece64c2e5de2fb73d65c8e042b4f3a691a6 packages/harness/src/runner.mjs
|
||||
a5ef1b65230239a7baf6d0e8f2b8a51c0516348c7c4339a55b3f0a1a6ff531ba packages/harness/tests/citation-runner.test.mjs
|
||||
330bc71bf6c7e64d3ddb70440903d2d9acf7878d44a49d7e30c2352ee4c807ec packages/harness/tests/fixtures/citation-adapter.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
c0d630798914e300e461c247340533328e97119e54909c6a9406340e61fed8b7 packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
406146ebbce3710f308243b684a1c17e7626c1b65a4468489364317e31537a48 packages/library/tests/guard.test.mjs
|
||||
39c8e6c8250a13fa43015fb2c407195e30ee642f729a9f6a644c38b4ea758a72 packages/seat/src/sandbox.mjs
|
||||
@@ -1,70 +0,0 @@
|
||||
✖ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5104.72293ms)
|
||||
✖ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (35.117198ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.286656ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 5250.151124
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/citation-availability.test.mjs:13:1
|
||||
✖ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5104.72293ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'citation-invalid'
|
||||
- 'citation-unavailable'
|
||||
^
|
||||
|
||||
at Object.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/bus/tests/citation-availability.test.mjs:29:14)
|
||||
at expectedException (node:assert:547:17)
|
||||
at expectsError (node:assert:672:21)
|
||||
at strict.rejects (node:assert:738:3)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/bus/tests/citation-availability.test.mjs:28:5
|
||||
at async withLibraryLock (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/library/src/mirror.mjs:171:18)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/bus/tests/citation-availability.test.mjs:27:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'citation-invalid',
|
||||
expected: 'citation-unavailable',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/citation-availability.test.mjs:40:1
|
||||
✖ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (35.117198ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
Comparison {
|
||||
+ code: 'citation-invalid'
|
||||
- code: 'citation-unavailable'
|
||||
}
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/bus/tests/citation-availability.test.mjs:45:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: citation-invalid: citation 1 (Book One/Characters/Mara Vell.md) isn't an indexed file at a commit reachable from the served commit
|
||||
at refuse (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/library/src/guard.mjs:24:42)
|
||||
at checkReply (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/library/src/guard.mjs:80:25)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async waitForActual (node:assert:615:5)
|
||||
at async strict.rejects (node:assert:738:25)
|
||||
at async TestContext.<anonymous> (file:///mnt/storage/scratch/tmp/tNoueZ/row217-mutant-xglaeqeb/packages/bus/tests/citation-availability.test.mjs:45:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7),
|
||||
expected: { code: 'citation-unavailable' },
|
||||
operator: 'rejects',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
M1-writer-fence: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M2-incoming-human: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M3-split-check-transaction: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M5-hide-library-unavailable: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
M4-drop-client-reason: killed (control green, mutant exit 1, hashes restored, restored green)
|
||||
@@ -1,3 +0,0 @@
|
||||
npm warn deprecated [email protected]: Use your platform's native DOMException instead
|
||||
|
||||
added 128 packages in 2s
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
added 2 packages in 205ms
|
||||
@@ -1,9 +0,0 @@
|
||||
✔ C2-06 runtime reads changed and unreadable reply limits without restarting (118.083931ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 227.817729
|
||||
@@ -1,234 +0,0 @@
|
||||
npm notice run @mosaic/[email protected] test
|
||||
npm notice run node --test tests/
|
||||
✔ C2-04: ensureCheckouts skips a library before a real clone and leaves no books path (66.766764ms)
|
||||
✔ a first launch clones the root at its branch, with the root's path as origin (47.521672ms)
|
||||
✔ the clone is not at its place until git clone has finished (31.999361ms)
|
||||
✔ a later launch fast-forwards a clean clone after a commit to the root, then finds it current (87.563022ms)
|
||||
✔ a clone ahead of the root keeps its commits and counts as current (53.447311ms)
|
||||
▶ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves
|
||||
✔ a modified file (53.258759ms)
|
||||
✔ an untracked file (52.286642ms)
|
||||
✔ a staged file (55.132154ms)
|
||||
✔ another branch (53.48074ms)
|
||||
✔ a detached HEAD (54.504119ms)
|
||||
✔ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves (269.989404ms)
|
||||
✔ a diverged clone gets the fetch into refs/remotes and is kept, not-fast-forward (53.461206ms)
|
||||
▶ a clone kept before the branch check, or for a failed status, gets no fetch
|
||||
✔ not-a-clone (27.485728ms)
|
||||
✔ hooks-present (31.094616ms)
|
||||
✔ submodule (38.060187ms)
|
||||
✔ config-changed (36.195255ms)
|
||||
✔ root-unreadable (36.385271ms)
|
||||
✔ root-detached (39.627905ms)
|
||||
✔ status-failed, on the root's branch and clean (42.704327ms)
|
||||
✔ status-failed, dirty (44.881211ms)
|
||||
✔ a clone kept before the branch check, or for a failed status, gets no fetch (297.899967ms)
|
||||
✔ a dirty clone whose fetch fails is kept, fetch-failed, exactly as it was (47.755395ms)
|
||||
✔ every git call the host makes, for a new clone and an existing one, carries maintenance.auto=false and gc.auto=0 (57.603139ms)
|
||||
✔ a clone with loose objects enough for gc --auto gets no maintenance or gc from the fetch and the merge (89.466874ms)
|
||||
▶ a clone with user.name or user.email in its config is kept, and git runs nothing in it
|
||||
✔ user.name (28.628791ms)
|
||||
✔ user.email (30.423895ms)
|
||||
✔ a clone with user.name or user.email in its config is kept, and git runs nothing in it (59.627127ms)
|
||||
✔ a commit git can't read after the fast-forward is null (57.084762ms)
|
||||
✔ a new clone whose commit can't be read refuses the launch and leaves nothing behind (21.081119ms)
|
||||
▶ a clone the session rigged is kept, and git runs nothing and writes nothing outside it
|
||||
✔ core.fsmonitor (39.453854ms)
|
||||
✔ core.hooksPath (34.616469ms)
|
||||
✔ a hook file (35.090442ms)
|
||||
✔ include.path (34.527401ms)
|
||||
✔ includeIf (35.13899ms)
|
||||
✔ a filter driver (34.195382ms)
|
||||
✔ origin moved (37.391948ms)
|
||||
✔ a second origin url (35.731817ms)
|
||||
✔ the origin url twice, both the root (33.999145ms)
|
||||
✔ an ext:: origin (31.652835ms)
|
||||
✔ a branch tracking another remote (33.3147ms)
|
||||
✔ a branch merging a tag (33.72502ms)
|
||||
✔ a fetch line onto local branches (34.126505ms)
|
||||
✔ no origin (32.973963ms)
|
||||
✔ a config file over the size cap (30.967833ms)
|
||||
✔ config a symlink to /dev/zero (31.51332ms)
|
||||
✔ the clone a symlink to the bait (32.976685ms)
|
||||
✔ the clone a file (39.528201ms)
|
||||
✔ the clone a plain directory (32.193931ms)
|
||||
✔ .git a gitdir: file (31.732811ms)
|
||||
✔ .git a symlink (36.499471ms)
|
||||
✔ .git/logs a symlink (34.327705ms)
|
||||
✔ .git/refs/heads a symlink (30.308688ms)
|
||||
✔ .git/objects a symlink (28.895664ms)
|
||||
✔ a reflog hard-linked to a file outside (28.33422ms)
|
||||
✔ HEAD a fifo (29.791372ms)
|
||||
✔ a commondir file (30.182546ms)
|
||||
✔ an alternates file (30.414863ms)
|
||||
✔ a gitlink staged, no .gitmodules (42.003032ms)
|
||||
✔ a gitlink and .gitmodules staged (47.484582ms)
|
||||
✔ a gitlink to a repository with its own gitlink (53.625899ms)
|
||||
✔ a gitlink and .gitmodules committed (45.90129ms)
|
||||
✔ a gitlink and submodule.active in config (43.005636ms)
|
||||
✔ a .git/modules with no gitlink (31.240083ms)
|
||||
✔ a clone the session rigged is kept, and git runs nothing and writes nothing outside it (1201.693467ms)
|
||||
▶ a root that can't be cloned refuses with the project id and leaves nothing behind
|
||||
✔ missing (9.543898ms)
|
||||
✔ not a repository (9.15995ms)
|
||||
✔ a plain directory inside another repository (13.291966ms)
|
||||
✔ unreadable (10.409599ms)
|
||||
✔ on no branch (11.130486ms)
|
||||
✔ missing an object (14.936384ms)
|
||||
✔ a root that can't be cloned refuses with the project id and leaves nothing behind (69.273079ms)
|
||||
✔ a clone whose root is on no branch, or gone, is kept and named (28.705151ms)
|
||||
✔ no credential or forge remote of the root reaches a clone (46.990023ms)
|
||||
✔ every project in the business file gets its own clone at its own branch (32.655381ms)
|
||||
✔ a clone past its time gets SIGTERM and refuses the launch, with nothing left in the workspace (514.003804ms)
|
||||
✔ a clone that ignores SIGTERM gets SIGKILL once the grace period is over (1016.843724ms)
|
||||
✔ a timeout signals git's process group, so a process git started dies with it (515.051887ms)
|
||||
✔ once a signalled git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (514.556145ms)
|
||||
✔ the budget is the setting's whole number of bytes from 1 MiB to 1 GiB, and the default for anything else (1.567727ms)
|
||||
✔ a stream past the default budget is not-collected with a lower bound, and a later collection catches up (65.101994ms)
|
||||
✔ a budget smaller than the streams counts over several collections, once each, and is known when it catches up (2.599724ms)
|
||||
✔ a line split across reads counts once (9.33078ms)
|
||||
✔ Claude history from before the ledger makes the first Pi collection harness-unsupported, for good (1.440992ms)
|
||||
✔ an empty claude-projects/ is no Claude history, and one filled after the ledger exists isn't checked (1.428192ms)
|
||||
✔ a claude-projects/ that can't be read records nothing, and the next collection checks again (1.330216ms)
|
||||
✔ the stream cap is the setting's whole number from 32 to 65536, and the default for anything else (0.16791ms)
|
||||
✔ more streams than the cap is not-collected, with cursors only for the streams opened, and a larger cap catches up (2.344595ms)
|
||||
✔ the default cap opens STREAMS streams and writes no more cursor lines than that (52.65919ms)
|
||||
✔ row 307 the known ledger row 270 wrote reads the same count (4.720302ms)
|
||||
✔ row 307 after the known ledger, one collection through pi's module answers the next count (3.122956ms)
|
||||
✔ row 307 the store-incomplete ledger row 270 wrote reads the same count (1.172174ms)
|
||||
✔ row 307 after the store-incomplete ledger, one collection through pi's module answers the next count (1.473641ms)
|
||||
✔ row 307 the store-unreadable ledger row 270 wrote reads the same count (1.233218ms)
|
||||
✔ row 307 after the store-unreadable ledger, one collection through pi's module answers the next count (1.478165ms)
|
||||
✔ row 307 the not-collected ledger row 270 wrote reads the same count (1.059533ms)
|
||||
✔ row 307 after the not-collected ledger, one collection through pi's module answers the next count (2.381792ms)
|
||||
✔ row 307 the claude-code ledger row 270 wrote reads the same count (1.16785ms)
|
||||
✔ row 307 after the claude-code ledger, one collection through pi's module answers the next count (1.422304ms)
|
||||
✔ row 307 the claude-history ledger row 270 wrote reads the same count (2.943093ms)
|
||||
✔ row 307 after the claude-history ledger, one collection through pi's module answers the next count (1.5333ms)
|
||||
✔ row 307 the torn ledger row 270 wrote reads the same count (1.006203ms)
|
||||
✔ row 307 after the torn ledger, one collection through pi's module answers the next count (2.284545ms)
|
||||
✔ row 307 core refuses an answer outside the contract and appends nothing (8.468181ms)
|
||||
✔ row 307 the module gets the store's two native directories, a copy of the cursors, the budget, the cap and first (2.320411ms)
|
||||
✔ an empty store, a store with no compaction and a failed start count 0, known (7.138038ms)
|
||||
✔ one and three completed compactions (2.441636ms)
|
||||
✔ a compaction copied into a branched stream counts once, under the stream it was first seen in (3.056ms)
|
||||
✔ one collection over two streams holding the same copy counts it once and writes it once (1.831681ms)
|
||||
✔ the same entry id at another time in another stream is another compaction (1.582065ms)
|
||||
✔ resume: each collection reads past its cursor and writes a key once (2.114301ms)
|
||||
✔ a partial trailing line waits for its newline (1.624959ms)
|
||||
✔ a missing ledger is not-collected and an unreadable one store-unreadable, never 0 (1.322325ms)
|
||||
✔ a symlinked ledger is store-unreadable and is not written through (1.293154ms)
|
||||
✔ a torn last ledger line makes the count unknown, a lower bound, and stays so (2.167108ms)
|
||||
✔ a bad ledger line in the middle makes the count unknown (3.331232ms)
|
||||
▶ a stream that shrank, changed under its cursor or went away is store-incomplete for good
|
||||
✔ shrink (2.038847ms)
|
||||
✔ rewrite (1.477185ms)
|
||||
✔ remove (1.974024ms)
|
||||
✔ a stream that shrank, changed under its cursor or went away is store-incomplete for good (6.254361ms)
|
||||
✔ a stream that isn't a regular file or a Pi session is store-unreadable, and that passes (1.252704ms)
|
||||
✔ a first line that isn't a session header is store-unreadable (1.120253ms)
|
||||
✔ a Claude run is harness-unsupported, and stays so after a Pi run (1.273691ms)
|
||||
✔ storeDir is the store sessionStore makes, without making it (1.538256ms)
|
||||
✔ the ledger is under no sandbox mount (5.456112ms)
|
||||
✔ rootHits: a top-level file, a new top-level directory, src/ and v1/ are the root; paths under known directories aren't (1.861197ms)
|
||||
✔ gateEnv keeps the named variables that are strings and drops everything else (0.310846ms)
|
||||
✔ isMosaicStack: a checkout whose HEAD descends from the root commit and has node_modules; nothing else (76.743834ms)
|
||||
✔ gateSteps: each package with tests but queue in name order, then each scripts/test-*.sh (2.377262ms)
|
||||
✔ runGate: every step passes, each with its own log and a summary line, under the environment it was given (211.160741ms)
|
||||
✔ runGate: the first failing step stops the gate and names its log (269.569796ms)
|
||||
✔ runGate: an abort stops the running step and everything in its group, and runs nothing after it (185.986993ms)
|
||||
✔ the CLI: root-file prints the hits and exits 2, or exits 0; gate exits 0, or 2 with the step and its log; anything else is usage (661.443234ms)
|
||||
✔ T3: publish pushes the work commit by oid to <user>/<branch> on the fork, with the token only through the helper (318.365034ms)
|
||||
✔ T3: the token is never in git's argv, the fork URL included; it reaches git on fd 3 only (157.63501ms)
|
||||
✔ T3: a moved fork branch refuses non-fast-forward; no + and no force (173.077055ms)
|
||||
✔ T3: D9a: an empty fork and an unrelated fork refuse remote-unrelated; a missing fork refuses fork-unavailable (379.595919ms)
|
||||
✔ T3: a fork past main refuses remote-unrelated until root catches up (152.254688ms)
|
||||
✔ T3: a wrong token refuses fork-unavailable; git's stderr isn't in the refusal (102.972548ms)
|
||||
✔ T3: a 302 is not followed: fork-unavailable, and the target sees no request (113.352932ms)
|
||||
✔ T3: the helper answers only the fork's host and port: a fork on another port gets no token (95.099891ms)
|
||||
✔ T3: a fork that echoes the token refuses credential-leak (131.28193ms)
|
||||
✔ T3: no tls parameter, no trust: the scratch CA reaches git only through it (91.935601ms)
|
||||
✔ D9 steps 3 and 4: ref-moved and identity-mismatch refuse before any request (143.070058ms)
|
||||
✔ publishRemote refuses a fork, user or destination that isn't shell- and ref-safe before any git (88.646013ms)
|
||||
✔ RUNNER_FILES is exactly what the runner and the harness sources it starts import (7.032234ms)
|
||||
✔ sandboxProblem names a missing bwrap and a bwrap that fails (15.78888ms)
|
||||
✔ every bind says why; the bundle and session file stay read-only over the run directory (2.196421ms)
|
||||
✔ row 65 a harness module's mounts bind read-only after the adapter, each with the module's reason (2.143393ms)
|
||||
✔ REQ-THREAD-2 a thread store binds its session directory and Claude transcripts, and nothing more (1.644658ms)
|
||||
✔ the host's git socket is bound only when given, read-only and before the writable binds (1.090126ms)
|
||||
✔ the git identity is the instance's, at <instance>@<business>.mosaic.invalid, and sandboxArgv refuses without it (1.690862ms)
|
||||
✔ a confined session's shell reaches its own workspace and run directory and nothing of the founder's or another session's (2106.854649ms)
|
||||
✔ a bind that exposes a stand-in, or a missing workspace bind, fails the matching check (2924.249794ms)
|
||||
✔ a confined session that runs tester-cli.mjs is refused as tester, and the same shim outside the sandbox binds (300.518853ms)
|
||||
✔ resolveSeat: by name under --repo resolves the repo layout (2.419588ms)
|
||||
✔ resolveSeat: by path resolves the fleet layout (0.765582ms)
|
||||
✔ resolveSeat: refusals for missing dir, missing launch.sh, non-executable launch.sh, invalid name, and unknown layout (1.626754ms)
|
||||
✔ tmuxContext: outside tmux, default socket, custom socket, and exec failure (1.236572ms)
|
||||
✔ makeRegistration produces a record that validates; each shape violation throws SeatError (1.593741ms)
|
||||
✔ writeRegistration/readRegistration: round trip, permissions, absence, and malformed records (2.34318ms)
|
||||
✔ updateTask: changes task, taskSetBy and updatedAt only, and refuses appropriately (2.203796ms)
|
||||
✔ CLI launch: registers, execs the fake launch script, and passes args through (66.404825ms)
|
||||
✔ CLI launch: --harness lands in the record (50.392752ms)
|
||||
✔ CLI launch: the launch script's own exit code passes through (46.659659ms)
|
||||
✔ CLI launch: relaunching a seat rewrites the one registration record (89.26575ms)
|
||||
✔ CLI launch: omitting --task records an empty string, not null (39.318048ms)
|
||||
✔ CLI seat task: updates only the task after a launch, and refuses on an unlaunched seat (96.331713ms)
|
||||
✔ CLI refusals: no args, unknown flag, missing config, already-registered env, and exec failure (164.27632ms)
|
||||
✔ samePath: equal paths, symlinked dirs, distinct dirs, and non-strings (0.422092ms)
|
||||
✔ resolveSetBy: explicit --by wins over the environment; absent or empty environment gives unknown; invalid explicit or environment values refuse with exit 4 (0.590318ms)
|
||||
✔ validateRegistration/readRegistration: taskSetBy is optional; a record without it (written before #1511) still loads unchanged; an invalid one is refused; the version does not change (0.734057ms)
|
||||
✔ updateTask: records setBy, preserves startedAt and every unrelated field, upgrades an old record in place only when the task is set, and replaces a previous attribution (0.906133ms)
|
||||
✔ CLI seat task: --by beats MOSAIC_AGENT_NAME, the environment beats nothing, empty environment is unknown, invalid --by or environment refuses with exit 4 and leaves the record byte for byte (330.90649ms)
|
||||
✔ REQ-THREAD-2 sessionStore: a legacy session keeps the thread's store, any other gets sessions/<s>/, each segment checked first (5.360486ms)
|
||||
✔ REQ-THREAD-2 sessionStore refuses legacy-store-unmapped for a thread whose old store no legacy session maps (1.608175ms)
|
||||
✔ REQ-THREAD-2 sessionWorkspace: private directories per session, unsafe segments and overlaps refused (3.523108ms)
|
||||
✔ REQ-THREAD-2 lockSessionWorkspace: one writer; a live host or run holds it, a stale lock is taken over, an unreadable one holds (15.189866ms)
|
||||
✔ REQ-THREAD-2 sessions.json v2: entries carry session and workspace, running() keys on the session, a v1 file still reads (1.889362ms)
|
||||
✔ REQ-LIMIT-1: family substring matching is no longer exported (1.378459ms)
|
||||
✔ sessionEnv passes only the allowlist, the repo's bin on PATH, and the run id (1.063207ms)
|
||||
✔ ZAI_API_KEY passes the session allowlist, and ZAI_TOKEN does not (0.239826ms)
|
||||
✔ sessionExit gives a runner's signal death back as the signal; a session credential is one whole set of nonempty variables (0.405172ms)
|
||||
✔ newRun: short ids, 0700 directories, and a refusal when the socket path won't fit (2.727102ms)
|
||||
✔ session file and launch log: 0600, the session file written once (2.111664ms)
|
||||
✔ endReason maps the runner's exit codes; a signal is killed (0.220582ms)
|
||||
✔ Registry mirrors to sessions.json; readSessions marks live entries; bad files refuse (2.216711ms)
|
||||
✔ a read-only Registry never writes sessions.json, refuses add() and leaves the file on remove() (2.154331ms)
|
||||
✔ REQ-THREAD-1 Registry.running keys a thread run by business, instance and thread (1.027065ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 threadStore checks both segments before the join and refuses an unsafe directory (2.628544ms)
|
||||
✔ stopSession refuses an unknown run, reports a stale one, and won't signal a pid that isn't a runner (1.552738ms)
|
||||
✔ a session runs in its sandbox as pid 1 of its namespace, claims, answers, and stops on mosaic stop (293.088316ms)
|
||||
✔ workRef and validBranch take only what a ref name can hold (2.280976ms)
|
||||
✔ a push lands as the task's work ref, a fast-forward lands after it, and main is the root's (187.443563ms)
|
||||
✔ a rewritten branch refuses non-fast-forward and the work ref stays (124.192671ms)
|
||||
✔ a branch with no history in common with main refuses unrelated-history (60.579235ms)
|
||||
✔ a bundle that needs commits the working repository lacks refuses missing-prerequisite (51.079109ms)
|
||||
✔ the root is fetched again before each push and main follows it, so a clone of a newer root pushes (129.47937ms)
|
||||
✔ a root moved back after the clone leaves the push's base unknown: missing-prerequisite (78.854404ms)
|
||||
✔ a commit with a broken object refuses invalid-bundle, and only because fsck is on (86.468293ms)
|
||||
✔ only a v2 bundle with the named branch is read (64.914471ms)
|
||||
✔ a branch named main, or named for another task, moves only this task's work ref (102.371349ms)
|
||||
✔ a record that throws moves the work ref back, or removes a new one (141.771502ms)
|
||||
✔ a work ref that can't go back refuses rollback-failed, naming the ref and the commit (362.776758ms)
|
||||
✔ a root that can't be read refuses root-unreadable (28.853641ms)
|
||||
✔ a git past its time gets SIGTERM, leaves no ref lock, and the next push lands (2132.860162ms)
|
||||
✔ a git that ignores SIGTERM gets SIGKILL once the grace period is over (1025.936026ms)
|
||||
✔ a working repository path that isn't a directory refuses (23.030329ms)
|
||||
✔ review bundles a pushed commit as refs/mosaic/review, leaving out what the reviewer has (120.899663ms)
|
||||
✔ review of a project with no working repository refuses unknown-commit (14.031146ms)
|
||||
✔ the runner's git tools hold the host's limits and branch rule (1.219295ms)
|
||||
✔ a reseed moves root but leaves a landed main, and main forwards once root contains it (184.469774ms)
|
||||
✔ after a landing, a push built on the root still lands and main stays where the landing put it (126.530409ms)
|
||||
✔ once the root shares no history with a landed main, a push is checked against main, not the root (179.004093ms)
|
||||
✔ a landing squashes the reviewed diff onto main as the bus host and moves main only at finish (105.224989ms)
|
||||
✔ a landing refuses ref-moved, base-conflict and root-file before it makes a commit (308.132399ms)
|
||||
✔ a landing whose applied diff isn't the reviewed one refuses patch-drift and leaves no worktree (121.415385ms)
|
||||
✔ finish refuses base-moved when main moved, and a record that throws moves main back (242.643351ms)
|
||||
✔ halted push receipt rolls back only its unrecorded ref and cleans temporary refs (198.696687ms)
|
||||
ℹ tests 218
|
||||
ℹ suites 0
|
||||
ℹ pass 218
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 6318.071226
|
||||
@@ -1,202 +0,0 @@
|
||||
{
|
||||
"base": "e0c6142f3",
|
||||
"testedRevision": "2d274a5b6c35c3e74b07206ffd724a6579bb149d",
|
||||
"tmpdir": "/mnt/storage/scratch/tmp/tNoueZ",
|
||||
"wholeSuites": {
|
||||
"library": {
|
||||
"tests": 142,
|
||||
"pass": 142,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"business": {
|
||||
"tests": 270,
|
||||
"pass": 270,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"bus": {
|
||||
"tests": 974,
|
||||
"pass": 974,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"cli": {
|
||||
"tests": 988,
|
||||
"pass": 988,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"harness": {
|
||||
"tests": 172,
|
||||
"pass": 172,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"seat": {
|
||||
"tests": 218,
|
||||
"pass": 218,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
"touched": {
|
||||
"touched-first": {
|
||||
"tests": 57,
|
||||
"pass": 56,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"touched-rerun": {
|
||||
"tests": 57,
|
||||
"pass": 57,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"availability-green": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"runtime-fixture-retry": {
|
||||
"tests": 1,
|
||||
"pass": 1,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
}
|
||||
},
|
||||
"mutants": {
|
||||
"M1-writer-fence": {
|
||||
"control": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"negative": {
|
||||
"tests": 6,
|
||||
"pass": 3,
|
||||
"fail": 3,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"restored": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"productHashesRestored": true
|
||||
},
|
||||
"M2-incoming-human": {
|
||||
"control": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"negative": {
|
||||
"tests": 6,
|
||||
"pass": 5,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"restored": {
|
||||
"tests": 6,
|
||||
"pass": 6,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"productHashesRestored": true
|
||||
},
|
||||
"M3-split-check-transaction": {
|
||||
"control": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"negative": {
|
||||
"tests": 13,
|
||||
"pass": 12,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"restored": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"productHashesRestored": true
|
||||
},
|
||||
"M4-drop-client-reason": {
|
||||
"control": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"negative": {
|
||||
"tests": 13,
|
||||
"pass": 12,
|
||||
"fail": 1,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"restored": {
|
||||
"tests": 13,
|
||||
"pass": 13,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"productHashesRestored": true
|
||||
},
|
||||
"M5-hide-library-unavailable": {
|
||||
"control": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"negative": {
|
||||
"tests": 3,
|
||||
"pass": 1,
|
||||
"fail": 2,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"restored": {
|
||||
"tests": 3,
|
||||
"pass": 3,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"productHashesRestored": true
|
||||
}
|
||||
},
|
||||
"totalWholeSuiteTests": 2764
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
library: 142/142 pass; fail=0 skipped=0 cancelled=0
|
||||
business: 270/270 pass; fail=0 skipped=0 cancelled=0
|
||||
bus: 974/974 pass; fail=0 skipped=0 cancelled=0
|
||||
cli: 988/988 pass; fail=0 skipped=0 cancelled=0
|
||||
harness: 172/172 pass; fail=0 skipped=0 cancelled=0
|
||||
seat: 218/218 pass; fail=0 skipped=0 cancelled=0
|
||||
Touched rerun 57/57; first run 56/57, new runtime fixture corrected.
|
||||
M1-M5 killed; each control/restored run green, hashes restored.
|
||||
No old test failed or was edited. scripts/test-*.sh left to Sage at landing.
|
||||
@@ -1,80 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5129.213097ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (32.312603ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.769445ms)
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (104.132156ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (90.030314ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (57.202238ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (41.82067ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (47.52786ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (45.049883ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (54.4217ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (86.893454ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (55.019525ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.383322ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (76.778515ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (24.114008ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (47.161109ms)
|
||||
✖ C2-06 runtime reads changed and unreadable reply limits without restarting (78.402278ms)
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (26.436831ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (21.452407ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (8.669666ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (8.204041ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (9.079346ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (10.338142ms)
|
||||
✔ C2-06 CLI replies reads revision and sends only the JSON settings to the human verb (1.898838ms)
|
||||
✔ C2-06 CLI replies requires a file and refuses tester writes before a bus call (0.465972ms)
|
||||
✔ C2-06 RESULT reply-invalid retries once, delivers only the valid answer and names reason (222.089187ms)
|
||||
✔ C2-06 RESULT citation-missing retries once, delivers only the valid answer and names reason (200.104611ms)
|
||||
✔ C2-06 RESULT citations-over-limit retries once, delivers only the valid answer and names reason (197.834891ms)
|
||||
✔ C2-06 RESULT citation-invalid retries once, delivers only the valid answer and names reason (210.156515ms)
|
||||
✔ C2-06 RESULT playground-cited-as-canon retries once, delivers only the valid answer and names reason (213.835593ms)
|
||||
✔ C2-06 RESULT citation-cross-universe retries once, delivers only the valid answer and names reason (209.912186ms)
|
||||
✔ C2-06 RESULT citation-unfetched retries once, delivers only the valid answer and names reason (198.705684ms)
|
||||
✔ C2-06 RESULT two guard refusals use the citation fixed text and exactly one retry (182.386586ms)
|
||||
✔ C2-06 RESULT JSON 34000 characters retries with a shorter valid answer (213.370025ms)
|
||||
✔ C2-06 RESULT JSON 70000 characters retries with a shorter valid answer (199.782915ms)
|
||||
✔ C2-06 RESULT two oversized JSON bodies use the length fixed text with citations required (184.820165ms)
|
||||
✔ C2-06 multibyte plain bodies also receive the one request-size retry (201.829013ms)
|
||||
✔ C2-06 two multibyte plain bodies use the length fallback (182.03426ms)
|
||||
✔ C2-06 RESULT a length refusal then citation refusal shares one retry and citation fallback (183.540139ms)
|
||||
✔ C2-06 fixed empty/failed replies defer unslop note until the next cited reply (274.786836ms)
|
||||
✔ C2-06 cited JSON above the old 32000 clip retains its citations and text (167.141798ms)
|
||||
✔ C2-06 a flagged cited answer keeps the note inside text and citations whole (168.83631ms)
|
||||
✔ C2-06 send_message typed tool runs every guard code before the valid RESULT (230.565935ms)
|
||||
✔ C2-06 outside library the old failed text, clip and unslop behavior hold (197.472747ms)
|
||||
✔ C2-06 outside library a refused send keeps the existing no-retry behavior (151.296315ms)
|
||||
✔ C2-06 the retry turn delivers citation-unavailable reason to the agent (184.635398ms)
|
||||
✔ C2-06 reply schema: free bodies, exact objects and safe refusal reasons (14.759264ms)
|
||||
✔ C2-06 citation setting and all four exact fixed texts (9.899391ms)
|
||||
✔ C2-06 default citation cap passes 20 and refuses 21, even with optional citations (76.751112ms)
|
||||
✔ C2-06 real Git citation scope, reachability, lines and normalized quotes (41.360225ms)
|
||||
✔ C2-06 playground cites pass but cannot state canon (23.671961ms)
|
||||
✔ C2-06 independent universes refuse; a hybrid and only its sources pass (41.572641ms)
|
||||
✔ C2-06 web cites require allowed definition, this session fetch and kept quote (10.468249ms)
|
||||
✔ C2-06 file origin is the path commit and trailer, while last follows served changes (31.989388ms)
|
||||
✔ C2-06 origin uses literal paths even when a filename contains a glob (20.084358ms)
|
||||
✔ C2-06 cited-commit guard reads exactly the C2-05a indexed file set with supporting scope (44.687642ms)
|
||||
✔ C2-06 reply limits fall back independently without coercion or inherited keys (0.462948ms)
|
||||
ℹ tests 57
|
||||
ℹ suites 0
|
||||
ℹ pass 56
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 11101.06711
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/citation-runtime.test.mjs:12:1
|
||||
✖ C2-06 runtime reads changed and unreadable reply limits without restarting (78.402278ms)
|
||||
Error: invalid-authority
|
||||
at fail (file:///home/jwoltje/.t3/worktrees/mosaic-stack/beakley-row217/packages/bus/src/broker.mjs:215:9)
|
||||
at checkBusiness (file:///home/jwoltje/.t3/worktrees/mosaic-stack/beakley-row217/packages/bus/src/broker.mjs:366:7)
|
||||
at new Broker (file:///home/jwoltje/.t3/worktrees/mosaic-stack/beakley-row217/packages/bus/src/broker.mjs:537:63)
|
||||
at startBroker (file:///home/jwoltje/.t3/worktrees/mosaic-stack/beakley-row217/packages/bus/src/runtime.mjs:274:14)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/beakley-row217/packages/bus/tests/citation-runtime.test.mjs:18:19)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
code: 'invalid-authority'
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
✔ C2-06 held library lock gives the agent citation-unavailable and its retry reason (5131.834326ms)
|
||||
✔ C2-06 malformed sync state is availability failure, never a fabricated invalid cite (31.609704ms)
|
||||
✔ C2-06 no mirror or freshly initialized empty mirror still means no served citation (31.510292ms)
|
||||
✔ C2-06 coder send_message guard covers every table refusal; inserts nothing (102.606635ms)
|
||||
✔ C2-06 research send_message guard covers every table refusal; inserts nothing (91.30209ms)
|
||||
✔ C2-06 stored check carries the file author trailer at an unrelated cited tip (55.686451ms)
|
||||
✔ C2-06 supporting cite cannot state canon, including a folder also marked playground (42.44166ms)
|
||||
✔ C2-06 supporting file stores supporting scope and its real agent trailer (48.386414ms)
|
||||
✔ C2-06 check evidence and insert are atomic when storing evidence fails (39.194827ms)
|
||||
✔ C2-06 live limits change both directions; unreadable file keeps checks and exact fixed texts (54.284625ms)
|
||||
✔ C2-06 page store is session-local, caps 20 fetches and 200 KiB, drops at disconnect (85.004961ms)
|
||||
✔ C2-06 transport passes safe capped guard reason; ordinary refusal envelope is byte-identical (54.117068ms)
|
||||
✔ C2-06 non-library businesses retain role.claim shape and unguarded free sends (26.131034ms)
|
||||
✔ C2-06 thread messages carry file/last evidence with one read per distinct path (76.437567ms)
|
||||
✔ C2-06 guarded request snapshot cannot change between check and insert (23.908928ms)
|
||||
✔ C2-06 library.limits.set is human-only and invalid settings leave file and receipts unchanged (39.656735ms)
|
||||
✔ C2-06 runtime reads changed and unreadable reply limits without restarting (113.293022ms)
|
||||
✔ C2-06 M11 human replacement works; omitted settings return to defaults (36.305063ms)
|
||||
✔ C2-06 M11 agents and tester cannot change settings, including by changing human (21.839826ms)
|
||||
✔ C2-06 M11 serialization cannot replace settings after the first fence (8.253422ms)
|
||||
✔ C2-06 M11 an unrelated actor cannot appoint itself human and change reply limits (7.674495ms)
|
||||
✔ C2-06 invalid setter values preserve the business and changes.jsonl (8.65299ms)
|
||||
✔ C2-06 validator accepts hand-edited settings; raw reader fails closed on invalid files (9.800617ms)
|
||||
✔ C2-06 CLI replies reads revision and sends only the JSON settings to the human verb (1.78485ms)
|
||||
✔ C2-06 CLI replies requires a file and refuses tester writes before a bus call (0.520156ms)
|
||||
✔ C2-06 RESULT reply-invalid retries once, delivers only the valid answer and names reason (220.792912ms)
|
||||
✔ C2-06 RESULT citation-missing retries once, delivers only the valid answer and names reason (195.400791ms)
|
||||
✔ C2-06 RESULT citations-over-limit retries once, delivers only the valid answer and names reason (196.181772ms)
|
||||
✔ C2-06 RESULT citation-invalid retries once, delivers only the valid answer and names reason (211.797981ms)
|
||||
✔ C2-06 RESULT playground-cited-as-canon retries once, delivers only the valid answer and names reason (212.360651ms)
|
||||
✔ C2-06 RESULT citation-cross-universe retries once, delivers only the valid answer and names reason (212.667005ms)
|
||||
✔ C2-06 RESULT citation-unfetched retries once, delivers only the valid answer and names reason (184.261348ms)
|
||||
✔ C2-06 RESULT two guard refusals use the citation fixed text and exactly one retry (184.957084ms)
|
||||
✔ C2-06 RESULT JSON 34000 characters retries with a shorter valid answer (216.343048ms)
|
||||
✔ C2-06 RESULT JSON 70000 characters retries with a shorter valid answer (198.338992ms)
|
||||
✔ C2-06 RESULT two oversized JSON bodies use the length fixed text with citations required (183.309434ms)
|
||||
✔ C2-06 multibyte plain bodies also receive the one request-size retry (198.411283ms)
|
||||
✔ C2-06 two multibyte plain bodies use the length fallback (182.244769ms)
|
||||
✔ C2-06 RESULT a length refusal then citation refusal shares one retry and citation fallback (184.948978ms)
|
||||
✔ C2-06 fixed empty/failed replies defer unslop note until the next cited reply (294.575418ms)
|
||||
✔ C2-06 cited JSON above the old 32000 clip retains its citations and text (169.454956ms)
|
||||
✔ C2-06 a flagged cited answer keeps the note inside text and citations whole (164.824669ms)
|
||||
✔ C2-06 send_message typed tool runs every guard code before the valid RESULT (213.365137ms)
|
||||
✔ C2-06 outside library the old failed text, clip and unslop behavior hold (198.225522ms)
|
||||
✔ C2-06 outside library a refused send keeps the existing no-retry behavior (155.955999ms)
|
||||
✔ C2-06 the retry turn delivers citation-unavailable reason to the agent (188.198987ms)
|
||||
✔ C2-06 reply schema: free bodies, exact objects and safe refusal reasons (17.723832ms)
|
||||
✔ C2-06 citation setting and all four exact fixed texts (11.590649ms)
|
||||
✔ C2-06 default citation cap passes 20 and refuses 21, even with optional citations (79.713842ms)
|
||||
✔ C2-06 real Git citation scope, reachability, lines and normalized quotes (41.208361ms)
|
||||
✔ C2-06 playground cites pass but cannot state canon (24.250695ms)
|
||||
✔ C2-06 independent universes refuse; a hybrid and only its sources pass (42.707909ms)
|
||||
✔ C2-06 web cites require allowed definition, this session fetch and kept quote (10.901286ms)
|
||||
✔ C2-06 file origin is the path commit and trailer, while last follows served changes (37.369269ms)
|
||||
✔ C2-06 origin uses literal paths even when a filename contains a glob (20.592546ms)
|
||||
✔ C2-06 cited-commit guard reads exactly the C2-05a indexed file set with supporting scope (51.682837ms)
|
||||
✔ C2-06 reply limits fall back independently without coercion or inherited keys (0.499884ms)
|
||||
ℹ tests 57
|
||||
ℹ suites 0
|
||||
ℹ pass 57
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 11134.473726
|
||||
@@ -1,10 +0,0 @@
|
||||
# Bentina
|
||||
|
||||
Builder seat, Codex gpt-6.1-sol, started by Sage under Q246 and mos-1566. Owns row 157, I2: the install images, the
|
||||
install config key, the endpoint helper and the egress proxy (docs/plans/2026-10-18_containerized-install-rows.md),
|
||||
reassigned from Researcher so the coding runs on Codex.
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread and works in its own worktree. It has no credentials of its
|
||||
own; it pushes only its own `bentina/*` branches through the repository credential helper (mos-0981), never `refactor`,
|
||||
`main` or another seat's branch. Claude seats orchestrate and review the install path (mos-1542 rule 4). Registered by
|
||||
Sage on 2026-10-24 so the queue can name the seat as row owner (store.mjs isSeatDir).
|
||||
@@ -1,8 +0,0 @@
|
||||
# Boyd
|
||||
|
||||
Builder seat, Codex gpt-6.1-sol, started by Mos under Q245 (mos-1506). Owns row 298 (the chief-of-staff grant scope, handed over from Megavolt).
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread (thread 48a3ae38) and works in its own worktree. It has no
|
||||
credentials of its own; it pushes only its own `boyd/*` branches through the repository credential helper (mos-0981),
|
||||
never `refactor`, `main` or another seat's branch. Claude seats orchestrate and review (Q245). Registered by Sage on
|
||||
2026-10-23 so the queue can name the seat as row owner (store.mjs isSeatDir).
|
||||
@@ -1,272 +0,0 @@
|
||||
# Row 298 (#1804, Q228): chief-of-staff grant scope
|
||||
|
||||
Owner Boyd (48a3ae38), reviewer Dewey. Branch `boyd/row298`, base `45dca69f6`.
|
||||
Assignment: mos-1496/Q245. Handoff: Megavolt megavolt-0203, local `7a141269c`;
|
||||
cherry-picked as `4de3cec27` (design) and `7cea739de` (UNTESTED code).
|
||||
Brief: `docs/plans/2026-10-23_mvp-readiness-rows.md`, chief-of-staff grant scope.
|
||||
Megavolt's original design remains in `agents/megavolt/work/queue-298/BUILD.md`.
|
||||
|
||||
## Authority and accepted design
|
||||
|
||||
Sage sage-3594, restated in sage-3612: launch.grantScope, lenient read with empty
|
||||
fallback, strict human-only write. No general organization setter may write it.
|
||||
Per-method agents/projects or agents/hosts/commands; host-enroll never in scope.
|
||||
Host command arrays match whole tokens and exact lengths. `grants.scope.set`
|
||||
from the human CLI is Approve; no Console page or chief-raised scope change.
|
||||
Mos mos-1496/1502 requires the same human-shell guard as `mosaic access`.
|
||||
The broker closes an in-scope request via scope and writes grant.scope.used;
|
||||
missing evidence must refuse execution. Narrowing before spend fails
|
||||
scope-changed. Empty scope ships; only Jason sets the live value (Q188).
|
||||
|
||||
No credential files read, no live grants, no deployment, no queue writes. Push
|
||||
only boyd/*, additive commits, no amend/force-push or attribution trailers.
|
||||
Sage owns queue, shared test slot and landing. No Node/tests before CLEAR.
|
||||
|
||||
## Implementation plan and ledger
|
||||
|
||||
Using writing-plans and executing-plans inline; the approved brief and D1-D6
|
||||
are the spec. This packet is the requested plan/tracking location.
|
||||
|
||||
- [x] Read brief, roster, implementation and handoff; register session.
|
||||
- [x] Bring Megavolt's two commits onto Boyd's branch without changing history.
|
||||
- [x] Add independent CLI tests in `packages/cli/tests/grants-scope.test.mjs`:
|
||||
scope read/set requests; agent-marker rejection before stdin/transport;
|
||||
--tester rejection; missing revision, malformed/empty/oversize input.
|
||||
- [x] Strengthen new business/bus grant-scope tests for exact commands,
|
||||
scope evidence binding, host-enroll exclusion and spent scope-changed.
|
||||
- [ ] On Sage CLEAR, observe targeted failures before fixes; fix inherited
|
||||
implementation using the existing human proof and grant executors.
|
||||
- [ ] Update bus/CLI docs, append BUILD-LOG before/after evidence, manifest.
|
||||
- [ ] On Sage CLEAR run touched suites; record exact results and mutants.
|
||||
- [ ] Commit UNTESTED until verified; push boyd/row298 only when slot permits;
|
||||
report to Sage and Dewey, cc Mos for pushes/blockers. Dewey reviews manifest.
|
||||
|
||||
Pre-flight interfaces: business checkGrantScope/grantScopeOf/grantInScope feed
|
||||
the instance writer and broker. Runtime supplies a fresh scope from the org
|
||||
file and routes the human setter to the same organization writer. CLI callFor
|
||||
supplies refuseInsideAgent and humanTransport. The grant executors consume the
|
||||
broker's immutable close/evidence. Tests use scratch files/fake Gitea only.
|
||||
|
||||
Review focus: exact argv length, stale scope before spend, forged/missing scope
|
||||
evidence, malformed fallback, and CLI agent ancestry. Tests must cover each.
|
||||
|
||||
Static findings before any Boyd Node/test run:
|
||||
|
||||
- Handoff introduced commandPrefixes beyond the accepted D2 shape, allowing
|
||||
trailing args. Remove it; only exact command arrays are authorized.
|
||||
- scope.used carries a digest without validating it, and no org revision.
|
||||
Bind evidence to the canonical scope snapshot and grant/close sequence;
|
||||
preserve historical grants when scope is later changed, recheck at spend.
|
||||
- Gitea recheck throws inside the spend transaction and rolls back spend on
|
||||
scope-changed. Preserve spend and log failure for that case (D6).
|
||||
- The optional giteaStart?. assertion always passes when the API is absent;
|
||||
use the real runGiteaGrant entry point. Fake Gitea tokens() does exist.
|
||||
|
||||
## Existing test changes (mos-1272)
|
||||
|
||||
Approved by Mos mos-1510 via Sage sage-3624; edited exactly as approved:
|
||||
|
||||
| File | Actual numstat | Reason |
|
||||
| --- | --- | --- |
|
||||
| packages/bus/tests/project-runtime.test.mjs | +1 / -1 | Vocabulary import pin adds grantScopeOf and grantInScope. |
|
||||
|
||||
Other test work is confined to row 298's new files. No pre-existing CLI tests
|
||||
will change. Record final numstat here before review.
|
||||
|
||||
## Human proof and organization ownership
|
||||
|
||||
CLI: `packages/cli/src/cli.mjs` callFor runs refuseInsideAgent before constructing
|
||||
humanTransport, as `accessCommand` does. The setter takes no --tester flag.
|
||||
`packages/bus/src/human.mjs` verifyHuman checks the nonce, CLI path and every
|
||||
ancestor's markers/argv; `bindHuman` and #human in broker.mjs require the
|
||||
business human, via cli, outsideAgent true. Tests will pin this chain's caller
|
||||
refusal. The scope receipt records by/via/outsideAgent and old/new sha256.
|
||||
|
||||
Org file: `packages/business/src/organization.mjs` regular() requires a regular,
|
||||
non-symlink file owned by the process uid and not writable by group/other;
|
||||
write() uses revision checks, locked durable receipts and atomic rename.
|
||||
The OS owner uid can edit it directly; the agent sandbox does not mount the
|
||||
user's config (`packages/seat/src/sandbox.mjs`). This is the existing cooperative
|
||||
human/process boundary, not a hostile same-uid isolation claim.
|
||||
|
||||
Chief enrollment: broker instances.set calls #human and #mayHuman before
|
||||
add/change; credential issue/delete use #requestCredential's human gate.
|
||||
launch.by is an organization-file setting, excluded from general setters;
|
||||
only that chief may auto-approve within scope. Additional chief instances
|
||||
remain on the per-grant human approval path.
|
||||
|
||||
## Validation
|
||||
|
||||
UNTESTED. No Boyd Node/test run yet; waiting for Sage CLEAR.
|
||||
M1: bypass in-scope check. M2: bypass invalid-value fallback. M3: remove human
|
||||
setter guard. M4: drop grant.scope.used. All need named failing tests on gate.
|
||||
|
||||
## Session correction
|
||||
|
||||
The initial SESSIONS entry labels startup 19:13Z; startup was approximately
|
||||
19:08Z. Message header timestamps in boyd-0001 through 0004 were estimates;
|
||||
use T3's receipt timestamps as authoritative. Subsequent reports use date -u.
|
||||
|
||||
## Departures from Megavolt 7a141269c (Sage sage-3624)
|
||||
|
||||
1. Removed commandPrefixes; host scope commands match exact token arrays only.
|
||||
2. grantScope callback now supplies one organization read `{value,revision}`.
|
||||
grant.scope.used includes that revision, canonical scope snapshot and digest;
|
||||
#approvedGrant validates the digest, shape, method, agent and close sequence.
|
||||
It uses the immutable snapshot so later narrowing doesn't revoke issued grants.
|
||||
3. Gitea scope-changed is caught inside the spend transaction and logs a terminal
|
||||
failure without rolling back its spend. Other recheck failures keep their
|
||||
existing behavior. Host already catches recheck failures after spending.
|
||||
|
||||
Additional handoff corrections: replaced optional nonexistent giteaStart with
|
||||
runGiteaGrant; added successful host executor/revoke and enrollment-exclusion
|
||||
coverage; added real runtime writer coverage and independent CLI guard tests.
|
||||
|
||||
Sage scheduled push at 19:41Z with MOSAIC_GITEA_CREDENTIAL_FILE unset, then T1
|
||||
lane B around 19:47Z (after explicit CLEAR), four new files whole and serial,
|
||||
hard stop 20:00Z. Fethry lane A is disjoint. No test was run early. Production
|
||||
corrections are marked UNTESTED under that slot mandate; baseline regression
|
||||
checks against the inherited implementation will run only on CLEAR.
|
||||
|
||||
## Candidate preparation (before T1)
|
||||
|
||||
The three static corrections, CLI/runtime coverage and docs are prepared but
|
||||
UNTESTED. `git diff --check` is clean. The approved import-pin edit is exactly
|
||||
1 addition / 1 deletion. M1-M4 are encoded in mutants.py (not run). No Node,
|
||||
https git, full suite or webui build has run in Boyd's worktree.
|
||||
|
||||
Review package: product/test/documentation files in MANIFEST.sha256, excluding
|
||||
append-only project logs and the preserved predecessor packet. The manifest
|
||||
identifies exact bytes for Dewey; each later product change regenerates it and
|
||||
requires a review delta. Existing tests changed: only project-runtime, 1/1.
|
||||
|
||||
## Dewey static review dewey-0933
|
||||
|
||||
N1: Added a positive control to the malformed-evidence fixture. A valid event
|
||||
must pass scope authorization and reach decision-mismatch on the deliberately
|
||||
absent definition binding; invalid events remain not-authorized. No spend.
|
||||
N2: Additional named mutants cover spend recheck, exact argv length, Gitea spend
|
||||
rollback, launch.by eligibility and accepting any evidence row (results below).
|
||||
N3: At spend only grant scope membership is rechecked, not whether the raising
|
||||
chief is still launch.by. This implements sage-3594 Q5; changing the launcher
|
||||
later does not by itself invalidate a pending scope-approved request.
|
||||
N4: The scope shortcut returns the closed decision view to the chief without
|
||||
sending a separate close message; documented in the bus verb table.
|
||||
N5: grant.scope is logged after the organization file commit in a separate bus
|
||||
transaction. A crash between them leaves durable changes.jsonl as the receipt,
|
||||
as with other organization writers. The setter does not claim cross-store
|
||||
atomicity.
|
||||
|
||||
## T1 lane B results (sage-3642, 2026-10-23 19:23Z–19:29Z)
|
||||
|
||||
TMPDIR: `/mnt/storage/scratch/tmp/boyd298-4bzr6fn7`. Each whole file ran serially
|
||||
as `timeout -k 10 180 node --test --test-concurrency=1 FILE`, TMPDIR set to that
|
||||
scratch directory. Final restored candidate results:
|
||||
|
||||
| Whole file | Pass | Fail | Skip |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| business/tests/grant-scope.test.mjs | 7 | 0 | 0 |
|
||||
| bus/tests/grant-scope.test.mjs | 14 | 0 | 0 |
|
||||
| bus/tests/grant-scope-runtime.test.mjs | 1 | 0 | 0 |
|
||||
| cli/tests/grants-scope.test.mjs | 4 | 0 | 0 |
|
||||
| bus/tests/project-runtime.test.mjs | 3 | 0 | 0 |
|
||||
|
||||
29/0/0 total. `final-1.log` through `final-5.log` hold the final output. The
|
||||
runtime's reload-needs-restart notice is expected: the fixture's boot document
|
||||
has fewer credential references than its organization document, as in the
|
||||
existing instances runtime tests. No credential contents are loaded from the
|
||||
real user config.
|
||||
|
||||
Initial run: business 7/0; bus 13/1 due to Boyd's test typo, an out-of-scope
|
||||
`opts` reference in the missing-scope assertion. Corrected only that new-test
|
||||
line, then bus 14/0 and the remaining files green. Dewey N1 positive control
|
||||
was added and the whole bus file passed again; final rerun above followed all
|
||||
mutants. No production code changed during this test window.
|
||||
|
||||
Mutants: all whole files, serial, with timeout -k 10 and the same TMPDIR.
|
||||
`mutants.py --sage-clear sage-3642 --logs SCRATCH/review-mutants --deadline
|
||||
2026-10-23T19:38:00+00:00` restores exact original source after each run.
|
||||
M1/M2/M3/M4 are brief/Sage mutants; M5–M10 cover review focus and dewey-0933.
|
||||
Each exited 1 with named assertion failures, no loader/syntax kill.
|
||||
|
||||
| Mutant | Change | Pass/fail | Named killer |
|
||||
| --- | --- | --- | --- |
|
||||
| M1 | skip raise scope check | 11/3 | bus out-of-scope Gitea waits; empty/bad scope waits; host argv exclusion |
|
||||
| M2 | skip invalid-value fallback | 5/2 | business missing/bad scope fallback; bad file scope fallback |
|
||||
| M3 | remove #human from scope verb | 13/1 | bus Q3 caller refusals |
|
||||
| M4 | drop grant.scope.used write | 9/5 | bus Q4 protected evidence assertion; four executor waits also fail |
|
||||
| M5 | skip scope digest check | 13/1 | bus Q4 bad evidence: decision-mismatch instead of not-authorized |
|
||||
| M6 | rethrow narrowing, rolling spend back | 13/1 | bus Q5 Gitea spent assertion |
|
||||
| M7 | same without length check | 6/1 | business Q2 shorter command prefix exclusion |
|
||||
| M8 | no-op #scopeRecheck | 12/2 | bus Q5 Gitea and host scope-changed outcomes |
|
||||
| M9 | remove launch.by check | 13/1 | bus Q6 second chief stays open |
|
||||
| M10 | accept any matched scope evidence row | 13/1 | bus Q4 bad evidence, with positive control |
|
||||
|
||||
Mutation log sha256 (under scratch/review-mutants):
|
||||
|
||||
```text
|
||||
55e9973af5fca0088963e2ca11fd81b2fb46dfead813a577c0e0aad2d6269b68 M1.log
|
||||
abd1b784eff5ae1333a7b47085d3e199cad6d27a00e2584edf0b62417ad4c888 M2.log
|
||||
1a56085e548d1e244f0f88fe12a45f77c162375880794f9ef88b241ed3a1704d M3.log
|
||||
9c120f3f7128488edaf8bfd6d41bae712e69e76da4195a0d4dc0e8336b02038f M4.log
|
||||
1bba88a3752823454acdaa51abde6aad66fdd5488801b4aceda02a3b42c8123d M5.log
|
||||
a4ce3cacca9f7ea56b8cdfd503c76173a8e4ff1d8a7ec07032c93f0b51aa60d8 M6.log
|
||||
acecd5afc93d68d96d713f8a9a2dc08351831a0b7360a13b4e30a572ad4167bf M7.log
|
||||
fce7fa505ccf4f2d4190bd03c209fd19f1cf2770d3ae1246a3bd03697594019e M8.log
|
||||
a830a7964890dd04a2dcc7a932a1502f1dea06419a1eae6b91a85f7878dc5681 M9.log
|
||||
38ce3e7f69f6c6ffe10133397465d52538a930a830f76256a8b9280f8df78e4b M10.log
|
||||
```
|
||||
|
||||
Full touched-package suites and every scripts/test-*.sh remain for Sage's full gate; this CLEAR authorized only the five whole files. Candidate remains
|
||||
marked Untested for the full gate. No queue row has been changed by Boyd.
|
||||
|
||||
## Dewey final delta review (dewey-0935, 2026-10-23 19:31:55Z)
|
||||
|
||||
Dewey reviewed 574ece13c..bcd93dc08 with local git only, no Node: CLEAN,
|
||||
nothing blocks. Verified all 13 manifest entries, exact package-file coverage,
|
||||
project-runtime 1/1, M5-M10 mutation sites, all ten mutation log hashes and
|
||||
counts, named assertion kills without loader/syntax errors, final five logs
|
||||
29/0/0, and N1-N5 coverage. No production code delta in this review range.
|
||||
|
||||
Formal Gitea APPROVE on #1804 and queue record wait on the row 291 hold release
|
||||
and Sage's go. Sage's touched-package and every scripts/test-*.sh gate remains
|
||||
required. Boyd has released lane B and has no running test processes.
|
||||
|
||||
## Rebase after row 239 (sage-3794)
|
||||
|
||||
Current branch: `boyd/row298-r2`, rebased from published row 298 tip
|
||||
`2fc27bce6bfac2debe9703782bf308132c26b393` onto
|
||||
`833ec1cc8d7c11842efb82e57c1a0b256c8d22d7`, which includes row 239 through
|
||||
`e0cb1db2c`. Original `boyd/row298` remains intact locally and remotely. A new
|
||||
Boyd branch carries the rebased candidate so no published history is amended
|
||||
or force-pushed. This section supersedes the original base/branch header for
|
||||
current candidate work.
|
||||
|
||||
Conflicts: only the first Boyd log append in `BUILD-LOG.md` and
|
||||
`docs/SESSIONS.md` conflicted while replaying 574ece13c. For each, verified the
|
||||
old commit's log started with the merge base bytes, then retained the new
|
||||
base's complete log bytes and appended only Boyd's suffix (434 and 281 bytes
|
||||
respectively). Later Boyd appends replayed automatically. No prior entries
|
||||
were removed or rewritten. Five commits replayed; the third/fourth range-diff
|
||||
entries differ only in append-log context; package-only range-diff is all `=`.
|
||||
|
||||
The overlapping product files merged automatically: broker.mjs, runtime.mjs
|
||||
and instance-settings.mjs had no textual conflicts. Inspected their diff
|
||||
against the new base: only the existing row 298 scope additions remain.
|
||||
Preserved row 239's injected writer, fire/delete beforeWrite callback, and
|
||||
commit() passing beforeWrite into writer.write. There is no pre-lock revoke
|
||||
call in commit(). `packages/business/src/organization.mjs` is byte-identical
|
||||
to the new base: beforeWrite still runs inside withLock, after revision and
|
||||
validation checks; post-revoke errors still carry revoked true. Broker's
|
||||
row-239 error handling and runtime's lock/revoke wiring remain intact.
|
||||
|
||||
Static checks only: package patch range-diff all equal, organization writer
|
||||
unchanged, diff whitespace clean, refreshed 13-file package manifest verifies.
|
||||
The only pre-existing row-298 test change remains project-runtime.test.mjs
|
||||
exactly 1/1 under mos-1510. No test files were changed for this rebase.
|
||||
UNTESTED on the new base: no Node, tests, mutants, builds or queue writes run.
|
||||
Earlier 29/0 and M1-M10 results apply to the old base only. Await Sage CLEAR
|
||||
for whole touched-file reruns; Dewey reviews the new candidate.
|
||||
|
||||
Row 321 (#1817) review assignment acknowledged; waiting for Sage's request
|
||||
and Gladstone's pushed docs-only F7/F10 run-sheet candidate.
|
||||
@@ -1,13 +0,0 @@
|
||||
612488b705853e75e6f8952e41552526f4d07dd297d7619d608d434ed75121d6 packages/bus/README.md
|
||||
63fdf6c048f0994af3551510119eeb294c71f8116702772844214930b827cc56 packages/bus/src/broker.mjs
|
||||
65425ead353017c99e04f1e0bcc3f85c4ba60054da293badaa0360e681e418dc packages/bus/src/runtime.mjs
|
||||
e7065db949cacfd4679a1031eebf5cde09ed196ce85612e8400ae563f02a0f18 packages/bus/tests/grant-scope-runtime.test.mjs
|
||||
4030cf584481a1db12d9e6f744015c48fdebd468335d065ead3e90180858d366 packages/bus/tests/grant-scope.test.mjs
|
||||
bc432d8d430433b9d84c00883584dc53d4b27afb5e93f739fe3ca28e80f01efa packages/bus/tests/project-runtime.test.mjs
|
||||
84d6dd15d5ca2926d8f7a34548c70c3e7a3c58e692f0b009414f1af35cb096cc packages/business/src/business.mjs
|
||||
e3b425f9ad2a0d4e6e0b55bd48827e144015662d95ace4163fe6474e5f98da81 packages/business/src/instance-settings.mjs
|
||||
fed4177325f65a2b9823a40a9c35c01d60c0520e3ff40b4574c3cf2c29cc096b packages/business/src/vocabulary.mjs
|
||||
b7f96e45b9ffca2a7ebc18dc446f0adcaac72d3900f098c60157cf6cbf1bfc13 packages/business/tests/grant-scope.test.mjs
|
||||
60fc267b7f8f9e83eeb0d0207c8abdef68d554f32b08d508e98dbf59b442a366 packages/cli/README.md
|
||||
b586907ca8f351f60dc19ec2683df75d2d70ddb12955d09fb14560c9d3bed3dc packages/cli/src/grants.mjs
|
||||
fb7c30b31facd887b03ff02dd6734d48a815978481b33bb21ec48604a51c5ff5 packages/cli/tests/grants-scope.test.mjs
|
||||
@@ -1,105 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Row 298 mutants. Run only with Sage's explicit CLEAR in Boyd's slot.
|
||||
|
||||
Each mutation is applied to this worktree, runs one whole new test file,
|
||||
then restores the exact original bytes, including after an interruption.
|
||||
Logs go to a caller-supplied scratch directory, never the repository root.
|
||||
"""
|
||||
import argparse
|
||||
import datetime
|
||||
import pathlib
|
||||
import subprocess
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[4]
|
||||
BROKER = ROOT / 'packages/bus/src/broker.mjs'
|
||||
VOCABULARY = ROOT / 'packages/business/src/vocabulary.mjs'
|
||||
BUS_TEST = 'packages/bus/tests/grant-scope.test.mjs'
|
||||
BUSINESS_TEST = 'packages/business/tests/grant-scope.test.mjs'
|
||||
|
||||
|
||||
def replace_once(source, old, new):
|
||||
if source.count(old) != 1:
|
||||
raise RuntimeError(f'expected exactly one mutant site, found {source.count(old)}')
|
||||
return source.replace(old, new, 1)
|
||||
|
||||
|
||||
def mutate(name, source):
|
||||
if name == 'M1':
|
||||
return replace_once(source,
|
||||
'if (!raise?.grant || !grantInScope(scope, raise.grant)) return view;',
|
||||
'if (!raise?.grant) return view;')
|
||||
if name == 'M2':
|
||||
return replace_once(source,
|
||||
'return scope === null ? { scope: GRANT_SCOPE_EMPTY, fallback: true } : { scope, fallback: false };',
|
||||
'return { scope: scope ?? value, fallback: false };')
|
||||
if name == 'M3':
|
||||
return replace_once(source,
|
||||
' #grantScopeVerb(s, verb, a) {\n this.#human(s);',
|
||||
' #grantScopeVerb(s, verb, a) {')
|
||||
if name == 'M4':
|
||||
old = """ this.#grantEvent(s.business, {
|
||||
action: 'grant.scope.used', grantDecision: d.id, decisionSeq: seq, method: raise.grant.method,
|
||||
agent: raise.grant.agent, scope, revision, scopeSha256: sha256(JSON.stringify(scope)),
|
||||
}, d.id);"""
|
||||
return replace_once(source, old, ' // MUTANT: scope evidence omitted.')
|
||||
if name == 'M5':
|
||||
return replace_once(source,
|
||||
"evidence.agent === grant.agent && evidence.scopeSha256 === sha256(JSON.stringify(checked.scope)) &&",
|
||||
"evidence.agent === grant.agent &&")
|
||||
if name == 'M6':
|
||||
start = source.index(" checked = this.#store.transaction(() => {\n const consumed = this.#consumeGrant")
|
||||
end = source.index('\n } catch (e) {', start)
|
||||
return source[:start] + " checked = this.#store.transaction(() => this.#giteaRecheck(business, decision, this.#consumeGrant(business, decision, 'gitea')));" + source[end:]
|
||||
if name == 'M7':
|
||||
return replace_once(source,
|
||||
'const same = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);',
|
||||
'const same = (a, b) => a.every((x, i) => x === b[i]);')
|
||||
if name == 'M8':
|
||||
return replace_once(source,
|
||||
" if (this.#closed(decision)?.via === 'scope' && !grantInScope(this.#scopeNow(business).scope, g)) fail('scope-changed');",
|
||||
" // MUTANT: no spend-time scope recheck.")
|
||||
if name == 'M9':
|
||||
return replace_once(source,
|
||||
' if (s.role !== this.#business(s.business).launch?.by) return view;',
|
||||
' // MUTANT: any chief instance can use scope.')
|
||||
if name == 'M10':
|
||||
start = source.index(' const evidence = JSON.parse(row.body);', source.index(' #scopeUsed('))
|
||||
end = source.index('\n }', start)
|
||||
return source[:start] + ' return true;' + source[end:]
|
||||
raise ValueError(name)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--sage-clear', required=True, help='CLEAR message key; required before any Node run')
|
||||
parser.add_argument('--logs', type=pathlib.Path, required=True)
|
||||
parser.add_argument('--mutant', choices=['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'all'], default='all')
|
||||
parser.add_argument('--deadline', default='2026-10-23T19:38:00+00:00')
|
||||
args = parser.parse_args()
|
||||
deadline = datetime.datetime.fromisoformat(args.deadline)
|
||||
args.logs.mkdir(parents=True, exist_ok=True)
|
||||
names = ['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10'] if args.mutant == 'all' else [args.mutant]
|
||||
for name in names:
|
||||
remaining = (deadline - datetime.datetime.now(datetime.timezone.utc)).total_seconds()
|
||||
if remaining <= 15:
|
||||
raise RuntimeError('Sage slot deadline reached; no new test run')
|
||||
path, test = (VOCABULARY, BUSINESS_TEST) if name in ['M2', 'M7'] else (BROKER, BUS_TEST)
|
||||
original = path.read_bytes()
|
||||
mutated = mutate(name, original.decode())
|
||||
log = args.logs / f'{name}.log'
|
||||
try:
|
||||
path.write_text(mutated)
|
||||
with log.open('w') as output:
|
||||
result = subprocess.run(['timeout', '-k', '10', str(int(min(180, remaining - 13))), 'node', '--test', '--test-concurrency=1', test],
|
||||
cwd=ROOT, stdout=output, stderr=subprocess.STDOUT,
|
||||
timeout=min(195, remaining - 1), check=False)
|
||||
print(f'{name}: exit={result.returncode} log={log}', flush=True)
|
||||
finally:
|
||||
path.write_bytes(original)
|
||||
# Exit 1 needs human inspection of the failing test names; errors are not kills.
|
||||
if result.returncode == 0:
|
||||
raise RuntimeError(f'{name} survived')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,10 +0,0 @@
|
||||
# Bradford
|
||||
|
||||
Builder seat, Codex gpt-6.1-sol, started by Sage under Q246 and mos-1572. Owns the push check row:
|
||||
`scripts/push-check.sh`, which passes a binary only when an approved review candidate lists its path and sha256
|
||||
(docs/plans/2026-10-24_push-guard-binary-manifest.md, #1825).
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread and works in its own worktree. It has no credentials of its
|
||||
own; it pushes only its own `bradford/*` branches through the repository credential helper (mos-0981), never `refactor`,
|
||||
`main` or another seat's branch. Poe gives the first Codex review and Dewey the Opus 5.5 landing review (mos-1542,
|
||||
mos-1571). Registered by Sage on 2026-10-24 so the queue can name the seat as row owner (store.mjs isSeatDir).
|
||||
@@ -1,162 +0,0 @@
|
||||
# Row 327 — reviewed binary push check (#1825)
|
||||
|
||||
2026-10-24 Bradford, branch bradford/row327, base b617b80f6.
|
||||
|
||||
## Plan and boundaries
|
||||
|
||||
Implement the scratch check's ordered tokens in scripts/push-check.sh, using an
|
||||
embedded Node program for byte-safe git paths and SHA-256 blob hashing. Bash is
|
||||
the public entry point; Node is already a repository requirement. Git commands
|
||||
use explicit resolved object IDs, disable external diff/textconv, and inspect
|
||||
committed bytes. No queue writes, hook changes, binary evidence, or live state.
|
||||
Fetch is opt-in. Read reviewed rows with the queue package rows() API rooted in
|
||||
the caller's repository; this preserves canonical/witness/replay checks.
|
||||
|
||||
Only the latest round counts; any changes receipt blocks that round. A matching
|
||||
approval authorizes exactly the manifest path/hash, or a path changed from the
|
||||
commit candidate's first parent with matching committed blob hash and mode.
|
||||
Deleted binaries need no candidate. Multiple --row values form a union.
|
||||
|
||||
Add scratch-only integration coverage in scripts/test-push-check.sh. Reuse queue
|
||||
test fixture helpers to bootstrap real scratch queues, then use queue verbs to
|
||||
open rounds and record receipts. All git writes, bare remotes and queues remain
|
||||
under TMPDIR. Test fail-closed ordering and five required mutants, generated as
|
||||
text copies in scratch. No old tests are modified. Add the TOOLS entry.
|
||||
|
||||
Every run needs Sage CLEAR; run timeout -k 10. Record plain-text results here or
|
||||
in this packet. After green checks, commit and push only bradford/row327 through
|
||||
the repository helper, send Sage and Poe tip/base/path sha256 manifest, and move
|
||||
327 in-review. Sage owns request posting and landing; Dewey reviews once there.
|
||||
|
||||
## Recovery and choices
|
||||
|
||||
Initial worktree queue next refused linked-worktree access as designed. Queue
|
||||
claim is performed from the canonical checkout; production reads in the guard
|
||||
retain the same refusal rather than invent a worktree override.
|
||||
|
||||
Requested Sage ruling on AGENTS log appends outside the brief's owned paths.
|
||||
|
||||
Sage sage-3989: lead handles BUILD-LOG and SESSIONS at landing. Session entry:
|
||||
2026-10-24 Bradford — row 327 / #1825 — implementation and scratch verification
|
||||
in this packet; outcome to be appended after acceptance.
|
||||
|
||||
Implementation note: commit candidates use an explicit first-parent diff (empty
|
||||
tree for a root commit), with rename detection disabled, like verify-commit.
|
||||
The changes-veto case has both an approval and a changes receipt; a veto mutant
|
||||
would otherwise still fail for lack of approval and provide false confidence.
|
||||
A receipt for another candidate cannot be produced through queue verbs: the
|
||||
suite corrupts only a scratch queue and expects the production reader to refuse.
|
||||
Diff color, external diff and textconv are disabled so scans inspect plain git
|
||||
output. Paths are read from NUL-delimited records (including spaces/tabs).
|
||||
|
||||
## Verification (Sage CLEAR sage-3991)
|
||||
|
||||
First new-suite run red: my whitespace-path fixture attempted a manifest path
|
||||
that the queue intentionally forbids. Corrected the fixture to a commit
|
||||
candidate, which can contain that git path. Production queue code and old tests
|
||||
remain unchanged. Raw first-run output is test-run-1.txt.
|
||||
|
||||
Second run green: PASS push-check 22 checks; KILLED skip-hash,
|
||||
accept-changes, earlier-round, working-tree, no-row. test-run-2.txt holds the
|
||||
plain-text receipt. bash -n both scripts and git diff --check passed. Runs used
|
||||
TMPDIR recorded in tmpdir.txt and timeout -k 10 240; all generated binary bytes
|
||||
were in disposable scratch repositories, never in this checkout or evidence.
|
||||
The slot was used for only the authorized new suite and syntax/diff checks.
|
||||
No claim of the lead's full scripts/test-*.sh landing gate is made here.
|
||||
|
||||
Final inspection after the first green run found a path-decoding concern: lossy
|
||||
UTF-8 decoding can conflate distinct git filenames. Hardened NUL-delimited path
|
||||
decoding to reject invalid UTF-8, and quote newline-containing paths in refusal
|
||||
output to preserve one STOP line. Added scratch cases for both. Requested a new
|
||||
CLEAR (bradford-0005) because the previous slot had already been released.
|
||||
|
||||
Final run (sage-3994 CLEAR) green on final code: PASS push-check 24 checks,
|
||||
all five mutants KILLED again, bash -n both scripts and git diff --check passed.
|
||||
Receipt: test-run-3.txt. The guard rejects non-UTF-8 git paths as environment
|
||||
errors rather than comparing replacement characters; newline paths remain
|
||||
checkable through commit candidates and refusals quote them on one line.
|
||||
|
||||
Acceptance for the builder stage: ordered tokens and stop behavior, explicit
|
||||
base/fetch, exact blob manifest/commit checks, latest-round/veto checks, deletion,
|
||||
log/FF/secrets/attribution refusals, and all required mutants are covered. Queue
|
||||
reads use rows() with production validation; tests use only scratch queues.
|
||||
Candidate-mismatched receipts are impossible through the queue API and are
|
||||
covered by a corrupt scratch queue refusing its read. The lead's full-suite gate,
|
||||
Poe first review, Dewey landing review, and adoption for Sage's next push remain
|
||||
landing stages. No hooks, role policy, credentials or other seats' paths changed.
|
||||
|
||||
## Poe first review R1 (poe-0010) — changes
|
||||
|
||||
cceea407e has a blocking subdirectory bypass: ls-tree without --full-tree can
|
||||
omit an existing binary outside the caller cwd, making it look deleted.
|
||||
Accepted the finding. Git now anchors all invocations at the repository root,
|
||||
ls-tree uses --full-tree, and diff/diff-tree use --no-relative. EXPECTED_LOG still
|
||||
resolves from the original caller cwd. Added outside-cwd and nested-binary cases
|
||||
under diff.relative=true: unreviewed stops, reviewed manifest/commit passes.
|
||||
No old test changed. New run requires Sage CLEAR before execution.
|
||||
|
||||
R1 verification under sage-3999 CLEAR: test-run-4.txt records PASS 29 checks
|
||||
and KILLED all five required mutants. Syntax and diff whitespace checks passed.
|
||||
A second bounded run used the new suite against cceea407e's script copied under
|
||||
TMPDIR: r1-regression-red.txt records the outside-cwd unreviewed binary reaching
|
||||
NO_BINARY/PUSH_READY (actual exit 0, expected 1). Thus the new regression detects
|
||||
the reviewed bug, while the revised guard refuses it. No code changed between
|
||||
the green run and this old-candidate reproduction. All runs used timeout -k 10.
|
||||
|
||||
Holding claimant queue writes per sage-3999 until Boyd finishes row 309's record.
|
||||
Last acknowledged row 327 state is in-progress (bradford-0010, revision 3868).
|
||||
|
||||
## Dewey landing review B1 (dewey-0956) — changes
|
||||
|
||||
Read the invited review body at /mnt/storage/scratch/tmp/dew327vWXloCT/body.md.
|
||||
B1 identifies a brief-level gap: numstat follows candidate/host git attributes,
|
||||
so *.bin diff makes a NUL-containing blob disappear from the binary-only set.
|
||||
The production script indeed filters numstat before reading any blob, consistent
|
||||
with that data flow. Proposed correction: enumerate every changed numstat path,
|
||||
skip absent/non-blob entries at SHA, classify binary when numstat says binary OR
|
||||
committed blob has NUL among first 8000 bytes. Read with cat-file, never worktree.
|
||||
Test committed .gitattributes, info/attributes, and core.attributesFile overrides
|
||||
in scratch; reject with no row, allow exact reviewed bytes; add NUL-scan mutant.
|
||||
Sage owns the brief amendment and next CLEAR/queue sequencing.
|
||||
|
||||
N1 acknowledged: candidate-equality check is defense in depth; invalid receipt
|
||||
cannot pass queue replay, so the corrupt-queue case does not isolate that check.
|
||||
N2/N3 recorded as described in review, without optional secrets/reader changes.
|
||||
N4 planned hardening: refuse unconfirmed durable tail notes from rows() with
|
||||
exit 2, with a real scratch witness-prefix case rather than a test-only reader.
|
||||
No test run or queue write started for B1/N4 before Sage CLEAR.
|
||||
|
||||
Sage sage-4013/4015 authorizes B1 and N4 within the brief; amendment committed on
|
||||
refactor at 9042754c4 (read with git show, no branch change). Fix and tests written
|
||||
before requesting CLEAR as directed. Tests cover all three attribute sources,
|
||||
approved manifest success under each override, exact 7999/8000 offset boundary,
|
||||
and a real prefix-witness rollback to yield an unconfirmed approval tail.
|
||||
Added only the requested sixth mutant, skip-nul-scan; the original five remain.
|
||||
No new production configuration knobs, no secrets-diff change, no queue writes.
|
||||
Will demonstrate red against the prior candidate using the new tests, then green
|
||||
against revised code, under the approved slot. Full landing gate remains Sage's.
|
||||
|
||||
After Dewey's round-2 CHANGES record (comment 31522, rev3876), Sage sage-4016
|
||||
released only the claimant return to in-progress. Acknowledged:
|
||||
`ok bradford-0017 rev 3877 row 327 in-review→in-progress`.
|
||||
No other queue write before the next in-review candidate move.
|
||||
Test slot remains pending Sage CLEAR after Gyro's build.
|
||||
|
||||
## Amendment 1 verification (sage-4017 CLEAR)
|
||||
|
||||
b1-regression-red.txt: new tests against 704910ca3 reproduce attributes-hidden
|
||||
asset.bin reaching NO_BINARY/PUSH_READY with exit0 instead of exit1.
|
||||
n4-regression-red.txt: revised code with only the N4 check removed lets the real
|
||||
scratch unconfirmed approval tail reach BINARY_REVIEWED/PUSH_READY, exit0 rather
|
||||
than exit2. These are expected negative controls; neither changed committed code.
|
||||
|
||||
Final full new-suite run is green: test-run-5.txt records PASS 38 checks and
|
||||
KILLED skip-hash, accept-changes, earlier-round, working-tree, no-row, skip-nul-scan.
|
||||
All runs used timeout -k 10 240 with the same scratch TMPDIR; no old tests were
|
||||
changed or run. bash -n both scripts and git diff --check also passed. No source
|
||||
changes followed this green run. Sage's full landing gate is still separate.
|
||||
|
||||
Scope in the final delta: classify all changed present blobs using numstat OR
|
||||
first-8000-byte NUL; fail closed on queue unconfirmed-tail notes; regression cases
|
||||
and requested sixth mutant; TOOLS entry and this plain-text packet. B1's brief
|
||||
amendment is Sage's 9042754c4; this branch does not edit the brief or queue files.
|
||||
@@ -1,27 +0,0 @@
|
||||
node:internal/modules/run_main:107
|
||||
triggerUncaughtException(
|
||||
^
|
||||
|
||||
AssertionError [ERR_ASSERTION]: LOG_OK
|
||||
FF_OK
|
||||
NO_BINARY
|
||||
SECRETS_CLEAN
|
||||
NO_ATTRIBUTION
|
||||
PUSH_READY ee394f31d1e52751716e2413049f41b2f3072e65..76acc948149e718091fcd3f3807257e752a6616e
|
||||
|
||||
|
||||
|
||||
0 !== 1
|
||||
|
||||
at Object.check (file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:44:12)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:100:7
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
@@ -1,27 +0,0 @@
|
||||
node:internal/modules/run_main:107
|
||||
triggerUncaughtException(
|
||||
^
|
||||
|
||||
AssertionError [ERR_ASSERTION]: LOG_OK
|
||||
FF_OK
|
||||
BINARY_REVIEWED 1
|
||||
SECRETS_CLEAN
|
||||
NO_ATTRIBUTION
|
||||
PUSH_READY c1a8a1e9b8c3988874a8f7a35afab7c06aea94a5..325cd3671a7bf70b9a3aee60f4446bc93594a12a
|
||||
|
||||
|
||||
|
||||
0 !== 2
|
||||
|
||||
at Object.check (file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:44:12)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:121:7
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 2,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
@@ -1,27 +0,0 @@
|
||||
node:internal/modules/run_main:107
|
||||
triggerUncaughtException(
|
||||
^
|
||||
|
||||
AssertionError [ERR_ASSERTION]: LOG_OK
|
||||
FF_OK
|
||||
NO_BINARY
|
||||
SECRETS_CLEAN
|
||||
NO_ATTRIBUTION
|
||||
PUSH_READY 896bdf0ef56596c67d2dc427275743c46026e832..ad9f9c86112fadafef4d4854f46bd9994fe2fe5d
|
||||
|
||||
|
||||
|
||||
0 !== 1
|
||||
|
||||
at Object.check (file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:44:12)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:130:7
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 0,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
@@ -1,21 +0,0 @@
|
||||
node:internal/modules/run_main:107
|
||||
triggerUncaughtException(
|
||||
^
|
||||
|
||||
AssertionError [ERR_ASSERTION]: queue: candidate manifest path must be a repo-relative path: "space tab\tasset.bin"
|
||||
|
||||
|
||||
2 !== 1
|
||||
|
||||
at Object.round (file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:61:12)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/bradford-row327/[eval1]:116:7
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 2,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
@@ -1,6 +0,0 @@
|
||||
PASS push-check 22 checks
|
||||
KILLED skip-hash
|
||||
KILLED accept-changes
|
||||
KILLED earlier-round
|
||||
KILLED working-tree
|
||||
KILLED no-row
|
||||
@@ -1,6 +0,0 @@
|
||||
PASS push-check 24 checks
|
||||
KILLED skip-hash
|
||||
KILLED accept-changes
|
||||
KILLED earlier-round
|
||||
KILLED working-tree
|
||||
KILLED no-row
|
||||
@@ -1,6 +0,0 @@
|
||||
PASS push-check 29 checks
|
||||
KILLED skip-hash
|
||||
KILLED accept-changes
|
||||
KILLED earlier-round
|
||||
KILLED working-tree
|
||||
KILLED no-row
|
||||
@@ -1,7 +0,0 @@
|
||||
PASS push-check 38 checks
|
||||
KILLED skip-hash
|
||||
KILLED accept-changes
|
||||
KILLED earlier-round
|
||||
KILLED working-tree
|
||||
KILLED no-row
|
||||
KILLED skip-nul-scan
|
||||
@@ -1 +0,0 @@
|
||||
/mnt/storage/scratch/tmp/YPrPwR
|
||||
@@ -1,8 +0,0 @@
|
||||
# Bubba
|
||||
|
||||
Builder seat, Codex gpt-6.1-sol, started by Mos under Q245 (mos-1506). Owns row 288 (agent write notices and library revert, handed over from Honker).
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread (thread 3d6672b5) and works in its own worktree. It has no
|
||||
credentials of its own; it pushes only its own `bubba/*` branches through the repository credential helper (mos-0981),
|
||||
never `refactor`, `main` or another seat's branch. Claude seats orchestrate and review (Q245). Registered by Sage on
|
||||
2026-10-23 so the queue can name the seat as row owner (store.mjs isSeatDir).
|
||||
@@ -1,501 +0,0 @@
|
||||
# Row 288 (#1793): C2-02 agent writes, notices, revert and Console saves
|
||||
|
||||
Owner: Bubba, Codex gpt-6.1-sol, thread 3d6672b5-5544-4b95-9e09-e79574f1aa14.
|
||||
Reviewer: Webby. Gate and landing: Sage. Append-only build record.
|
||||
|
||||
## 2026-10-23 start and implementation plan
|
||||
|
||||
Base 45dca69f6 on bubba/row288. Direct mandate mos-1499 (Q245), confirmed sage-3613.
|
||||
The canonical `scripts/mosaic queue next bubba` returned `nothing`; Sage owns the owner transition.
|
||||
The initial worktree invocation refused linked-worktree use; retried in canonical checkout.
|
||||
|
||||
Spec: docs/plans/2026-10-20_case2-rows.md, C2-02; agents/gosalyn/work/case2/DESIGN.md ruling after r11.
|
||||
Handoffs: Honker queue-283 BUILD.md Q4 (missing/non-100644 delete refuses); Morgana
|
||||
queue-225 BUILD.md A2 at 66f7becf2 (strict revert arguments/result), confirmed by Fethry fethry-0005.
|
||||
`project` is the business.projects key, never a chat UUID.
|
||||
|
||||
Dependencies merged with their commits intact, no amend or force-push:
|
||||
- 283 origin/honker/row283-build 88ec5e8e4 (new E4 head to follow).
|
||||
- 285 origin/scrooge/row285-r2 53db6b7ca.
|
||||
- 286 origin/ludwig/row286-r2 573fa0be0.
|
||||
- 284: no named remote branch yet. Tool changes come last.
|
||||
All merge commits are marked Untested. Nothing has run under Node. Sage's latest instruction
|
||||
sage-3613 reserves **all Node and test runs** for CLEAR; this supersedes the initial targeted-test
|
||||
permission. Build untested now as instructed, then run RED/GREEN checks/mutants on CLEAR.
|
||||
|
||||
Architecture: one host-only plumbing writer under the existing library lock; broker authorizes and
|
||||
selects credentials, then inserts the fixed notice directly. Human save/revert use editor +
|
||||
library-human independently of seat lifecycle. No worktree, deferred push, role expansion or UI.
|
||||
|
||||
### Tasks and acceptance
|
||||
|
||||
- [ ] Plumbing: new library/src/write.mjs, mirror state publication and package exports; new
|
||||
library/tests/write.test.mjs. One-parent write/delete, byte-exact content, seat identity/trailer,
|
||||
stale-base, nonregular/missing deletes, retry once on an unrelated remote change, push failure
|
||||
without local ref movement, human editor and revert reachability/single-path checks.
|
||||
- [ ] Broker + runtime: library.doc.write/delete, library.file.save, library.revert; strict keys,
|
||||
creative + library.write + live unheld project grant; direct exact notice; human-only save/revert.
|
||||
New bus/tests/library-write.test.mjs covers authorization, unchanged refs, A2 contract and socket.
|
||||
- [ ] Transport: only human library.file.save joins the existing large-save exception. New tests
|
||||
prove >64 KiB save accepted, agent writes retain 64 KiB bound, malformed/oversize saves refuse.
|
||||
- [ ] Tools after 284: library_doc_write/delete in harness tools; exact eight/ten-name snapshots
|
||||
in a new harness test; cli dispatch wiring.
|
||||
- [ ] Verify on CLEAR: new tests, library/bus/harness suites and all scripts/test-*.sh on Sage's
|
||||
assigned slot. Mutants remove supporting guard and force push; both must fail. Fixture-token
|
||||
search over captured output. No gate, landing or queue move claimed before Sage's acceptance.
|
||||
|
||||
Pre-flight interfaces: broker consumes library writer {project,path,commit}; revert adds reverted;
|
||||
writer consumes C2-03b push {pushed} or {raced,tip} and supportingPath(mapping,universe,path,tree).
|
||||
State publication must add optional lastPush while preserving old state readability. Refusals must
|
||||
restore fetched remote-tracking refs as well as preserve served. Runtime must bind credential file
|
||||
references itself; no file, identity, message or credential is supplied by the agent.
|
||||
|
||||
Necessary file-scope additions: packages/bus/src/runtime.mjs (actual adapter injection),
|
||||
packages/library/src/index.mjs (exports), and CLI's existing console adapter if saves require it.
|
||||
Reported to Sage in bubba-0002. Existing tests will not be edited without Mos's OK via Sage.
|
||||
|
||||
Review focus: remote tip races, nonregular entries and folded paths, unsafe human credential before
|
||||
git, revert after revoked/fired writer, and large-request exception never extending agent writes.
|
||||
|
||||
### Existing-test changes
|
||||
|
||||
None authored by Bubba yet. Dependency test changes remain their owners' original commits.
|
||||
|
||||
## 2026-10-23 first static build (not a gate result)
|
||||
|
||||
283 E4 merged intact at 76d651dba. Honker next reports e67c27b32 (test environment only), to merge
|
||||
before push. Della reports row 284 has not been built/pushed; row224's 23816cf28 is not a 284 head.
|
||||
No speculative 284 pin. Typed tools and served-blob lookup integration remain pending 284.
|
||||
|
||||
Implemented (unrun): bare plumbing writer, one-parent commit and fixed trailer, exact-content blobs,
|
||||
base comparison, supporting path guard and delete regular-blob check, one remote-race retry,
|
||||
ref restoration on refusal, immediate served publication/lastPush; human save and reachable one-path
|
||||
business-trailer revert; broker grants/identity/notice path; runtime adapter wiring; large-save socket
|
||||
exception. New tests: library/tests/write.test.mjs and bus/tests/library-write.test.mjs. No old test edits.
|
||||
|
||||
### Approved scope additions, sage-3628
|
||||
|
||||
Every hunk outside the brief's owned list:
|
||||
- `packages/bus/src/runtime.mjs`: `humanWriteOptions` checks editor before choosing the human slot;
|
||||
three library adapter entries bind dataRoot, command and the host-only seat store reference. These
|
||||
are needed to make actual bus calls reach the new writer without accepting agent-supplied files.
|
||||
- `packages/library/src/index.mjs`: export writeLibraryDoc/saveLibraryFile/revertLibraryCommit so
|
||||
runtime's existing library module adapter can call them.
|
||||
- `packages/library/src/sync.mjs`: shared write guard with opaque token compared by identity;
|
||||
push's race fetch recognizes only that owner and does not clear its guard; ordinary sync and a
|
||||
forged token still refuse library-sync-busy. Narrow publishLibraryWrite validates ids, reads the
|
||||
locked state, rebuilds the index via readLibrary, moves served/tracking and writes lastPush. The
|
||||
raw writeState remains private and is not exported through index.mjs.
|
||||
|
||||
Ludwig ludwig-0064 reviewed the intended interface and requested the opaque token (implemented),
|
||||
narrow publication (implemented), whole library + bus library-credential checks and a token mutant
|
||||
(planned). His 573fa0be0 remains current and unrun. 288's additions are separate commits, not folded
|
||||
into 286. Tracking restores only if the whole write refuses, not between the first race and retry.
|
||||
|
||||
Known tradeoff, accepted by Sage sage-3628 for MVP: the brief holds the flock through network Git;
|
||||
readers can hit the existing 5-second library-sync-busy while it runs. Structural supportingPath
|
||||
preflight is pure and precedes Git; served/fetched listTree checks repeat it with the real tree before
|
||||
any remote write. A tree-dependent check necessarily reads the tree first (Honker honker-0184 item2).
|
||||
|
||||
### Mutants for CLEAR
|
||||
|
||||
- Remove the `pathOf` calls for agent operations: the M12 broker/bare-ref tests must fail on a
|
||||
story/unsupported path while checking remote, tracking and served refs.
|
||||
- Prefix the push refspec in syncCommand with `+`: write.test moved-target race must fail, because
|
||||
its command seam preserves production syncCommand's refspec (only remote URL/protocol are fixture).
|
||||
- Replace `writers.get(mirror) === writeToken` with `true`: write.test forged-token case must fail.
|
||||
|
||||
No Node, test, build or mutant has run. `git diff --check` is clean. Counts are not claimed.
|
||||
|
||||
### Console dispatch integration
|
||||
|
||||
The existing cli delegates its transport wiring to console-bus.mjs, so the save dispatch needs that
|
||||
file too: one null `librarySave` option and one `--send` assignment to library.file.save. cli.mjs
|
||||
threads that option into startServer; row C2-11b owns the actual route/page that consumes it. New
|
||||
webui/tests/library-write-options.test.mjs covers --send and the user transport boundary. 225 owns
|
||||
libraryRevert dispatch; 288 adds only librarySave to avoid overlapping that ownership. Additional
|
||||
scope reported to Sage and Fethry. No changes to an existing test.
|
||||
|
||||
## 2026-10-23 second static pass and dependency review
|
||||
|
||||
First push: c867cada9 on origin/bubba/row288, reported bubba-0005 to Sage/Webby/Mos and
|
||||
bubba-0006 to Fethry/Ludwig. No PR created and no review/gate requested as complete.
|
||||
|
||||
Ludwig ludwig-0065 checked the exact sync diff against 286 without running anything. Token identity,
|
||||
ordinary-sync exclusion, 286 R1 preservation, guard key and end-of-write tracking restoration fit.
|
||||
F1: state publication could fail after served moved, leaving old state/new served. Root cause is
|
||||
publication order without rollback, compared against sync's existing rollback. Added an unrun
|
||||
filesystem rename-failure regression, then changed the narrow helper: on failure it validates the
|
||||
state under the same lock, CAS-restoring served if state has not published the new commit. If rename
|
||||
succeeded but directory fsync failed and the state validates against new served, it keeps that pair.
|
||||
All failure cases answer outcome-unknown; tracking remains the commit already pushed remotely.
|
||||
Verification is pending CLEAR, so this is a proposed fix, not a tested resolution.
|
||||
|
||||
Added the actual broker-to-bare tests for each M12 path refusal (both agent verbs), unchanged remote
|
||||
and all mirror refs, exact write/delete notices, and human revert after fixture grant removal/hold.
|
||||
The bare fixture moved to new library/tests/write-fixture.mjs so broker tests reuse real plumbing.
|
||||
Added the raw socket proof-nested-save-name case to pin the parsed-verb large-request check.
|
||||
Missing editor/slot tests now make the mirror metadata invalid first: reaching Git would change the
|
||||
refusal, so the tests check the pre-Git gate rather than merely count remote commands.
|
||||
|
||||
Additional required doc hunk: packages/library/README.md appends the four verb contracts,
|
||||
lastPush shape, exact notice, lock tradeoff and publication failure behavior. No existing test from
|
||||
the dependency/base has changed. All new/modified tests in this pass were authored by this row.
|
||||
`git diff --check` remains clean. No Node/tests/build/mutants run; 284 and CLEAR remain pending.
|
||||
|
||||
## 2026-10-23 early review follow-up (Webby E1-E6; Ludwig F2)
|
||||
|
||||
Sage sage-3652 approves console-bus.mjs wiring (null option + --send dispatch), confirms editor.user
|
||||
as the sole human login source and reserves CLEAR for T3/T4 after T2. Ordinary sync()'s separate
|
||||
post-rename fsync gap stays out of 288 per that ruling; no change to sync()'s existing rollback.
|
||||
|
||||
Honker 283 head 46bad7ea3 merged intact: mapping editor.user is optional, and if present uses the
|
||||
existing plain Gitea-user pattern. The omission at mapping level is valid; human writes refuse it.
|
||||
|
||||
- Ludwig F2 / Webby E6: confirmed the previous runtime used the fetch bot's mapping.user wrongly.
|
||||
Runtime now passes mapping.editor.user to humanCredential, never mapping.user. Missing user gives
|
||||
library-human-missing before Git. New real-runtime cases pin both save and revert with a separate
|
||||
fetch-bot login, positive pushes under her-gitea-login, and no command for an absent editor login.
|
||||
The broker's credential.agent is s.role, not args: added an exact assertion and strict-key refusal
|
||||
cases for caller-supplied agent and credential.
|
||||
- E1: replaced the business-id RegExp interpolation with a literal startsWith(business.id + '/')
|
||||
check and ID_PATTERN on only the instance suffix. New acme.co vs acme-co trailer test.
|
||||
- E2: new broker→bare case holds the seat in the fetch command. beforePush must refuse
|
||||
library-write-no-grant with all local refs and the remote unchanged and no notice. New mutant:
|
||||
remove `options.beforePush?.();` in write.mjs; the E2 test must fail.
|
||||
- E3: new broker cases for expired rotate_by, fire.stopped without fire.done, missing role.publish
|
||||
project, grant/identity Gitea-user mismatch, and missing identity name/email, for both agent verbs.
|
||||
- E4: the exceptional publication failure currently returns outcome-unknown before the broker has
|
||||
a successful result to put in a notice, so a remote agent commit can exist without a Console
|
||||
notice. There is no durable notice outbox/retry in this row. The trailer commit remains human
|
||||
revertible by id after sync; this is an explicit known failure-mode gap for the manifest, not
|
||||
a claim that every failed publication emits a notice. A new real-push test breaks state decoding
|
||||
after push admission, pins outcome-unknown, old served and no notice. It also found a local error
|
||||
propagation gap: errors before publishLibraryWrite's internal try now normalize to outcome-unknown
|
||||
in the writer once push has succeeded, so the caller is never told an ordinary refused-write code.
|
||||
- E5: 284 still has no build. Tools/8-or-10 snapshot and served-blob integration remain pending.
|
||||
librarySave is intentionally only an adapter option until C2-11b supplies its route/page.
|
||||
|
||||
All tests above are newly authored by row288 and remain unrun; no changes to baseline/dependency
|
||||
tests. RED/GREEN and mutants await CLEAR. Proposed fixes are not claimed verified. The new host-only
|
||||
library write module imports the existing pure ID_PATTERN to match the broker's accepted instance ids.
|
||||
|
||||
## 2026-10-23 mos-1520 ruling: post-push notice is required
|
||||
|
||||
Correction to the E4 interpretation above: Mos rejected the known-gap treatment. The requirement
|
||||
stays: a pushed agent commit has the exact notice even if local publication then fails. This is not
|
||||
an outbox or retry. The writer now calls the broker's trusted synchronous onPushed callback as soon
|
||||
as push returns pushed:true, before publication. The callback records the exact library-write notice
|
||||
and action.allowed in the normal Console-store transaction. Publication failure still answers
|
||||
outcome-unknown. The notice's Revert can refuse library-revert-not-agent until sync makes that commit
|
||||
reachable from served; README now says that explicitly and removes the rejected gap description.
|
||||
|
||||
The row's own real-push corruption test now pins the exact notice body with the pushed id, old
|
||||
served and outcome-unknown; after restoring readable state it pins Revert's refusal before sync and
|
||||
success after sync. The successful-write adapter fixture calls onPushed too, matching runtime's
|
||||
writer contract. No existing baseline/dependency test changed (mos-1520 explicitly authorizes this
|
||||
row's test correction without mos-1272).
|
||||
|
||||
Residual Console-store failure: if notice insertion/routing/its event transaction fails, the broker
|
||||
calls a separate host log sink with {event:library-notice-store-failed,code:outcome-unknown,business,
|
||||
instance,op,commit}. It logs no args, path content, credential, raw SQL or exception output. Runtime's
|
||||
new library.log adapter writes this metadata to stderr. The caller gets outcome-unknown even if
|
||||
recording action.refused in that same broken store fails. A new real-push test uses temporary SQLite
|
||||
abort triggers on notice insertion and refusal evidence, checks remote advanced/served unchanged,
|
||||
no message, the exact external log and outcome-unknown. It does not claim a notice can be stored in
|
||||
a failed Console store. If the host log sink itself also fails, no durable log can be promised; the
|
||||
caller still receives outcome-unknown. The runtime log hunk is the required residual-failure wiring.
|
||||
|
||||
Mutant added: move `options.onPushed?.({ project: context.project, path: change.path, commit });`
|
||||
from before `await publishLibraryWrite(...)` to immediately after that await inside the same try.
|
||||
Successful operations keep their notice, but the outcome-unknown publication path drops it. The
|
||||
C2-02 E4 real-push corruption test must fail on its exact notice assertion. Run on CLEAR and restore.
|
||||
|
||||
No Node/tests/build/mutants run. Static git diff --check clean. Della's first284 head0ed4fbab9 is
|
||||
explicitly incomplete and not a finished dependency; waiting for her complete-head pin before tools.
|
||||
|
||||
Webby webby-0253 (static, cef503cb9) closes E4 per mos-1520; no tests ran. N1: a failed notice insert throws from onPushed before publication, so served stays at the prior commit until sync; the store-failure test pins this safe direction. Only E5 (284 tools/snapshot integration) remains open in this early review.
|
||||
|
||||
## 2026-10-23 complete284 merge and final tool integration (unrun)
|
||||
|
||||
Della della-0037 supplied complete untested head47db04eba85ac3ceb7e81385603f97bb6f8c1a38,
|
||||
replacing the incomplete head. Merged intact as c0ca3894c. Its22423816cf28 and2164f3fbc25a
|
||||
lineage is retained. Three conflicts were in overlapping production wiring only:
|
||||
- broker.mjs: keep Della's LIBRARY_LOOKUPS object and #requestLibraryLookup byte-for-byte, and
|
||||
keep288 writer/notice methods; LIBRARY_VERBS contains both sets and request dispatch calls lookup.
|
||||
- runtime.mjs: keep lookup adapter plus288's metadata log and write adapters.
|
||||
- library/index.mjs: keep index/query exports,286's push/humanCredential exports and288's writer exports.
|
||||
No dependency test body was changed in the merge. These are overlapping consumer integrations,
|
||||
not rewrites of dependency commits. Every prerequisite still needs its own gate (mos-1351).
|
||||
|
||||
Added library_doc_write/library_doc_delete after the five lookups, only for a creative definition
|
||||
with a within-role library.write grant and library enabled. Closed schemas carry exactly
|
||||
{universe,path,base,content} and {universe,path,base}; base is string-or-null with 40-lowercase-hex
|
||||
pattern. No project, business, author, credential, commit or message. tools.action is library.write.
|
||||
New harness/tests/library-write-tools.test.mjs pins per-role eight/ten names, both schema invariants,
|
||||
no repo/commit/business/accept, exact required/verb/action, nullable base, and missing library/grant
|
||||
or noncreative exclusion. This satisfies sage-3678 and mos-1523's replacement coverage condition.
|
||||
|
||||
Publication's narrow helper now calls indexFor for the new served commit instead of only readLibrary,
|
||||
so the284 lookup index is rebuilt before publication. New broker integration uses library.get's
|
||||
served blob as write/delete base, independently checks served:path, reads the new text/blob immediately,
|
||||
preserves default-canon null, then sees null after delete. No change to284's query behavior.
|
||||
|
||||
### Authorized baseline-test migration, own commit (mos-1523 via sage-3677)
|
||||
|
||||
File: packages/harness/tests/library-tools.test.mjs. Numstat: +4/-4, exactly.
|
||||
The noncreative LOOKUPS assertion at :33 is unchanged. Every existing lookup schema assertion stays.
|
||||
The four old/new lines are:
|
||||
|
||||
```diff
|
||||
- ? ['web_search', 'web_fetch'] : []), ...LOOKUPS];
|
||||
+ ? ['web_search', 'web_fetch'] : []), ...LOOKUPS, 'library_doc_write', 'library_doc_delete'];
|
||||
-test('M3: per-role snapshots contain six names, or eight with the C2-08 web grant', t => {
|
||||
+test('M3: per-role snapshots contain eight names, or ten with the C2-08 web grant', t => {
|
||||
- for (const [i, tool] of tools.filter(t => t.name.startsWith('library_')).entries()) {
|
||||
+ for (const [i, tool] of tools.filter(t => LOOKUPS.includes(t.name)).entries()) {
|
||||
- assert.deepEqual(tools.map(t => t.name), ['send_message', ...LOOKUPS]);
|
||||
+ assert.deepEqual(tools.map(t => t.name), ['send_message', ...LOOKUPS, 'library_doc_write', 'library_doc_delete']);
|
||||
```
|
||||
|
||||
Additional schema mutant (mos-1523): add `commit: str("caller commit")` to writeBase in tools.mjs,
|
||||
thereby adding it to either/both write schemas. The new-file schema test must fail both its exact
|
||||
property set and forbidden-property assertions. Run on CLEAR and restore. No further assertion
|
||||
change in library-tools.test.mjs is authorized or made.
|
||||
|
||||
All code/tests/mutants remain unrun. No Node, build or syntax check before Sage's named CLEAR.
|
||||
Static diff --check is clean. Scope additions stay listed above, now including indexFor import and
|
||||
call in the previously approved narrow publication helper. E5 implementation is present; review and
|
||||
acceptance are pending evidence, not claimed complete.
|
||||
|
||||
## 2026-10-23 testing and landing boundary (sage-3682)
|
||||
|
||||
Latest complete dependency2845d587a552 (test/docs only over47db04eba) merged intact as f8f79ea2f.
|
||||
Own tool implementation cd2f50dae and separate mos-1523 migration29455c0c5 are pushed; Webby reads
|
||||
E5 and Dewey checks the migration. Static manifest-r1 covered21 own paths at f8f79ea2f.
|
||||
|
||||
Sage reserves first focused runs/RED-GREEN/mutants for T7, provisionally about22:25Z, unless he
|
||||
explicitly frees an earlier lane. No Node before his CLEAR. This is a schedule, not CLEAR. Full
|
||||
library/bus/harness and shell gates still need their own authorized slot; no gate result is claimed.
|
||||
|
||||
Before the gate, incorporate landed refactor after283/224/284 land while preserving every
|
||||
prerequisite. Under the standing add-commits/no-force-push rule, update this published branch by merge
|
||||
rather than rewriting its pushed history. 288 lands last in the chain; no landing is authorized here.
|
||||
|
||||
## 2026-10-23 E5 static closure and N2 wording
|
||||
|
||||
Dewey dewey-0948: the mos-1523 migration at29455c0c5 is static CLEAN, exactly+4/-4, with the
|
||||
noncreative assertion unchanged and new-file schema coverage meeting every condition. Webby
|
||||
webby-0263: E5 closed on29455c0c5/cd2f50dae (f8f79ea2f;98ca25ab1 only BUILD.md), nothing blocking.
|
||||
Both ran nothing; Webby did not read the scratch manifest, so no manifest verification is implied.
|
||||
|
||||
Webby N2: delete inherited the write base description "or null to create". Delete now overrides only
|
||||
that description: "The existing file's blob from library_get; a missing file cannot be deleted".
|
||||
The reviewed nullable-base schema/required keys/verbs remain unchanged. The row's new schema test
|
||||
pins create wording only on write and existing-file wording without create on delete. No further
|
||||
assertion change in the baseline library-tools.test.mjs. No Node/tests run; still await Sage CLEAR.
|
||||
|
||||
## 2026-10-23 dependency283 follow-up (honker-0195)
|
||||
|
||||
Merged origin/honker/row283-build b2a1f4092 intact, fast-forward lineage from46bad7ea3. It changes
|
||||
supporting.test's helper and Honker's BUILD receipts only; no production source changed. Honker
|
||||
reports library98/98, business231/231 and14/14 mutants killed on that dependency head. Those are
|
||||
his dependency receipts, not verification of288's combined branch. No288 Node/tests run; Sage's
|
||||
CLEAR is still required. The dependency's own gate/landing remains Sage's responsibility.
|
||||
|
||||
## 2026-10-23 new candidate after283 landing (sage-3727, honker-0200)
|
||||
|
||||
Created bubba/row288-r2 from the preserved published bubba/row2887c53adf10, then rebased with
|
||||
--rebase-merges --no-update-refs onto93694c5185d0a7f989d2fe78fb620e44599b744e. This supersedes
|
||||
the earlier merge-only refresh plan for this candidate: Sage explicitly requested a fresh branch,
|
||||
not a force-push. Both local and remote bubba/row288 remain7c53adf10, unchanged.
|
||||
|
||||
Git skipped12 duplicate283 commits already replayed upstream. Range-diff of
|
||||
45dca69f6..bubba/row288 against93694c518..bubba/row288-r2 (before this receipt) has35 equal
|
||||
commits,12 dropped,0 modified,0 added. Full output: scratch/bubba-row288/rebase-r2-range-diff.txt
|
||||
under /mnt/storage. The other prerequisite commits retain their patches; row216/224 identities are
|
||||
unchanged where Git could retain them. This is not new verification of any prerequisite.
|
||||
|
||||
Replayed merges had the same launcher-footer and broker/runtime/index conflicts as before. Reused
|
||||
the exact previously reviewed combined file bytes, keeping both launcher test bodies and all lookup
|
||||
and writer paths. Static comparison before this receipt: all21 own manifest paths byte-identical
|
||||
to7c53adf10; all16 other changed paths exactly match93694c518 upstream. These include newly landed
|
||||
226 and coordination/docs changes already on that base, not new288 edits. No baseline assertion or
|
||||
production change was introduced by conflict resolution.
|
||||
|
||||
Sage's base93694c518 is an ancestor of the candidate; old283 b2a1f4092 is not. Static diff --check
|
||||
clean. No Node, test, syntax, build, mutant or gate run. Named CLEAR/T7 still pending;288 lands last.
|
||||
|
||||
## 2026-10-24 static preflight before landed284 base (sage-4282)
|
||||
|
||||
No Node, npm, test, syntax, mutant, queue command or gate ran. Still on bubba/row288-r2,
|
||||
b44152ac6 plus this static follow-up; await Sage's landed284 base before a fresh candidate branch.
|
||||
Do not treat the earlier T7 estimate as CLEAR. Webby remains reviewer.
|
||||
|
||||
### Updated C2-02 brief and contract names (webby-0282 N1)
|
||||
|
||||
Read C2-02 on origin/refactor 95d4991d20a4ef291c824d37c886eaeaa9be7062; current brief blob 85e6fe2ecfc53ed615b7b61aade88ae0cbb222ef
|
||||
(the new ruling is identified by Sage as5e8a720b). Statically checked both the candidate and current
|
||||
refactor versions of all six creative contracts: roles/companion.md, research.md, ideas.md,
|
||||
proofreader.md, fact-checker.md and continuity.md. Every one names library_doc_write and
|
||||
library_doc_delete, exactly the two add() names in candidate harness/src/tools.mjs. No role contract
|
||||
change is needed or made. Exact-name evidence is tool-contract-audit.json in the scratch dir below.
|
||||
|
||||
### mos-1584 fixture audit
|
||||
|
||||
The new row288 harness tests reach businessDoc through resolvedFor, but their callbacks add only a
|
||||
creative role; they add no library business project. library:true is the typedTools option, not a
|
||||
businessDoc project. The broker/runtime/bare-library tests build minimal business objects directly,
|
||||
not businessDoc. The migrated baseline harness test likewise adds no library business project.
|
||||
There is therefore no new row288 businessDoc-with-library fixture requiring a chief-reference edit.
|
||||
The current and future landed-base imported fixtures must be rechecked after the pending rebase;
|
||||
any validating businessDoc fixture that adds a library project must retain/provide chief gitea.
|
||||
|
||||
Shortened only two row288-authored fixture credential values: write-fixture.mjs uses fx288-write,
|
||||
and the runtime test's two slots use fx288-human. Both are11 characters, below24. This corrects the
|
||||
25-character runtime value and avoids an edge at the older23-character write value. No assertion
|
||||
changed, no baseline test edit and no credential file was read. No live credential action occurred.
|
||||
|
||||
### mos-1612 whole-file run-list preparation (not run authorization)
|
||||
|
||||
Static lexer traversed real import/re-export/require and new-URL module-entry edges, skipping
|
||||
comments/quoted fixture code; reverse closures carry a chain witness for every selected test.
|
||||
Used the union of this older candidate and the current refactor source snapshots so newer importers
|
||||
are visible without prematurely rebasing. It selected270 whole test files. Required whole library,
|
||||
bus and harness suites add17 distinct files, making a proposed union of287 (not a narrow grep list):
|
||||
bus115, business2, cli58, harness16, library13, plugins1, processing-control1, seat5, tasks9, webui67.
|
||||
The brief also names all12 scripts/test-*.sh runners. No file/runner was executed.
|
||||
|
||||
packages/cli/tests/case1-accept.test.mjs is explicitly excluded under mos-1592/1612. The11
|
||||
nonliteral-import files have a manual expression audit; all already occur in the import-selected
|
||||
whole-file set. Generated programs and runtime plugin discovery are recorded static limitations,
|
||||
not asserted fully resolved by the lexer. Whole suites and the named script runners retain their
|
||||
brief-required coverage. Regenerate after landed284 rebase; report exact final sha/list before CLEAR.
|
||||
Each approved gate later needs own root/webui npm ci, required editor build, short scratch TMPDIR,
|
||||
whole files and gate skip receipts under the then-current rules. These are plans, not past evidence.
|
||||
|
||||
Artifacts: /mnt/storage/scratch/bubba-row288/static-2026-10-24/
|
||||
- import-run-list.py SHA256 ec18031c87bf6f96b3e794e2e56747bc5e1fe37580de7ce9444c60cd5f18ddc0
|
||||
- whole-files.txt SHA256 b2d6c11349268c347e51a64fe6bf9e7c4d560238a8fc5b5e10f600f1e6e8a39e
|
||||
- import-witnesses.json SHA256 01702657d34c4f2c0635f38741d0a5b57cfdda63d5e96897f188d03971afd5d9
|
||||
- dynamic-import-audit.txt SHA256 42b8721fde783c618e1347f2609ad6e4ae3144f563272f0bbbeb45c34f751018
|
||||
- brief-required-whole-files.txt SHA256 254828414cd9b1b0a785df5c23b7f2b9ea7564d1f85e648899801e46194d135f
|
||||
- proposed-whole-files.txt SHA256 bee666dce2c3f2d0bafe7e963fb443ad356b6ae8719ac3cb8ee413a329578035
|
||||
- brief-script-runners.txt SHA256 02cd25af486c163189977106e055575145bffba688c7836e2a508f5ec91e76d4
|
||||
- tool-contract-audit.json SHA256 bf07865d796b8b0aed85d84c015430ea03468c5331bcaae9eb80efafe1a182be
|
||||
- fixture-audit.json SHA256 436a69a6b8548d8426390e867ed4b0f83693a3116d825c26c6f8a3e788f477d6
|
||||
|
||||
## 2026-10-25 landed-base transplant (sage-4338), UNTESTED
|
||||
|
||||
Named base: 78b69e1e68b2b8a9dc4c02564381a0792c0c7549, including landed284 ce0b6ed41.
|
||||
New branch bubba/row288-r3-landed; published r2 e7c31a90d is untouched.
|
||||
The initial --rebase-merges replay tried to reapply already-landed285 and conflicted;
|
||||
aborted without resolving those conflicts. Transplanted only the twelve Bubba nonmerge
|
||||
commits, in order, onto the named base using cherry-pick. No dependency commits replayed.
|
||||
|
||||
Conflict resolutions (no test conflicts, no assertion changes):
|
||||
- BUILD-LOG.md and docs/SESSIONS.md: preserve the entire upstream side, append Bubba entries.
|
||||
- broker.mjs: retain landed LIBRARY_LOOKUPS and lookup dispatch, add writer verbs/methods;
|
||||
retain the complete landed library.status replyLimits branch after writer/save/revert dispatch.
|
||||
- server.mjs: retain landed refusal envelope including reason, combine project/library save detection.
|
||||
- library/index.mjs: retain every landed export, append the writer exports.
|
||||
- webui cli.mjs and console-bus.mjs: preserve landed libraryRevert and add librarySave alongside it.
|
||||
- runtime.mjs (notice follow-up): retain landed lookup adapter, add metadata-only log sink.
|
||||
All other changes merged automatically. No business role/vocabulary file or dependency packet changed.
|
||||
Baseline test migration remains packages/harness/tests/library-tools.test.mjs +4/-4 (mos-1523).
|
||||
Only additional own-test edit removes a trailing blank EOF line in write-fixture.mjs.
|
||||
|
||||
Line-reference recheck: the sole explicit source-line citation in this append-only packet,
|
||||
noncreative LOOKUPS :33, is still exactly line33 of library-tools.test.mjs and unchanged.
|
||||
Historical fired-chief path4308 described an older broker; current fire.stopped/fire.done are
|
||||
broker.mjs5126/5147 (firing detection863-865). Those historical receipts remain historical.
|
||||
Old head/brief identifiers and T7 times above are historical, not the present base or CLEAR.
|
||||
|
||||
Final import-list audit uses candidate + exact named-base import graphs, eleven changed source
|
||||
modules as roots, and all touched tests; no text grep selects a test. 272 whole files selected,
|
||||
plus17 brief-required library/bus/harness files =289 files. Package counts: bus116, business2,
|
||||
cli59, harness16, library13, plugins1, processing-control1, seat5, tasks9, webui67.
|
||||
All12 current scripts/test-*.sh runners retained. case1-accept.test.mjs excluded explicitly.
|
||||
The eleven nonliteral import expression sites were rechecked; whole parent tests already selected.
|
||||
Generated programs/runtime plugin discovery remain documented static limitations.
|
||||
Artifacts and chain witnesses: /mnt/storage/scratch/bubba-row288/static-r3/.
|
||||
No Node, npm, test, syntax check, build, mutant or gate run. Pending Sage CLEAR.
|
||||
|
||||
## 2026-10-25 first CLEAR and delete-path RED/GREEN (sage-4396/4398)
|
||||
|
||||
Own root npm ci rc0; own webui npm ci rc0; editor build rc0. Fresh TMPDIR from mktemp
|
||||
under /mnt/storage/scratch/tmp. All Node whole-file runs nice19, timeout600 kill-after10.
|
||||
Initial own write.test.mjs rc1,10 pass/2 fail: delete and revert-to-absent hit library-git.
|
||||
Isolated bare Git confirms update-index --force-remove rc128 (requires worktree), while
|
||||
--index-info rc0. First replacement and two delimiter-investigation reruns still rc1,
|
||||
10/2: runGit's stdin argument names an input FILE, not input text. No pre-existing test
|
||||
ran or was edited. Final correction writes a private NUL-delimited removal record in the
|
||||
already-cleaned staging dir and supplies that file to update-index -z --index-info.
|
||||
Whole write.test.mjs now rc0,12/12,0 skipped/cancelled. Source-only fix in owned write.mjs.
|
||||
Logs remain /mnt/storage/scratch/bubba-row288/gate-r3/ (write-fixed through write-fixed4).
|
||||
Sage4398 authorizes this fix and requires committed new candidate + driver restart from
|
||||
first whole file. Focused green is not the complete gate; remaining acceptance pending.
|
||||
|
||||
## 2026-10-25 new broker-fixture RED/GREEN, driver restart pending
|
||||
|
||||
Candidate7932c979a driver first library file rc0,12/12; second own bus library-write rc1,
|
||||
0/14 (fixture FK and undefined dataRoot). Own fixture lacked gitea_users parent; insert
|
||||
with valid16-hex nonce, consistent with landed credential tests. First attempted fixture
|
||||
nonce was invalid and INSERT OR IGNORE hid it; corrected nonce, no product/schema changes.
|
||||
Every bare.dataRoot reference was undefined: use bare.context.dataRoot. After these fixes,
|
||||
whole file rc1,13/14, last assertion assumed lines were strings; query returns [line,text].
|
||||
Corrected this row's new assertion to exact [1,'new served text']; whole file rc0,14/14,
|
||||
0 skipped/cancelled. Intermediate logs bus-fixture-fixed{,2,3} under gate-r4 retained.
|
||||
Only owned new bus/tests/library-write.test.mjs changes (+14/-12); no pre288 test changed
|
||||
or failed. Commit this fixture correction, then restart all289 whole files from the start.
|
||||
|
||||
## 2026-10-25 creative typed-tool fixture RED/GREEN
|
||||
|
||||
Candidate4fb11e74a restart: library write12/12 rc0; bus write14/14 rc0; own harness
|
||||
library-write-tools rc1,0/3 before assertions: new creative role fixture omitted the
|
||||
Gitea credential reference required by landed285. Added the same fixture reference copy
|
||||
as landed library-tools.test.mjs (no credential file read); no assertion changes. Whole
|
||||
own harness file now3/3 rc0. Only new owned test+BUILD changed. No pre288 test failed.
|
||||
Commit and restart driver from first whole file again; gate still not claimed green.
|
||||
|
||||
## 2026-10-25 completed candidate gate (sage-4396), SLOT RETURNED
|
||||
|
||||
Tested candidate2848d832e (three additive fix commits after requested8a47c462a).
|
||||
Driver restarted from first whole file after EACH fix. Positive gate-r6: all289 whole
|
||||
files rc0,2604 pass/0 fail/0 cancelled/1 deliberate FED R7 skip. Full required suites:
|
||||
library168/168 (13 files), bus1035/1035 (116), harness180/180 (16). Other selected:
|
||||
business25/25, cli619 pass/1 skip, plugins8/8, processing-control7/7, seat69/69,
|
||||
tasks95/95, webui398/398. Case1 acceptance excluded. Final import graph regenerated on
|
||||
2848d832e in static-r6: whole-files.txt byte-identical to static-r3 selection.
|
||||
|
||||
All12 scripts rc0: test-auth,conductor,config,discord,extension-package,
|
||||
federation-acceptance,foundation,land-work,push-check,queue,release,task.
|
||||
FED R7 dedicated runner covers ordinary-suite skip. Queue wrapper28/0 and node156/156;
|
||||
canonical-root verify/render check deliberately skipped in this linked worktree.
|
||||
Root/webui own npm ci and editor build rc0 before runs. All tests nice19, sequential,
|
||||
whole-file timeout600/kill-after10; scripts timeout1800/kill-after10. Fresh mktemp TMPDIR
|
||||
/mnt/storage/scratch/tmp/ for each restarted driver; no /tmp test root.
|
||||
|
||||
Six mutants killed (each rc1), restored positive whole files each rc0:
|
||||
- M1 supporting checks removed: broker M12 refusal assertion.
|
||||
- M2 forced push refspec: unrelated-blob retry/new-parent and guard assertions.
|
||||
- M3 forged owner token: missing expected rejection in exact-token test.
|
||||
- M4 beforePush grant recheck removed: held-during-fetch expected rejection.
|
||||
- M5 notice after publication: E4 exact notice and failed-store assertions.
|
||||
- M6 caller commit in schema: exact property-set schema assertion.
|
||||
Source SHA256 restored after every mutant; git status clean afterward.
|
||||
Captured logs across all four run attempts scanned for both fixture credentials:0 hits.
|
||||
No pre288 test failed; no pre288 assertion changed beyond approved mos-1523 +4/-4.
|
||||
|
||||
Per-run rc and log hashes: gate-r6-results.tsv; counts: gate-r6-summary.json in this
|
||||
packet. Full logs, mutant diffs, drivers and JSONL receipts under
|
||||
/mnt/storage/scratch/bubba-row288/gate-r6/. Earlier RED/intermediate logs retained in r3-r5.
|
||||
Slot-returned report sent to Sage as bubba-0034; no further tests after slot return.
|
||||
|
||||
Review notes to carry into request (webby-0296): N1 baseline library-tools.test.mjs73
|
||||
still says tool names unchanged while the pin gains writer names; retained to honor the
|
||||
narrow +4/-4 permission. N2 librarySave is dispatch plumbing only; C2-11b owns the route
|
||||
that consumes it. N3 sync comment omission is cosmetic and unchanged from reviewed r2.
|
||||
Commit-count correction: r3 initial head8a47c462a had13 commits, twelve transplants plus
|
||||
receipt (BUILD +36, SESSIONS +2, fixture EOF -1). Current tested head adds three fix commits.
|
||||
Formal manifest review/gate acceptance and landing remain Sage/Webby stages, not claimed.
|
||||
@@ -1,308 +0,0 @@
|
||||
kind name rc restored_rc log_sha256
|
||||
whole-file packages/library/tests/write.test.mjs 0 e0f6a09b70316beebbf33966b35bfd05b4a12b587744dadc9239bd28de1b976c
|
||||
whole-file packages/bus/tests/library-write.test.mjs 0 e0e9e609b20ea0564a7611046026cbdfd007832e0eb13507798e958d8d106ef0
|
||||
whole-file packages/harness/tests/library-write-tools.test.mjs 0 c8a3a493d1d2abce785e94fdda5b1732e8d4a5e6eb19767af1b7e8b5e560cf3b
|
||||
whole-file packages/webui/tests/library-write-options.test.mjs 0 2491eb6a01a0b4b2127bcb6a87a5dc778d079b7d1ea445509a1dffc49dea9051
|
||||
whole-file packages/bus/tests/access-revoke.test.mjs 0 a1b317bb687e8c369440f5481b4ef309615afb5a5922fa306980d2024019e544
|
||||
whole-file packages/bus/tests/account-migration.test.mjs 0 e697b58a1bb9b37c609b441fe786e557c7f0279e7a31eea791483ce4567db318
|
||||
whole-file packages/bus/tests/address.test.mjs 0 977f755d29a8e75578d0bef48ec40b7045736014b2e53e15a03cdb6dd39696d8
|
||||
whole-file packages/bus/tests/agents.test.mjs 0 3e8116bad1ab5594e627ba3e9f5403414885959935bcd9e6f75f1af4c625d4b0
|
||||
whole-file packages/bus/tests/approval-binding.test.mjs 0 d2fbee516b57857f3a6562427d2a08bd7fdb772aacabd33ebd9d2990f01ec7fa
|
||||
whole-file packages/bus/tests/broker.test.mjs 0 400e7f0616bc7432d8cb2a9efbae3c84d5b44ef59ce7f8fbebd4c802e2a9f44e
|
||||
whole-file packages/bus/tests/business.test.mjs 0 f42502884a158ed1d190b37b3884e19d44547ececf068f91765b8ad15faffba3
|
||||
whole-file packages/bus/tests/channel-proof.test.mjs 0 3984a7e2da2a60e60d0309f719a45a3ef04bca767bac34e00a760e19e941d732
|
||||
whole-file packages/bus/tests/chief-of-staff.test.mjs 0 8dd57acf0101d4c92ada92f4c33f68061d4e2cb430179a8ab99a0b7fc9a19997
|
||||
whole-file packages/bus/tests/citation-availability.test.mjs 0 d34d84d44b5949024ce6b32708c68e10b00a84600bb03598bf9538b358750455
|
||||
whole-file packages/bus/tests/citation-guard.test.mjs 0 acab66e65fd41f1fbfd9524f80456553fc033d8bfc18a9bec7a813bd0d4552d8
|
||||
whole-file packages/bus/tests/citation-runtime.test.mjs 0 ce33310d333c7a0af7451c3a3b610f5178961b80b6b63a839909b67657fd161e
|
||||
whole-file packages/bus/tests/comment-cursors.test.mjs 0 cd4de90a070faf2bdb776a96a6ba43aa4854f6f5f1b2b7459740bd7bdc0ffb7e
|
||||
whole-file packages/bus/tests/comment-migration.test.mjs 0 773659855873805b5bd950101d950945213658fde42d8012211e742ba9ddcc09
|
||||
whole-file packages/bus/tests/console-decide.test.mjs 0 275fc0a24a03f2f27210a65e2bd21ce615ec9b6b400c4e4177ddb97a9e8e85be
|
||||
whole-file packages/bus/tests/creative.test.mjs 0 eb950d5680ff7e4e09a9c11b1c169d4a740011ea72bb75921d35571ef5373df2
|
||||
whole-file packages/bus/tests/credential-claim.test.mjs 0 b2d40e4d2a353f4154af4974d5779f7b20c652a8110da3183f95959ae2540941
|
||||
whole-file packages/bus/tests/credential-status.test.mjs 0 ed367e3d123c9629b7d3d22f6fa60f48c74e71b36982c54ad2b3e8419f515431
|
||||
whole-file packages/bus/tests/credential-store.test.mjs 0 0fd528ba27757393973cba5b21da573bc681659416962bf7d3a3dff3018414af
|
||||
whole-file packages/bus/tests/credential-verbs.test.mjs 0 154b123af420abf08c6ab8b7bc6439052e7ab65c772abb0caac5e9b9cd3608e9
|
||||
whole-file packages/bus/tests/credentials.test.mjs 0 6474b45c076f474a6881d0dddd0cd3b4cd385d52ac4c55ef1a9f8c10e0028277
|
||||
whole-file packages/bus/tests/csuite-messaging.test.mjs 0 c0229df65240be8ad014d83def48dbd64a952b701f46e40ff01efdebb5644d6a
|
||||
whole-file packages/bus/tests/daily-quota-runtime.test.mjs 0 62d686aa1852088af569cd3b921194db6873311f2ba04e55b15a93900b1615cd
|
||||
whole-file packages/bus/tests/decision-close.test.mjs 0 9599744860a4e6e330ce50b8e93c478546edce5545a9171bed068743a266ae5c
|
||||
whole-file packages/bus/tests/decision-route.test.mjs 0 2b2a9570dab83b1d454f56c1311cb41103a14bcff49e207cbb4ac5d4c73d6f0f
|
||||
whole-file packages/bus/tests/decisions.test.mjs 0 a753df7d939155adf13c7177926728b2760cf61770117dd1655f29fe2c88a26f
|
||||
whole-file packages/bus/tests/end-launch.test.mjs 0 ff7a27c35e35be424cbefa799e219ffc073c494214642b4ce56ceed6b359335e
|
||||
whole-file packages/bus/tests/fire-revokes-grants.test.mjs 0 8e6bee9421480af8a1326d65903f258d5ea0a79df6188bf18301f32a5260547e
|
||||
whole-file packages/bus/tests/gitea-grant-docker.test.mjs 0 8b639ee86d1a7d2ef267e1d36264f4ce1b5beed2c8ce084c39c0de1d699ca8a0
|
||||
whole-file packages/bus/tests/gitea-grant.test.mjs 0 8fa39b3e58cfac4ec97f02ff876fde1a40a1894c826306c0b77d45c73586f753
|
||||
whole-file packages/bus/tests/gitea-migration.test.mjs 0 689fb43a38718f5f5d00ffb3b6d998d5d454854d5e77a936b56d7c4192ee12e9
|
||||
whole-file packages/bus/tests/grant-enroll.test.mjs 0 a8be59931d37a5c787c2087d29d766d6b701bbe34f8343134148292cd29d345c
|
||||
whole-file packages/bus/tests/grant-executor.test.mjs 0 0a7f5be29b28140c9f8e7f67c6a897eb455677fba4459952a83982f2b23c87e0
|
||||
whole-file packages/bus/tests/grant-host.test.mjs 0 54c4ed722116914221e9320fd41723e32aad59284e98d8e177130b0f4c4fe6c4
|
||||
whole-file packages/bus/tests/grant-migration.test.mjs 0 7cfaa3f24d1dc070d7bdb8de76b08fabcdb6877d3367c59f7601e08f683d658b
|
||||
whole-file packages/bus/tests/grant-scope-runtime.test.mjs 0 f8bccf5324f1e10282dfb4f4fd0f63c76c8e9481ae6cc0845a1d9028e3d9633e
|
||||
whole-file packages/bus/tests/grant-scope.test.mjs 0 e30a8ced066ad214a6f70dd4a39c75bacf296032a3201e4605fa3c8df23e0159
|
||||
whole-file packages/bus/tests/hard-waits.test.mjs 0 78d92a14781286d3ca11989786a8698a2b796ad1db78769fd5b3c7653ad7639e
|
||||
whole-file packages/bus/tests/host-run.test.mjs 0 51d231611940444d2c2a37fbb7b14267c705c1b5e453b02367d0a6def214dc93
|
||||
whole-file packages/bus/tests/host-tools.test.mjs 0 3bc5b5413661edd2026bca1721055ec7dce8d115918cc10c8f334e527176d23b
|
||||
whole-file packages/bus/tests/human.test.mjs 0 5c8f3fd402ae4e130029b3203ed41b3cb45b8781417d31dec1f47ebddd516349
|
||||
whole-file packages/bus/tests/instances-verb.test.mjs 0 940ca3884930f539272a2c39ca7e1c7fa3e51b3a4ea6fdcfb21719c652152257
|
||||
whole-file packages/bus/tests/interpreter.test.mjs 0 d0c6190a428005b7750b59e665968657b242b322af05ca7bdd4cd7e815b7f4ab
|
||||
whole-file packages/bus/tests/land.test.mjs 0 e9ecd1d8011ab6789fc3254bb069e76631b68b20ad65ae844ee12e0dc3b97cb0
|
||||
whole-file packages/bus/tests/launch-notice.test.mjs 0 750a54d4c40559c7fb5414071bace8056d6bfa71dfdbec4de12c94c90299c3c5
|
||||
whole-file packages/bus/tests/launcher-released.test.mjs 0 4d59486ca3077a4b2f51141ab79df635feb6b7bca2d6c0cfe5839a6a93715de6
|
||||
whole-file packages/bus/tests/library-credential.test.mjs 0 db7e2dc4afe23f74c49795e4dcd3d28414435519029a837641cbb35bd3f4fcef
|
||||
whole-file packages/bus/tests/library-lookups.test.mjs 0 fa18b5d4c829ec35ebbf519c4346a2ac38cff7538d58ea663acbbdd7930a6015
|
||||
whole-file packages/bus/tests/library-sync.test.mjs 0 ee0ab1ad2549d3e6ae6d8123fa99d697d9be6c629e09131da82f0ab6d58a60e2
|
||||
whole-file packages/bus/tests/library.test.mjs 0 62b663034a5de8d6d1abfaf3f94327d7aae435e3350874b424eefdb28bca1bd1
|
||||
whole-file packages/bus/tests/lifecycle-revoke.test.mjs 0 c0810c743b5108773b6cfbc2d108fa09ea274c437433355277ce2b1295fbf692
|
||||
whole-file packages/bus/tests/lifecycle-verbs.test.mjs 0 926bcfb20ab58a4ecbe85b4f8feb915f72adcdc6d6aee84f814187d0ac998efd
|
||||
whole-file packages/bus/tests/limit-checks.test.mjs 0 919d745dc570172716b1e06d0ea1e8f16ae7b05dbadba77fe92dbbcc8eb4cba7
|
||||
whole-file packages/bus/tests/limit-stop.test.mjs 0 2fc1ebee4e4d4862a100ed9ba97ace1e6d3fb3c608abea63b1ff634a04d5649a
|
||||
whole-file packages/bus/tests/limits-runtime.test.mjs 0 5845176b73f98a499d92096ce0d22a3987ada664a529bdbb26230c2d00b9e65c
|
||||
whole-file packages/bus/tests/limits.test.mjs 0 333f6757d9d00eda74e7d4641af660c9a0ce3d978e6a8550139d3a461c1d5866
|
||||
whole-file packages/bus/tests/message-citation.test.mjs 0 38422c1d6faf076c750c3fccb7e927e38fe955cc28778511acccf5704df5b191
|
||||
whole-file packages/bus/tests/message-filter.test.mjs 0 2ba52728df27756ac19ba65fe0705e7cf7a2a786a3b4df77a4eb4eec8072604c
|
||||
whole-file packages/bus/tests/messages.test.mjs 0 b87de4ab04682d59a2faa7b3fc64751247454e628e9c1ebd4c07b1df2acbf11c
|
||||
whole-file packages/bus/tests/messaging.test.mjs 0 831b48a9de594e17e8fc47f16ab8c2d722e8d57068a7d39deeaf4c0fa8d136bb
|
||||
whole-file packages/bus/tests/model-proxy.test.mjs 0 99c5128733ae5bb16489171513c158ec1e34dfce1d07c60f6bccb0f84ab7afb9
|
||||
whole-file packages/bus/tests/name-migration.test.mjs 0 bb8f92a17f6a022c7ec63161cccc0bb49a26c2a591fc369375cbebfa93a277a2
|
||||
whole-file packages/bus/tests/names.test.mjs 0 0fcf60cc8c7dee3e85548c759f03e1792de92b59131bb9fe4282a3b07859366c
|
||||
whole-file packages/bus/tests/peer-transport.test.mjs 0 3cb547003e50695ec2a25c950819b304f15203302281c00758a12c9b89b60f40
|
||||
whole-file packages/bus/tests/peercred.test.mjs 0 e75c700a68ba0c1013c8f36178d6554f0321dc331b2198fd5ffc1a684df76c3e
|
||||
whole-file packages/bus/tests/plugins-verb.test.mjs 0 359fef350befd1d743bcca89a96ebd0757346fd7c0622ba364039ba827620d26
|
||||
whole-file packages/bus/tests/principal.test.mjs 0 732724e6bb2bb953e7dbbbae5c23cc0a1c33a7b7b202f5cb8b46be9363bcb392
|
||||
whole-file packages/bus/tests/process.test.mjs 0 9c5883ea2ca858131317fa9be66d2a51a5d86dbe03c515b0544f4db56b2456a1
|
||||
whole-file packages/bus/tests/processing-runtime.test.mjs 0 bb6b94ac654d069abd6e484031893e649e239d933c135b226d1cb2fbd5a94ca9
|
||||
whole-file packages/bus/tests/processing-timeout.test.mjs 0 323036aa7f32f7aa324f61595531a29f3d5ef0ae2c24aec029842f2783d6be76
|
||||
whole-file packages/bus/tests/processing-web.test.mjs 0 dbd1543498fbc8d0625990436ae668b3a382eedeecd098b929c13d2bb61939ff
|
||||
whole-file packages/bus/tests/processing.test.mjs 0 529ec93e767444970ff03acb1ba719b45033daac239256c9cbd587c39f926a71
|
||||
whole-file packages/bus/tests/project-await.test.mjs 0 e948d721ef06ce95f909880942f7e7ebd73b2f42563e1faedacc7b403b8ebedf
|
||||
whole-file packages/bus/tests/project-files.test.mjs 0 3691b04705c17d4ef7218bc15771560aca5586c00ba0fd3fdf2a80f63d8dc659
|
||||
whole-file packages/bus/tests/project-runtime.test.mjs 0 9d8d6cedeb2044f19e548dda0e32cae1e997b75a6d89072f7367b6e0ce17a44f
|
||||
whole-file packages/bus/tests/publish.test.mjs 0 87f7a382580432646ca89d1228377719cb177bfdbb4f74ad617f6a70dbfb4b33
|
||||
whole-file packages/bus/tests/reload.test.mjs 0 25aa45aca6ba24d72e9e5ad66dfc8c049375c8df121dd748dde09af52f16f853
|
||||
whole-file packages/bus/tests/replies.test.mjs 0 0f05dc2194896540a1488310107e31b7e779cc02c381c201d0c95f69ab39fc51
|
||||
whole-file packages/bus/tests/requirements.test.mjs 0 29569dc30659dbecf359117cc9a59ff37927c60f5514b8ceb8d3796c2c3e53d1
|
||||
whole-file packages/bus/tests/review.test.mjs 0 a8daea8602be9429a8044ad636a438c18eee8ec77b6fa272dce606116d01de8c
|
||||
whole-file packages/bus/tests/revoke-window.test.mjs 0 1435c543c9367204f4ae6d25c2cb97145e762cb18e78ea90a15eb1672a220353
|
||||
whole-file packages/bus/tests/room-check.test.mjs 0 bbe5ac7abfb7e1b30f6fc8f9a247cd28aca82a8783753434339b790dd9857e1c
|
||||
whole-file packages/bus/tests/rooms.test.mjs 0 506fad116ab1d9bb2520fe691adc91ca26e64faa96ced35c193cb11da4e07ccb
|
||||
whole-file packages/bus/tests/routes-verb.test.mjs 0 c09fef3cb022bf7713cde4e1c512feefe67090eff05451fda9f55272140c916e
|
||||
whole-file packages/bus/tests/schema.test.mjs 0 2a1a668dc408aaebe6f604ec5c3b8858211edc52930e1a552173cecedf806d72
|
||||
whole-file packages/bus/tests/session-clear.test.mjs 0 1fce03f1d2a41f5ba294e9d406980a1d3251bc9a5dd4a02897413d6be3d9681c
|
||||
whole-file packages/bus/tests/session-compactions.test.mjs 0 745510273a9eaaf61de4c6453c5dcc70e4a6020c0bcec69673621eefa593dab7
|
||||
whole-file packages/bus/tests/sessions.test.mjs 0 d6c0337e0981ecb9aae2e912c27145bbd831e196828b2d59029666ceae5f605c
|
||||
whole-file packages/bus/tests/single-use.test.mjs 0 6f5cf7d47716ce94eccb069f9b7e5625c3587737921231649fc74e8bfd3aad3c
|
||||
whole-file packages/bus/tests/spec-migration.test.mjs 0 ede4ca62a772261bc868f4dfcb4861c9c3670110ba2afd39cc44183398c2eafd
|
||||
whole-file packages/bus/tests/spec-review.test.mjs 0 951aa2a54cfe4bf0960dd3d2180874cb8183ff9b0aee7b7251b05df11385e1a5
|
||||
whole-file packages/bus/tests/spec-socket.test.mjs 0 65735a2557e19b3d63a3ce7198c80fb5059f1974acd0708a89f192857b43b095
|
||||
whole-file packages/bus/tests/spec.test.mjs 0 488ab443b41b06b6ae4434f5b2ee8904169aa08ab3527f3ae4c3f438e54f9909
|
||||
whole-file packages/bus/tests/staff-request.test.mjs 0 edeb4ceffae3af33e330e1fac5d74c4fb1861d52ec5ac5005689791ab74da555
|
||||
whole-file packages/bus/tests/state.test.mjs 0 3b5f916c494563fc7c18f89450e0cecbbdad8e24680b373e897253b9ea6064fe
|
||||
whole-file packages/bus/tests/store.test.mjs 0 39d0a4033b89eff9b29ea6dcf6e56696a1d20a41e0e14b4bc8efbfae7962ecf4
|
||||
whole-file packages/bus/tests/task-page.test.mjs 0 6446cfc1a43cb4206b4130f316251d3d9a820f929a6efc59dc74e7cbe1fbd258
|
||||
whole-file packages/bus/tests/task-read.test.mjs 0 37134ced43ad5ada4291ad5e3474dcf7063892443b06d54a7456cd4cddb9cf2f
|
||||
whole-file packages/bus/tests/tasks.test.mjs 0 9d91ee510a7447545c2cf93ae6779544a05e01bb70346e595b91a4800fa42d7b
|
||||
whole-file packages/bus/tests/tester-threads.test.mjs 0 ff843610e02f20c5e1ab19de27b131ae7cbc3fd87b16d85e68336b5e914ffd77
|
||||
whole-file packages/bus/tests/tester-writes.test.mjs 0 517c41e666d2c59b7ffb6ddb22898ef58b816bb26eaa47e1ce7508087b607df5
|
||||
whole-file packages/bus/tests/tester.test.mjs 0 19eff6ddb3aca05ad5c006ac15e7860311f56941055850e86b8075cd39eff0d1
|
||||
whole-file packages/bus/tests/thread-claims.test.mjs 0 ee146e984bb3ae82ad60f90c83035053ff2966ffea91015b6c3c4f93b7e019bd
|
||||
whole-file packages/bus/tests/thread-migration.test.mjs 0 1dc2ae4e920d40a6fc2b1033f43ac0a2f766bfb86f07a596a983b9c1bccf87d5
|
||||
whole-file packages/bus/tests/thread-shares.test.mjs 0 3f99a82e9e4a43fa788ebb231c5e712969809fa83b6ca66f04b8cad13f411235
|
||||
whole-file packages/bus/tests/threads.test.mjs 0 2e5ba2be69a34c71f41a819c7a5e8615fcd085f847f9aa6d16095b9c8d742552
|
||||
whole-file packages/bus/tests/transport.test.mjs 0 c9d28b9acfc0c2213838df0d960506156ef6fffec24a0cee7336324f105fac0e
|
||||
whole-file packages/bus/tests/usage-broker.test.mjs 0 26fc080c6ffcb7c64cca39a07f302b59c21d1425ca3c90120eb3d3bb751c49da
|
||||
whole-file packages/bus/tests/usage-migration.test.mjs 0 cfc65c4233aedb325293170e782ccb83fcfdd85cc4afed1e913e91785fa4b7cf
|
||||
whole-file packages/bus/tests/usage-runtime.test.mjs 0 faa5fce30cbd7002137acfca3cde68b49b74321fb27b8a190736b35601430866
|
||||
whole-file packages/bus/tests/usage.test.mjs 0 d36d21e0b3f5c9621b50e8b71ff6d8daa341f5954f3612b7cc93cb6c734215c0
|
||||
whole-file packages/bus/tests/user-principal.test.mjs 0 1b56d881de2975ec4e3bc27fa15bc495ae0600709457da579337f0c9c98651e5
|
||||
whole-file packages/bus/tests/viewer.test.mjs 0 942ba4fd96c3bb4c527eb129e69ddb5cb7660915e8458cfee47661d268db0e24
|
||||
whole-file packages/bus/tests/web.test.mjs 0 048e3ef2840934f95d7e00de6502b19342215cfe5d00d1b8ada7c1bc6e87cfa1
|
||||
whole-file packages/bus/tests/workflow-roles.test.mjs 0 1bed1351ec3c50ddce65f9b8108f93a5c4061ef5cf36f3d09706d85b13e085ed
|
||||
whole-file packages/business/tests/case1-business-file.test.mjs 0 4481abbce73eae119fbedc5edf65120fa494931913aac6f0273b04263c251cc9
|
||||
whole-file packages/business/tests/launch-settings.test.mjs 0 540f5170ddc7e79a8abd9584c4586eade3ecc1f7544489060db99552c75e4685
|
||||
whole-file packages/cli/tests/access-boot.test.mjs 0 e41e1f1949d3568f8845234d573282c18a185578389d6947140cf540d7f99dc8
|
||||
whole-file packages/cli/tests/access.test.mjs 0 9e2a813092ad4b60cd89443424eb4142f217265e52ff7b769b7f16d247d5a367
|
||||
whole-file packages/cli/tests/app.test.mjs 0 5f5244ba0061dc4ffd1565c4abd3168d7cb2e6398625b69c841a54544b9a35a7
|
||||
whole-file packages/cli/tests/boot-status.test.mjs 0 ca090577e20ea46315cb377668e309571380e2323c867a8b90d0537022e681b7
|
||||
whole-file packages/cli/tests/case1-hostcheck.test.mjs 0 403e1127da5637904e8fe1c1eed5a7865c5bd5ee1c5d0fe684837a7370c41de4
|
||||
whole-file packages/cli/tests/case2-install.test.mjs 0 df8edefe13297ced929d09f01eec5c7ecf38c355d9871368cb19f2f392ae057a
|
||||
whole-file packages/cli/tests/case2-persona-import.test.mjs 0 5dc7a93c03567ec0e85e43bcafe07109881c30b2e83b4c4eab4631a155daece0
|
||||
whole-file packages/cli/tests/case2-unit.test.mjs 0 39b349dfd3125e74b780ce28e9ec24465a6a8c2bb9e431c819864f4eff1fdb77
|
||||
whole-file packages/cli/tests/channel-cli.test.mjs 0 9fd9c30aa604f77b7a069912cb987293af36f2f138cce850f8d26946f5ce42cd
|
||||
whole-file packages/cli/tests/channel-recovery.test.mjs 0 52c6bd980cd54ef22b9e6c78260a1e389e8177526340129ac64fbafa7f2e01ab
|
||||
whole-file packages/cli/tests/cli.test.mjs 0 59327fd89e3fb8f927210df6a2c62afe4522e59f59129b1967be2a238c498f26
|
||||
whole-file packages/cli/tests/compactions-launch.test.mjs 0 c9006b3039a6616be1816f5ce85bf68ba4fb54dadf10447e52fc92f7ed57bbe5
|
||||
whole-file packages/cli/tests/config.test.mjs 0 35e39fb0551e23f5738d0c30d66bd233f2290040885c511e526f0f0468b31cad
|
||||
whole-file packages/cli/tests/credentials.test.mjs 0 2b55cde2318a034ec4152e712863ac54f07f1b4db752c6282507d7f621bde67d
|
||||
whole-file packages/cli/tests/federation-acceptance.test.mjs 0 cca971a93a5dfd20e603b45cc2158b58ea0638e8bb7a33e6e0c5e12178ffa3df
|
||||
whole-file packages/cli/tests/follow.test.mjs 0 26a3ad0dbc124aff48a5f4908e3d8b78cb871e5560c0e389de457f58aea2dfe3
|
||||
whole-file packages/cli/tests/git-socket.test.mjs 0 10c21c34a79ebd5f89f6ed9182a492e9f42f0512a68f758c0566a763a84abeb9
|
||||
whole-file packages/cli/tests/grants-scope.test.mjs 0 37967ca8e82a89a0e88ed872fa562b5c094282cc759853b6dc31c292204bef3c
|
||||
whole-file packages/cli/tests/grants.test.mjs 0 687af745932625ea1d439a8139c760f14b4a327bf9b15c5b5b1cdbc7ea6be09f
|
||||
whole-file packages/cli/tests/host.test.mjs 0 50010e97e44392f28006bbd4127146b8aa1712ff4a016ca10864923701213dce
|
||||
whole-file packages/cli/tests/hosts.test.mjs 0 d5d507c3968c45b2aa25067d6bbb1eedd69785c0aa1bb51177c63b6ad64fcb53
|
||||
whole-file packages/cli/tests/idle-stop-race.test.mjs 0 8e6171855003b0f40921863430dc89cf20f8bbf14a9ce3c115f90486f08232b5
|
||||
whole-file packages/cli/tests/instances.test.mjs 0 c6b4d59443baa4af029af76a846a8093669a7593490f21408a2c40ad027acccf
|
||||
whole-file packages/cli/tests/launch-account.test.mjs 0 6cb63446fc8dbb6217e6d925caabb37a28bcf1ea5c27cf8d515d67c7842553b8
|
||||
whole-file packages/cli/tests/launch-limit-checks.test.mjs 0 fae971d715a90d1dbbeb3c054932a02d253e0a0d036d3b0db4e0c9edcd5ad7ef
|
||||
whole-file packages/cli/tests/launch-limits.test.mjs 0 d3f4b2c57e776bf6bbcafba6dbd9c4728918b0d81fc606dcd7d2dffefdad4001
|
||||
whole-file packages/cli/tests/launch-routes.test.mjs 0 e2bec020f96238079908c03537366c64800de0913a83f3a2877606d0266548d6
|
||||
whole-file packages/cli/tests/launcher.test.mjs 0 beafda99d34a532f3a1d6f96565b7a780e03924939b6c30b01a8169cceaa792a
|
||||
whole-file packages/cli/tests/lifecycle.test.mjs 0 014a2cea6d3f2a9f21f7fc16dc68b34740b03726612851047b877f8c1194ebe0
|
||||
whole-file packages/cli/tests/limits-tokens.test.mjs 0 6fdf9e6946dfb579cde42ec500d8cb8473a9d8318f43caecee7561a5e40fdec1
|
||||
whole-file packages/cli/tests/limits.test.mjs 0 bc2f13959d087ccaf6977c4cf1294e6fcee21f968677ab169580ce79643add18
|
||||
whole-file packages/cli/tests/mark-read.test.mjs 0 64864c54ab910488d55136b88f351771489cf744ba1c21e5c479121694dd88ab
|
||||
whole-file packages/cli/tests/model-proxy.test.mjs 0 119a5d02870a4062992efba7f44ee9dfe69ecf8a7076f121aa24a8c7edf24cf0
|
||||
whole-file packages/cli/tests/names.test.mjs 0 c2160aeb0c68855f59b5d97dc3b6101b7800028df708f5f42430ae5854eb23e2
|
||||
whole-file packages/cli/tests/notifier.test.mjs 0 18e62f48de18cc4d57916a556adeb3befb13921d5d7b036ef5a7f2bfa460cdc1
|
||||
whole-file packages/cli/tests/optional-tracker.test.mjs 0 e5adddfee06b2f1cbd2ec50caf84b5acbc58d4ff4ec4c1bc539a4535a3991827
|
||||
whole-file packages/cli/tests/other-tree.test.mjs 0 2dae57af2b8d508f2792ce37191aebf0cd28ad75f7621d4ab9f8d6daa60b748f
|
||||
whole-file packages/cli/tests/processing-cli.test.mjs 0 44b2854ba03810cdda3ccf0c6de883f953089d532bfcdc8f4bdd3faffac80fe9
|
||||
whole-file packages/cli/tests/project-name-repo.test.mjs 0 0468b9ecde6189d1398eef2e7e8043e870aa867a8a9d22b20b2ded26dc1543b5
|
||||
whole-file packages/cli/tests/project.test.mjs 0 79e648106151ca220d9535b16c416dfdcffffaed41e3c211e4325c151f0775f7
|
||||
whole-file packages/cli/tests/publish-socket.test.mjs 0 59a02b1fcc284407b06d0d2df8e6e1e5323059daa2e47c690f30a718d1e7c682
|
||||
whole-file packages/cli/tests/reply-limits.test.mjs 0 554a353d61891c3cbe8da01062025dcb0756ba4f4e7ab3fb8d7b56ceccf64437
|
||||
whole-file packages/cli/tests/revoke-window.test.mjs 0 743fdb0135e507dea5b968265907e5ac9228284b130feb0057d91e70ad561c02
|
||||
whole-file packages/cli/tests/session-clear.test.mjs 0 5abbd894dee9cfcb3464a40e5045f9062402d5ffe567972113715cc9e24c6ce3
|
||||
whole-file packages/cli/tests/session-cli.test.mjs 0 c469aed70c1ae408e176189f23a849f3acf0bfc7dc3ba1132c101a931359a462
|
||||
whole-file packages/cli/tests/session-launch.test.mjs 0 cde78f9dcee9afa243692fb0493697104425b61589bd7be6c4cbdb0f4bfbd5e5
|
||||
whole-file packages/cli/tests/stack-copy.test.mjs 0 3b92b3772c060378cd2ec0c1bf7fe6662721721a11d99d83c9debe3e3aa929c2
|
||||
whole-file packages/cli/tests/stack-instances.test.mjs 0 2839e390f564a6e58cd514ce4061ec0b741ed07b4e2b755a337439737601d97e
|
||||
whole-file packages/cli/tests/tester-http.test.mjs 0 bd9c598c84dd0be3b9873176c63e418ccc004265153be68e0cbe51c40b1ff91f
|
||||
whole-file packages/cli/tests/tester-reads.test.mjs 0 50a71ffd9093c4d51d8ad07bc9edbbd76306922f290d28194d656cd78f8528c5
|
||||
whole-file packages/cli/tests/tester-threads.test.mjs 0 cd3dd0020472c269d61934ddb32d77f6dc297090d63e819288f4038fe9edf096
|
||||
whole-file packages/cli/tests/tester.test.mjs 0 437498258b4ea5c2f2bfa8fe66114106ac10944911bd40bca944f2078b34e45f
|
||||
whole-file packages/cli/tests/thread-cli.test.mjs 0 c29897119f279434bec0248c12beb5ce97f6214b8b0bec995061000f047b1600
|
||||
whole-file packages/cli/tests/thread-launch.test.mjs 0 459ef35e2b4f9cb87151577f252282a716ddbd4985f26e9e26c01b08af13a7f2
|
||||
whole-file packages/cli/tests/thread-revoke.test.mjs 0 b8a72080a9624ce4bbc1b23b8903be1b74a8a6ced35b0b60f503d92a22d1028c
|
||||
whole-file packages/cli/tests/trackers-boot.test.mjs 0 f83d72dac4eec7369d62b495745e1fdeeb4ff1ba2e1efb376c9b583da1765a1d
|
||||
whole-file packages/cli/tests/transport.test.mjs 0 e0ae6c26b5669d4b955deffe941a3c4314be12297e72d6c099de750170688d9c
|
||||
whole-file packages/cli/tests/usage.test.mjs 0 639ebccda23e0e094d62cb0e7e5c80c403b74b284ac5189fb0d92e63387c92f8
|
||||
whole-file packages/cli/tests/verbs.test.mjs 0 43eefd242a987efe42d145d7863372a2b0a397031baec12ecd4c9e0644daff12
|
||||
whole-file packages/harness/tests/bundle.test.mjs 0 75fd5a9a6fa0b46078952ce216348e39ce481f6fc00b89f85da9ff729d5ba100
|
||||
whole-file packages/harness/tests/citation-runner.test.mjs 0 933021f114882a6c58f4071446a07d49ebc9f99c062ffe1fedc1f13b799db389
|
||||
whole-file packages/harness/tests/claude-gate.test.mjs 0 f66053597c8209c5175810e33d8b878ad74eb314f4057f5b4b0b1ac625272329
|
||||
whole-file packages/harness/tests/claude-session.test.mjs 0 9c4d8ffc00efd0da75d143bca1cd33f30f3e762e20086270d941170e80c962ed
|
||||
whole-file packages/harness/tests/creative.test.mjs 0 3433184ced3427613d645807f0757896baf52d214c3dd6a4a12c3951bbdc50ce
|
||||
whole-file packages/harness/tests/gate.test.mjs 0 991670779d9cf6f733d0060c6f1a59d122ab8e99f7e0a5f7183c9e974f1b1aaf
|
||||
whole-file packages/harness/tests/git-tools.test.mjs 0 2837565ec16cd8c4d032311675a1468bc4bc756ee0696d0e57ea35ffd56eea44
|
||||
whole-file packages/harness/tests/library-tools.test.mjs 0 05a8a5d8e8c4e7b3435d4a9b3f6292816356a99f7156ded2ef7873e1c84f8de7
|
||||
whole-file packages/harness/tests/mcp-server.test.mjs 0 6ce4c6c39b8a1ed70fbeaca410781a62d69a6412333e03640296048b799a09b9
|
||||
whole-file packages/harness/tests/pi-session.test.mjs 0 570376f798b43e82bbc1972f1d50d3915e94a8e4ca00e50076ab390df9830d7d
|
||||
whole-file packages/harness/tests/raise-domain.test.mjs 0 aa6be675614d9324c3ddc01ef40347b235adbccfe6cd73081096ae9e9742d754
|
||||
whole-file packages/harness/tests/runner.test.mjs 0 d3f8c752897e359e10a8e9d507c10ef3760a5ae37999f6f143cb222c42568437
|
||||
whole-file packages/harness/tests/skills.test.mjs 0 2f34800387f4d7f8b8d5f6758cd197f77d11034011bf7f4f79f4d74c582e3f0f
|
||||
whole-file packages/harness/tests/spec-tools.test.mjs 0 29cd1f7094266963a995f636d9575337246a9868d42a48f02231a99251261f47
|
||||
whole-file packages/harness/tests/tools.test.mjs 0 f27638f1fa38fd2d15a352f6c21f7980688d48d580f5a59dab1520fd7c30b30c
|
||||
whole-file packages/library/tests/guard.test.mjs 0 6529c2b48c252eeaf9c19487507a03cf46d952e7ffb3a41e640a54590e312df0
|
||||
whole-file packages/library/tests/index-build.test.mjs 0 4747cb8c842cdc424db727cb3b0e36a6d35f4e9c5c31c1a3bf61314897c2cf6d
|
||||
whole-file packages/library/tests/links.test.mjs 0 9b89f9275f19035c5f079b6920b248466048626c634153eba2fec165f9f6388f
|
||||
whole-file packages/library/tests/mapping.test.mjs 0 9110b98f955dd71588357858b913194ccf9e04dca9aa7c4559600cbe9b9e8e71
|
||||
whole-file packages/library/tests/mirror.test.mjs 0 cc2326da9796dbbbf5b3faa121180a7f00c43816a232a96faece7b58570f1227
|
||||
whole-file packages/library/tests/query.test.mjs 0 f1209bc132a63cba9a7312cbed7e3098126e05c792356648f1d9ec497a11aa82
|
||||
whole-file packages/library/tests/reader.test.mjs 0 3e17f34697ae65524cf7908dcc9ca1b24025bbc92989b2ba05f6e75c0f839c3b
|
||||
whole-file packages/library/tests/render.test.mjs 0 5e68091a309a07e5502b9cc500c7cdfabaa9e246bb77b0c04a0dd86bb9bfcde1
|
||||
whole-file packages/library/tests/scope.test.mjs 0 f55dec854adcd311d614b66959c5655cb3419d7ae7b06fe1f648b43cdecef32e
|
||||
whole-file packages/library/tests/supporting.test.mjs 0 2f50bbe9c942360a5becf5bb984ed5aedb12628d4578ea85c6e433ad0ad73130
|
||||
whole-file packages/library/tests/survey.test.mjs 0 72108eb8a07b990b93ca62c5fa4b55f1f89f3254ca1cf59d3de8ad194dcc3a0d
|
||||
whole-file packages/library/tests/sync.test.mjs 0 a68c69492149b6e9dc7dbf24fc434ebfd3243b2db2c7654b00107b997e99ead0
|
||||
whole-file packages/plugins/tests/harness-compactions.test.mjs 0 9eb9f67c06ae17b33198fbcdb443a0c73ca9cc0cd157cae2359a0647d2db3658
|
||||
whole-file packages/processing-control/tests/task.test.mjs 0 8db6adda6b5d5f7437e9e4cdf961134493409d7227fde02c0b0a76aeb21186f0
|
||||
whole-file packages/seat/tests/compactions-budget.test.mjs 0 1849994f45bfcccfb4ce18915887c740947a98041aa7bd66590ae7a62fa7078e
|
||||
whole-file packages/seat/tests/compactions-ledger.test.mjs 0 af689c631c9d62dee11f4400112fd10df82567c1f49d9f0d423b9d19d6f860d7
|
||||
whole-file packages/seat/tests/compactions.test.mjs 0 cf5e74e1211560ca47a2c13e8002635097f486e2ca06698795bc38263d889f3c
|
||||
whole-file packages/seat/tests/sandbox.test.mjs 0 c09d89b8e1b22db25578f62cd4a1d3b9f441d652178fb675800efb31de33a577
|
||||
whole-file packages/seat/tests/session.test.mjs 0 82171646932cddfc68f0e90ca3355f9595d32c5d228c1fdb855c06cb1d9c2feb
|
||||
whole-file packages/tasks/tests/adapter.test.mjs 0 8843067c21942ae6165a7feaced2382fd9d02d0c62bd30772191393cb5d962b8
|
||||
whole-file packages/tasks/tests/comment-restart.test.mjs 0 25aa6e953cf19ed3ae368581035b9d883ed924b41d593240e2b4ab5ba39f2982
|
||||
whole-file packages/tasks/tests/fields.test.mjs 0 e4eafd6b17a46262dddc548263da993bc3a672adca1cadcc698b6d8374f11e2d
|
||||
whole-file packages/tasks/tests/processing.test.mjs 0 0b89866cc076c43c37534dba926d492d8d334d08a6886325e3d4ac6ddbc88897
|
||||
whole-file packages/tasks/tests/shapes.test.mjs 0 0b8cc660a07e048d007993d726ae5b8e1f343cb571c18ee0284c3ba0c4b41602
|
||||
whole-file packages/tasks/tests/startup.test.mjs 0 5b44d779ab4ec86922dd35ce7c78096de02c0a0f2363cc6c2a5ee07816efc2ad
|
||||
whole-file packages/tasks/tests/sync.test.mjs 0 513ce9f6e64a3fa0179f8cc9b27db671267a43cdc44ab93f38d21982dd2b9631
|
||||
whole-file packages/tasks/tests/tree.test.mjs 0 d3c8f91f59150259b3226e9306c98efbaf2aa17b5b74cb9b376a103620f8aefe
|
||||
whole-file packages/tasks/tests/verbs.test.mjs 0 47b075d01ef38a5d0228902a6f9bcfec0b78b1a958cd071e8114139af73bca53
|
||||
whole-file packages/webui/tests/agents-browser.test.mjs 0 d3ae822399f58d2c4dfd90e054811a60663a66f9d3fbe69a76aa4ce7dc7260d0
|
||||
whole-file packages/webui/tests/agents.test.mjs 0 be18c8fed41173900617d3b646fac1ce14c07c208e7f24d6567f61f55c5c4dc2
|
||||
whole-file packages/webui/tests/assistant.test.mjs 0 056e4c2a37b7b395741ed1ba33546031a6e4ca53db843bd877b93bed764e02ad
|
||||
whole-file packages/webui/tests/board-held.test.mjs 0 01a24d222092ad46c24ea94f684a018b787dfc8d26a0f7d7fda5d9df7192e695
|
||||
whole-file packages/webui/tests/browser-edge.test.mjs 0 4d10b4fcefbc64cdf12bbfbd9b47f74810b3219f70624c35490cb23d66d3c4a1
|
||||
whole-file packages/webui/tests/browser.test.mjs 0 d8c31b7cc16d93961d65959fa9653eaba906f81da3a34e19b3da7cc922f840c3
|
||||
whole-file packages/webui/tests/bus-browser.test.mjs 0 ab1538aaabfdb02c336da61675a0d1d7f367483bc500a380e7f0ece050ab8609
|
||||
whole-file packages/webui/tests/bus.test.mjs 0 fd7acdf189fef230af80c32c4c972d9bfb1564069d7c4ed649c3a49bb6636e1e
|
||||
whole-file packages/webui/tests/channel-chat.test.mjs 0 678b8e3c9152662487fee1c52c8abcae95029b0672d5bbe26a824bbdb4a7ee0b
|
||||
whole-file packages/webui/tests/chat-browser.test.mjs 0 ec29dd03ac7950dfa90e31f72ae74e2112718f1c02ce4dce8055194a328b5f5b
|
||||
whole-file packages/webui/tests/chat-instances.test.mjs 0 72c88b1eb11397bcff524af72cfe826a276b97b58e33465c6e3334e2746e7783
|
||||
whole-file packages/webui/tests/chat-replies-browser.test.mjs 0 bea9b1f9333bc913b2f01c29a792ea4b2fdbed3ebc64b42548e06f0bd75c9fc5
|
||||
whole-file packages/webui/tests/chat-sessions-access.test.mjs 0 f2de41c7d1f6e246a8a13dc33e8662932964facc5b93d8f85ed5fca760c87fd8
|
||||
whole-file packages/webui/tests/chat.test.mjs 0 4c6564d3565b01d68f7d16937aafddbef2ec3e04744fa9d1544ac0500a386ff7
|
||||
whole-file packages/webui/tests/conversation.test.mjs 0 1c3f8811256ad82d7771a06878c3e70dc3d6f2beab82366b837780a7873ff6f1
|
||||
whole-file packages/webui/tests/decide-browser.test.mjs 0 c53e1b962df99686f9739e258b2b86fe6325544ab02509833f9b1176f1303845
|
||||
whole-file packages/webui/tests/decide-sso.test.mjs 0 f96f8085015a96e11aca2d94bfb9e75318c0c0dfa9659049ec7b7e31ad7bc6de
|
||||
whole-file packages/webui/tests/decision-http.test.mjs 0 c89b7af200edb82f9986479199f359cf6a06c870f1bcf22b538cdf3b167f1258
|
||||
whole-file packages/webui/tests/discord.test.mjs 0 1c3e6d64a370adbc6c7cb24391989e9c00d97330d393943402ff5c6a99c5f9fc
|
||||
whole-file packages/webui/tests/docs-browser.test.mjs 0 f39d989ccdc561175643583b27bc19ee76fa25dec5947baa206b0c38b41c1e2a
|
||||
whole-file packages/webui/tests/editor-browser.test.mjs 0 c807f81d596b3a2e3d2ea55e560f29e181a0354ce48676c6760844855acb0dd3
|
||||
whole-file packages/webui/tests/editor.test.mjs 0 6953a85fe791e9087d14c3bf5075de2c4a651e1a502937da3226065c529ffd2b
|
||||
whole-file packages/webui/tests/granted-user.test.mjs 0 ae3baaa0d2a1ed1ad3e9625a46a8071222dfdef4c2a70ae3ba5bf159b85dec0b
|
||||
whole-file packages/webui/tests/history-return-flow.test.mjs 0 8f9ceeb41a64ec2849383a78f4997f7383c86a01eb6cf1d16747c2eb6c7448d4
|
||||
whole-file packages/webui/tests/instances-browser.test.mjs 0 33b9cd4be552f89809e75f72c54f73dbe6459a5c53401a79a4d887e5a658c442
|
||||
whole-file packages/webui/tests/instances.test.mjs 0 904abfc06358c99b0f646c3e728027cd7bba2b27c98c767c7da95016e531277c
|
||||
whole-file packages/webui/tests/library-cli.test.mjs 0 dda07bd1b0d65058723c4d5e50f94fefb1ee103c33c8f61c13841cfedfd53f41
|
||||
whole-file packages/webui/tests/library-routes.test.mjs 0 5cd1f4c6ea99cce38ce59eee085ab31f9aa8bba39cebbaf52b355c4d8fec3098
|
||||
whole-file packages/webui/tests/library-status.test.mjs 0 0b4fb5a07a3d35fb2237401b460ddd3832a2f6fa357f6fbb06b8463251b77faa
|
||||
whole-file packages/webui/tests/limits-browser.test.mjs 0 1a55050c92be5b93e447878feafe59e017b205d114413e6de000faf784df1dad
|
||||
whole-file packages/webui/tests/limits-route.test.mjs 0 b74fe734b0ccbdde716bb52bc15791f80a0b251514a6b01d6ba59164b9639123
|
||||
whole-file packages/webui/tests/messages.test.mjs 0 19bce52278091c8d37ca48c1f6f72bc400cd9a9b3038ae9f31e35444fdab05b8
|
||||
whole-file packages/webui/tests/pinned-copy.test.mjs 0 a8c99249fda05c5be773c8d2231e2dd1a3f3b7d10a40a7ec3e6ca6c6cfb4c85a
|
||||
whole-file packages/webui/tests/preview.test.mjs 0 7f7fbb11dd5915b3351b5086ec9b0f0bed6837a32a2e5902b707fcb54f1bf1c3
|
||||
whole-file packages/webui/tests/processing-browser.test.mjs 0 ed5970f1e2b1fa393c80db5e5551523e77ad0ee107dfa686a76c5d923b7e2d8f
|
||||
whole-file packages/webui/tests/processing.test.mjs 0 ac7a3a0ff51bb15c04e228186d771dd75ef515e09156cd080a8bea881e7cdd8d
|
||||
whole-file packages/webui/tests/project-file.test.mjs 0 8bf04994dec5c6d6670bbae055802759588c27b04010582732cbbf32c2921487
|
||||
whole-file packages/webui/tests/project-name-repo.test.mjs 0 ca773d7109f132bd099c43003a8269edfa96b2ba3a9e01e3694fa6bd12b9143e
|
||||
whole-file packages/webui/tests/proof-cli.test.mjs 0 5095f1ec66a3fc153467baef2291073e27aba17fdc2757e0a3cf2a03057a6547
|
||||
whole-file packages/webui/tests/proof.test.mjs 0 cdb948d261f52232c6e31e25baaf234bd0af3b6d90360a41a6142d2f34a8a797
|
||||
whole-file packages/webui/tests/reads.test.mjs 0 ef69c9c1dc9a55d526a704297aa4e2802cdca8f0e1fd70ff79efad2114a071a6
|
||||
whole-file packages/webui/tests/relaunch.test.mjs 0 e9f075560291cb446dabcaeb86c8800b5ea4ca0396c6a999ddbff88b245cefd1
|
||||
whole-file packages/webui/tests/return-flow.test.mjs 0 bf809ee139c15e9b6b8fe7f6e0f2ce00d0860aa460f145242fc732eafe8da8de
|
||||
whole-file packages/webui/tests/room-browser.test.mjs 0 23286bf46f341220f9e89cc1d229f46a579edb2eae5d688fc768f99ee343c858
|
||||
whole-file packages/webui/tests/room-http.test.mjs 0 a921e1991386cb5e184475cf47a012b3020b575968268e9f3c0b396e244a1819
|
||||
whole-file packages/webui/tests/routes-browser.test.mjs 0 df1283a6e1c5970b404b314b6b76dbf412e5318d76f296ec00164c932166b020
|
||||
whole-file packages/webui/tests/routes.test.mjs 0 055aa274fa66910a4ff1518fea49fbbbbbc5360dc16e825a460538f312a0781d
|
||||
whole-file packages/webui/tests/send-browser.test.mjs 0 da1547383522dbfd74a571b5d7625a310ae88f8adddff0c2bd33cb59df3ac137
|
||||
whole-file packages/webui/tests/send.test.mjs 0 f273e78388935b5fbc18a974f50cb85789436d51c47a4d8dccaf4af4742c2392
|
||||
whole-file packages/webui/tests/serve.test.mjs 0 1971344643d9cf6b4440d95c9ede42093235883ffab04fc4b614c1b7e7078f22
|
||||
whole-file packages/webui/tests/settings-form.test.mjs 0 80bd949d1666f2fe1f4caa051e2c34e742bab0e4adbe5584bd534d9bad8bef53
|
||||
whole-file packages/webui/tests/settings-write.test.mjs 0 7090474fff40910edb93c032feef248adc40ad21666d09c3610cf10279164f99
|
||||
whole-file packages/webui/tests/shell.test.mjs 0 844287f7797201473f1fb8d97ff2355ff3ff505006723678db78f26d3e5c2a40
|
||||
whole-file packages/webui/tests/sso-browser.test.mjs 0 1f70c36ce7d054ad435e52d63083c8fe19cd71e70c723518de5e58b69a426a0a
|
||||
whole-file packages/webui/tests/sso.test.mjs 0 6d7b3061bdc6e22744634ddc5612ff781e5c952a120a346c29eead66a3736438
|
||||
whole-file packages/webui/tests/tester-browser.test.mjs 0 425c54a84e5bf04ca91d8dc57ee83c14aff14a38159243f10f1c9114dd563967
|
||||
whole-file packages/webui/tests/tester-cli.test.mjs 0 5eb7296792f16f24d4486f39101007114b3db81c6ab53ab969e925caaffaa7d9
|
||||
whole-file packages/webui/tests/tester-listener.test.mjs 0 43927869c50a0e223d121e2dea2d10346a053a39fc8157c9fc4813b7c3b17e1f
|
||||
whole-file packages/webui/tests/tester-socket.test.mjs 0 c05962be7f87084404c53e4f7ed2caffff3d69e98e69a3c9f3c53b150cc804e5
|
||||
whole-file packages/webui/tests/thread-claims-browser.test.mjs 0 cbb2aeca0de2c64dd4c8d063d3e45140738d8f4064d38effeaec245ed7181b42
|
||||
whole-file packages/webui/tests/thread-claims.test.mjs 0 164a6c927abd819218be6386e123b234dd9955b122bace699e0a12201797791c
|
||||
whole-file packages/webui/tests/thread-sharing.test.mjs 0 ad64ab207702483aed6f16d13393e5f3c5a1ab0a0c2dcdf32717e8148a45078c
|
||||
whole-file packages/webui/tests/usage-browser.test.mjs 0 14be967dcae157cbb0a7b9ea4e0bc67337941d91a11d789baeb3d3c8353ac0e9
|
||||
whole-file packages/webui/tests/usage.test.mjs 0 4e20eee53c3eb79dc2930ca054977d06da88dba45b706a96ed94abaea6ec3e93
|
||||
whole-file packages/webui/tests/user-option-swap.test.mjs 0 bd43c257ae31cad2ca6c7a0b3ee49c6e323737d236fb7ff2a2105fd5e59b9767
|
||||
whole-file packages/webui/tests/views.test.mjs 0 4226ea02d33b9de8f2eaf9f93b0a551cbd9e6100560a8811eed90aa8de76974c
|
||||
script scripts/test-auth.sh 0 03999aab66446a4192ea9855f5cc1bd406080d0dfa5250b45b30e118556a0d5a
|
||||
script scripts/test-conductor.sh 0 79b7a689ed96792d42edd1d14796e0293e84e2e339b49476e457ad89e1c4a186
|
||||
script scripts/test-config.sh 0 2c3c87fb193e82fa17428933eb69cb2b34a589e8338f7a94aaa8256729fdf08f
|
||||
script scripts/test-discord.sh 0 5c6918b4415e8eabc5df31ac5ad696ec2afdfe3d498d69eae64f228a3807eddb
|
||||
script scripts/test-extension-package.sh 0 1f672a73e507cc57a204f7d3806ddcb211a0a8fb3ffccefc12bbc41e299f65ac
|
||||
script scripts/test-federation-acceptance.sh 0 febb0148bc1316bba3189aacf34d7c78f5f5db5d97a35aa4528dfadbec8bfbd0
|
||||
script scripts/test-foundation.sh 0 3de063333ce60ef1ca1986ecdd8ac30187a2316b7ca8e3ae4b4e6c8bd435caee
|
||||
script scripts/test-land-work.sh 0 ec90beab6246420982f872a4f45a7173e7a06f4aa263630d6ec4a4865176cde0
|
||||
script scripts/test-push-check.sh 0 0304c110dc5cf269fd8a4bea9759e5d48895a51c9d411814ce39ca924073da79
|
||||
script scripts/test-queue.sh 0 f678da9550eb6daa5268465b3a07beefd661e506ed38b8e11bf0a1b4a68cc781
|
||||
script scripts/test-release.sh 0 ad0f2a6b271275003783d3ffab5520f167ea79e26683710ce92a71600037360c
|
||||
script scripts/test-task.sh 0 ad511e52af4bc0a843eabbb3efcedd88c89468ccee43be9022e23880d7901f16
|
||||
mutant M1-supporting 1 0 10581fdab579db4d63322eee3369a1a740266e00a7dcbaa95e7651a7e0447ab8
|
||||
mutant M2-force-push 1 0 b137e8362ae3e26a090a82e8c41c3e87beeaac43183cdd6db67aba55d5e372c9
|
||||
mutant M3-forged-token 1 0 bda603c18b7b2bf468a21e139f0cff0c15c22e19c9d41cf8c50f9c3ae0bd128d
|
||||
mutant M4-grant-before-push 1 0 a642ef8e57a98c1488bb787da241292e6ed5446ca4117940fb0ddb9800c6a105
|
||||
mutant M5-notice-after-publication 1 0 5645138c2cef5d1999948744783ff3904a78e9cefd7421674386a2d0c5fdc45a
|
||||
mutant M6-commit-schema 1 0 7201f53cb976b2db1994c4e25f7f6e8b58eea323c060dbddbfa0372464adb686
|
||||
|
@@ -1,102 +0,0 @@
|
||||
{
|
||||
"total": {
|
||||
"tests": 2605,
|
||||
"pass": 2604,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 1,
|
||||
"todo": 0
|
||||
},
|
||||
"packages": {
|
||||
"library": {
|
||||
"files": 13,
|
||||
"tests": 168,
|
||||
"pass": 168,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"bus": {
|
||||
"files": 116,
|
||||
"tests": 1035,
|
||||
"pass": 1035,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"harness": {
|
||||
"files": 16,
|
||||
"tests": 180,
|
||||
"pass": 180,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"webui": {
|
||||
"files": 67,
|
||||
"tests": 398,
|
||||
"pass": 398,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"business": {
|
||||
"files": 2,
|
||||
"tests": 25,
|
||||
"pass": 25,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"cli": {
|
||||
"files": 59,
|
||||
"tests": 620,
|
||||
"pass": 619,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 1,
|
||||
"todo": 0
|
||||
},
|
||||
"plugins": {
|
||||
"files": 1,
|
||||
"tests": 8,
|
||||
"pass": 8,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"processing-control": {
|
||||
"files": 1,
|
||||
"tests": 7,
|
||||
"pass": 7,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"seat": {
|
||||
"files": 5,
|
||||
"tests": 69,
|
||||
"pass": 69,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
},
|
||||
"tasks": {
|
||||
"files": 9,
|
||||
"tests": 95,
|
||||
"pass": 95,
|
||||
"fail": 0,
|
||||
"cancelled": 0,
|
||||
"skipped": 0,
|
||||
"todo": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
# Bushroot
|
||||
|
||||
Builder seat, Claude Haiku 5.5, started by Sage under mos-1008 item 2 (a low-level model under Q177) for the row
|
||||
that retires the control board writer on 7331 (#1696).
|
||||
|
||||
No launcher in this directory. The seat runs as a T3 thread and works in its own worktree. It has no
|
||||
credentials of its own; until the credentials row settles per-agent identity, it pushes only its own `bushroot/*`
|
||||
branches through the repository credential helper (mos-0981), never `refactor`, `main` or another seat's branch.
|
||||
@@ -1,295 +0,0 @@
|
||||
# row333 P5 implementation — Mos1961
|
||||
|
||||
Base: 09a847eda. Branch: t3/model-proxy-p5-quota-usage. Actor: Codex.
|
||||
Accepted brief: docs/plans/2026-10-24_model-proxy-rows.md P5; associated design D18–D20 with mos-1600 correction.
|
||||
|
||||
Queue next codex refused a linked worktree; no canonical mutation. Parent supplied accepted assignment/authority and coordinated runtime collector ownership. No remote issue posting or live configuration/credential reads.
|
||||
|
||||
Ruling: preserve existing schema by carrying safe modelKeyId in usage cursor metadata; proxy telemetry uses a separate source excluded from turnRecords and every quota check. Existing account limits stay compatible. A model key daily quota is keys.<12-hex-id> with reset/timeZone; unset remains no quota. Human-only protection applies to model-key limit changes and resets. No launcher/session/harness/business route edits.
|
||||
|
||||
Verification uses serial nice19 node tests with private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG and unchanged test budgets. Broad/full gates reserved to parent after row334 target returns. Receipts below are actual command outputs; failures retained.
|
||||
|
||||
Parent steering receipts: runtime ownership confirmed createUsage/createLimits collector wiring/tick/close exclusively P5; Fethry avoids this area. Broker changes only usage option accepted by human plugins.set and mustStop run identity. No launch/harness/session/business-route bytes changed.
|
||||
|
||||
Exact additive old expectation update authorized by parent: kinds.test.mjs old five-entry Object.keys(KINDS) expected array retains all five in their original order and adds usage. loader.test.mjs complete loaded() expected objects retain all original members and add usage:[]. No old assertion was removed, guard relaxed, timeout increased or sleep added.
|
||||
|
||||
First RED receipts: 01-token-red (native key limit incorrectly allows); 02-contract-red (daily key quota, key schema and HTTP method absent); 04-integration-red (new collector absent; native attribution and plugins.set config missing); 08-edges-red (lookup fails open, nonhuman usage writer allowed, Console labels absent); 10-lookup-behavior-red (existing runtime lookup extracted unchanged: missing exception for missing/foreign/ambiguous ownership). 09 captured the preceding missing export, not behavior proof. 05 captured duplicate local variable syntax error, fixed before 06. Runtime fixture failures 12/13 were missing required process identity then incorrect cap extraction; corrected fixture follows actual runtime contract. 14 proves actual model-key issue/preflight, native accounting at key quota, stopping, later launch denial and broker human plugin setting path.
|
||||
|
||||
Unexpected existing named failure (reported to parent before any rerun): receipt18 was 169/170, failing `REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check` at limit-stop.test.mjs:61. Cause: additional run in the broker's second mustStop argument violated its existing exact subject contract. Fix keeps that argument unchanged; run moves to a separate internal third context and is consumed by host lookup only. The old assertion remains byte-for-byte unchanged. Correction to initial parent message: the quoted name here is the exact failing test name (the first report paraphrased it).
|
||||
|
||||
Scoped receipt19: original contract corrected, 170/170 current whole-file tests GREEN. Parent then required direct native-context/no-bypass regression: receipt20 genuinely RED (`stop:false` on a supplied safe-looking modelKeyId when lookup returned null). Removed that fallback entirely and stripped caller modelKeyId/run from the public check subject. Only trusted host resolver can provide the ID; only the separate third internal context provides run. Receipt21: direct context tests, original unmodified limit-stop file and proxy telemetry whole files 15/15 GREEN. Retiring/current mapping rejects wrong business/instance/run and unknown or ambiguous retained IDs.
|
||||
|
||||
Final implementation decisions and evidence:
|
||||
|
||||
- Native source records carry only the immutable run modelKeyId. New and retained generations resolve from safe Credentials.status metadata; missing, duplicate, foreign or no-longer-retained mappings fail `proxy-key-refused`. Third mustStop context is internal and associated by the broker from its authenticated session, never an agent argument. Missing context is fail-closed (receipt23 genuine RED `stop:false`, fixed in receipt24).
|
||||
- `tokens.keys.<12hex>` accepts the daily quota shape, uses daily-quota when reset/timeZone are present, and remains unset by default. Existing named account keys and account daily quotas retain their plugins and contracts. All model-key quota/reset changes and usage module/poll changes are fenced at both organization validation points for every writer, tester included.
|
||||
- Management queue HTTP GET is fixed to loopback with count=100, original 5-second default and 8 MiB response cap, no retries/redirects. Client api_key and upstream source hash immediately to the first 12 SHA-256 hex characters. Fields are whitelisted; malformed batches are atomic. No raw values, upstream body or arbitrary error text reaches product store/log/view/audit.
|
||||
- Exactly one bus writer owns the collector, shares one management client, drains once and assigns metadata owners, including retained keys. Unknown msk IDs get reconcile receipts; disabled businesses and foreign unmanaged keys get no telemetry. Polling defaults 15 seconds, accepts integer 1..59 and serializes concurrent ticks. `@proxy/cliproxy-queue` records are append-only but excluded before every native turn record/total/limit decision. Availability and account counts are explicitly proxy-reported in the Console.
|
||||
- Named upstream-value mutant changed `accountId: sha256(event.source).slice(0,12)` to the raw `event.source`: receipt16 exit1, four tests failed. Restoration matched original client SHA256 f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441, receipt17 positive 15/15. Final receipt24 also runs after restoration and is GREEN.
|
||||
- Final current whole-file verification: `bash agents/codex/work/queue-333/verify-scoped.sh` → 174/174 PASS, 24 explicitly listed whole files, serial nice19, private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG, original test budgets. Raw output: receipts/24-final-current-wholefiles-green.txt SHA256 3358af061c35d42b00d5ee1e001939534c5e7563d4f5418ea85431605d0b9f6d. Runner SHA256 c8a2bf4539bffe38f3198308fd60e9c1ad338841b406af160ab0739c15394290.
|
||||
- Source freeze: source-inputs.sha256 enumerates all 202 consumed repository inputs (182 modules/scripts plus 20 schema/PIN/other files), traced on final execution and rehashed unchanged after it. Manifest SHA256 b4662dcafb2aeb27a06e5dbd3b9d0b6d184e8624e344fed351ff20e3b255951b. Raw per-process trace is receipts/source-inputs.raw.jsonl. candidate-sourcepaths.txt and candidate-sourcehashes.sha256 list every changed package file for parent combination; receipts.sha256 covers every raw run and source trace. Runner/trace use no content logging.
|
||||
- Cleanup: original private mktemp root removed and absence verified; scoped runner EXIT trap removes its separate private root. All fixture servers/stores close through test cleanup. Mutant backup and temporary root marker removed. Isolated worktree retained for parent review; no production process, real proxy, account, config, credential path or provider was contacted.
|
||||
|
||||
Limits and handoff: scoped GREEN is not the full landing gate. No package/full gates, Chromium/browser gates, acceptance binary, canonical queue mutation, remote issue post, push, merge or landing was run. Full/browser/combined gates remain with the parent under 1014.Q264 after admission; fresh independent Codex review is the parent's next task. No self-approval is claimed. Base remains 09a847eda and no unlanded662/657/658 feature bytes were imported.
|
||||
|
||||
## R2 fixtures
|
||||
|
||||
Base 09a847eda, row 333 tip ddb3e961f, R2 fixture commit 12eba4b59. Author: Claude (sub-agent of the Mosaic Stack lead, T3 c5c1e8ba). Issue #1831. No product code, business document schema or test assertion changed.
|
||||
|
||||
Cause. Row 333 added packages/plugins/src/model-quota.mjs and imports it from packages/business/src/launch.mjs:3 and packages/business/src/organization.mjs:11. The cli release fixtures build smaller copies than a real stack copy: they copy packages/business/src and add only packages/plugins/src/kinds.mjs. Their business loader therefore failed with "Cannot find module .../packages/plugins/src/model-quota.mjs". Real copies are unaffected, because scripts/stack-copy.sh ships all of packages/plugins (COPY_PATHS, line 41). R1's evidence ran the 24 touched test files only (verify-scoped.sh, 174/174) and no package or cli gate, so it never built a release fixture copy and could not see this.
|
||||
|
||||
Fixture changes (tests only):
|
||||
|
||||
- packages/cli/tests/business-imports.mjs (new, 26 lines): businessImportedFiles(repo) reads the relative imports of every .mjs under packages/business/src and returns, sorted and repo-relative, the files outside that directory they reach, following those files' own imports. An import of a missing file throws. At this tip it returns packages/library/src/limits.mjs, mapping.mjs, problems.mjs, packages/plugins/src/kinds.mjs and packages/plugins/src/model-quota.mjs.
|
||||
- packages/cli/tests/stack-release-fixture.mjs:314 (copies for stack-release.test.mjs, stack-release-external.test.mjs and stack-upgrade.test.mjs): after the business, library and roles copy, copy each returned file that is not already in the copy. kinds.mjs is skipped on purpose, because the fixture has already written its KINDS_OLD or KINDS_NEW form there.
|
||||
- packages/cli/tests/stack-release.test.mjs:1994 (the RCOPIES copies): same loop.
|
||||
|
||||
Searched for other fixtures that copy packages/business/src without the whole plugins directory: the grep over packages/*/tests, scripts and scripts/testing finds only those two. packages/cli/tests/case2-install.test.mjs:74 copies packages/business/src/vocabulary.mjs alone, which has no imports. stack-copy.test.mjs and stack-release-external.test.mjs:450 copy tracked files or the whole repository, so they carry model-quota.mjs already.
|
||||
|
||||
Production check (every place that copies, mounts or packages business code or plugins/src/kinds.mjs without the whole plugins directory):
|
||||
|
||||
- scripts/stack-copy.sh:32 copies packages/business/src and :41 copies the whole packages/plugins, so model-quota.mjs reaches every real copy. scripts/case2-install.sh:185 calls it.
|
||||
- scripts/stack-release.sh:371 and :378 import the copy's own packages/business/src/business.mjs, which reaches launch.mjs and so model-quota.mjs. That copy comes from stack-copy.sh, which takes both directories from the same commit.
|
||||
- packages/seat/src/sandbox.mjs RUNNER_FILES (:50-:72) mounts packages/business/src/vocabulary.mjs (:67) and packages/plugins/src/kinds.mjs (:68) only. A transitive import walk from all 19 listed files reaches no file of packages/business or packages/plugins outside that list; launch.mjs, organization.mjs, business.mjs, loader.mjs and model-quota.mjs are not reached. vocabulary.mjs and kinds.mjs import nothing. packages/seat/src imports only vocabulary.mjs from business (compactions.mjs:46, sandbox.mjs:40, session.mjs:42). model-quota.mjs is therefore not needed in the sandbox.
|
||||
- scripts/test-darkwing-launch.mjs:34 and scripts/test-rocko-launch.mjs:25 copy packages/seat/src alone, which needs only vocabulary.mjs.
|
||||
- Containerfile:23-26 copies contracts, src, two processing-control files and adapters; src imports nothing from packages. compose.yaml mounts the data root and the auth file only.
|
||||
- scripts/mosaic:35 and scripts/case2-precheck.sh:85,171 import business code from the repository or copy they sit in, which holds all of packages/plugins.
|
||||
|
||||
Result: no production path misses model-quota.mjs. No product change was needed or made.
|
||||
|
||||
RED, on ddb3e961f before the change (whole files, from packages/cli, one at a time, TMPDIR /mnt/storage/scratch/tmp/QYOMZY):
|
||||
|
||||
- stack-release.test.mjs: 224 tests, 56 pass, 168 fail, 0 skip, 186 s. 127 log lines carry the missing-module message.
|
||||
- stack-release-external.test.mjs: 25 tests, 4 pass, 21 fail, 0 skip, 32 s.
|
||||
- stack-upgrade.test.mjs: 21 tests, 7 pass, 14 fail, 0 skip, 25 s.
|
||||
|
||||
These match the counts the join child recorded (56/168, 4/21, 7/14).
|
||||
|
||||
GREEN, on 12eba4b59:
|
||||
|
||||
- stack-release.test.mjs: 224/224 pass, 0 fail, 0 skip, 694 s. stack-release-external.test.mjs: 25/25, 88 s. stack-upgrade.test.mjs: 21/21, 66 s.
|
||||
- cli whole (node --test tests/*.test.mjs): 1045 tests, 1044 pass, 0 fail, 1 skip, 656 s. The skip is "FED R7 scratch two-instance acceptance", which names scripts/test-federation-acceptance.sh as the way to run it.
|
||||
- business 286/286, 3 s. bus 1380/1380, 49 s. plugins 123/123, 1 s. model-proxy 108/108, 1.4 s. webui 492/492, 63 s. No skips in these. The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed.
|
||||
- The counts for business (286) and plugins (123) are lower than the join's (292, 128) because the join included row 332's tests; this branch stays on base 09a847eda.
|
||||
|
||||
Mutant. With the helper changed to drop model-quota.mjs from its result (a one-line filter in business-imports.mjs), stack-release.test.mjs gave 224 tests, 56 pass, 168 fail in 183 s, with 127 "Cannot find module .../packages/plugins/src/model-quota.mjs" lines. The helper then printed four files, without model-quota.mjs. git checkout restored the file; git status --short printed nothing afterwards.
|
||||
|
||||
## Join onto landed 332
|
||||
|
||||
Written 2026-11-02T22:49Z by Claude (sub-agent of the Mosaic Stack lead, T3 c5c1e8ba), author of this join. Issue #1831. Checkout branch t3/row-333-join-replay.
|
||||
|
||||
Base and heads. Row 333 R2 head 0ef269da9 on base 09a847eda (R1 503b91e56, overlay 2627321f6, docs c012b2e0a and ddb3e961f, R2 fixtures 12eba4b59 and 0ef269da9). Row 332 landed on refactor at 5df0e9d6f (R2 and the lead correction). The branch started at 5df0e9d6f with no commits of its own and a clean tree. Command: git -c core.attributesFile=/mnt/storage/scratch/q284gate/union.attributes merge --no-ff --no-commit 0ef269da9. Merge commit c0c291cda, parents 5df0e9d6f and 0ef269da9, made at 22:33:47Z.
|
||||
|
||||
Why a replay. The earlier join (eabeb1aa8) was made on 332 R1. Row 332 then changed (R2 and a lead fix) and row 333 gained two fixture commits. Both rows change packages/business/src/launch.mjs and packages/plugins/README.md.
|
||||
|
||||
Conflicts. Exactly two paths, the two named in the brief. No other path conflicted.
|
||||
|
||||
- packages/business/src/launch.mjs, import block (lines 3 to 8 before resolution). 332 changed the errors import to `{ BusinessError, refuse }` for the proxy route refusals in checkModels. 333 added `import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs"` for the daily model leaves in checkTokenLimits. They do not contradict. Resolution: both imports, the model-quota line first, then `{ BusinessError, refuse }`. The rest of launch.mjs merged without conflict: 332's checkModels route handling and the checkAccount `proxy` credential, and 333's checkTokenLimits keys block.
|
||||
- packages/plugins/README.md, end of file (lines 331 to 378 before resolution). 332 appended "Per-session proxy context (P3)" and 333 appended "Proxy usage telemetry (row333 / P5)" after the same last paragraph. Resolution: keep both, P3 section first, one blank line between, P5 section last.
|
||||
|
||||
Other paths touched by both sides, merged without a conflict and not edited by hand: BUILD-LOG.md and docs/SESSIONS.md (union attribute, both sides' lines kept), and packages/cli/tests/stack-release.test.mjs (333's 3 lines for the business-imports helper, 332's R2 hermetic-launch edits). No product or test file was edited by hand.
|
||||
|
||||
Comparison with the reference resolution (/mnt/storage/scratch/tmp/iLeQSZ/join-resolution.patch). I took git diff 5df0e9d6f for the two files and compared it with the reference patch after removing the index lines. The result is identical, and the hunk headers (-1,5 +1,6; -76,8 +77,16; -365,3 +365,12) are equal too, so there is no difference to explain. The reference was a diff against the 332 R1 blobs. launch.mjs is d9ef01b40 and README.md is d4625c9f6 on both 332 R1 and landed 332, so R2 and the lead fix did not change these two files, which is why the earlier resolution carries over unchanged. A correction to the merge commit message: it says the files match the reference "apart from hunk offsets", but the hunk offsets match as well. The commit stays as made.
|
||||
|
||||
Tests, on c0c291cda. node_modules linked from /mnt/storage/src/mosaic-stack (a link at the root and a real directory of links under packages/webui), TMPDIR /mnt/storage/scratch/tmp/Z280Ko (31 bytes), each suite whole, one at a time, from its package directory with node --test tests/*.test.mjs, 30-minute limit, started 22:34:09Z. Nothing was skipped, failed or rerun except as noted.
|
||||
|
||||
| Suite | Tests | Pass | Fail | Skip | Time |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| business | 293 | 293 | 0 | 0 | 2 s |
|
||||
| plugins | 129 | 129 | 0 | 0 | 1 s |
|
||||
| bus | 1382 | 1382 | 0 | 0 | 48 s |
|
||||
| model-proxy | 108 | 108 | 0 | 0 | 1 s |
|
||||
| harness | 205 | 205 | 0 | 0 | 13 s |
|
||||
| seat | 223 | 223 | 0 | 0 | 6 s |
|
||||
| webui | 498 | 498 | 0 | 0 | 132 s |
|
||||
| cli | 1102 | 1101 | 0 | 1 | 669 s |
|
||||
| bash scripts/test-federation-acceptance.sh | 1 | 1 | 0 | 0 | 5 s |
|
||||
|
||||
The one cli skip is "FED R7 scratch two-instance acceptance", which names scripts/test-federation-acceptance.sh as the way to run it. That script passed 1/1 in the last row, with "R7 cleanup: no child groups, ports or sockets remain". The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed. Business and plugins are one test higher than the earlier join's 292 and 128, and bus 1382 is two above R2's 1380 on the 09a847eda base; this record does not attribute those differences to a cause.
|
||||
|
||||
Cleanup. No test process of mine remained after the runs. The node_modules links and the TMPDIR were removed; git ls-files -co --exclude-standard | grep node_modules printed nothing, and git status --short showed only this file and docs/SESSIONS.md before this commit.
|
||||
|
||||
## R3 rotation fix
|
||||
|
||||
Written 2026-11-03 by Claude Opus 5.5, implementation sub-agent of the Mosaic Stack lead (T3 c5c1e8ba). Issue #1831. Brief: /mnt/storage/scratch/mosaic-lead/briefs/row333-r3-fix.md. Review: /mnt/storage/scratch/mosaic-lead/reviews/row333-opus.md, findings 1 to 5. Branch t3/row333-r3-fix on base b37cc5087. Product, tests and docs are commit 3692fca52.
|
||||
|
||||
### Ruling 1: the quota follows the agent's key lineage
|
||||
|
||||
- Model record. `Credentials.#format` accepts an optional `previous`: a non-empty array of at most 64 entries, each exactly `{ keyId, retiredAt }` with a 12-hex id and a canonical ISO time. Anything else refuses `credential-format`, on write and when the file is opened. A record without the field loads unchanged. Safe status shows `previous` (ids and times) next to `retiring`, and an empty array for a record without it. No key value is in it.
|
||||
- When an id is added. `ModelKeys` adds an id when the key leaves the record. On a rotation the old key first becomes retiring, as before, and its id moves to `previous` when the sweep removes it, at grace expiry or at once when no run is bound to it. On a re-issue (the `#issue` path where the proxy no longer lists the old key) the old id goes straight to `previous`. The field stays absent until the first id leaves. Past 64 the writer drops the oldest, so a record never carries 65; the format refuses 65 as well. A fire removes the record, as before, so a re-hired agent starts a new lineage. The revocation proofs still compare whole records with `isDeepStrictEqual`; a test fires an agent whose record carries `previous` and the proof holds.
|
||||
- Lineage. An agent's lineage is its current id, its retiring ids, then its earlier ids. `modelUsageKey` checks uniqueness over every lineage on the host: an id in two agents' lineages, or twice in one, refuses `proxy-key-refused`. The new `modelKeyLineages` lists the business's lineages and applies the same host-wide check. `createLimits` takes a `keyLineages` hook, which refuses by default, and passes `lineages` to the checks only when a daily key leaf exists. The subject's key must be in exactly one lineage read in the same call, or the launch refuses and the turn stops. `report` shows every limit `check failed: proxy-key-refused` when the lineages can't be read.
|
||||
- daily-quota. A key leaf applies to a subject whose key is in the lineage holding the leaf's id, and its tally sums the day's records for every id in that lineage. Usage records and the Console per-key counts stay per key id. Missing or malformed `lineages` throws `bad-lineages`; account quotas never need them.
|
||||
- mustStop resolves the run's bound key, and that key's lineage decides the leaf. A run may be bound only to the current or a retiring key. A run whose bound id has moved to `previous` refuses `proxy-key-refused`, which stops it.
|
||||
- Orphaned leaves. A leaf whose id is in no hired agent's lineage counts its own id only and matches no subject, so it refuses no launch. The limits code logs `{event: 'limit-key-orphaned', business, path}` once when a leaf becomes orphaned, not per launch, and again only if it stops being orphaned and becomes orphaned later. `orphanedKeys` feeds `orphanedKeyQuotas` in the usage view, and the Console usage view lists each one: "Key quota <id> matches no agent, so it limits nothing. A fire and re-hire gives the agent a new key; set the quota on the new key id." A fire and re-hire therefore leaves the old leaf orphaned, and the human sees it in that view. The Token limits panel can only reset leaves, not rename them, so the text points at the new key id rather than at that panel.
|
||||
- Docs. packages/plugins/usage/cliproxy-queue/README.md (where row 333 documents `tokens.keys` leaves), packages/plugins/README.md (the limit-check interface gains `lineages` and `subject.modelKeyId`, plus the daily-quota section) and packages/plugins/limit-check/daily-quota/README.md each gain the rotation and orphan sentences. The business package documents no model-key leaf, so it has no doc change.
|
||||
- Rollback. A release from before this round refuses a record that carries `previous` with `credential-format`, which fails closed. No live stack holds proxy model records yet (no proxy cutover until Vikunja #774), so no migration was built.
|
||||
|
||||
Departures from the expected shape, and why:
|
||||
|
||||
- 65 entries: both refuse and trim. The format refuses 65 (a hand-edited or foreign record), and the writer trims to the newest 64 so the bus never writes one. Both are pinned.
|
||||
- A keyless agent under a key quota refuses even when every key leaf is orphaned. An orphaned leaf matches no subject, so the refusal is not needed to enforce it, but resolving the subject's key comes first and I kept that fail-closed order rather than add a second path that skips it.
|
||||
- Moving a leaf through the human writer. The brief says moving a leaf from A to B on rotation day must not reset the count. The tally does sum A and B: a leaf named B whose `since` is the day's start counts 160 (90 on A, 70 on B) and refuses. But the human settings writer treats a rename as a new leaf and stamps `since` with the move time, so a leaf moved through the writer counts only the usage after the move (100 in the test, not 160). I did not change the writer: the `since` stamping is the row 125/126 human-writer contract, in the business package, and changing it widens this round. With the lineage, the move is not needed, since the leaf on A keeps applying after rotation. Both cases are pinned in p5-key-lineage.test.mjs. Recommended follow-up if the lead wants a moved leaf to keep its count: let the writer carry `since` over when the old and new ids are in one lineage.
|
||||
- The proxy-usage owner map stays current plus retiring. It attributes proxy queue events, which can only name keys the proxy still accepts, so earlier ids would never match. That is telemetry, not the quota, and I left it.
|
||||
|
||||
### Ruling 2: key-quota-no-model-key
|
||||
|
||||
`modelUsageKey` throws `key-quota-no-model-key` when the agent has no model record, or one with no key issued. `createLimits` passes that code and `proxy-key-refused` through by name; any other lookup failure is still `proxy-key-refused`. Pass-through, after grepping `proxy-key-refused` across packages/*/src: the broker's organization-error pass-through list gains the code (bus/src/broker.mjs; no organization writer raises it today, but it now passes through the same way as the other proxy key codes). The launcher maps every bus refusal to `limit-check-failed` with message `bus: <code>`, and the turn-end stop reason is `limit: bus failed <code>`; neither needed a change, and both are pinned for the new code (cli launch-limit-checks.test.mjs, bus limit-stop.test.mjs). With no key quota there is no lookup and no refusal.
|
||||
|
||||
### Ruling 3: rotation between preflight and mayLaunch
|
||||
|
||||
The lineage covers it. Finding 3's case is preflight admitting A, the sweep rotating A to B, and `mayLaunch` checking B. B and A are now one lineage, so a leaf named A matches the subject B and counts A and B: the launch refuses. The rotation test asserts exactly this state (A retiring, B current, `mayLaunch` refuses under the A leaf). After a re-issue, A is not current or retiring, so binding a run to A refuses. I found no gap, so `mayLaunch` does not take the admitted key id.
|
||||
|
||||
### Ruling 4: the usage module gets readUsageQueue only
|
||||
|
||||
`createProxyUsage` hands the module `Object.freeze({ readUsageQueue: () => management.readUsageQueue() })`. cliproxy-queue reads `read({ readUsageQueue })`. The test wraps the real loader to capture the argument. It has exactly one own key, `readUsageQueue`, a function, is frozen with `Object.prototype` as its prototype, and a walk over every own property, accessor and prototype reachable from it finds neither the client, its prototype, its class nor any of its other methods by name or by reference. Spies on every client method show only `readUsageQueue` was called, and the event was still recorded.
|
||||
|
||||
### Ruling 5: fixture deadlines
|
||||
|
||||
Each wait in p5-telemetry-fixture.mjs (`waitLog`, `waitQueue`, `settleInitial`, `pollSettledAfterTick`) races a deadline on the real `setTimeout`, captured when the module loads, before any test mocks timers. The default is `WAIT_MS` = 5000 ms; the fixture takes `waitMs`. The rejection names what it waited for, for example `p5 fixture: no usage queue read number 1 within 50 ms`. The new test mocks every timer API, never advances it, and asserts all four rejections by exact message with `waitMs: 50`. The p5-background.test.mjs header is updated.
|
||||
|
||||
### Tests
|
||||
|
||||
Added: packages/bus/tests/p5-key-lineage.test.mjs (9 tests). It uses the real `Credentials`, `ManagementClient`, `ModelKeys` and its sweep, `createLimits`, `modelUsageKey`, `modelKeyLineages` and the daily-quota module, with a fake loopback management server, a made-up management key and a fresh temp root. Only `Date` is mocked.
|
||||
|
||||
- Rotation mid-day under a hit leaf named A: refuses before, right after (A retiring, B current), inside the grace, after the grace (A in `previous`) and after a restart that reloads the record. The run bound to A stops at its turn end after the rotation. Another agent stays allowed.
|
||||
- Re-issue: the proxy no longer lists A at preflight, B is issued, A is in `previous`, and the leaf still refuses, including after a restart. A limit of 101 allows.
|
||||
- The leaf moved from A to B on rotation day still refuses with count 160, and the run bound to A stops.
|
||||
- The settings-writer move: `since` is the move time and the count is 100.
|
||||
- Lineage uniqueness: an id in two agents' lineages refuses both, and the report shows check failed. An id twice in one lineage refuses too.
|
||||
- Format: a record without `previous` loads; thirteen malformed values refuse `credential-format` on write and on open, including 65 entries, a key value in place of an id and an empty array; 64 earlier plus 64 retiring load within the 16384-byte cap.
|
||||
- A re-issue on a record holding 64 drops the oldest.
|
||||
- Fire and re-hire: the revocation proof holds with `previous` present, the old leaf is orphaned, three launches go ahead, one log line, the view lists it, and no key value is in the logs, view, receipts, status or store files.
|
||||
- Ruling 2 on `modelUsageKey`, `mayLaunch` and `mustStop`, and no lookup without a key quota.
|
||||
|
||||
Also added: three daily-quota tests (lineage match and count, orphan, `bad-lineages`), one usage-render test (the orphan list, escaped), the ruling 4 test in proxy-usage.test.mjs, the ruling 5 test in p5-background.test.mjs, and the new code in limit-stop.test.mjs and cli launch-limit-checks.test.mjs. Changed for the new rules: limit-checks.test.mjs (a leaf on a retiring key now applies to the agent's current key too, so the launch refuses; an unrelated lineage still allows), p5-key-context.test.mjs (the two no-owner cases now expect `key-quota-no-model-key`; a wrong run stays `proxy-key-refused`), p5-key-compatibility.test.mjs (passes `lineages` to the module) and the p5-telemetry-fixture.mjs waits.
|
||||
|
||||
### Runs
|
||||
|
||||
All on 3692fca52, one at a time, each under a 30-minute limit, with TMPDIR under /mnt/storage/scratch/tmp and output to files there. Each whole run is `node --test` over the package's tests directory.
|
||||
|
||||
| Run | Tests | Pass | Fail | Skip | Time |
|
||||
|---|---|---|---|---|---|
|
||||
| bus whole | 1393 | 1393 | 0 | 0 | 49 s, 23:55:28Z to 23:56:17Z on 2026-11-02 |
|
||||
| plugins whole | 132 | 132 | 0 | 0 | 0.3 s, 23:56Z |
|
||||
| business whole | 293 | 293 | 0 | 0 | 2.6 s, 23:56Z |
|
||||
| webui whole | 499 | 499 | 0 | 0 | 66 s, 23:56:50Z to 23:57:56Z |
|
||||
| cli stack-release.test.mjs | 225 | 225 | 0 | 0 | 664 s, 23:58:03Z on 2026-11-02 to 00:09:07Z on 2026-11-03 |
|
||||
| cli stack-release-external.test.mjs | 25 | 25 | 0 | 0 | 88 s, 00:09:07Z to 00:10:35Z |
|
||||
| cli stack-upgrade.test.mjs | 25 | 25 | 0 | 0 | 69 s, 00:10:35Z to 00:11:44Z |
|
||||
| cli launch-limit-checks.test.mjs | 5 | 5 | 0 | 0 | 0.2 s, 00:11:44Z |
|
||||
|
||||
The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed. Against the join record above, bus is up 11 (the 9 lineage tests, the ruling 4 test and the ruling 5 test), plugins up 3 (the daily-quota tests) and webui up 1 (the usage-render test); business is unchanged. The other changed tests changed existing cases or added table rows, not tests.
|
||||
|
||||
### Mutants
|
||||
|
||||
Each was applied to the committed tree, run against the named file, and restored with `git checkout -- <file>`; `git status --short` was clean after each.
|
||||
|
||||
| Mutant | Change | Killed by | Result |
|
||||
|---|---|---|---|
|
||||
| M1 | daily-quota matches a key leaf to the subject by the leaf's own id only | p5-key-lineage.test.mjs:101, the rotation test: right after the rotation the launch was allowed where a refusal with count 100 was expected. Also :138 (re-issue), :156 (moved leaf, run not stopped), :252 (fire and re-hire) and daily-quota.test.mjs:197 | lineage 4 of 9 fail, daily-quota 1 of 17 fail |
|
||||
| M2 | the tally counts only the leaf's own id | p5-key-lineage.test.mjs:155, the moved-leaf test: allowed where limit 160 and count 160 were expected. Also :179 (writer move), :252 (count 100, expected 105) and daily-quota.test.mjs:197 | lineage 3 of 9 fail, daily-quota 1 of 17 fail |
|
||||
| M3 | `#issue` records no old id on a re-issue | p5-key-lineage.test.mjs:137, the re-issue test: `previous` was undefined where `[{ keyId: 'f6548f12575e', retiredAt: '2026-10-24T12:01:00.000Z' }]` was expected. Also :241 (trim at 64) | lineage 2 of 9 fail |
|
||||
| M4 | the usage module gets `{ client: management, readUsageQueue }` | proxy-usage.test.mjs:89: own keys were `['client', 'readUsageQueue']` | 1 of 8 fail |
|
||||
| M4b | the client hidden as a non-enumerable property on the `readUsageQueue` function | proxy-usage.test.mjs:98: the walk reached the client | 1 of 8 fail |
|
||||
|
||||
M4b is extra; it shows the ruling 4 test finds a hidden path and not only an extra own key.
|
||||
|
||||
### Not done
|
||||
|
||||
- The settings writer still stamps a new `since` on a renamed leaf (Departures above). Recommended follow-up, not built.
|
||||
- No migration, per the brief: no live stack holds proxy model records yet.
|
||||
- No push, queue, Vikunja, Gitea or PR action, per the brief.
|
||||
|
||||
## R4 since carry
|
||||
|
||||
Written 2026-11-03 by Claude Opus 5.5, implementation sub-agent of the Mosaic Stack lead (T3 c5c1e8ba). Issue #1831. Brief: /mnt/storage/scratch/mosaic-lead/briefs/row333-r4-fix.md. Branch t3/row333-r4-fix on the R3 tip fe3ef5128 (base b37cc5087, no rebase). Product, tests and docs are commit f65faf9df. The R3 section above is unchanged; where R4 changes something it says, this section says so.
|
||||
|
||||
### Ruling 1: a moved key quota keeps its count
|
||||
|
||||
- The lookup. runtime.mjs builds `keyLineage(business, keyId)` as `modelKeyLineage(credentials.status(), business, keyId)` and passes it to `launchSettings`. `modelKeyLineage` (limits.mjs) returns the lineage in that business holding the id, or `[]` when none does. It is built on `modelKeyLineages`, so the same host-wide uniqueness check runs and a duplicate id throws. It reads the bus's own credential records through their safe status: ids, never a key value. The writer hands it only a business id and a key id, so no caller-supplied lineage reaches it, and the runtime spreads `organization` before `keyLineage`, so an organization option can't replace it.
|
||||
- The writer. `stamp` keeps its rules: a leaf with a stored `since` at the same path keeps it, and a caller-supplied `since` that differs refuses `invalid-request` (on a new leaf any caller `since` differs, so it always refuses). New: a `tokens.keys` leaf with no stored `since` that is a daily key quota asks the lookup for its key's lineage and takes the earliest stored `since` among the old document's `tokens.keys` daily key quotas whose ids are in it. Whether the same write removes the old leaf doesn't matter. With none it takes now. `reset` runs after `stamp` in the same write, so a reset sets now, in the move write or a later one.
|
||||
- Lookup failure. `launchSettings`'s default `keyLineage` throws, so a writer built without one refuses. A throw, an answer that isn't an array, an id that isn't twelve lowercase hex, or a non-empty answer without the asked id refuses `OrganizationError('proxy-key-refused')` and writes nothing. The broker already passes that code through by name. A write that adds no new daily key quota never calls the lookup: account limits, legacy leaves, a changed or unchanged quota, a reset.
|
||||
- Remove then re-add. A quota removed in one write and added back in a later one finds no old leaf, so it is a new quota and gets now. Documented in the `carried` comment and the READMEs.
|
||||
- Docs. packages/plugins/usage/cliproxy-queue/README.md: the last paragraph's "stamps a new `since` on a renamed leaf ... restarts its count" is replaced by the carry rule, the remove-then-re-add rule and the lookup refusal. packages/plugins/README.md (daily-quota section) and packages/plugins/limit-check/daily-quota/README.md (model-key section) gain the carry sentence. packages/business/README.md had no `since` rule and, as the R3 review said, no model-key leaf; it now has a paragraph after `launch.limits.tokens.daily` on the leaf, the writer's `since` rules with the carry, and `keyLineage`.
|
||||
|
||||
Choices and departures, and why:
|
||||
|
||||
- Which leaves ask. Only a new leaf that is a daily key quota once stamped (`isDailyModelQuota` with `since` set to now). A twelve-hex-named plain `{limit}` leaf is a legacy account limit under row 333's rule, so it keeps the plain new-leaf rule and the lookup is not called. Source leaves must be daily key quotas too, so a legacy leaf's `since` never carries into a daily quota.
|
||||
- A leaf that changes shape at the same path, a legacy `{limit, since}` becoming a daily quota, keeps its stored `since` under the existing same-path rule. Unchanged; found while writing the default-lookup case, which now adds a fresh id.
|
||||
- Earliest against latest. The business test separates them: A from T0, B added from A (T0) and then reset to T1, both moved to C, and C takes T0 where the latest would give T1. Mutant M3 shows the test tells them apart.
|
||||
- The real-runtime test uses a re-issue, not a rotation. The runtime keeps its `ModelKeys` inside and exposes no rotate, and its sweep rotates only at `rotateBy`, 30 days after issue, which no daily window spans without mocking the runtime's clock. The re-issue gives the same shape of lineage (B current, A among the earlier ids) and goes through the real `startBroker` wiring, the broker's `limits.set` and the runtime's own lookup. The rotation path through the writer is p5-key-lineage's R4 writer test, with the real `Credentials`, `ModelKeys`, `createLimits` and daily-quota module.
|
||||
- The R3 "settings-writer move" test, which pinned a count of 100, now requires 160 and is renamed for R4. The R3 departure 3 and its "Not done" item are superseded by this ruling.
|
||||
|
||||
### Ruling 2: the orphan set on every refresh
|
||||
|
||||
`observeOrphans` (limits.mjs) runs in `refresh`, which the runtime calls after each committed verb and at boot, and in `orphanedKeys`. With no daily key quota left it stores an empty set for the business; otherwise it reads the lineages and calls `noteOrphans`, which logs each id not in the stored set and stores the current set. When the lineages can't be read it leaves the stored set as it was and logs nothing. So a quota removed and added back logs again, and an unchanged orphan logs once however many refreshes see it. The set is in memory: a restart is a fresh observation, and a quota still orphaned after it logs once more. No marker is persisted. This is in the `orphansLogged` comment and the cliproxy-queue README.
|
||||
|
||||
Consequence: the orphan line now comes at the first refresh that sees the orphan, which can be boot or the refresh at the start of a launch decision, before that decision's own refusal line. Two R3 tests asserted the old order and now expect the orphan line first: the fire and re-hire test (the line comes at the keyless launch before the re-hire, not at the first launch after it) and the ruling 2 test. The number of orphan lines is unchanged in both.
|
||||
|
||||
### Ruling 3: the barrier's last yield
|
||||
|
||||
p5-telemetry-fixture.mjs captures `realSetImmediate` at module load with the other real timers, and `pollSettledAfterTick` yields on it inside the deadline, so a mocked `setImmediate` can't hold the barrier and the deadline covers the whole wait. Both options in the ruling, since together they cost nothing. The new p5-background test mocks `Date`, `setInterval`, `setTimeout` and `setImmediate`, advances one poll tick through the barrier, never ticks again, and requires the barrier to settle within a real bound of twice `WAIT_MS`, with the second queue read seen and the proxy state `available`. Against the R3 fixture it fails "pollSettledAfterTick did not settle" (about 10 s, the outer bound); I checked that before keeping the test.
|
||||
|
||||
### Ruling 4: records
|
||||
|
||||
- The 64-id bound is a limit. A lineage holds the current id, the retiring ids and the newest 64 earlier ids. Once an id falls out of the newest 64, a quota named by it is in no lineage, so it is orphaned while the agent stays hired: it limits nothing and the usage view lists it. Moving the quota to a current id fixes it, and since the old id is no longer in the lineage the writer can't carry its `since`, so the moved quota starts at now. Recorded here and in the cliproxy-queue README.
|
||||
- R3 departure 4, corrected. Its reason, that proxy queue events "can only name keys the proxy still accepts, so earlier ids would never match", is wrong. A queued event the proxy accepted before the key left the record and that the bus drains after it names an id that is no longer current or retiring. proxy-usage.mjs:42-67 builds its owner map from current and retiring ids only, so that event goes to the reconcile log as `proxy-usage-unknown-key` and is not recorded. That loses telemetry attribution for the event. It is not a quota bypass: quotas count the native transcript records, which carry the run's bound key id. The owner map is unchanged in R4.
|
||||
|
||||
### Tests
|
||||
|
||||
Added:
|
||||
|
||||
- packages/bus/tests/p5-key-lineage.test.mjs. The R3 writer test becomes the R4 writer test: A's quota is set at the start, the agent uses 60 on A, rotates, the human moves the unchanged quota to B, B's `since` equals A's, and after 30 more on A and 70 on B the launch refuses with count 160 and the report shows 160; a reset after the move sets now, the count is 0 and the launch goes ahead. New: a lineage that can't be read (an id in two agents' lineages) refuses a write adding a key quota with `proxy-key-refused`, the file unchanged, and a write adding none (a changed limit and a legacy hex leaf) saves without asking. New: an orphaned quota removed and added back logs twice, three more refreshes, a launch and `orphanedKeys` add nothing, and after a restart three refreshes add exactly one.
|
||||
- packages/bus/tests/p5-runtime.test.mjs. Real `startBroker`, fake loopback proxy: a 2-token quota on A, a turn spends 2 on A, the launch refuses, the proxy stops listing A, `modelPreflight` issues B, `limits.set` moves the unchanged quota to B with no reset, the stored leaf is B with A's `since`, no key value is in the limits view, and the next `mayLaunch` refuses.
|
||||
- packages/bus/tests/p5-background.test.mjs. The ruling 3 barrier test.
|
||||
- packages/business/tests/token-limit-settings.test.mjs, with a stub lookup. One test: B added beside A carries A's time; earliest over latest; an id in no lineage gets now; a caller-supplied `since` refuses on a new leaf, a moved leaf and with the carried time itself; a reset in the move write sets now; removed and added back gets now. The other: no lookup for account limits, legacy hex leaves, a changed quota or a reset; a lookup that throws (with and without a code) or answers a string, a list holding a number, a list holding an uppercase id, a list without the asked id or an object refuses `proxy-key-refused` with the file unchanged; the default writer refuses a new daily key quota and saves account and legacy limits.
|
||||
|
||||
Changed: the existing P5 business test passes a lookup answering `[]`, since a writer without one now refuses that leaf. In p5-key-lineage, the R3 fire and re-hire test and the ruling 2 test expect the orphan line first (Ruling 2 above).
|
||||
|
||||
### Runs
|
||||
|
||||
One at a time, each under a 30-minute limit (`timeout -k 10 1800 node --test`), Node v26.8.1, with TMPDIR under /mnt/storage/scratch/tmp and output to files there. Each whole run is `node --test` over the package's tests directory. All times are 2026-11-03 UTC. The first runs were on the working tree that became f65faf9df, committed with no edit between; the cli stack runs and the closing whole-package runs were on f65faf9df itself, the latter after the mutants were restored.
|
||||
|
||||
| Run | Tree | Tests | Pass | Fail | Skip | Time |
|
||||
|---|---|---|---|---|---|---|
|
||||
| bus whole | before commit | 1397 | 1397 | 0 | 0 | 50 s, 00:55:51Z to 00:56:41Z |
|
||||
| plugins whole | before commit | 132 | 132 | 0 | 0 | under 1 s, 00:56:53Z |
|
||||
| business whole | before commit | 295 | 295 | 0 | 0 | 4 s, 00:56:53Z to 00:56:57Z |
|
||||
| webui whole, run 1 | before commit | 499 | 498 | 1 | 0 | 88 s, 00:57:00Z to 00:58:28Z |
|
||||
| webui editor-browser.test.mjs alone | before commit | 16 | 16 | 0 | 0 | 15 s, 00:58:47Z to 00:59:02Z |
|
||||
| webui whole, run 2 | before commit | 499 | 499 | 0 | 0 | 119 s, 00:59:06Z to 01:01:05Z |
|
||||
| cli launch-limit-checks.test.mjs | before commit | 5 | 5 | 0 | 0 | under 1 s, 01:01:23Z |
|
||||
| cli stack-release.test.mjs | f65faf9df | 225 | 225 | 0 | 0 | 741 s, 01:02:50Z to 01:15:11Z |
|
||||
| cli stack-release-external.test.mjs | f65faf9df | 25 | 25 | 0 | 0 | 98 s, 01:15:25Z to 01:17:03Z |
|
||||
| cli stack-upgrade.test.mjs | f65faf9df | 25 | 25 | 0 | 0 | 148 s, 01:17:07Z to 01:19:35Z |
|
||||
| harness tools.test.mjs | f65faf9df | 23 | 23 | 0 | 0 | under 1 s, 01:20:41Z |
|
||||
| bus whole | f65faf9df | 1397 | 1397 | 0 | 0 | 54 s, 01:22:35Z to 01:23:29Z |
|
||||
| plugins whole | f65faf9df | 132 | 132 | 0 | 0 | 1 s, 01:23:29Z to 01:23:30Z |
|
||||
| business whole | f65faf9df | 295 | 295 | 0 | 0 | 4 s, 01:23:30Z to 01:23:34Z |
|
||||
| webui whole | f65faf9df | 499 | 499 | 0 | 0 | 131 s, 01:23:38Z to 01:25:49Z |
|
||||
|
||||
The webui run 1 failure was editor-browser.test.mjs:93, the CSP editor test: `Condition timed out: !document.querySelector("#doc-save").disabled` at :122, with the host's load average between 45 and 60. R4 changes nothing webui loads. The file passed alone and the whole package passed twice after, so I read it as load, not R4; both runs are listed. The model-final-completion.test.mjs:69 flake (16 !== 19) did not appear in either bus run. Against R3, bus is up 4 (p5-key-lineage's lookup-failure and orphan re-add tests, the p5-runtime move test, the p5-background barrier test; the writer test is renamed, not added) and business up 2. Plugins and webui are unchanged.
|
||||
|
||||
Pins. No test pins any changed path with a hash: the grep of every test, script and fixture naming a changed file's basename for a 64-hex string found only packages/queue/tests/fixtures/queue-marked.md, which names none of the four READMEs. The tests that read a changed file by path (limit-checks.test.mjs:319 and :323, host-run.test.mjs:429) are in packages/bus, run whole. Outside the four packages, harness tools.test.mjs imports `SETTINGS_KEYS` from launch-settings.mjs and ran whole (above). Nineteen packages/cli test files import `startBroker` from bus runtime.mjs; they import, they don't pin, and beyond the four cli files the brief names they were not run (Not done).
|
||||
|
||||
### Mutants
|
||||
|
||||
Each was applied to f65faf9df, run against the named files, and restored with `git checkout -- <file>`; `git status --short` was empty after each.
|
||||
|
||||
| Mutant | Change | Killed by | Result |
|
||||
|---|---|---|---|
|
||||
| M1 | launch-settings.mjs:73 `entry.since = kept ?? now;`, so stamp ignores the lineage | p5-key-lineage.test.mjs:173, the writer test, at :185: B's `since` was the move time `2026-10-24T12:01:00.000Z` where A's `2026-10-24T12:00:00.000Z` was expected. p5-runtime.test.mjs:62 at :106: the stored B leaf had the move time, not A's. token-limit-settings.test.mjs:178 at :184: B took the write time 08:00 where A's 07:00 was expected. Also p5-key-lineage :198 at :206 and token-limit-settings :204 at :212, both because the lookup is never called (`asked` was 0 where 1 was expected, and `[]` where `[A]` was) | p5-key-lineage 2 of 11 fail, p5-runtime 1 of 2, token-limit-settings 2 of 9 |
|
||||
| M2 | runtime.mjs:346 passes `launchSettings` no `keyLineage` | p5-runtime.test.mjs:62 at :88: `proxy-key-refused` from the broker at the first `limits.set` that adds a key quota, since the writer's default lookup refuses. The R3 P5 runtime test at :39 fails the same way | p5-runtime 2 of 2 fail |
|
||||
| M3 | launch-settings.mjs:96 sorts descending, so the latest `since` wins | token-limit-settings.test.mjs:178 at :189: C had `since` 08:00 (T1, B's reset time) where 07:00 (T0, A's) was expected | token-limit-settings 1 of 9 fail. p5-key-lineage and p5-runtime pass (13 of 13): each of their moves has one source leaf, so earliest and latest are the same there |
|
||||
| M4 | limits.mjs:130, `refresh` no longer calls `observeOrphans` | p5-key-lineage.test.mjs:348, the orphan re-add test, at :358: one `limit-key-orphaned` line where two were expected; the set was never cleared, so the re-added leaf was still remembered. Also the R3 fire and re-hire test at :299 and the R3 ruling 2 test at :341, each missing the orphan line the refresh now logs first | p5-key-lineage 3 of 11 fail |
|
||||
| M4b | limits.mjs:90 returns `[]` with no daily key quota but leaves the remembered set alone | p5-key-lineage.test.mjs:348 at :358, the same one-line-for-two failure | p5-key-lineage 1 of 11 fail |
|
||||
| M5 | p5-telemetry-fixture.mjs restored to its R3 content | p5-background.test.mjs:71, the barrier test: `pollSettledAfterTick did not settle` after 10 s | p5-background 1 of 5 fail |
|
||||
|
||||
M4b and M5 are extra. M4b shows the empty set itself is needed, not only the refresh call. M5 shows the ruling 3 test fails on the R3 barrier, whose last yield used the mocked `setImmediate` outside the deadline.
|
||||
|
||||
### Not done
|
||||
|
||||
- No push, queue, Vikunja, Gitea or PR action, per the brief.
|
||||
- No migration or persisted orphan marker, per the rulings.
|
||||
- The proxy-usage owner map still holds only current and retiring ids (Ruling 4 above).
|
||||
- The nineteen packages/cli test files that import bus runtime.mjs were not run beyond the four the brief names: they import it and pin nothing, and the runtime change adds only the lookup, used when a write adds a daily key quota.
|
||||
@@ -1,31 +0,0 @@
|
||||
packages/bus/src/broker.mjs: OK
|
||||
packages/bus/src/limits.mjs: OK
|
||||
packages/bus/src/proxy-usage.mjs: OK
|
||||
packages/bus/src/runtime.mjs: OK
|
||||
packages/bus/src/usage.mjs: OK
|
||||
packages/bus/tests/limit-checks.test.mjs: OK
|
||||
packages/bus/tests/p5-key-context.test.mjs: OK
|
||||
packages/bus/tests/p5-runtime.test.mjs: OK
|
||||
packages/bus/tests/proxy-usage.test.mjs: OK
|
||||
packages/bus/tests/usage.test.mjs: OK
|
||||
packages/business/src/business.mjs: OK
|
||||
packages/business/src/launch.mjs: OK
|
||||
packages/business/src/organization.mjs: OK
|
||||
packages/business/src/plugin-settings.mjs: OK
|
||||
packages/business/tests/plugin-settings.test.mjs: OK
|
||||
packages/business/tests/token-limit-settings.test.mjs: OK
|
||||
packages/model-proxy/README.md: OK
|
||||
packages/model-proxy/src/client.mjs: OK
|
||||
packages/model-proxy/tests/usage-client.test.mjs: OK
|
||||
packages/plugins/README.md: OK
|
||||
packages/plugins/limit-check/daily-quota/index.mjs: OK
|
||||
packages/plugins/limit-check/token-limit/index.mjs: OK
|
||||
packages/plugins/src/kinds.mjs: OK
|
||||
packages/plugins/tests/daily-quota.test.mjs: OK
|
||||
packages/plugins/tests/kinds.test.mjs: OK
|
||||
packages/plugins/tests/loader.test.mjs: OK
|
||||
packages/plugins/tests/token-limit.test.mjs: OK
|
||||
packages/plugins/usage/cliproxy-queue/README.md: OK
|
||||
packages/plugins/usage/cliproxy-queue/index.mjs: OK
|
||||
packages/webui/src/public/bus.js: OK
|
||||
packages/webui/tests/usage-render.test.mjs: OK
|
||||
@@ -1,31 +0,0 @@
|
||||
c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5 packages/bus/src/broker.mjs
|
||||
18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3 packages/bus/src/limits.mjs
|
||||
5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59 packages/bus/src/proxy-usage.mjs
|
||||
969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6 packages/bus/src/runtime.mjs
|
||||
4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29 packages/bus/src/usage.mjs
|
||||
45870a4903d1996915c0086a6beb4d0a4c75b38386b7c5e6d98b5bc811c3b541 packages/bus/tests/limit-checks.test.mjs
|
||||
e37114eab9c5f21015ea8e429f0574d3ea34b06263f1e42b83b31b8d2df222a7 packages/bus/tests/p5-key-context.test.mjs
|
||||
241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c packages/bus/tests/p5-runtime.test.mjs
|
||||
84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5 packages/bus/tests/proxy-usage.test.mjs
|
||||
2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340 packages/bus/tests/usage.test.mjs
|
||||
aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9 packages/business/src/business.mjs
|
||||
0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c packages/business/src/launch.mjs
|
||||
fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7 packages/business/src/organization.mjs
|
||||
9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50 packages/business/src/plugin-settings.mjs
|
||||
f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6 packages/business/tests/plugin-settings.test.mjs
|
||||
bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07 packages/business/tests/token-limit-settings.test.mjs
|
||||
2e97ddcf7deac43002f60c44571056273ddffd4aa0ed0d86f15f550d958a106e packages/model-proxy/README.md
|
||||
f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441 packages/model-proxy/src/client.mjs
|
||||
1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1 packages/model-proxy/tests/usage-client.test.mjs
|
||||
d54d94604d2f8944292fd5a11be8378afc84c06fb6a04137221bfe1a89c5389c packages/plugins/README.md
|
||||
3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b packages/plugins/limit-check/daily-quota/index.mjs
|
||||
4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524 packages/plugins/limit-check/token-limit/index.mjs
|
||||
eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78 packages/plugins/src/kinds.mjs
|
||||
3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71 packages/plugins/tests/daily-quota.test.mjs
|
||||
f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba packages/plugins/tests/kinds.test.mjs
|
||||
8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b packages/plugins/tests/loader.test.mjs
|
||||
6e96bb96278ec754ca1816a24f49ef677771615ab5cf186ae41969fc2f93d8cc packages/plugins/tests/token-limit.test.mjs
|
||||
e9deb2504741f45645cd52ea6a1daee031cd2d3d44775a1221e76cec73c6b480 packages/plugins/usage/cliproxy-queue/README.md
|
||||
6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96 packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93 packages/webui/src/public/bus.js
|
||||
39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c packages/webui/tests/usage-render.test.mjs
|
||||
@@ -1,31 +0,0 @@
|
||||
packages/bus/src/broker.mjs
|
||||
packages/bus/src/limits.mjs
|
||||
packages/bus/src/proxy-usage.mjs
|
||||
packages/bus/src/runtime.mjs
|
||||
packages/bus/src/usage.mjs
|
||||
packages/bus/tests/limit-checks.test.mjs
|
||||
packages/bus/tests/p5-key-context.test.mjs
|
||||
packages/bus/tests/p5-runtime.test.mjs
|
||||
packages/bus/tests/proxy-usage.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/business/src/business.mjs
|
||||
packages/business/src/launch.mjs
|
||||
packages/business/src/organization.mjs
|
||||
packages/business/src/plugin-settings.mjs
|
||||
packages/business/tests/plugin-settings.test.mjs
|
||||
packages/business/tests/token-limit-settings.test.mjs
|
||||
packages/model-proxy/README.md
|
||||
packages/model-proxy/src/client.mjs
|
||||
packages/model-proxy/tests/usage-client.test.mjs
|
||||
packages/plugins/README.md
|
||||
packages/plugins/limit-check/daily-quota/index.mjs
|
||||
packages/plugins/limit-check/token-limit/index.mjs
|
||||
packages/plugins/src/kinds.mjs
|
||||
packages/plugins/tests/daily-quota.test.mjs
|
||||
packages/plugins/tests/kinds.test.mjs
|
||||
packages/plugins/tests/loader.test.mjs
|
||||
packages/plugins/tests/token-limit.test.mjs
|
||||
packages/plugins/usage/cliproxy-queue/README.md
|
||||
packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
packages/webui/src/public/bus.js
|
||||
packages/webui/tests/usage-render.test.mjs
|
||||
@@ -1,20 +0,0 @@
|
||||
# Intended admitted-runner controls — execution pending
|
||||
|
||||
These are first guards to establish on the admitted runner. Current controls have NOT run after the priority STOP; no source guard is described as observed RED/GREEN.
|
||||
|
||||
| R1 finding | Whole-file control | Baseline first guard / RED cause | Fixed positive and boundary controls |
|
||||
|---|---|---|---|
|
||||
|1 P1 identity|packages/bus/tests/p5-identity.test.mjs|Boot foreign sentinel still leaves queueCalls=1 where0 required; later foreign/refused listener increments calls; all are behavior assertions, not fixture errors.|Matching sentinel drains without any issued agent key; boot/later refusal zero queue consumption; human plugins/usage reads stay available; fresh sentinel check precedes each drain; sticky refusal never retries the management list.|
|
||||
|2 P2 namespace/checks|packages/bus/tests/p5-key-compatibility.test.mjs|Plain abcdefabcdef account native count at10 is ignored; no-model lookup returns proxy-key-refused below limit; empty checks wrongly perform metadata lookup; chief reset of plain account leaf refuses.|Below/at legacy quota, original account count/report with no proxy and unrelated proxy metadata; zero lookups for plain leaves or empty checks (legacy and daily); shared validated daily shape; daily model matching/report positive; old/new daily/plain/removal/reset human fence; malformed partial daily schema refuses.|
|
||||
|3 P2 nonblocking|packages/bus/tests/p5-background.test.mjs|The queue response is causally held; queue arrival plus one event-loop barrier leaves f.bus=null because503 startBroker awaits the poll. Startup assertion must fail before releasing the held response.|Ready/control/native key preflight/native usage/limit work completes while held; interval shares singleflight; explicit success/failure release updates availability; close of a held poll remains pending at4999ms and completes at the original5000ms virtual client deadline. No sleeps/deadline increase.|
|
||||
|
||||
The preserved24 whole files remain explicitly listed in whole-files.txt, plus the three new controls and the affected existing ModelKeys whole file (28 total). Current503-added cumulative-model fixture tests in token-limit/limit-checks/p5-key-context are corrected to legacy plain-account or accepted DAILY model semantics; their count/refusal/ownership assertions remain. All original09a847 base assertions/deadlines are retained; authorized usage inventory additions are unchanged.
|
||||
|
||||
Overlay sequence (isolated private copies only):
|
||||
1. Materialize Git503b91e56137482abef475bc3b1b72a64b0a329c in a private admitted runner root. Do not run product from this author worktree.
|
||||
2. Apply packet/baseline-controls.patch, which adds exactly the current three control files and fake fixture; it changes no production byte. This is the original503 baseline for all three first guards.
|
||||
3. Execute each control whole file under the admitted private gate-tool/native priority contract. Retain every genuine behavior RED.
|
||||
4. Apply packet/baseline-to-fixed.patch. It is the complete fixed source/test delta with the four already-installed controls removed from the patch to avoid reapplication. This must yield packet/source-tests.patch's exact fixed overlay on503.
|
||||
5. Rehash every fixed input, run the three controls then all28 current whole files with original budgets, collect native priority root/actual-child evidence, raw receipts/exit codes, actual consumed-source map and cleanup. Priority/setup failure stops, not retries.
|
||||
|
||||
Additional forensic snapshot: baselines/runtime-before-background-fix.mjs captures finding1+2-prepared runtime immediately before the finding3 source edit. It is evidence only; canonical baseline for replay is Git503 plus controls. No snapshot substitutes unobserved source controls for runtime evidence.
|
||||
@@ -1,34 +0,0 @@
|
||||
# Admitted-runner entry and native priority contract — NOT RUN / NOT ADMITTED
|
||||
|
||||
Worktree/source root (unchanged binding):
|
||||
`/home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f`
|
||||
|
||||
HEAD must remain `503b91e56137482abef475bc3b1b72a64b0a329c` until applicable runner GREEN. This packet is an UNCOMMITTED source/test overlay, not a new accepted product commit. Parent owns the dedicated1014 admission/profile and runtime execution. No full/browser/provider/namespace or scheduler change is part of this packet.
|
||||
|
||||
## Entry ownership and limitation
|
||||
|
||||
The actual diagnostic entry used in receipt07 was
|
||||
`agents/codex/work/queue-333/r1-repair/run-strict19.sh`, calling the private
|
||||
`run-priority.mjs` and `priority-guard.mjs` in that directory. Those exact source
|
||||
bytes are preserved as evidence. It is **NOT an admitted gate entry and must not
|
||||
be retried**: native drift was observed and Node --test's root did not execute
|
||||
its forwarded preload, so the direct-child handshake capture was incomplete.
|
||||
`run-light.sh` is likewise an old nice-only behavior runner, not a strict19 gate.
|
||||
|
||||
No new execution entry/profile on1014 has been admitted. The parent must name
|
||||
and pin its private gate-tool entry and the actual selected root before running.
|
||||
Do not substitute either old runner or the original503 scoped runner. Read-only
|
||||
R2 may examine this packet before runtime acceptance; it cannot admit a gate.
|
||||
|
||||
## Requirements for the parent's private gate-tool entry
|
||||
|
||||
1. Invoke only the exact whole-file list in the frozen packet, serial concurrency1. Preserve all existing test timeouts and budgets. Use a fresh mktemp private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG for each baseline/fixed pass; no real instance/auth/env/credential paths, provider traffic or host proxy.
|
||||
2. Establish native own-process priority19 in the actual gate-tool root before module execution: setPriority(0,19) and native readback. A shell's relative nice or inherited priority is not evidence. The observer/root must itself retain the required priority for the run; any setup refusal or observed drift is STOP/UNVERIFIED, never behavior RED.
|
||||
3. Establish the same own-process native preexec/set/readback in **every actual test child**, not only a preload forwarded to a Node test runner or an inert wrapper. The gate root must execute its own prelude, and each test child must execute its prelude before importing the tested modules. Do not add a no-op prelude that misses Node's --test parent. No retry/repeated renice or host-daemon modification around drift is permitted.
|
||||
4. Capture native getPriority(child.pid) from the direct parent before tested module execution and after tested module work while that child still exists; use a causal acknowledgement barrier rather than a timed race. Capture child self-readbacks before/after and on exit as well. Record pid/ppid, phase, actual priority, exit/signal and the source pin of every private helper. Both root and actual testchild evidence are required. A missing/ESRCH sample, missing handshake, setup failure or drift makes the pass unverified, independent of test assertion counts.
|
||||
5. Pin the gate helper path/hash/Gitblob, selected test root and applied overlay hash in each raw receipt. Resolve the baseline/fixed source manifests before execution. Record exact Node version and all consumed module/data inputs from the real admitted pass; the static map here is not execution provenance.
|
||||
6. Run the per-control baseline first guards against the preserved503 baseline plus the current controls-only overlay. Only the named behavior assertion failure with complete strict19 capture is intended RED. Missing imports, fixture/setup errors, timeout/priority failures are not RED. Then apply the complete fixed overlay and run each control and all28 listed whole files. Preserve output/exit statuses without normalizing raw whitespace. Recheck hashes after execution and collect cleanup proof.
|
||||
|
||||
Programmatic Node test-runner entry or a native preexec wrapper may implement
|
||||
these requirements, but the implementation and target profile remain the
|
||||
parent's admission decision. This document authorizes no workstation retry.
|
||||
@@ -1,43 +0,0 @@
|
||||
# P5 independent R1 response
|
||||
|
||||
Starting candidate: 503b91e56137482abef475bc3b1b72a64b0a329c.
|
||||
Original base:09a847edaa25b609bac7728ff83f224708a29399.
|
||||
Review: REVIEW-R1.md, copied without edits; SHA2567c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008.
|
||||
All findings preserved as CHANGES until fixes have actual RED/GREEN evidence.
|
||||
|
||||
Source verification:
|
||||
1. Confirmed unconditional client callback permits queue reads after ModelKeys sentinel refusal.
|
||||
2. Confirmed regex-only key classification changes valid legacy account limits and chief resets; host lookup also runs for zero checks. Accepted scope requires daily model quotas, not cumulative model namespace takeover. Repair will use the validated daily shape consistently and drop the invented cumulative model interpretation.
|
||||
3. Confirmed startup awaits proxyUsage.tick and may wait the existing management-client timeout for optional telemetry. Repair will supervise first poll in background with unchanged deadlines/singleflight/close.
|
||||
|
||||
Original candidate, runner, raw receipts and source pins remain unchanged. R1 repair evidence is separate in this directory. No independent approval/self-review, heavy/full/browser gate or deployment authority claimed.
|
||||
|
||||
Priority evidence correction (Mos1971): command text `nice -n19` is insufficient on this workstation (ananicy node16/bash-4). Earlier R1 receipts01–06 are behavior observations with priority unverified; no strict19 acceptance claim attaches to them. New bounded checks use OWN-process native setPriority(0,19) plus readback before modules and at beforeExit/exit, and wrapper native getPriority(child.pid) before/after the direct child. A setup failure, any observed drift or incomplete capture returns78 UNVERIFIED/STOP; it is never treated as intended RED or GREEN. No scheduler/daemon mutation, repeated renice, deadline change or retry around a priority refusal is authorized.
|
||||
|
||||
## Native priority STOP (receipt07)
|
||||
|
||||
Actual trace07-priority-native.jsonl: wrapper PID2643577 before=19, after=16; test PID2643590 before-modules=19, after-modules=16, exit=16. Six behavior assertions completed, but the test runner reports a file failure because priority guard changed exit status. This is **UNVERIFIED/STOP exit78**, not intended RED and not GREEN. Node --test forwarded --import to its test subprocess, so the direct test-runner parent did not execute that preload: the requested direct-child handshake/capture is also incomplete. No priority or provenance proof is inferred from command text or the six assertions. No further local test runs are authorized after this observed drift; no scheduler mutation or retry was attempted. Admitted runner verification is required. Source/regression preparation continues under the user's explicit fallback mandate.
|
||||
|
||||
## Finding 1 source response / priority-unverified behavior observations
|
||||
|
||||
Added ModelKeys.verifyIdentity(), serialized by the existing controller. It requires the existing ready state, performs a fresh sentinel-only management-list check, never issues an agent credential, never reconciles, and honors sticky proxy-open refusal. Collector now awaits client acquisition; the P5 runtime usage callback verifies that identity before returning its management client. Boot refusal and later failure retain the human surface, unavailable telemetry and value-free receipt, with zero queue drain. Matching sentinel requires no issued agent key.
|
||||
|
||||
Receipts01/02: actual behavior REDs under nice-relative priority, later reclassified priority-UNVERIFIED. Boot observed queue1 vs expected0; later refusal queue2 vs expected1; changed-listener predrain control likewise failed. Receipt03 recorded12/12 behavior passes after the fix (identity, proxy collector, native quota runtime files), also priority-UNVERIFIED. These are observations only, not strict19 acceptance. Current identity controls now await the initial poll's actual receipt to preserve the same assertions after the nonblocking startup change; current bytes have not run.
|
||||
|
||||
## Finding 2 source response / priority-unverified behavior observations
|
||||
|
||||
A shared pure isDailyModelQuota() validates key ID and the full daily {limit,since,reset,timeZone} leaf. Business schema, daily and cumulative checks, host metadata lookup and both old/new organization fences use it. Plain {limit,since} keys stay legacy account leaves regardless of twelve-hex spelling; token-limit matches/reports account only. Zero loaded checks returns before any model metadata lookup. Daily model changes, plain→daily, daily→plain/removal and reset remain human-only; plain legacy chief resets remain permitted. The invented cumulative model-key interpretation is removed, not moved into a new namespace.
|
||||
|
||||
Receipts04/05 captured actual legacy failures (lookup refusals, wrong account matching, empty checks, chief reset) under nice-relative priority. Receipt04 also contained a new fixture missing-system error; receipt05 corrects the fixture and demonstrates the actual chief-reset refusal. Receipt06 recorded6/6 behavior passes after source repair, priority-UNVERIFIED. Receipt07 later observed strict-priority drift and STOP. Candidate503-specific cumulative-model test fixtures are retargeted to accepted daily leaves with every enforcement assertion retained; the appended token-limit test now asserts legacy account semantics. Pre-P5/base assertions and deadlines remain unchanged. No post-STOP execution is claimed.
|
||||
|
||||
## Finding 3 source response / execution pending
|
||||
|
||||
Prepared p5-background.test.mjs with a queue response held open, explicit queue-arrival/event-loop barriers (no sleeps or racing deadlines), native readiness/control/key-preflight/usage/limit work while held, scheduled singleflight, success/failure release, and cleanup at the original5000ms management deadline using virtual timers. First guard is that f.bus is nonnull while the queue is still held; original503 awaits that held response and should fail this behavior assertion. These controls have NOT RUN locally, not RED/GREEN evidence.
|
||||
|
||||
Saved exact immediately-pre-fix runtime bytes in baselines/runtime-before-background-fix.mjs. Fixed runtime uses one supervised usageTick function for the initial call and later interval. The first call is background; the same collector singleflight and original close/pending/client deadline apply. Only P5 usage wiring/tick hunks changed; no launcher/session/harness/business route edits. Admitted runner must establish genuine priority-verified RED then GREEN on the pinned baseline/fixed overlays before any new product commit.
|
||||
|
||||
## Static packet handoff — no product commit
|
||||
|
||||
Per latest owner direction, HEAD remains original503 and all repairs stay UNCOMMITTED. No local tests or Node product execution followed receipt07 STOP, including no syntax-check substitute. New background controls and final current source bytes are pending execution. The packet contains the complete source/test diff from503 (including untracked controls/helper), controls-only baseline overlay, baseline→fixed remainder, exact baseline/fixed bytes with SHA256/size/Gitblob IDs, static module/dependency edges and full28-file list. Its input map is explicitly STATIC, not a fresh consumed-source observation. Genuine strict19 baseline RED/fixed GREEN and actual consumed-source capture must come from the admitted runner before any product commit. The parent may request new read-onlyR2 on these exact bytes before execution; this author issues no independent/self-review verdict.
|
||||
|
||||
Gate entry/root and root+actual-testchild native preexec/readback requirements are in GATE-ENTRY.md. Existing diagnostic drivers are preserved only as failed/incomplete priority evidence and are not authorized for retry. Dedicated1014 admission/profile and private gate-tool entry remain pending with the parent. Cleanup from every actual test run used private mktemp EXIT/test fixture cleanup. No scheduler, live proxy/account/credential/provider, P3 launcher/session/harness/business-route, queue, remote or landing state was changed.
|
||||
@@ -1,82 +0,0 @@
|
||||
# P5 row333 independent implementation review — Mos1966 / Mos1961
|
||||
|
||||
Verdict: **CHANGES**
|
||||
|
||||
Reviewer: independent Codex review sub-agent; not the implementation author.
|
||||
Implementation author: Codex builder, isolated worktree `/home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f`.
|
||||
Git-recorded author/committer: Jason Woltje; commit subject `feat: add optional proxy usage and human model-key quotas (row333)`.
|
||||
Candidate: `503b91e56137482abef475bc3b1b72a64b0a329c`.
|
||||
Base: `09a847edaa25b609bac7728ff83f224708a29399`.
|
||||
Review time: 2026-10-26 23:03 UTC (2026-10-26 18:03 CDT).
|
||||
|
||||
Reviewed the exact candidate/base Git objects, all 31 changed package files, and supporting callers/contracts. The isolated worktree HEAD equals the full candidate and its status was clean. The parent's integrated row334 product was not substituted for this candidate. Requirements are accepted P5 in `docs/plans/2026-10-24_model-proxy-rows.md`, design D18–D20 with the mos-1600 per-key/no-raw-upstream correction, and the review assignment's compatibility and nonblocking constraints.
|
||||
|
||||
## Findings
|
||||
|
||||
### 1. P1 — Do not drain a listener after its instance identity was refused
|
||||
|
||||
Primary location: candidate `packages/bus/src/runtime.mjs:387–389`; destructive read at `packages/bus/src/proxy-usage.mjs:31–33`.
|
||||
|
||||
Source trigger: enable `plugins.usage: "cliproxy-queue"`, point the instance at a loopback management listener that accepts its management authentication but lacks this config directory's sentinel (for example a different instance with a reused management key). `ModelKeys.reconcile()` checks the sentinel before modifying the list (`model-keys.mjs:80–84`) and throws `proxy-open`; runtime intentionally catches that refusal to retain the control surface (`runtime.mjs:326–327`). Nevertheless the new collector receives `client: () => modelProxyClient` unconditionally and performs the queue GET at startup and on later ticks. It never consults the controller's identity/readiness refusal.
|
||||
|
||||
The GET consumes the other listener's queue. Resolving local owners *after* `module.read()` and dropping/logging unknown IDs cannot undo that consumption. The local Store writer lock prevents two local writers, but does not establish ownership of a remote loopback listener. This is a new P5 side effect after a fail-closed refusal; it is not a request to change P2's existing decision to keep human controls available.
|
||||
|
||||
Smallest remedy: fence the collector's management-client access behind verified identity for this instance, honoring boot and subsequent sentinel refusals before any queue GET. Keep an unavailable telemetry state and value-free receipt when verification is absent; do not retry around `proxy-open`. This must not require a particular agent to have an issued key merely to establish instance identity.
|
||||
|
||||
Required regression evidence: a fake listener accepts management auth and returns a valid foreign sentinel/list, while its queue records/drains calls. With telemetry enabled, assert `proxy-open`, zero queue requests/consumption across startup and scheduled ticks, and an available human/control surface. Add the matching-instance positive case and a refusal after a previously successful identity check. Current `p5-runtime.test.mjs` uses the correct sentinel and enables telemetry only after startup; `proxy-usage.test.mjs` bypasses this host identity boundary entirely.
|
||||
|
||||
### 2. P2 — Twelve-hex legacy account names lose their quota, reset, and no-check behavior
|
||||
|
||||
Primary location: candidate `packages/plugins/limit-check/token-limit/index.mjs:33–35`; related new gates at `packages/bus/src/limits.mjs:126–136` and `packages/business/src/organization.mjs:85–91`.
|
||||
|
||||
Concrete legacy input: `launch.account.name = "abcdefabcdef"`, an ordinary existing `tokens.keys.abcdefabcdef = { limit: 10, since: <canonical timestamp> }`, and native records/subject whose `account` is `abcdefabcdef`. No proxy or model record is needed by this previously valid configuration. `ID_PATTERN` accepts this account name (`business/src/vocabulary.mjs:206`; `launch.mjs:85–92`), and the base token-limit matched every keys leaf against `account` (`base token-limit/index.mjs:31–34`). Nothing in the accepted P5 brief reserves existing twelve-hex account names.
|
||||
|
||||
The candidate changes this plain leaf to match `modelKeyId` solely because its name matches a regex. Consequently:
|
||||
|
||||
- With `token-limit` enabled and no proxy/model record, `createLimits` returns `proxy-key-refused` even below the account limit, before asking the check. At the plug-in level, known account records at the limit are instead ignored and its count becomes zero.
|
||||
- With no limit checks configured, `state().checks` is `[]`, so it passes the `!st.checks` guard. The same lookup still runs before the empty loop and returns `proxy-key-refused`. The base returned `allow:true` / `stop:false` here. Thus an unused legacy limit now blocks launches/stops turns even though enforcement is switched off.
|
||||
- With proxy metadata present, the resolved model ID generally differs from the account name; the account quota silently stops matching its original records. The new organization fence also prevents the chief's previously permitted reset of this plain account leaf.
|
||||
|
||||
These outcomes follow directly from the branches above, independently of the builder's test counts. They are introduced regressions, not Mos1864 baseline defects. The same reasoning applies to the previously examined valid name `abcdef012345`; the parent's additional `abcdefabcdef` example confirms the ambiguity without relying on a digit-leading name.
|
||||
|
||||
Smallest contract-preserving remedy within accepted P5: distinguish the genuinely new daily model-key leaf by its validated `reset`/`timeZone` shape, retain ordinary `{limit,since}` keys leaves as legacy account limits, and use that same classification consistently in the host lookup, matching, reports and both organization fences (including old-to-new/removal transitions). Preserve the empty-check path before performing metadata lookup. P5 requires daily model-key quotas; newly added cumulative model-key support must not silently take over the existing account namespace. If cumulative model-key quotas are retained, they need an unambiguous separately authorized representation.
|
||||
|
||||
Required regression evidence: cover `abcdefabcdef` with plain account limits, no proxy/model record, below/at limit, original account report count and chief reset; repeat with proxy metadata whose ID differs. Cover no configured checks with that legacy leaf and with a new daily model-key leaf: preserve the established no-check result without resolving model metadata. Retain positive daily per-key enforcement, current/retiring native lookup, and human-only changes/removals/resets for actual model-key daily quotas. Existing P5 tests cover an invented cumulative model-key interpretation and a daily key, but not this legacy collision or the empty-check branch.
|
||||
|
||||
### 3. P2 — Optional telemetry adds a blocking startup dependency
|
||||
|
||||
Primary location: candidate `packages/bus/src/runtime.mjs:865–867`.
|
||||
|
||||
Source trigger: correct sentinel/reconciliation, telemetry enabled at boot, and a queue endpoint that stalls while other management operations work. The initial `await proxyUsage.tick()` waits for that queue read, up to the existing five-second client deadline (`model-proxy/src/client.mjs:10,45`). The process waits for `startBroker()` before sending its ready answer and launch capabilities (`bus/src/process.mjs:147–152`). Thus optional telemetry delays native readiness/launch admission even though it has no quota authority. Later timer ticks are independent of native requests; the startup await is the exception.
|
||||
|
||||
Smallest remedy: start the first poll in the same supervised background path as subsequent ticks, preserving single-flight handling, value-free errors and close cleanup. Do not increase any existing deadline.
|
||||
|
||||
Required regression evidence: hold a fake queue response open while allowing required reconcile requests, prove startup/native readiness completes before releasing the queue, and exercise native usage/limit work while a poll is outstanding. Then release/fail the response and verify availability, no duplicate drain and bounded cleanup. Current whole-file receipts contain no such slow-queue readiness test.
|
||||
|
||||
## Independent evidence checks
|
||||
|
||||
Performed read-only Git/filesystem/hash analysis, not product execution:
|
||||
|
||||
- `source-inputs.sha256` SHA-256 is exactly `b4662dcafb2aeb27a06e5dbd3b9d0b6d184e8624e344fed351ff20e3b255951b`. All **202** listed file hashes match candidate Git blobs and the pinned isolated tree, with zero mismatches. The 944 raw JSONL entries contain exactly 202 distinct path/hash pairs, exactly equal to the manifest; no path has multiple traced hashes.
|
||||
- All **31** changed package paths exactly equal `candidate-sourcepaths.txt`; every entry in `candidate-sourcehashes.sha256` matches both sources. That manifest's SHA-256 is `b1457ec57c0fb695f05a08ba20b420820be5f32cac2b77ac5ea20b02115153e2`.
|
||||
- All **25** entries in `receipts.sha256` match candidate blobs and isolated-tree bytes. Receipt-manifest SHA-256: `a8b91660ada571eab9c0328b74407517ec63e1ff56172302acec1d347253a810`. Raw source-trace SHA-256: `9c16aa4b8e6d81aa5b9867fec5e0890b22e90db5c307da55badfcfa9f240aef1`.
|
||||
- The scoped runner explicitly names **24 whole test files**, uses `nice -n 19`, `--test-concurrency=1`, and private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG with cleanup. Its SHA-256 is `c8a2bf4539bffe38f3198308fd60e9c1ad338841b406af160ab0739c15394290`. These are verified runner bytes and recorded output, not independent observation of the original processes' environment.
|
||||
- Receipt24 records **174 tests, 174 pass, 0 fail/cancelled/skipped/todo**, SHA-256 `3358af061c35d42b00d5ee1e001939534c5e7563d4f5418ea85431605d0b9f6d`. This remains builder scoped evidence, not an independent test run, full gate or browser gate.
|
||||
|
||||
RED history is retained as RED. Receipt16 records the upstream-value mutant with **11/15 passing and four failing tests**: the client exposes the raw account value, while collector validation refuses it and downstream expectations fail. Receipt17 records restored **15/15**. Final client bytes hash to `f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441`, matching the documented restoration hash and final source pins. The receipts do not contain a separately captured pre/post backup or mutant patch hash, so byte-identical restoration at that historical instant is documented by the builder rather than independently replayed here.
|
||||
|
||||
Receipt18 is **169/170**, with the exact existing `REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check` assertion failing at `limit-stop.test.mjs:61` because `run` was added to the original second subject argument. The candidate keeps that argument's shape and puts `{run}` in the private third context. The entire original limit-stop file is byte-identical to base. Receipt19 records **170/170** after that correction. Receipt20 is a genuine **2/3** RED for the supplied modelKeyId fallback; receipt21 is **15/15** after its removal. Receipt22 records **173/173**. Receipt23 is a genuine **3/4** RED for missing native context; receipt24 records **174/174** after the explicit context refusal. These were builder development REDs, not prior independent review findings, and are not relabelled GREEN. Receipt05 also remains a syntax-error RED despite its filename; receipts12/13 remain failed runtime-fixture runs.
|
||||
|
||||
All modified pre-existing test files other than the two authorized inventory updates retain their entire base bytes as an unchanged prefix. The kinds/loader edits are the strictly additive `usage`/`usage:[]` expected inventories; no old assertion or deadline was removed or weakened.
|
||||
|
||||
## Other source conclusions and limits
|
||||
|
||||
Telemetry source rows are excluded at the start of `turnRecords`, before native totals and quota input. The collector validates and whitelists persisted fields, uses hashed client/upstream identities, retains only safe failure metadata, serializes concurrent ticks, and routes current/retiring ownership from credential status. Malformed/unknown/oversize/non-finite/unsafe counts cannot flow through the new queue client as raw values into store, error, audit or Console fields: the queue operation reuses fixed loopback GET, count=100, original response cap/deadline and value-free errors/receipts. No second queue consumer was found in the product sources; finding 1 concerns foreign-listener identity rather than local double counting.
|
||||
|
||||
Native model-key authority comes from the host's run map and credential metadata, not a JSON-supplied key ID. Lookup rejects missing/duplicate owners, foreign business/instance/run, missing retained generations and ambiguous IDs. The broker's private context is derived from its authenticated session; the public subject drops supplied run/modelKeyId fields. The new usage and model-quota fences run before validation and again against serialized bytes, compare against the old human, and reject tester/agent identities even when names collide. Finding 2 concerns which leaves those otherwise fail-closed fences classify.
|
||||
|
||||
Polling is absent by default, defaults to 15 seconds when enabled, validates integer 1..59, and is exposed through the exact human `plugins.set` argument contract. Console native key rows and optional proxy-reported account counts are separated and labelled; telemetry is explicitly described as incomplete and non-enforcing. Broker imports are unchanged, kinds remains import-free, and no host management implementation was added to the pure Broker/sandbox import closure. No P3 launcher/session/harness/business-routing files changed.
|
||||
|
||||
No tests, Node/product runtime, HTTP, browser, provider, real instance config, credential files or live proxy paths were run/read. Hash checking used repository files only. No code, tests, helpers, queue, session/build logs, issues, posts, pushes, commits, merges or live state were changed; this report is the only authorized write. Static analysis establishes the reported branch behavior; the suggested regression cases remain to be executed by the authorized builder/gate owner. Hash equality verifies the captured inputs/receipts, not completeness of uninstrumented reads or independent execution provenance.
|
||||
|
||||
These three findings are in the candidate delta. No pre-existing issue is being promoted to a new landing blocker; any separately identified baseline defect belongs under Mos1864 unless a required gate is RED. #662 / 72f77815 and #657/#658 remain excluded/backlog; #267/#289 are outside the 10-27 slice but remain in full scope. The #660 full-gate target is not admitted by this review. No landing authority or full/browser/combined-gate approval is implied.
|
||||
@@ -1,960 +0,0 @@
|
||||
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { Store } from './store.mjs';
|
||||
import * as projectModule from '../../project/src/index.mjs';
|
||||
import * as libraryModule from '../../library/src/index.mjs';
|
||||
import { Broker, BusError, LIBRARY_FETCH_FIX } from './broker.mjs';
|
||||
import { Credentials } from './credentials.mjs';
|
||||
import { serve } from './server.mjs';
|
||||
import { launchSettings } from '../../business/src/launch-settings.mjs';
|
||||
import { readSessions, sessionsFile, stopSession } from '../../seat/src/session.mjs';
|
||||
import { compactionCount, storeDir } from '../../seat/src/compactions.mjs';
|
||||
import { publishRemote, workingRepo, WorkingError } from '../../seat/src/working.mjs';
|
||||
import { createLoader, hasModule } from '../../plugins/src/loader.mjs';
|
||||
import { pluginSettings } from '../../business/src/plugin-settings.mjs';
|
||||
import { loadManagementClient } from '../../model-proxy/src/client.mjs';
|
||||
import { ProxyPage } from './proxy-page.mjs';
|
||||
import { sha256 } from '../../model-proxy/src/common.mjs';
|
||||
import { initializeProxy } from '../../model-proxy/src/settings.mjs';
|
||||
import { ModelKeys, modelOrganization, stopModelRuns, MODEL_STOP_TIMEOUT_MS } from './model-keys.mjs';
|
||||
import { instanceSettings } from '../../business/src/instance-settings.mjs';
|
||||
import { organizationWriter, OrganizationError, setReplyLimits } from '../../business/src/organization.mjs';
|
||||
import { credentialVerbs } from './credential-verbs.mjs';
|
||||
import { loadBusiness } from '../../business/src/business.mjs';
|
||||
import { loadRole } from '../../business/src/role.mjs';
|
||||
import { resolveInstance } from '../../business/src/resolve.mjs';
|
||||
import { canonicalJson } from '../../business/src/util.mjs';
|
||||
import { busBusiness } from './business.mjs';
|
||||
import { webService } from './web.mjs';
|
||||
import { hostExecutor, sweepRunDir } from './host-run.mjs';
|
||||
import { grantKeys, hostGrant, hostReference, sweepHostKeys } from './host-grant.mjs';
|
||||
import { giteaGrant, giteaKeys, giteaStart, giteaReference } from './gitea-grant.mjs';
|
||||
import { verifyPrincipal } from './principal.mjs';
|
||||
import { loadAccess } from '../../business/src/access.mjs';
|
||||
import { inspectInterpreter, recordInterpreterStart } from './interpreter.mjs';
|
||||
import { createPeerReader } from './peercred.mjs';
|
||||
import { createUsage } from './usage.mjs';
|
||||
import { createProxyUsage } from './proxy-usage.mjs';
|
||||
import { createLimits, modelUsageKey } from './limits.mjs';
|
||||
import { createProcessing } from '../../processing-control/src/coordinator.mjs';
|
||||
import { discordProcessingHooks } from '../../discord/src/processing.mjs';
|
||||
import { createContainerStopper } from '../../processing-control/src/containers.mjs';
|
||||
|
||||
// Row 194 (D3): the verbs the instance writer commits, whose answers carry restart.
|
||||
const INSTANCE_VERBS = new Set(['instances.set', 'veto.set', 'instance.hire', 'instance.fire']);
|
||||
// FED R4 (#1801, design 3.7): the revocation timer's period.
|
||||
export const ACCESS_SWEEP_MS = 30_000;
|
||||
// Trusted host API. S1 supplies resolved definitions, S6 supplies launch records and ends them.
|
||||
// Human limits writes use the shared organization writer behind the verified transport.
|
||||
// `tasks` is S3's adapter factory: ({broker, credentials, businesses}) => {handle, timeout, close}.
|
||||
// REQ-HARN-2, REQ-PLUG-2 (decision 0b81b0c5): one web service per business. Its search source is
|
||||
// the "search-source" plug-in the business's organization file switches on: searxng-url (the
|
||||
// business var web.searxng) or searxng-bundled. With none, web.search refuses "not configured" and
|
||||
// web.fetch still works. A plug-in that refuses to load is logged and leaves search off; it never
|
||||
// stops the broker. Under harness-builtin the harness serves web itself, so the broker gets no
|
||||
// service and refuses the web verbs.
|
||||
export async function webServices(businesses, { log = (e) => process.stderr.write(`plugins: ${JSON.stringify(e)}\n`), deps } = {}) {
|
||||
const services = new Map();
|
||||
for (const [name, b] of Object.entries(businesses)) {
|
||||
const loader = createLoader({ log });
|
||||
await loader.load(b.plugins ?? {});
|
||||
const [source] = loader.modules('search-source');
|
||||
// "harness-builtin" is served by the harness itself, not the broker: no broker web verbs.
|
||||
if (loader.loaded()['search-source'][0] === 'harness-builtin') continue;
|
||||
// The module takes the business var web.searxng; "searxng-bundled" ignores it.
|
||||
const settings = { searxng: b.vars?.['web.searxng'] };
|
||||
const search = source ? { search: async (query, opts) => source.search(settings, query, deps, opts) } : null;
|
||||
services.set(name, webService({ search, deps }));
|
||||
}
|
||||
return services;
|
||||
}
|
||||
// Row 65 (REQ-PLUG-2): the thinking levels each harness module in this tree applies, for the route
|
||||
// checks a write runs, which are synchronous. A module that doesn't load, or answers anything but a
|
||||
// list of names, answers null, which refuses the write. The tree is pinned, so a module changes only
|
||||
// with a re-pin, and a re-pin restarts the bus.
|
||||
export async function harnessLevels({ log = (e) => process.stderr.write(`plugins: ${JSON.stringify(e)}\n`) } = {}) {
|
||||
const levels = new Map();
|
||||
let names = [];
|
||||
try {
|
||||
names = readdirSync(fileURLToPath(new URL('../../plugins/harness/', import.meta.url))).filter((name) => hasModule('harness', name));
|
||||
} catch (e) {
|
||||
log({ event: 'harness-levels-unread', message: e.message });
|
||||
}
|
||||
for (const name of names) {
|
||||
const loader = createLoader({ log });
|
||||
if ((await loader.load({ harness: [name] })).refused.length) continue;
|
||||
try {
|
||||
const list = loader.modules('harness')[0].levels();
|
||||
if (Array.isArray(list) && list.every((level) => typeof level === 'string')) levels.set(name, Object.freeze([...list]));
|
||||
} catch (e) {
|
||||
log({ event: 'harness-levels-failed', name, message: e.message });
|
||||
}
|
||||
}
|
||||
return (name) => levels.get(name) ?? null;
|
||||
}
|
||||
// Row 224 C2-05b: a host-only adapter. A failed fetch keeps serving immutable old
|
||||
// objects, as C2-03a requires; no caller may select a repo, commit or sync --accept.
|
||||
export function createLibraryLookup({ dataRoot, sync, now = () => Date.now() }) {
|
||||
const methods = { find: libraryModule.find, get: libraryModule.get, search: libraryModule.search,
|
||||
manuscript: libraryModule.manuscript, universeInfo: libraryModule.universeInfo };
|
||||
return async (context, { method, args, authorize }) => {
|
||||
if (!Object.hasOwn(methods, method)) throw new libraryModule.LibraryError('query-argument-invalid', 'unknown lookup');
|
||||
authorize();
|
||||
const source = { ...context, dataRoot };
|
||||
let state = await libraryModule.libraryStatus(source);
|
||||
authorize();
|
||||
// sage-2819 / dewey-0852: failed attempts also pace inline retries. Otherwise an
|
||||
// outage makes every lookup refetch while lastFetch remains old or null.
|
||||
const recentAttempt = Math.max(state.lastFetch === null ? -Infinity : Date.parse(state.lastFetch),
|
||||
state.lastError === null ? -Infinity : Date.parse(state.lastError.at));
|
||||
const age = now() - recentAttempt;
|
||||
if (age > libraryModule.SYNC_INTERVAL_MS || age < 0) {
|
||||
try { await sync(source); }
|
||||
catch (error) {
|
||||
// A timer may already be fetching this mirror. Its current served state is still safe.
|
||||
if (!(error instanceof libraryModule.LibraryError) || error.code !== 'library-sync-busy') throw error;
|
||||
}
|
||||
authorize();
|
||||
state = await libraryModule.libraryStatus(source);
|
||||
}
|
||||
if (!state.served) throw new libraryModule.LibraryError('library-commit', 'library has never been synced');
|
||||
authorize();
|
||||
return methods[method]({ repo: libraryModule.mirrorPath(source), commit: state.served,
|
||||
mapping: libraryModule.checkMapping(context.business.projects[context.project]) }, args);
|
||||
};
|
||||
}
|
||||
|
||||
// B1: discovery is evidence of a process, never authority to stop it. Keep this
|
||||
// host-only inventory across the launcher's Registry[] recovery gap and endLaunch.
|
||||
// A failed boot read cannot be repaired by a later empty registry: that would lose
|
||||
// the very prior runs whose existence this inventory must establish.
|
||||
function modelRunInventory(dataRoot, bound, credentials) {
|
||||
const known = new Map(), terminal = new Map(), validated = new Map();
|
||||
const refuse = () => { throw new BusError('proxy-stop-failed'); };
|
||||
const same = (a, b) => ['business', 'role', 'run', 'pid', 'startTime', 'runnerPid', 'runnerStartTime', 'keyId'].every(k => a[k] === b[k]);
|
||||
const shape = s => {
|
||||
if (!s || ['business', 'instance', 'run'].some(k => typeof s[k] !== 'string' || !s[k])
|
||||
|| ['pid', 'runnerPid'].some(k => !Number.isSafeInteger(s[k]) || s[k] < 2)
|
||||
|| ['startTime', 'runnerStartTime'].some(k => typeof s[k] !== 'string' || !/^\d+$/.test(s[k]))
|
||||
|| (s.modelKeyId !== undefined && (typeof s.modelKeyId !== 'string' || !/^[a-f0-9]{12}$/.test(s.modelKeyId)))) refuse();
|
||||
return { business: s.business, role: s.instance, instance: s.business + '/' + s.instance,
|
||||
run: s.run, pid: s.pid, startTime: s.startTime, runnerPid: s.runnerPid,
|
||||
runnerStartTime: s.runnerStartTime, keyId: s.modelKeyId };
|
||||
};
|
||||
const refresh = () => {
|
||||
const file = sessionsFile(dataRoot), stat = lstatSync(file);
|
||||
if (!stat.isFile() || stat.isSymbolicLink()) refuse();
|
||||
const entries = readSessions(dataRoot).map(shape), seen = new Set();
|
||||
const after = lstatSync(file);
|
||||
if (!['dev', 'ino', 'size', 'mtimeMs', 'ctimeMs'].every(k => stat[k] === after[k])) refuse();
|
||||
// Validate the whole snapshot before merging any of it. Missing entries do
|
||||
// not erase known identities; the host may have just rewritten Registry[].
|
||||
for (const r of entries) {
|
||||
const key = r.business + ':' + r.run;
|
||||
if (seen.has(key) || (known.has(key) && !same(known.get(key), r))) refuse();
|
||||
seen.add(key);
|
||||
}
|
||||
for (const r of entries) known.set(r.business + ':' + r.run, r);
|
||||
};
|
||||
let bootChecked = false;
|
||||
try { refresh(); bootChecked = true; } catch { /* hold retirement, not the human/control surface */ }
|
||||
// startTimeOf/live alone conflate absence and read errors. Only a missing proc
|
||||
// directory, or a zombie with the SAME recorded start ticks, confirms an exit.
|
||||
const liveIdentity = (pid, ticks, proof, part) => {
|
||||
if (proof[part]) return false;
|
||||
let raw;
|
||||
try { raw = readFileSync(`/proc/${pid}/stat`, 'utf8'); }
|
||||
catch (error) {
|
||||
if (error.code !== 'ENOENT') refuse();
|
||||
try { lstatSync(`/proc/${pid}`); } catch (missing) { if (missing.code === 'ENOENT') { proof[part] = true; return false; } }
|
||||
refuse();
|
||||
}
|
||||
const fields = raw.slice(raw.lastIndexOf(')') + 2).trim().split(/\s+/);
|
||||
if (!/^[A-Z]$/.test(fields[0]) || !/^\d+$/.test(fields[19]) || fields[19] !== ticks) refuse();
|
||||
if (fields[0] === 'Z') { proof[part] = true; return false; }
|
||||
return true;
|
||||
};
|
||||
const runs = instance => {
|
||||
try {
|
||||
if (!bootChecked) refuse();
|
||||
refresh();
|
||||
const live = [], checked = [];
|
||||
for (const r of known.values()) {
|
||||
if (r.instance !== instance) continue;
|
||||
const key = r.business + ':' + r.run;
|
||||
const proof = terminal.get(key) ?? { outer: false, runner: false };
|
||||
terminal.set(key, proof);
|
||||
let associated = false;
|
||||
if (!proof.outer || !proof.runner) {
|
||||
const record = credentials.modelRecord(instance);
|
||||
associated = !!record && [record.keyId, ...record.retiring.map(k => k.keyId)].includes(r.keyId);
|
||||
const prior = validated.get(key);
|
||||
if (!associated && (!prior || !same(prior, r))) refuse();
|
||||
}
|
||||
const outerLive = liveIdentity(r.pid, r.startTime, proof, 'outer'), runnerLive = liveIdentity(r.runnerPid, r.runnerStartTime, proof, 'runner');
|
||||
// Never interpret an unknown/wrong key on a surviving prior run as no
|
||||
// old-key users. A confirmed exit may be retired without key guessing.
|
||||
if (outerLive || runnerLive) {
|
||||
// Provenance permits strict exit confirmation, NEVER filtering away a
|
||||
// surviving run whose model-key association has disappeared.
|
||||
if (!associated) refuse();
|
||||
const current = bound.get(r.business + ':' + r.run);
|
||||
if (current && (current.instance !== r.instance || current.keyId !== r.keyId
|
||||
|| current.pid !== r.pid || current.startTime !== r.startTime)) refuse();
|
||||
live.push(r);
|
||||
}
|
||||
if (associated && (outerLive || runnerLive)) checked.push(r);
|
||||
}
|
||||
// A newly bound launch whose registry publication has not happened is
|
||||
// uncertain, not absent. Do not grant retirement through that startup gap.
|
||||
for (const r of bound.values()) if (r.instance === instance && !known.has(r.business + ':' + r.run)) refuse();
|
||||
// Commit ONLY after the entire same-instance view passed both identities,
|
||||
// live binding consistency, later known entries and unpublished bindings.
|
||||
// Existing M1 terminal bits remain independently monotonic and unchanged.
|
||||
for (const r of checked) validated.set(r.business + ':' + r.run, { ...r });
|
||||
return live;
|
||||
} catch { refuse(); }
|
||||
};
|
||||
return {
|
||||
runs,
|
||||
authorizeStop(requests) {
|
||||
for (const r of requests) {
|
||||
const current = bound.get(r.business + ':' + r.run);
|
||||
if (!current || current.instance !== r.instance || current.keyId !== r.keyId
|
||||
|| current.pid !== r.pid || current.startTime !== r.startTime) refuse();
|
||||
if (!runs(r.instance).some(found => same(found, r))) refuse();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function startBroker({
|
||||
dataRoot,
|
||||
businesses,
|
||||
launches = [],
|
||||
readers = [],
|
||||
repoRoots = [],
|
||||
tasks = null,
|
||||
organization = null,
|
||||
// Row 199: the tests' scratch CA for publish's git (`-c http.sslCAInfo=...`). process.mjs drops
|
||||
// it from the boot config, so only an in-process caller sets it.
|
||||
publishTls = [],
|
||||
// C2-03a: the tests' stand-in for syncCommand, a shorter timer and a scratch config dir for the
|
||||
// slot, { command, intervalMs, configDir }. A boot config is JSON and can't carry a function, so
|
||||
// a librarySync without one is refused.
|
||||
librarySync = null,
|
||||
// FED R3 (#414): the access file and its loader context, { file, context } (R1's loadAccess).
|
||||
// Without it no user binds. R6 and R8 pass it; the live boot config doesn't yet. FED R4 (#1801):
|
||||
// intervalMs, the revocation timer's period (design 3.7, 30 s), in-process only like librarySync's.
|
||||
access = null,
|
||||
// Row 252 (#1753, design section 2): the checked console.sso subjects, [{provider, iss, sub}], each an
|
||||
// owner of the business (Webby N1). The boot config carries them; no socket verb sets them. Empty, no
|
||||
// Console owner binds and the terminal owner is unchanged.
|
||||
consoleOwners = [],
|
||||
// P1 validated sidecar from the trusted host; never a socket request setting.
|
||||
proxy = null,
|
||||
}) {
|
||||
if (!Array.isArray(consoleOwners) || consoleOwners.length > 512 || consoleOwners.some((o) => o === null || typeof o !== 'object' || Array.isArray(o) ||
|
||||
Object.keys(o).length !== 3 || ['provider', 'iss', 'sub'].some((k) => typeof o[k] !== 'string' || !o[k] || o[k].length > 512)))
|
||||
throw new BusError('invalid-host-request');
|
||||
const owners = Object.freeze(consoleOwners.map((o) => Object.freeze({ provider: o.provider, iss: o.iss, sub: o.sub })));
|
||||
if (access !== null && (typeof access?.file !== 'string' || access.context === null || typeof access.context !== 'object'
|
||||
|| (Object.hasOwn(access, 'intervalMs') && !(Number.isSafeInteger(access.intervalMs) && access.intervalMs > 0))))
|
||||
throw new BusError('invalid-host-request');
|
||||
if (librarySync !== null && (typeof librarySync?.command !== 'function'
|
||||
|| (Object.hasOwn(librarySync, 'intervalMs') && !(Number.isSafeInteger(librarySync.intervalMs) && librarySync.intervalMs > 0))
|
||||
|| (Object.hasOwn(librarySync, 'configDir') && typeof librarySync.configDir !== 'string')))
|
||||
throw new BusError('invalid-host-request');
|
||||
let modelProxyClient = null, proxyPage = null, proxyUsage = null, usageTimer = null;
|
||||
let modelKeys = null, modelTimer = null, modelSweep = null;
|
||||
const modelRuns = new Map();
|
||||
let store, credentials, server, adapter, processing, syncTimer = null, syncPass = null, accessTimer = null;
|
||||
try {
|
||||
const proxyReceipt = entry => process.stderr.write(`model-proxy: ${JSON.stringify(entry)}\n`);
|
||||
const references = {};
|
||||
for (const [business, b] of Object.entries(businesses)) {
|
||||
for (const [role, r] of Object.entries(b.roles))
|
||||
if (r.credentials) references[business + '/' + role] = r.credentials;
|
||||
if (b.tracker?.sync?.credentials) references[business + '/@sync'] = b.tracker.sync.credentials;
|
||||
}
|
||||
const protectedRoots = [
|
||||
fileURLToPath(new URL('../../../', import.meta.url)),
|
||||
...repoRoots,
|
||||
...Object.values(businesses).flatMap((b) => Object.values(b.projects ?? {}).filter(p => p.kind !== 'library').map((p) => p.root)),
|
||||
];
|
||||
// Row 199 (#1697, design D1): the per-agent store is <configDir>/secrets/agents.
|
||||
const storeRoot = organization ? join(organization.dir, 'secrets', 'agents') : null;
|
||||
store = new Store(dataRoot);
|
||||
// Store's writer lock admits one bus per data root before it holds the management client.
|
||||
if (proxy) {
|
||||
if (!organization) throw new BusError('not-configured');
|
||||
modelProxyClient = await loadManagementClient({ configDir: organization.dir, proxy, receipt: proxyReceipt });
|
||||
}
|
||||
|
||||
// Row 234 (#1740, r6 X4 third bullet): each host grant record gives its agent a store reference to
|
||||
// host.<id>, so a restart finds the keys the grant executor wrote. The loader refuses host.<id> in a
|
||||
// role's credentials, so these never meet a business-file reference.
|
||||
const granted = new Set();
|
||||
for (const g of store.all('SELECT business, agent, host, rotate_by FROM host_grants ORDER BY business, agent, host')) {
|
||||
granted.add(g.business + '/' + g.agent + '/' + g.host);
|
||||
if (!Object.hasOwn(businesses, g.business)) continue;
|
||||
const refs = (references[g.business + '/' + g.agent] = { ...(references[g.business + '/' + g.agent] ?? {}) });
|
||||
refs['host.' + g.host] = hostReference(storeRoot, g.business, g.agent, g.host, g.rotate_by);
|
||||
}
|
||||
// Row 235 (r6 section 6, N1): a host.<id> key file with no record goes before Credentials loads.
|
||||
for (const entry of sweepHostKeys(storeRoot, Object.keys(businesses), granted))
|
||||
process.stderr.write(`hosts: ${JSON.stringify({ event: 'host-key-swept', ...entry })}\n`);
|
||||
// Row 236 (#1742, #436b r5 section 5): each gitea grant record gives its agent a store reference to
|
||||
// gitea, and `held` names the files memory must not load until reconcile or a revoke.
|
||||
const { held } = storeRoot ? giteaStart(store, storeRoot, businesses, references) : { held: [] };
|
||||
credentials = new Credentials({ references, repoRoots: protectedRoots, dataRoot, storeRoot, held,
|
||||
modelAgents: proxy ? Object.entries(businesses).flatMap(([id, b]) => Object.keys(b.roles).map(role => id + '/' + role)) : [] });
|
||||
if (proxy) {
|
||||
const inventory = modelRunInventory(dataRoot, modelRuns, credentials);
|
||||
modelKeys = new ModelKeys({ credentials, client: modelProxyClient, configDir: organization.dir,
|
||||
baseUrl: `http://127.0.0.1:${proxy.port}`, receipt: proxyReceipt, rotateGraceMinutes: proxy.rotateGraceMinutes ?? 120,
|
||||
runs: inventory.runs,
|
||||
stopRuns: async runs => {
|
||||
inventory.authorizeStop(runs);
|
||||
await stopModelRuns({ runs, sessions: () => readSessions(dataRoot), stop: run => stopSession(dataRoot, run, { timeoutMs: MODEL_STOP_TIMEOUT_MS }), receipt: proxyReceipt });
|
||||
for (const r of runs) {
|
||||
if (inventory.runs(r.instance).some(found => found.run === r.run)) throw new BusError('proxy-stop-failed');
|
||||
}
|
||||
for (const r of runs) modelRuns.delete(r.business + ':' + r.run);
|
||||
} });
|
||||
// Keep the control/human surface available, but refuse every launch on failed reconcile.
|
||||
try { await modelKeys.reconcile(); } catch (error) { proxyReceipt({ action: 'proxy.boot-refused', code: error.code }); }
|
||||
}
|
||||
const configureProxyPage = () => {
|
||||
proxyPage = new ProxyPage({ client: modelProxyClient, instanceTag: sha256(organization.dir).slice(0, 12),
|
||||
// P2 supplies the model metadata; only the matching business's record
|
||||
// participates in this owner view. No credential value is read here.
|
||||
keyRecords: business => credentials.status().filter(r => r.service === 'model' && r.instance?.startsWith(business + '/'))
|
||||
.map(r => ({ keyId: r.keyId, agent: r.instance.slice(business.length + 1), issuedAt: r.issuedAt, state: r.state })),
|
||||
});
|
||||
};
|
||||
if (modelProxyClient) configureProxyPage();
|
||||
|
||||
// vikunja:19/305: the plug-in switch through the same human-only path as the limits: the verbs
|
||||
// plugins and plugins.set, logged in changes.jsonl with the actor, a missing module refused.
|
||||
const plugins=organization?pluginSettings({dir:organization.dir,rolesDir:organization.rolesDir,exists:hasModule}):null;
|
||||
const levels=organization?await harnessLevels():()=>null;
|
||||
const settings=organization?launchSettings({...organization,sessions:()=>readSessions(dataRoot),levels}):null;
|
||||
// Row 194 (#1692, brief item 8, row 199 D13): a fire or a delete revokes the agent's credentials
|
||||
// after the writer's checks and before its write, under the writer's lock (row 239). Fire revokes
|
||||
// each service of the entry and keeps the store directory, delete calls remove (sage-1593). A
|
||||
// service the running bus doesn't know (an agent created since the start) has nothing in memory,
|
||||
// so it goes on, and then no token or tmp file may remain in the agent's store directory
|
||||
// (sage-1592). Any failure stops the verb with the file unchanged.
|
||||
const revokeFailed = (message) => new OrganizationError('credential-revoke-failed', message);
|
||||
function revoke(business, agent, how, services) {
|
||||
const instance = business + '/' + agent;
|
||||
const outside = [];
|
||||
try {
|
||||
if (how === 'delete' && storeRoot) credentials.remove(instance);
|
||||
else
|
||||
for (const service of services) {
|
||||
try {
|
||||
if (!credentials.revoke(instance, service).file) outside.push(service);
|
||||
} catch (e) {
|
||||
if (e.code !== 'credential-unknown') throw e;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw revokeFailed(`${agent}: ${e.code ?? 'credential-file'}`);
|
||||
}
|
||||
if (storeRoot) {
|
||||
let left = [];
|
||||
try {
|
||||
left = readdirSync(join(storeRoot, business, agent));
|
||||
} catch (e) {
|
||||
if (e.code !== 'ENOENT') throw revokeFailed(`${agent}: store directory can't be read`);
|
||||
}
|
||||
if (left.length > 0) throw revokeFailed(`${agent}: ${left.sort().join(' and ')} still in the store`);
|
||||
}
|
||||
// A file or env reference outside the store keeps its token for a restart (row 199 section 6).
|
||||
return { revoked: services, outsideStore: how === 'fire' ? outside : [] };
|
||||
}
|
||||
// Row 165 (#1662): the human adds and changes role instances through instances and instances.set.
|
||||
const proxyOrganization = modelKeys ? modelOrganization({ modelKeys, writer: organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }) }) : null;
|
||||
const instances=organization?instanceSettings({dir:organization.dir,rolesDir:organization.rolesDir,system:organization.system,levels,revoke,
|
||||
...(proxyOrganization ? { writer: proxyOrganization.writer, revoke: proxyOrganization.revoke(revoke) } : {})}):null;
|
||||
const usageLog = entry => process.stderr.write(`usage: ${JSON.stringify(entry)}\n`);
|
||||
const keyForRun = (business, run) => modelRuns.get(business + ':' + run)?.keyId ?? null;
|
||||
const usage = await createUsage({ store, dataRoot, businesses, log: usageLog, keyForRun,
|
||||
proxyView: business => proxyUsage?.view(business) ?? null });
|
||||
proxyUsage = createProxyUsage({ store, log: usageLog, client: async () => {
|
||||
if (!modelKeys) return null;
|
||||
await modelKeys.verifyIdentity();
|
||||
return modelProxyClient;
|
||||
},
|
||||
records: () => credentials.status(),
|
||||
read: () => Object.fromEntries(Object.keys(businesses).map(id => [id, settings ? settings.current(id) : businesses[id]])) });
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the limit checks read the organization file at
|
||||
// each ask, so a limit, a reset or a switched-on check takes effect without a restart.
|
||||
const limitLog = entry => process.stderr.write(`limits: ${JSON.stringify(entry)}\n`);
|
||||
const limits = createLimits({ store, read: id => settings ? settings.current(id) : businesses[id], log: limitLog,
|
||||
keyForSubject: (business, subject) => modelUsageKey(credentials.status(), modelRuns, business, subject) });
|
||||
for (const id of Object.keys(businesses)) await limits.refresh(id);
|
||||
const withTokens = (id, result) => ({ ...result, tokens: limits.report(id) });
|
||||
// Row 210 (#1707, design D7 step 6) and row 234 (#1740, r6 E2): the run dir and the host enrollment half.
|
||||
const runRoot = organization ? join(organization.dir, 'secrets', 'run') : null;
|
||||
let broker;
|
||||
processing = createProcessing({ dataRoot, ...discordProcessingHooks(dataRoot), containerStop: createContainerStopper({ dataRoot }),
|
||||
onTransition: () => broker.reconcileProcessing(),
|
||||
onStop: stop => broker.recordProcessingStop(stop),
|
||||
log: line => process.stderr.write(`${line}\n`),
|
||||
});
|
||||
// C2-04: mirrors are host state, never session checkouts. An unsafe
|
||||
// existing mirror refuses startup before a socket can become ready.
|
||||
for (const business of Object.values(businesses))
|
||||
for (const [project, entry] of Object.entries(business.projects ?? {}))
|
||||
if (entry.kind === 'library') {
|
||||
try { await processing.work(() => libraryModule.ensureMirror({ business, project, dataRoot })); }
|
||||
catch (e) { if (!e.code?.startsWith('processing-')) throw e; }
|
||||
}
|
||||
// C2-03a: the slot is <configDir>/secrets/<business>/library-gitea (design 10 step 4). Sync only
|
||||
// checks that it is there; the askpass helper reads it.
|
||||
// C2-03b: the broker chooses. The chief's grant store file once a chief has Gitea grant evidence,
|
||||
// the slot before that, or a refusal sync records. The answer carries no file to sync but this one.
|
||||
const slotDir = librarySync?.configDir ?? organization?.dir ?? null;
|
||||
const fetchCredential = business => {
|
||||
const choice = broker.libraryFetchCredential(business.id);
|
||||
if (choice.kind === 'chief')
|
||||
return { kind: 'chief', user: choice.user, file: storeRoot ? giteaReference(storeRoot, business.id, choice.agent).file : null };
|
||||
if (choice.kind === 'slot') return { kind: 'slot', file: slotDir ? join(slotDir, 'secrets', business.id, libraryModule.SLOT) : null };
|
||||
return { refused: choice.refused };
|
||||
};
|
||||
const syncOptions = business => ({
|
||||
credential: fetchCredential(business),
|
||||
...(librarySync ? { command: librarySync.command } : {}),
|
||||
});
|
||||
const humanWriteOptions = context => {
|
||||
const mapping = libraryModule.checkMapping(context.business.projects[context.project]);
|
||||
if (!mapping.editor) throw new libraryModule.LibraryError('library-mapping-invalid', 'editor is required');
|
||||
return { credential: libraryModule.humanCredential(context, { user: mapping.editor.user, configDir: slotDir }),
|
||||
...(librarySync ? { command: librarySync.command } : {}) };
|
||||
};
|
||||
// Row 194 (#1692, D3): after every write that commits, the broker takes the business as a restart
|
||||
// would load it. The credential references, the project roots the Credentials store protects
|
||||
// and the tracker bots are fixed at start (the Credentials store, the tasks adapter), so a file
|
||||
// whose references, roots or bots differ from the boot copy isn't reloaded, and the write
|
||||
// answers restart: true. Hire adds neither. A human create of a credentialed definition adds
|
||||
// references, so it answers restart: true, and issue works after the restart (brief item 7).
|
||||
// A role not in the boot copy matches only with no references and no bot. A reference compares
|
||||
// by its kind and path only: row 199's issue rewrites the date in the file outside this reload,
|
||||
// Credentials keeps its own copy of the date, and the broker never reads it.
|
||||
const fixedRef = ({ file, env, store }) => ({ file, env, store });
|
||||
const fixedRole = r => canonicalJson({
|
||||
credentials: Object.fromEntries(Object.entries(r?.credentials ?? {}).map(([service, ref]) => [service, fixedRef(ref)])),
|
||||
tracker: r?.tracker ?? null,
|
||||
});
|
||||
const fixedAtStart = b => ({
|
||||
roles: Object.fromEntries(Object.entries(b.roles).map(([role, r]) => [role, fixedRole(r)])),
|
||||
sync: canonicalJson(b.tracker?.sync ?? null),
|
||||
roots: canonicalJson(Object.values(b.projects ?? {}).filter(p => p.kind !== 'library').map(p => p.root).sort()),
|
||||
// A library entry has no root, and its mirror is ensured at start (C2-04), so each one is fixed whole.
|
||||
libraries: canonicalJson(Object.fromEntries(Object.entries(b.projects ?? {}).filter(([, p]) => p.kind === 'library'))),
|
||||
});
|
||||
const sameFixed = (boot, b) => fixedAtStart(b).sync === boot.sync && fixedAtStart(b).roots === boot.roots
|
||||
&& fixedAtStart(b).libraries === boot.libraries
|
||||
&& Object.entries(fixedAtStart(b).roles).every(([role, f]) => f === (boot.roles[role] ?? fixedRole(null)));
|
||||
const booted = new Map(Object.entries(businesses).map(([id, b]) => [id, fixedAtStart(b)]));
|
||||
const reloadLog = entry => process.stderr.write(`organization: ${JSON.stringify(entry)}\n`);
|
||||
function reload(id) {
|
||||
try {
|
||||
const b = loadBusiness(id, { dir: organization.dir, rolesDir: organization.rolesDir });
|
||||
const resolved = {};
|
||||
for (const instance of Object.keys(b.roles)) resolved[instance] = resolveInstance({ system: organization.system, business: b, instance });
|
||||
const next = busBusiness(b, resolved);
|
||||
if (!sameFixed(booted.get(id), next)) {
|
||||
reloadLog({ event: 'reload-needs-restart', business: id });
|
||||
return false;
|
||||
}
|
||||
broker.reloadBusiness(id, next);
|
||||
return true;
|
||||
} catch (e) {
|
||||
reloadLog({ event: 'reload-failed', business: id, message: e.message });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
broker = new Broker({
|
||||
// FED R3: the access file is read per user request; a refusal leaves the user no grant.
|
||||
access: access ? () => loadAccess(access.file, access.context) : null,
|
||||
// FED R4 (#1801, design 3.7 trigger 1): a request stats the file and reads it only when this
|
||||
// changes. A failed stat is a stamp of its own, so a removed file reads (and refuses) once.
|
||||
accessStamp: access ? () => {
|
||||
try {
|
||||
const st = lstatSync(access.file, { bigint: true });
|
||||
return `${st.dev}:${st.ino}:${st.size}:${st.mtimeNs}:${st.ctimeNs}:${st.mode}:${st.uid}`;
|
||||
} catch (e) {
|
||||
return `unreadable:${e.code ?? 'error'}`;
|
||||
}
|
||||
} : null,
|
||||
// Row 270 (264c): session.list's compaction count, read from the session store's ledger.
|
||||
compactions: ({ business, thread, session, legacy }) => {
|
||||
const dir = storeDir(dataRoot, business, thread, session, { legacy });
|
||||
return dir ? compactionCount(dir) : { count: null, known: false, reason: 'store-unreadable', at: null };
|
||||
},
|
||||
hostGrant: runRoot ? hostGrant({ configDir: organization.dir, runRoot }) : null,
|
||||
// Row 235 (#1741, r6 X4, X5): the grant executor's claim, register and issue, never use().
|
||||
hostKeys: storeRoot ? grantKeys({ credentials, storeRoot }) : null,
|
||||
processing,
|
||||
// Row 236 (#1742): the Gitea grant path. The admin slot is <configDir>/secrets/grants/<business>/gitea.
|
||||
giteaGrant: organization ? giteaGrant({ configDir: organization.dir }) : null,
|
||||
giteaKeys: storeRoot ? giteaKeys({ credentials, storeRoot }) : null,
|
||||
usage,
|
||||
limits,
|
||||
store,
|
||||
businesses,
|
||||
library: {
|
||||
lookup: createLibraryLookup({ dataRoot, sync: context =>
|
||||
processing.work(() => libraryModule.sync(context, syncOptions(context.business))) }),
|
||||
log: entry => process.stderr.write(`library: ${JSON.stringify(entry)}\n`),
|
||||
readFile: context => libraryModule.readLibraryFile({ ...context, dataRoot }),
|
||||
status: context => libraryModule.libraryStatus({ ...context, dataRoot }),
|
||||
sync: (context, { accept }) => processing.work(() => libraryModule.sync({ ...context, dataRoot }, { ...syncOptions(context.business), accept })),
|
||||
// C2-02: trusted references only. The askpass helper alone opens a credential file.
|
||||
writeDoc: (context, options) => processing.work(() => libraryModule.writeLibraryDoc({ ...context, dataRoot }, {
|
||||
...options, credential: { ...options.credential,
|
||||
file: storeRoot ? giteaReference(storeRoot, context.business.id, options.credential.agent).file : null },
|
||||
...(librarySync ? { command: librarySync.command } : {}),
|
||||
})),
|
||||
saveFile: context => processing.work(() => libraryModule.saveLibraryFile({ ...context, dataRoot }, humanWriteOptions(context))),
|
||||
revert: context => processing.work(() => libraryModule.revertLibraryCommit({ ...context, dataRoot }, humanWriteOptions(context))),
|
||||
LibraryError: libraryModule.LibraryError,
|
||||
// C2-06: the citation guard, the reply limits read from the business file at each check (none
|
||||
// configured reads as unreadable, so requireCitation is true), and thread.messages' `last`.
|
||||
guard: (context, body, options) => libraryModule.guardReply({ ...context, dataRoot }, body, options),
|
||||
replyLimits: id => libraryModule.resolveReplyLimits(organization
|
||||
? organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }).readRaw(id) : { readable: false }),
|
||||
last: (context, paths) => libraryModule.lastCommits({ ...context, dataRoot }, paths),
|
||||
GuardError: libraryModule.GuardError,
|
||||
},
|
||||
project: {
|
||||
readSpec: context => projectModule.readSpec({ ...context, dataRoot }),
|
||||
writeRecord: context => processing.work(() => projectModule.writeRecord({ ...context, dataRoot })),
|
||||
listFiles: context => projectModule.listProjectFiles({ ...context, dataRoot }),
|
||||
readFile: context => projectModule.readProjectFile({ ...context, dataRoot }),
|
||||
writeFile: context => projectModule.writeHumanFile({ ...context, dataRoot }),
|
||||
ProjectError: projectModule.ProjectError,
|
||||
},
|
||||
// limits and limits.set (organization.set is limits.set) carry each token limit's count; a
|
||||
// plugins.set reloads the business's limit checks in the background.
|
||||
organization:settings?(proxyOrganization?.wrap ?? (operation => operation))((id,verb,args,actor,context)=>{
|
||||
if(verb==='limits')return withTokens(id,settings.read(id));
|
||||
if(verb==='plugins')return plugins.read(id);
|
||||
// Row 256 (#1761): the actor is the reader, so endProtected is the delete check for that reader.
|
||||
if(verb==='instances')return instances.read(id,actor);
|
||||
// Row 65 (mos-0840): the Console's routing table.
|
||||
if(verb==='routes')return settings.routes(id);
|
||||
// Row 298 (#1804, Q228): the chief's grant scope as the file stands, the fallback shown.
|
||||
if(verb==='grants.scope')return instances.grantScopeRead(id);
|
||||
// Row 194 (#1692, V5): a delete's checks at the verb, with no write and no reload.
|
||||
if(verb==='instances.check')return instances.checkDelete(id,args.instance,actor);
|
||||
// Row 194 b6 (webby-0094 B1): a fire's checks against the file, before step A.
|
||||
if(verb==='instance.fireCheck')return instances.checkFire(id,args.name);
|
||||
// Internal read-only path: no reload, journal, credential or publication.
|
||||
if(verb==='instance.hireCheck')return instances.checkHire(id,args);
|
||||
let result;
|
||||
if(verb==='limits.set')result=withTokens(id,settings.set(id,args,actor));
|
||||
else if(verb==='instances.set')result=instances.set(id,args,actor);
|
||||
else if(verb==='routes.set')result=settings.setRoutes(id,args,actor);
|
||||
else if(verb==='plugins.set')result=plugins.set(id,args,actor);
|
||||
// Row 194 (#1692, V6): the human's keep and noHire lists, through the instance writer.
|
||||
else if(verb==='veto.set')result=instances.veto(id,args,actor);
|
||||
// Row 298: the human's grant scope, through the instance writer.
|
||||
else if(verb==='grants.scope.set')result=instances.grantScope(id,args,actor);
|
||||
// C2-06 M11: the human's replyLimits, through the organization writer's fence.
|
||||
else if(verb==='library.limits.set')result=setReplyLimits(organizationWriter({dir:organization.dir,rolesDir:organization.rolesDir}),id,args,actor);
|
||||
// Row 194 (D2.1, D2.2): the chief's hire and fire, with the reason in the change context.
|
||||
else if(verb==='instance.hire')result=instances.hire(id,args,{actor,context});
|
||||
else if(verb==='instance.fire')result=instances.fire(id,{name:args.name},{actor,context});
|
||||
else throw new BusError('invalid-request');
|
||||
// Row 194 (D3 item 2): one reload, after every verb that committed, then the limit checks.
|
||||
const live=reload(id);
|
||||
limits.refresh(id).catch(e=>limitLog({event:'limit-refresh-failed',business:id,message:e.message}));
|
||||
// Row 194 b6 (webby-0094 B1, sage-2241): every instance-writer verb says whether the reload
|
||||
// took, so a refused one (credentials, roots, ...) shows the restart line for a keep or a
|
||||
// hire too. The other writers' answers carry no restart field.
|
||||
return INSTANCE_VERBS.has(verb)?{...result,restart:!live}:result;
|
||||
}):null,
|
||||
// Row 194 (D2.3): the role files as they stand, for the hire checks.
|
||||
roleFile: organization ? (name) => loadRole(organization.rolesDir, name) : null,
|
||||
secretCheck: (value) => credentials.assertClean(value),
|
||||
credentialStatus: () => credentials.status(),
|
||||
// Row 199 (#1697, design section 6): issue, rotate, revoke and delete, live with no restart; each
|
||||
// rewrites or records through the organization writer, so changes.jsonl holds the receipt.
|
||||
proxyPage: async (verb, args, scope) => {
|
||||
if (!proxyPage) throw new BusError('not-configured');
|
||||
return proxyPage.request(verb, args, scope);
|
||||
},
|
||||
proxyInit: organization ? async args => {
|
||||
const settings = await initializeProxy({ configDir: organization.dir, dataRoot, ...args });
|
||||
modelProxyClient = await loadManagementClient({ configDir: organization.dir, proxy: settings, receipt: proxyReceipt });
|
||||
configureProxyPage();
|
||||
return settings;
|
||||
} : null,
|
||||
credentialVerbs: organization
|
||||
? credentialVerbs({ credentials, writer: organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }) })
|
||||
: null,
|
||||
// Row 65: a new launch binds only on a harness its business switches on, read from the file
|
||||
// as it stands now; an unreadable file switches none on.
|
||||
harnessOn: (id, name) => {
|
||||
try {
|
||||
const b = settings ? settings.current(id) : businesses[id];
|
||||
return Array.isArray(b?.plugins?.harness) && b.plugins.harness.includes(name);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// Row 298 (#1804, Q228): one read binds launch.grantScope to the organization revision.
|
||||
// A missing organization reader or unreadable file cannot authorize an automatic grant.
|
||||
grantScope: (id) => {
|
||||
if (!settings) return { value: undefined, revision: null };
|
||||
const { document, revision } = instances.writer.read(id);
|
||||
return { value: document.launch?.grantScope, revision };
|
||||
},
|
||||
// Row 194 (#1692, D4.1, B8): bus.tester as the file sets it now; an unreadable file is off.
|
||||
testerOn: (id) => {
|
||||
try {
|
||||
const b = settings ? settings.current(id) : businesses[id];
|
||||
return b?.vars?.['bus.tester'] === true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
broker.reconcileProcessing();
|
||||
processing.start();
|
||||
const processingWork = () => {
|
||||
const state = processing.read();
|
||||
if (state.invalid) throw new BusError(state.code);
|
||||
if (state.halted) throw new BusError('processing-halted');
|
||||
};
|
||||
// Process identities must be supplied for every managed run when using the human transport.
|
||||
const launchRecords = [];
|
||||
function bindLaunch(r) {
|
||||
if (
|
||||
!Number.isSafeInteger(r.pid) ||
|
||||
r.pid < 2 ||
|
||||
typeof r.startTime !== 'string' ||
|
||||
!/^\d+$/.test(r.startTime)
|
||||
)
|
||||
throw new BusError('invalid-launch-process');
|
||||
const { modelKeyId, ...record } = r;
|
||||
if (modelKeys) {
|
||||
modelKeys.assertLaunchable(r.business + '/' + r.role);
|
||||
const m = credentials.modelRecord(r.business + '/' + r.role);
|
||||
if (!m || ![m.keyId, ...m.retiring.map(k => k.keyId)].includes(modelKeyId)) throw new BusError('proxy-key-refused');
|
||||
}
|
||||
const cap = broker.bindLaunch(record);
|
||||
launchRecords.push({ ...r });
|
||||
if (modelKeys) modelRuns.set(r.business + ':' + r.run, { ...r, instance: r.business + '/' + r.role, keyId: modelKeyId });
|
||||
return { business: r.business, run: r.run, cap };
|
||||
}
|
||||
const bound = launches.map(bindLaunch);
|
||||
const readCaps = readers.map((business) => ({ business, cap: broker.bindReader({ business }) }));
|
||||
if (tasks) {
|
||||
adapter = await tasks({ broker, credentials, businesses, processing });
|
||||
if (typeof adapter?.handle !== 'function' || !Number.isSafeInteger(adapter.timeout) || adapter.timeout < 1)
|
||||
throw new BusError('invalid-adapter');
|
||||
}
|
||||
const web = await webServices(businesses);
|
||||
// Row 210 (#1707, design D7 step 6): clear what a killed bus child left, before anyone can call.
|
||||
if (runRoot) sweepRunDir(runRoot);
|
||||
// Row 234 (r6 X3): end the enrollments a killed bus child left, before anyone can call.
|
||||
broker.reconcileGrants();
|
||||
const interpreter = inspectInterpreter();
|
||||
recordInterpreterStart(store.directory, interpreter);
|
||||
const peerReader = createPeerReader({ interpreter });
|
||||
const principalPaths = {
|
||||
human: fileURLToPath(new URL('./human-cli.mjs', import.meta.url)),
|
||||
tester: fileURLToPath(new URL('./tester-cli.mjs', import.meta.url)),
|
||||
user: fileURLToPath(new URL('./user-cli.mjs', import.meta.url)),
|
||||
console: fileURLToPath(new URL('../../webui/src/cli.mjs', import.meta.url)),
|
||||
consoleCli: fileURLToPath(new URL('./console-cli.mjs', import.meta.url)),
|
||||
};
|
||||
const path = join(store.directory, 'broker.sock');
|
||||
// The existing host executor owns SSH and its key lifecycle. Combine its revocation
|
||||
// signal with processing cancellation without changing its proof or credential entry points.
|
||||
const host = runRoot ? hostExecutor({ root: runRoot, credentials: {
|
||||
busy: (...args) => credentials.busy(...args),
|
||||
useFor: (session, name, fn, options) => credentials.useFor(session, name, (token, meta) =>
|
||||
fn(token, { ...meta, signal: meta.signal
|
||||
? AbortSignal.any([meta.signal, processing.signal()]) : processing.signal() }), options),
|
||||
} }) : null;
|
||||
server = await serve({
|
||||
web: (business) => web.get(business) ?? null,
|
||||
host: host ? { busy: (...args) => host.busy(...args),
|
||||
run: (...args) => processing.work(() => host.run(...args)) } : null,
|
||||
tasks: adapter ? { handle: adapter.handle, timeout: adapter.timeout } : null,
|
||||
broker,
|
||||
path,
|
||||
peerReader,
|
||||
authenticateHuman: (proof, peer) => {
|
||||
const p = verifyPrincipal({ human: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindHuman({ business: p.business, human: p.id, via: 'cli', outsideAgent: true });
|
||||
},
|
||||
authenticateTester: (proof, peer) => {
|
||||
const p = verifyPrincipal({ tester: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindTester({ business: p.business });
|
||||
},
|
||||
// FED R3 (design 3.6): checks 1 and 2 are row 196's user kind; check 3, the live grant, is bindUser's.
|
||||
authenticateUser: (proof, peer) => {
|
||||
const p = verifyPrincipal({ user: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindUser({ business: p.business, user: p.id });
|
||||
},
|
||||
// Row 252 (#1753): a fresh proof per connection, a cap for the Console verbs only.
|
||||
authenticateConsole: (proof, peer) => {
|
||||
const p = verifyPrincipal({ console: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords, consoleOwners: owners });
|
||||
return broker.bindConsole({ business: p.business, human: p.id, subject: p.subject });
|
||||
},
|
||||
});
|
||||
// Row 235 (r6 X3): the remote undo of interrupted host grants, once the bus is up, so a start doesn't
|
||||
// wait on the network.
|
||||
broker.reconcileHosts();
|
||||
// Row 236 (#436b r5 section 5): the Gitea grants' remote undo, settle and open revokes, likewise.
|
||||
broker.reconcileGitea();
|
||||
// S6 launcher operations. The host decides capacity and the instance list; the broker
|
||||
// authorizes role.launch and keeps the evidence, refusals included.
|
||||
// A refusal is recorded against the caller, as request() records one.
|
||||
function refusing(cap, fn, subject = null) {
|
||||
try {
|
||||
return fn();
|
||||
} catch (e) {
|
||||
if (!(e instanceof BusError)) throw e;
|
||||
broker.refuse(cap, e.code, subject);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
const authorizeLaunch = (cap, instance) =>
|
||||
refusing(cap, () => broker.authorize(cap, 'role.launch', { target: instance }));
|
||||
// Row 93 (#1587): the host's git socket. A push is checked before the host takes the bundle
|
||||
// and recorded once the ref moved; a reviewer's fetch is checked against its review.requested.
|
||||
const checkPush = (cap, task_ref) => refusing(cap, () => broker.checkPush(cap, task_ref), task_ref);
|
||||
const reviewFetch = (cap, args) => refusing(cap, () => broker.reviewFetch(cap, args), args?.task_ref);
|
||||
// Row 137 (#1631): the git socket's land op. checkLand's refusal is the run's, like checkPush's.
|
||||
// A landing then ends in recordLand or landRefused under its ticket, which outlive the run's cap.
|
||||
const checkLand = (cap, args) => refusing(cap, () => broker.checkLand(cap, args), args?.task_ref);
|
||||
// Row 199 (#1697, design D9b): the git socket's publish op. checkPublish's refusal is the run's.
|
||||
// The gitea token is used only under the open ticket, keyed from the agent checkPublish checked,
|
||||
// and the op table returns no token. A publish then ends in recordPublish or publishRefused,
|
||||
// which files any refusal once, withGitea's included.
|
||||
const checkPublish = (cap, args) => refusing(cap, () => broker.checkPublish(cap, args), args?.task_ref);
|
||||
const withGitea = async (ticket, fn) => credentials.useFor(broker.publishSession(ticket), 'gitea', fn);
|
||||
// The push itself runs here, where the token is (D9 step 5), and the git socket's host polls
|
||||
// for its end: the host's op channel answers one op at a time within 10 s, and ls-remote and
|
||||
// push can take longer. Fork, user, source and dst all come from the ticket. A WorkingError's
|
||||
// code is the refusal; git's stderr stays here.
|
||||
const remotes = new Map();
|
||||
function publishPush(ticket) {
|
||||
if (remotes.has(ticket)) throw new BusError('publish-busy');
|
||||
const { business, project, fork, user, source, dst } = broker.publishTarget(ticket);
|
||||
const entry = { state: 'running' };
|
||||
remotes.set(ticket, entry);
|
||||
processing.work(() => withGitea(ticket, (token) =>
|
||||
publishRemote({ repo: workingRepo(dataRoot, business, project), fork, user, source, dst, token, tls: publishTls }).catch((e) => {
|
||||
throw e instanceof WorkingError ? new BusError(e.code) : e;
|
||||
}),
|
||||
)).then(
|
||||
(r) => Object.assign(entry, { state: 'pushed', ...r }),
|
||||
(e) => {
|
||||
// Not a refusal: the error's name and code only, never a message that could carry git's output.
|
||||
if (!(e instanceof BusError)) process.stderr.write(`bus: publish git-failed: ${JSON.stringify({ name: e?.name, code: e?.code })}\n`);
|
||||
Object.assign(entry, { state: 'refused', code: e instanceof BusError ? e.code : 'git-failed' });
|
||||
},
|
||||
).then(() => {
|
||||
if (entry.held) settle(ticket, entry, entry.held);
|
||||
});
|
||||
return { state: 'running' };
|
||||
}
|
||||
// Row 242 (#1748): the git socket gave up on a publish (publish-timeout) whose push it never
|
||||
// collected. Its publishRefused waits for the push: until that ends the ticket stays open, so
|
||||
// checkPublish refuses another publish on the decision with publish-busy (row 237). A push that
|
||||
// reached the fork is then recorded, which spends the decision; one that didn't is filed with
|
||||
// the socket's code. Either way the decision can't push a second ref.
|
||||
function settle(ticket, entry, code) {
|
||||
remotes.delete(ticket);
|
||||
try {
|
||||
if (entry.state === 'pushed') {
|
||||
try {
|
||||
broker.recordPublish(ticket, { ref: entry.ref, commit: entry.commit, previous: entry.previous });
|
||||
process.stderr.write(`bus: publish ${ticket}: pushed after the git socket refused ${code}; recorded\n`);
|
||||
return;
|
||||
} catch (e) {
|
||||
if (!(e instanceof BusError)) throw e;
|
||||
code = e.code;
|
||||
}
|
||||
}
|
||||
broker.publishRefused(ticket, { code });
|
||||
} catch (e) {
|
||||
process.stderr.write(`bus: publish ${ticket}: not settled: ${JSON.stringify({ name: e?.name, code: e?.code })}\n`);
|
||||
}
|
||||
}
|
||||
function publishRefused(ticket, args) {
|
||||
const entry = remotes.get(ticket);
|
||||
if (!entry) return broker.publishRefused(ticket, args);
|
||||
if (!/^[a-z-]{1,64}$/.test(args?.code ?? '')) throw new BusError('invalid-request');
|
||||
if (entry.state === 'running') entry.held = args.code;
|
||||
else settle(ticket, entry, args.code);
|
||||
return args.code;
|
||||
}
|
||||
function publishResult(ticket) {
|
||||
const entry = remotes.get(ticket);
|
||||
if (!entry) throw new BusError('publish-unknown');
|
||||
if (entry.state !== 'running') remotes.delete(ticket);
|
||||
return { ...entry };
|
||||
}
|
||||
// Metadata only (service, date, state); the token stays in Credentials.
|
||||
function credentialStatus(business, role) {
|
||||
return credentials
|
||||
.status()
|
||||
.filter((c) => c.instance === business + '/' + role)
|
||||
.map(({ service, date, state, keyId, issuedAt }) => ({ service, date, state, ...(service === 'model' ? { keyId, issuedAt } : {}) }));
|
||||
}
|
||||
// C2-03a: each library entry with a sync user fetches once at start, then every 60 s. A pass
|
||||
// still running skips the tick. Only codes are logged, never git's output.
|
||||
const timed = Object.values(businesses).flatMap(business => Object.entries(business.projects ?? {})
|
||||
.filter(([, entry]) => entry.kind === 'library' && Object.hasOwn(entry, 'user')).map(([project]) => ({ business, project })));
|
||||
const syncLog = entry => process.stderr.write(`library: ${JSON.stringify(entry)}\n`);
|
||||
const syncAll = async () => {
|
||||
for (const { business, project } of timed) {
|
||||
try {
|
||||
const { code } = await libraryModule.sync({ business, project, dataRoot }, syncOptions(business));
|
||||
if (code !== null) syncLog({ event: 'library-sync-held', business: business.id, project, code,
|
||||
...(code === 'library-fetch-no-grant' ? { fix: LIBRARY_FETCH_FIX } : {}) });
|
||||
} catch (e) {
|
||||
if (e?.code === 'library-sync-busy') continue;
|
||||
syncLog({ event: 'library-sync-refused', business: business.id, project,
|
||||
code: e instanceof libraryModule.LibraryError ? e.code : 'library-sync-failed' });
|
||||
}
|
||||
}
|
||||
};
|
||||
const tick = () => {
|
||||
const state = processing.read();
|
||||
if (!syncPass && !state.halted && !state.invalid)
|
||||
syncPass = processing.work(syncAll).catch(e => {
|
||||
if (!e.code?.startsWith('processing-')) syncLog({ event: 'library-sync-refused', code: 'library-sync-failed' });
|
||||
}).finally(() => { syncPass = null; });
|
||||
};
|
||||
if (timed.length) {
|
||||
tick();
|
||||
syncTimer = setInterval(tick, librarySync?.intervalMs ?? libraryModule.SYNC_INTERVAL_MS);
|
||||
syncTimer.unref();
|
||||
}
|
||||
const stopSync = async () => { clearInterval(syncTimer); syncTimer = null; await syncPass; };
|
||||
// FED R4 (#1801, design 3.7 trigger 2): every 30 s the broker re-reads the access file, so a hand
|
||||
// edit or an expiry with no request ends the lost runs within one period.
|
||||
if (access) {
|
||||
accessTimer = setInterval(() => {
|
||||
try {
|
||||
broker.accessSweep();
|
||||
} catch (e) {
|
||||
process.stderr.write(`access: ${JSON.stringify({ event: 'access-sweep-failed', code: e.code ?? 'error' })}\n`);
|
||||
}
|
||||
}, access.intervalMs ?? ACCESS_SWEEP_MS);
|
||||
accessTimer.unref();
|
||||
}
|
||||
if (modelKeys) {
|
||||
modelTimer = setInterval(() => {
|
||||
if (modelSweep) return;
|
||||
modelSweep = modelKeys.sweep().catch(error => proxyReceipt({ action: 'proxy.sweep-refused', code: error.code ?? 'proxy-key-issue-failed' })).finally(() => { modelSweep = null; });
|
||||
}, 1000);
|
||||
modelTimer.unref();
|
||||
}
|
||||
// One bounded queue read at a time. The service applies the configured
|
||||
// 1..59 second poll deadline; this tick only checks whether a read is due.
|
||||
usageTimer = setInterval(() => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); }, 1000);
|
||||
usageTimer.unref();
|
||||
await proxyUsage.tick();
|
||||
return {
|
||||
broker,
|
||||
credentials,
|
||||
// P2 consumes this inside the bus only. No process IPC/verb returns it.
|
||||
get modelProxy() { return modelProxyClient; },
|
||||
path,
|
||||
bindLaunch,
|
||||
recoverLaunch: ({ modelKeyId, ...record }) => broker.recoverLaunch(record),
|
||||
endLaunch: (r) => { const out = broker.endLaunch(r); modelRuns.delete(r.business + ':' + r.run); return out; },
|
||||
modelPreflight: async ({ business, role }) => {
|
||||
const current = settings ? settings.current(business) : businesses[business];
|
||||
if (!Object.hasOwn(current?.roles ?? {}, role)) throw new BusError('unknown-role');
|
||||
return modelKeys ? modelKeys.preflight(business + '/' + role) : null;
|
||||
},
|
||||
modelStall: async ({ business, role, run, keyId }) => {
|
||||
const record = modelRuns.get(business + ':' + run);
|
||||
if (!record || record.role !== role || record.keyId !== keyId) throw new BusError('proxy-stop-failed');
|
||||
await stopModelRuns({ runs: [record], reason: 'proxy-stall', sessions: () => readSessions(dataRoot),
|
||||
stop: id => stopSession(dataRoot, id, { timeoutMs: MODEL_STOP_TIMEOUT_MS }), receipt: proxyReceipt });
|
||||
modelRuns.delete(business + ':' + run);
|
||||
return { stopped: true };
|
||||
},
|
||||
threadsState: (business) => broker.threadsState(business),
|
||||
threadIdle: (r) => broker.threadIdle(r),
|
||||
// Row 125 (#1619, REQ-LIMIT-4): the launcher asks the limit checks before every launch.
|
||||
mayLaunch: async ({ business, instance, provider, model, account = null }) => {
|
||||
processingWork();
|
||||
return limits.mayLaunch(business, { instance, provider, model, account });
|
||||
},
|
||||
identity: (cap) => broker.identity(cap),
|
||||
authorizeLaunch,
|
||||
checkPush,
|
||||
recordPush: (cap, push) => refusing(cap, () => broker.recordPush(cap, push), push?.task_ref),
|
||||
reviewFetch,
|
||||
checkLand,
|
||||
recordLand: (ticket, land) => broker.recordLand(ticket, land),
|
||||
landRefused: (ticket, args) => broker.landRefused(ticket, args),
|
||||
checkPublish,
|
||||
withGitea,
|
||||
publishPush,
|
||||
publishResult,
|
||||
recordPublish: (ticket, pushed) => broker.recordPublish(ticket, pushed),
|
||||
publishRefused,
|
||||
landHeld: (record) => broker.landHeld(record),
|
||||
// Row 156 (#1651): the launcher's landing pass.
|
||||
landHolders: (business) => broker.landHolders(business),
|
||||
landRelease: (r) => broker.landRelease(r),
|
||||
// Row 194 (#1692, D1.1): the launcher's lifecycle pass.
|
||||
lifecycleRequests: (business) => broker.lifecycleRequests(business),
|
||||
lifecycleTake: (r) => broker.lifecycleTake(r),
|
||||
lifecycleDelete: (r) => broker.lifecycleDelete(r),
|
||||
lifecycleDone: (r) => broker.lifecycleDone(r),
|
||||
// Row 271 (264d, #1776): the launcher's clear pass.
|
||||
sessionClears: (business) => broker.sessionClears(business),
|
||||
sessionClearExited: (r) => broker.sessionClearExited(r),
|
||||
sessionClearUncertain: (r) => broker.sessionClearUncertain(r),
|
||||
sessionClearRetire: (r) => broker.sessionClearRetire(r),
|
||||
sessionClearStart: (r) => broker.sessionClearStart(r),
|
||||
refuse: (cap, code, subject) => broker.refuse(cap, code, subject),
|
||||
credentialStatus,
|
||||
launches: bound,
|
||||
readers: readCaps,
|
||||
async close() {
|
||||
clearInterval(usageTimer);
|
||||
await proxyUsage.close();
|
||||
clearInterval(modelTimer);
|
||||
await modelSweep;
|
||||
clearInterval(accessTimer);
|
||||
await stopSync();
|
||||
await server.close();
|
||||
await adapter?.close?.();
|
||||
await processing?.close();
|
||||
store.close();
|
||||
credentials.close();
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
clearInterval(usageTimer);
|
||||
await proxyUsage?.close();
|
||||
clearInterval(modelTimer);
|
||||
clearInterval(accessTimer);
|
||||
await server?.close();
|
||||
await adapter?.close?.();
|
||||
await processing?.close();
|
||||
store?.close();
|
||||
credentials?.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Static bytes/Git/diff only. Never imports product modules or runs tests."""
|
||||
from pathlib import Path
|
||||
import hashlib, json, subprocess, re, io, tarfile, gzip, tempfile, shutil
|
||||
ROOT=Path.cwd()
|
||||
OUT=ROOT/'agents/codex/work/queue-333/r1-repair/packet'
|
||||
OUT.mkdir(exist_ok=True)
|
||||
HEAD='503b91e56137482abef475bc3b1b72a64b0a329c'
|
||||
assert subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip()==HEAD
|
||||
assert subprocess.check_output(['git','diff','--cached','--name-only'],text=True).strip()==''
|
||||
OBJECT_FORMAT=subprocess.check_output(['git','rev-parse','--show-object-format'],text=True).strip()
|
||||
assert OBJECT_FORMAT=='sha1'
|
||||
def digest(data): return hashlib.sha256(data).hexdigest()
|
||||
def blob(data): return hashlib.sha1(b'blob '+str(len(data)).encode()+b'\0'+data).hexdigest()
|
||||
def head_bytes(p):
|
||||
result=subprocess.run(['git','show',f'{HEAD}:{p}'],capture_output=True)
|
||||
return result.stdout if result.returncode==0 else None
|
||||
def jsonfile(name,value): (OUT/name).write_text(json.dumps(value,indent=2,sort_keys=True)+'\n')
|
||||
tracked=set(subprocess.check_output(['git','diff','--name-only',HEAD,'--','packages'],text=True).splitlines())
|
||||
untracked=set(subprocess.check_output(['git','ls-files','--others','--exclude-standard','--','packages'],text=True).splitlines())
|
||||
changed=sorted(tracked|untracked)
|
||||
CONTROLS=['packages/bus/tests/p5-identity.test.mjs','packages/bus/tests/p5-key-compatibility.test.mjs','packages/bus/tests/p5-background.test.mjs','packages/bus/tests/p5-telemetry-fixture.mjs']
|
||||
assert set(CONTROLS)<=untracked
|
||||
parts={}
|
||||
for p in changed:
|
||||
if p in tracked:
|
||||
part=subprocess.check_output(['git','diff','--binary','--full-index',HEAD,'--',p])
|
||||
else:
|
||||
result=subprocess.run(['git','diff','--no-index','--binary','--full-index','--','/dev/null',p],capture_output=True)
|
||||
assert result.returncode==1,(p,result.stderr)
|
||||
part=result.stdout
|
||||
assert part
|
||||
parts[p]=part
|
||||
(OUT/'source-tests.patch').write_bytes(b''.join(parts[p] for p in changed))
|
||||
(OUT/'baseline-controls.patch').write_bytes(b''.join(parts[p] for p in sorted(CONTROLS)))
|
||||
(OUT/'baseline-to-fixed.patch').write_bytes(b''.join(parts[p] for p in changed if p not in CONTROLS))
|
||||
jsonfile('changed-source-tests.json',[{'path':p,'bytes':(ROOT/p).stat().st_size,'sha256':digest((ROOT/p).read_bytes()),'git_blob':blob((ROOT/p).read_bytes()),'head_git_blob':blob(head_bytes(p)) if head_bytes(p) is not None else None} for p in changed])
|
||||
whole=(ROOT/'agents/codex/work/queue-333/r1-repair/whole-files.txt').read_text().splitlines()
|
||||
assert len(whole)==28 and len(set(whole))==28
|
||||
(OUT/'whole-files.txt').write_text('\n'.join(whole)+'\n')
|
||||
# Conservative static closure: old captured inputs + current controls/changed
|
||||
# files + all shipped selectable plug-ins/role data, literal module and URL edges.
|
||||
seed={line.split(' ',1)[1] for line in (ROOT/'agents/codex/work/queue-333/source-inputs.sha256').read_text().splitlines()}
|
||||
seed.update(whole);seed.update(changed)
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'agents/codex/work/queue-333/r1-repair').glob('*') if p.is_file())
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'packages/plugins').glob('*/*/index.mjs'))
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'packages/plugins/src').glob('*.mjs'))
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'roles').rglob('*') if p.is_file())
|
||||
for p in ['AGENTS.md','package.json','package-lock.json','RELEASE','docs/plans/2026-10-24_model-proxy-rows.md','docs/plans/2026-10-24_stack-model-proxy.md']:
|
||||
if (ROOT/p).is_file(): seed.add(p)
|
||||
patterns=[('module',re.compile(r'''\b(?:import|export)\s+(?:[^;'\"]*?\s+from\s*)?['\"]([^'\"]+)['\"]''')),
|
||||
('dynamic-literal',re.compile(r'''\bimport\s*\(\s*['\"]([^'\"]+)['\"]''')),
|
||||
('url-data',re.compile(r'''new\s+URL\s*\(\s*['\"]([^'\"]+)['\"]'''))]
|
||||
inputs=set();pending=list(seed);edges=[];external=[];selectors=[]
|
||||
while pending:
|
||||
p=pending.pop()
|
||||
if p in inputs: continue
|
||||
file=ROOT/p
|
||||
if not file.is_file(): continue
|
||||
inputs.add(p)
|
||||
if file.suffix not in {'.mjs','.js','.cjs'}:continue
|
||||
src=file.read_text()
|
||||
if re.search(r'\bimport\s*\(\s*(?![\'\"\s])',src) or 'pathToFileURL(' in src:
|
||||
selectors.append(p)
|
||||
for kind,pattern in patterns:
|
||||
for spec in pattern.findall(src):
|
||||
if not spec.startswith('.'):
|
||||
if kind!='url-data': external.append({'from':p,'specifier':spec,'kind':kind})
|
||||
continue
|
||||
resolved=(file.parent/spec).resolve()
|
||||
try: rel=str(resolved.relative_to(ROOT))
|
||||
except ValueError: continue
|
||||
if resolved.is_file():
|
||||
edges.append({'from':p,'to':rel,'specifier':spec,'kind':kind});pending.append(rel)
|
||||
parent=file.parent
|
||||
while parent==ROOT or ROOT in parent.parents:
|
||||
package=parent/'package.json'
|
||||
if package.is_file(): pending.append(str(package.relative_to(ROOT)));break
|
||||
parent=parent.parent
|
||||
fixed={p:(ROOT/p).read_bytes() for p in sorted(inputs)}
|
||||
baseline={}
|
||||
for p in sorted(inputs):
|
||||
before=fixed[p] if p in CONTROLS else head_bytes(p)
|
||||
if before is not None:baseline[p]=before
|
||||
|
||||
def manifest(values):
|
||||
return [{'path':p,'bytes':len(data),'sha256':digest(data),'git_blob':blob(data),'head_git_blob':blob(head_bytes(p)) if head_bytes(p) is not None else None} for p,data in values.items()]
|
||||
jsonfile('fixed-inputs.json',manifest(fixed));jsonfile('baseline-inputs.json',manifest(baseline))
|
||||
(OUT/'fixed-inputs.sha256').write_text(''.join(f'{digest(data)} {p}\n' for p,data in fixed.items()))
|
||||
(OUT/'baseline-inputs.sha256').write_text(''.join(f'{digest(data)} {p}\n' for p,data in baseline.items()))
|
||||
jsonfile('static-dependencies.json',{'provenance':'STATIC conservative input closure, NOT execution/consumed-source evidence','roots':whole,'literal_edges':sorted(edges,key=lambda e:(e['from'],e['to'],e['kind'])),'external_or_builtin_specifiers':sorted(external,key=lambda e:(e['from'],e['specifier'])),'nonliteral_selectors_require_actual_runner_capture':sorted(set(selectors)),'included_shipped_plugins_and_roles':True})
|
||||
def archive(name,values):
|
||||
with open(OUT/name,'wb') as raw:
|
||||
with gzip.GzipFile(filename='',mode='wb',fileobj=raw,mtime=0) as zipped:
|
||||
with tarfile.open(fileobj=zipped,mode='w') as tar:
|
||||
for p,data in values.items():
|
||||
info=tarfile.TarInfo(p);info.size=len(data);info.mode=0o644;info.mtime=0;info.uid=info.gid=0
|
||||
tar.addfile(info,io.BytesIO(data))
|
||||
archive('fixed-input-bytes.tar.gz',fixed);archive('baseline-input-bytes.tar.gz',baseline)
|
||||
# Verify archived bytes match both manifests; hashes/Git blob IDs are byte pins,
|
||||
# never claims that unexecuted modules or tests passed.
|
||||
for name,values in [('fixed-input-bytes.tar.gz',fixed),('baseline-input-bytes.tar.gz',baseline)]:
|
||||
with tarfile.open(OUT/name,'r:gz') as tar:
|
||||
assert set(tar.getnames())==set(values)
|
||||
for p,data in values.items(): assert tar.extractfile(p).read()==data
|
||||
# Original evidence must remain identical to the original Git candidate.
|
||||
original=ROOT/'agents/codex/work/queue-333'
|
||||
old_files=subprocess.check_output(['git','ls-tree','-r','--name-only',HEAD,'--',str(original.relative_to(ROOT))],text=True).splitlines()
|
||||
for p in old_files:
|
||||
assert (ROOT/p).read_bytes()==head_bytes(p),f'original evidence changed: {p}'
|
||||
# Base test prefixes are retained except the two explicitly authorized additive
|
||||
# registry inventory changes which already existed at503 and remain unchanged.
|
||||
base='09a847edaa25b609bac7728ff83f224708a29399'
|
||||
prefixes=[]
|
||||
for p in changed:
|
||||
if '/tests/' not in p:continue
|
||||
before=subprocess.run(['git','show',f'{base}:{p}'],capture_output=True)
|
||||
if before.returncode==0:
|
||||
retained=(ROOT/p).read_bytes().startswith(before.stdout)
|
||||
assert retained,p
|
||||
prefixes.append(p)
|
||||
jsonfile('preserved-base-test-prefixes.json',prefixes)
|
||||
# Static application check in disposable byte trees, never a product run or a
|
||||
# second Git worktree/branch. Verify both overlay routes reproduce exact bytes.
|
||||
tmp=Path(tempfile.mkdtemp(prefix='p5-static-overlay-'))
|
||||
try:
|
||||
archive_bytes=subprocess.check_output(['git','archive','--format=tar',HEAD,'--',*sorted(tracked)])
|
||||
direct=tmp/'direct';staged=tmp/'staged';direct.mkdir();staged.mkdir()
|
||||
for target in [direct,staged]:
|
||||
with tarfile.open(fileobj=io.BytesIO(archive_bytes),mode='r:') as tar:tar.extractall(target,filter='data')
|
||||
def apply(target,name):
|
||||
subprocess.run(['git','apply','--check',str(OUT/name)],cwd=target,check=True,capture_output=True)
|
||||
subprocess.run(['git','apply',str(OUT/name)],cwd=target,check=True,capture_output=True)
|
||||
apply(direct,'source-tests.patch')
|
||||
apply(staged,'baseline-controls.patch')
|
||||
for path in tracked:assert (staged/path).read_bytes()==head_bytes(path)
|
||||
apply(staged,'baseline-to-fixed.patch')
|
||||
for path in changed:
|
||||
assert (direct/path).read_bytes()==(ROOT/path).read_bytes()
|
||||
assert (staged/path).read_bytes()==(ROOT/path).read_bytes()
|
||||
jsonfile('static-overlay-check.json',{'status':'byte-application-verified-no-product-execution','source_patch_equals_controls_then_remainder':True,'changed_package_files':len(changed),'temporary_trees_removed':True})
|
||||
finally:shutil.rmtree(tmp)
|
||||
assert not tmp.exists()
|
||||
review=ROOT/'agents/codex/work/queue-333/r1-repair/REVIEW-R1.md'
|
||||
assert digest(review.read_bytes())=='7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008'
|
||||
evidence={str(p.relative_to(ROOT)):p.read_bytes() for p in sorted((ROOT/'agents/codex/work/queue-333/r1-repair/receipts').iterdir()) if p.is_file()}
|
||||
evidence.update({str(review.relative_to(ROOT)):review.read_bytes()})
|
||||
for p in sorted((ROOT/'agents/codex/work/queue-333/r1-repair/baselines').iterdir()):
|
||||
if p.is_file():evidence[str(p.relative_to(ROOT))]=p.read_bytes()
|
||||
jsonfile('r1-raw-evidence.json',manifest(evidence))
|
||||
archive('r1-raw-evidence-bytes.tar.gz',evidence)
|
||||
index={'status':'UNCOMMITTED_STATIC_PACKET_EXECUTION_PENDING','head':HEAD,'original_base':base,'review_sha256':'7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008','changed_package_files':len(changed),'whole_test_files':len(whole),'fixed_static_input_files':len(fixed),'baseline_static_input_files':len(baseline),'git_object_format':OBJECT_FORMAT,'files':{p.name:{'bytes':p.stat().st_size,'sha256':digest(p.read_bytes())} for p in sorted(OUT.iterdir()) if p.is_file() and p.name not in {'INDEX.json','packet.sha256'}}}
|
||||
jsonfile('INDEX.json',index)
|
||||
(OUT/'packet.sha256').write_text(''.join(f'{digest(p.read_bytes())} {p.name}\n' for p in sorted(OUT.iterdir()) if p.is_file() and p.name!='packet.sha256'))
|
||||
print(json.dumps({k:index[k] for k in ['status','head','changed_package_files','whole_test_files','fixed_static_input_files','baseline_static_input_files']},sort_keys=True))
|
||||
print('source-tests.patch SHA256 '+digest((OUT/'source-tests.patch').read_bytes()))
|
||||
print('INDEX.json SHA256 '+digest((OUT/'INDEX.json').read_bytes()))
|
||||
@@ -1,77 +0,0 @@
|
||||
{
|
||||
"baseline_static_input_files": 301,
|
||||
"changed_package_files": 18,
|
||||
"files": {
|
||||
"baseline-controls.patch": {
|
||||
"bytes": 19496,
|
||||
"sha256": "9b64bfe45f20f59ae62812529c5f4ef4a41f29ea9124cf42dd6e9c32f5089711"
|
||||
},
|
||||
"baseline-input-bytes.tar.gz": {
|
||||
"bytes": 793317,
|
||||
"sha256": "add6f177692f774a0a4370c95d28d3e72a3aa4e76adab886ed6bdcc01a965e2b"
|
||||
},
|
||||
"baseline-inputs.json": {
|
||||
"bytes": 84849,
|
||||
"sha256": "9f18698d9b327c8664461decf939e7fcbb6a756e81f93e88dc1d2d51511a7ea8"
|
||||
},
|
||||
"baseline-inputs.sha256": {
|
||||
"bytes": 29893,
|
||||
"sha256": "a287f6218039b825bb84c5902d68f0659cbedc9c89d5c2cff6e63fd0a64dfeed"
|
||||
},
|
||||
"baseline-to-fixed.patch": {
|
||||
"bytes": 21127,
|
||||
"sha256": "f3808e3a13fc9244f2301a8f6237fd07d5ed62f496765ef6c281f245713b7e68"
|
||||
},
|
||||
"changed-source-tests.json": {
|
||||
"bytes": 5017,
|
||||
"sha256": "42f770fc3e2384362efd1e416091355c064b6cca22dd40f3b5ef8f7b67e43a52"
|
||||
},
|
||||
"fixed-input-bytes.tar.gz": {
|
||||
"bytes": 811710,
|
||||
"sha256": "ce03510187334794f10c57b3ce022cbb31fb0324a50e9a225a1c8bb9a06540c4"
|
||||
},
|
||||
"fixed-inputs.json": {
|
||||
"bytes": 87745,
|
||||
"sha256": "505c022b46d0871d979c1dc9455a5d0a34ba5442fdeb5bc6195509e56a06b3b2"
|
||||
},
|
||||
"fixed-inputs.sha256": {
|
||||
"bytes": 31194,
|
||||
"sha256": "8f47fbe78ca155f2bc45f5c76e0cc2204af655b5485fc4bb55db5b21f2f7095f"
|
||||
},
|
||||
"preserved-base-test-prefixes.json": {
|
||||
"bytes": 98,
|
||||
"sha256": "fcbb8633c9cf0bdee9aeb1bfa8026c868c880cdbeea5369fa35928a9e87daacb"
|
||||
},
|
||||
"r1-raw-evidence-bytes.tar.gz": {
|
||||
"bytes": 27138,
|
||||
"sha256": "e7edd87316c9617caf2d30f7f8fc2ef38a6e918a781173bd40b251a81f878f6d"
|
||||
},
|
||||
"r1-raw-evidence.json": {
|
||||
"bytes": 2825,
|
||||
"sha256": "e2d81fd97a93d13805fe009428dcab77cafd2e99f6f9330b8ae08bc56af06306"
|
||||
},
|
||||
"source-tests.patch": {
|
||||
"bytes": 40623,
|
||||
"sha256": "a78bc385801b64be270fb9d6e84672c443738a5fce8eb68f7d2a01359a57a770"
|
||||
},
|
||||
"static-dependencies.json": {
|
||||
"bytes": 168863,
|
||||
"sha256": "3a1878a64719ad3c733c4e6a7b3fee091fb97be5591e126a6d2cb971262fc8b1"
|
||||
},
|
||||
"static-overlay-check.json": {
|
||||
"bytes": 186,
|
||||
"sha256": "521a779bb862349c137bd3cce0e319e7565c80657c437cc794bf3f9848689319"
|
||||
},
|
||||
"whole-files.txt": {
|
||||
"bytes": 1217,
|
||||
"sha256": "c32f33ebc78f09a0549b0b0ba185771bf1cdb3149e9579204147f4b827a66a56"
|
||||
}
|
||||
},
|
||||
"fixed_static_input_files": 312,
|
||||
"git_object_format": "sha1",
|
||||
"head": "503b91e56137482abef475bc3b1b72a64b0a329c",
|
||||
"original_base": "09a847edaa25b609bac7728ff83f224708a29399",
|
||||
"review_sha256": "7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008",
|
||||
"status": "UNCOMMITTED_STATIC_PACKET_EXECUTION_PENDING",
|
||||
"whole_test_files": 28
|
||||
}
|
||||
Loaded 100 of 13725 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user