cueline 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +8 -0
- package/.codex-plugin/plugin.json +18 -0
- package/LICENSE +21 -0
- package/README.ja.md +144 -0
- package/README.ko.md +144 -0
- package/README.md +144 -0
- package/README.zh-CN.md +144 -0
- package/README.zh-TW.md +144 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/bin/cueline +14 -0
- package/config/routing.default.json +28 -0
- package/config/routing.schema.json +58 -0
- package/dist/src/api.d.ts +34 -0
- package/dist/src/api.js +153 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/browser/browser-adapter.d.ts +15 -0
- package/dist/src/browser/browser-adapter.js +2 -0
- package/dist/src/browser/browser-adapter.js.map +1 -0
- package/dist/src/browser/codex-iab/bootstrap.d.ts +66 -0
- package/dist/src/browser/codex-iab/bootstrap.js +41 -0
- package/dist/src/browser/codex-iab/bootstrap.js.map +1 -0
- package/dist/src/browser/codex-iab/chatgpt-client.d.ts +10 -0
- package/dist/src/browser/codex-iab/chatgpt-client.js +180 -0
- package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -0
- package/dist/src/browser/codex-iab/selectors.d.ts +3 -0
- package/dist/src/browser/codex-iab/selectors.js +17 -0
- package/dist/src/browser/codex-iab/selectors.js.map +1 -0
- package/dist/src/cli/main.d.ts +7 -0
- package/dist/src/cli/main.js +196 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/skill-links.d.ts +2 -0
- package/dist/src/cli/skill-links.js +64 -0
- package/dist/src/cli/skill-links.js.map +1 -0
- package/dist/src/core/controller-loop.d.ts +36 -0
- package/dist/src/core/controller-loop.js +292 -0
- package/dist/src/core/controller-loop.js.map +1 -0
- package/dist/src/core/errors.d.ts +10 -0
- package/dist/src/core/errors.js +18 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/ids.d.ts +5 -0
- package/dist/src/core/ids.js +51 -0
- package/dist/src/core/ids.js.map +1 -0
- package/dist/src/core/runtime.d.ts +12 -0
- package/dist/src/core/runtime.js +35 -0
- package/dist/src/core/runtime.js.map +1 -0
- package/dist/src/core/state-machine.d.ts +28 -0
- package/dist/src/core/state-machine.js +99 -0
- package/dist/src/core/state-machine.js.map +1 -0
- package/dist/src/jobs/locks.d.ts +8 -0
- package/dist/src/jobs/locks.js +24 -0
- package/dist/src/jobs/locks.js.map +1 -0
- package/dist/src/jobs/status.d.ts +22 -0
- package/dist/src/jobs/status.js +53 -0
- package/dist/src/jobs/status.js.map +1 -0
- package/dist/src/jobs/supervisor.d.ts +22 -0
- package/dist/src/jobs/supervisor.js +96 -0
- package/dist/src/jobs/supervisor.js.map +1 -0
- package/dist/src/protocol/parse-command.d.ts +2 -0
- package/dist/src/protocol/parse-command.js +23 -0
- package/dist/src/protocol/parse-command.js.map +1 -0
- package/dist/src/protocol/types.d.ts +67 -0
- package/dist/src/protocol/types.js +2 -0
- package/dist/src/protocol/types.js.map +1 -0
- package/dist/src/protocol/validate-command.d.ts +2 -0
- package/dist/src/protocol/validate-command.js +181 -0
- package/dist/src/protocol/validate-command.js.map +1 -0
- package/dist/src/router/availability.d.ts +3 -0
- package/dist/src/router/availability.js +55 -0
- package/dist/src/router/availability.js.map +1 -0
- package/dist/src/router/config-loader.d.ts +3 -0
- package/dist/src/router/config-loader.js +92 -0
- package/dist/src/router/config-loader.js.map +1 -0
- package/dist/src/router/materialize.d.ts +8 -0
- package/dist/src/router/materialize.js +39 -0
- package/dist/src/router/materialize.js.map +1 -0
- package/dist/src/router/resolver.d.ts +6 -0
- package/dist/src/router/resolver.js +55 -0
- package/dist/src/router/resolver.js.map +1 -0
- package/dist/src/router/types.d.ts +24 -0
- package/dist/src/router/types.js +2 -0
- package/dist/src/router/types.js.map +1 -0
- package/dist/src/runners/process-runner.d.ts +15 -0
- package/dist/src/runners/process-runner.js +124 -0
- package/dist/src/runners/process-runner.js.map +1 -0
- package/dist/src/runners/registry.d.ts +17 -0
- package/dist/src/runners/registry.js +57 -0
- package/dist/src/runners/registry.js.map +1 -0
- package/dist/src/runners/runner-adapter.d.ts +32 -0
- package/dist/src/runners/runner-adapter.js +4 -0
- package/dist/src/runners/runner-adapter.js.map +1 -0
- package/dist/src/state/atomic-write.d.ts +1 -0
- package/dist/src/state/atomic-write.js +27 -0
- package/dist/src/state/atomic-write.js.map +1 -0
- package/dist/src/state/event-log.d.ts +8 -0
- package/dist/src/state/event-log.js +56 -0
- package/dist/src/state/event-log.js.map +1 -0
- package/dist/src/state/paths.d.ts +9 -0
- package/dist/src/state/paths.js +37 -0
- package/dist/src/state/paths.js.map +1 -0
- package/dist/src/state/store.d.ts +23 -0
- package/dist/src/state/store.js +108 -0
- package/dist/src/state/store.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +2 -0
- package/dist/src/version.js.map +1 -0
- package/docs/architecture.md +83 -0
- package/docs/assets/README.md +51 -0
- package/docs/assets/cueline-banner-dark.svg +41 -0
- package/docs/assets/cueline-banner-light.svg +41 -0
- package/docs/assets/cueline-loop-en.svg +77 -0
- package/docs/assets/cueline-loop-ja.svg +77 -0
- package/docs/assets/cueline-loop-ko.svg +77 -0
- package/docs/assets/cueline-loop-zh-CN.svg +77 -0
- package/docs/assets/cueline-loop-zh-TW.svg +77 -0
- package/docs/assets/cueline-mark-dark.svg +10 -0
- package/docs/assets/cueline-mark-light.svg +10 -0
- package/docs/assets/cueline-wordmark-dark.svg +19 -0
- package/docs/assets/cueline-wordmark-light.svg +19 -0
- package/docs/compatibility.md +60 -0
- package/docs/controller-protocol.md +106 -0
- package/docs/provenance.md +10 -0
- package/docs/runner-contract.md +61 -0
- package/docs/state-and-recovery.md +67 -0
- package/evals/evals.json +41 -0
- package/install.sh +70 -0
- package/package.json +73 -0
- package/schemas/controller-command.schema.json +53 -0
- package/schemas/controller-observation.schema.json +32 -0
- package/skills/cueline/SKILL.md +80 -0
- package/skills/cueline/agents/openai.yaml +4 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RunPaths {
|
|
2
|
+
home: string;
|
|
3
|
+
runsDir: string;
|
|
4
|
+
runDir: string;
|
|
5
|
+
events: string;
|
|
6
|
+
snapshot: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function defaultCueLineHome(environment?: NodeJS.ProcessEnv): string;
|
|
9
|
+
export declare function runPaths(home: string, runId: string): RunPaths;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { runtimeEnvironment } from "../core/runtime.js";
|
|
4
|
+
const RUN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
5
|
+
export function defaultCueLineHome(environment = runtimeEnvironment()) {
|
|
6
|
+
const configured = environment.CUELINE_HOME;
|
|
7
|
+
const userHome = environment.HOME ?? homedir();
|
|
8
|
+
if (!configured || configured.trim() === "") {
|
|
9
|
+
return path.resolve(userHome, ".cueline");
|
|
10
|
+
}
|
|
11
|
+
if (configured === "~") {
|
|
12
|
+
return path.resolve(userHome);
|
|
13
|
+
}
|
|
14
|
+
if (/^~[/\\]/.test(configured)) {
|
|
15
|
+
return path.resolve(userHome, configured.slice(2));
|
|
16
|
+
}
|
|
17
|
+
return path.resolve(configured);
|
|
18
|
+
}
|
|
19
|
+
export function runPaths(home, runId) {
|
|
20
|
+
if (!RUN_ID_PATTERN.test(runId)) {
|
|
21
|
+
throw new Error(`RUN_ID_INVALID: '${runId}'`);
|
|
22
|
+
}
|
|
23
|
+
const resolvedHome = path.resolve(home);
|
|
24
|
+
const runsDir = path.join(resolvedHome, "runs");
|
|
25
|
+
const runDir = path.join(runsDir, runId);
|
|
26
|
+
if (!runDir.startsWith(runsDir + path.sep)) {
|
|
27
|
+
throw new Error(`RUN_ID_INVALID: '${runId}'`);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
home: resolvedHome,
|
|
31
|
+
runsDir,
|
|
32
|
+
runDir,
|
|
33
|
+
events: path.join(runDir, "events.jsonl"),
|
|
34
|
+
snapshot: path.join(runDir, "snapshot.json"),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/state/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAU5D,MAAM,UAAU,kBAAkB,CAAC,WAAW,GAAsB,kBAAkB,EAAE;IACtF,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC;IAC5C,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa;IAClD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,OAAO;QACP,MAAM;QACN,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC;QACzC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC;KAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type RunEvent } from "./event-log.js";
|
|
2
|
+
import { type RunPaths } from "./paths.js";
|
|
3
|
+
export type RunReducer<State> = (state: State, event: RunEvent) => State;
|
|
4
|
+
export interface RunStoreOptions<State> {
|
|
5
|
+
home: string;
|
|
6
|
+
runId: string;
|
|
7
|
+
initialState: State;
|
|
8
|
+
reducer: RunReducer<State>;
|
|
9
|
+
now?: () => Date;
|
|
10
|
+
}
|
|
11
|
+
export declare class RunStore<State> {
|
|
12
|
+
#private;
|
|
13
|
+
readonly paths: RunPaths;
|
|
14
|
+
readonly runId: string;
|
|
15
|
+
private constructor();
|
|
16
|
+
static create<State>(options: RunStoreOptions<State>): Promise<RunStore<State>>;
|
|
17
|
+
static load<State>(options: RunStoreOptions<State>): Promise<RunStore<State>>;
|
|
18
|
+
get state(): State;
|
|
19
|
+
get lastSequence(): number;
|
|
20
|
+
append(type: string, payload: unknown): Promise<RunEvent>;
|
|
21
|
+
snapshot(): Promise<void>;
|
|
22
|
+
replay(): Promise<State>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { atomicWriteJson } from "./atomic-write.js";
|
|
3
|
+
import { appendEvent, readEvents } from "./event-log.js";
|
|
4
|
+
import { runPaths } from "./paths.js";
|
|
5
|
+
const STATE_PROTOCOL = "cueline/state/0.1";
|
|
6
|
+
function clone(value) {
|
|
7
|
+
return structuredClone(value);
|
|
8
|
+
}
|
|
9
|
+
function parseSnapshot(contents, runId) {
|
|
10
|
+
const parsed = JSON.parse(contents);
|
|
11
|
+
if (parsed.protocol !== STATE_PROTOCOL ||
|
|
12
|
+
parsed.run_id !== runId ||
|
|
13
|
+
!Number.isSafeInteger(parsed.last_sequence) ||
|
|
14
|
+
parsed.last_sequence < 0 ||
|
|
15
|
+
parsed.state === undefined) {
|
|
16
|
+
throw new Error("STATE_SNAPSHOT_INVALID");
|
|
17
|
+
}
|
|
18
|
+
return parsed;
|
|
19
|
+
}
|
|
20
|
+
export class RunStore {
|
|
21
|
+
paths;
|
|
22
|
+
runId;
|
|
23
|
+
#initialState;
|
|
24
|
+
#reducer;
|
|
25
|
+
#now;
|
|
26
|
+
#state;
|
|
27
|
+
#lastSequence;
|
|
28
|
+
constructor(options, state, lastSequence) {
|
|
29
|
+
this.runId = options.runId;
|
|
30
|
+
this.paths = runPaths(options.home, options.runId);
|
|
31
|
+
this.#initialState = clone(options.initialState);
|
|
32
|
+
this.#reducer = options.reducer;
|
|
33
|
+
this.#now = options.now ?? (() => new Date());
|
|
34
|
+
this.#state = clone(state);
|
|
35
|
+
this.#lastSequence = lastSequence;
|
|
36
|
+
}
|
|
37
|
+
static async create(options) {
|
|
38
|
+
const paths = runPaths(options.home, options.runId);
|
|
39
|
+
await mkdir(paths.runDir, { recursive: true });
|
|
40
|
+
const existing = await readEvents(paths.events);
|
|
41
|
+
if (existing.length > 0) {
|
|
42
|
+
throw new Error(`RUN_ALREADY_EXISTS: '${options.runId}'`);
|
|
43
|
+
}
|
|
44
|
+
return new RunStore(options, options.initialState, 0);
|
|
45
|
+
}
|
|
46
|
+
static async load(options) {
|
|
47
|
+
const paths = runPaths(options.home, options.runId);
|
|
48
|
+
const events = await readEvents(paths.events);
|
|
49
|
+
let state = clone(options.initialState);
|
|
50
|
+
let lastSequence = 0;
|
|
51
|
+
try {
|
|
52
|
+
const snapshot = parseSnapshot(await readFile(paths.snapshot, "utf8"), options.runId);
|
|
53
|
+
if (snapshot.last_sequence <= events.length) {
|
|
54
|
+
state = clone(snapshot.state);
|
|
55
|
+
lastSequence = snapshot.last_sequence;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
state = clone(options.initialState);
|
|
60
|
+
lastSequence = 0;
|
|
61
|
+
}
|
|
62
|
+
for (const event of events) {
|
|
63
|
+
if (event.sequence > lastSequence) {
|
|
64
|
+
state = options.reducer(state, event);
|
|
65
|
+
lastSequence = event.sequence;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return new RunStore(options, state, lastSequence);
|
|
69
|
+
}
|
|
70
|
+
get state() {
|
|
71
|
+
return clone(this.#state);
|
|
72
|
+
}
|
|
73
|
+
get lastSequence() {
|
|
74
|
+
return this.#lastSequence;
|
|
75
|
+
}
|
|
76
|
+
async append(type, payload) {
|
|
77
|
+
if (type.trim() === "") {
|
|
78
|
+
throw new Error("EVENT_TYPE_INVALID");
|
|
79
|
+
}
|
|
80
|
+
const event = {
|
|
81
|
+
sequence: this.#lastSequence + 1,
|
|
82
|
+
timestamp: this.#now().toISOString(),
|
|
83
|
+
type,
|
|
84
|
+
payload,
|
|
85
|
+
};
|
|
86
|
+
await appendEvent(this.paths.events, event);
|
|
87
|
+
this.#state = this.#reducer(this.#state, event);
|
|
88
|
+
this.#lastSequence = event.sequence;
|
|
89
|
+
return event;
|
|
90
|
+
}
|
|
91
|
+
async snapshot() {
|
|
92
|
+
const snapshot = {
|
|
93
|
+
protocol: STATE_PROTOCOL,
|
|
94
|
+
run_id: this.runId,
|
|
95
|
+
last_sequence: this.#lastSequence,
|
|
96
|
+
state: this.#state,
|
|
97
|
+
};
|
|
98
|
+
await atomicWriteJson(this.paths.snapshot, snapshot);
|
|
99
|
+
}
|
|
100
|
+
async replay() {
|
|
101
|
+
let state = clone(this.#initialState);
|
|
102
|
+
for (const event of await readEvents(this.paths.events)) {
|
|
103
|
+
state = this.#reducer(state, event);
|
|
104
|
+
}
|
|
105
|
+
return state;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CUELINE_VERSION = "0.1.0";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## System boundary
|
|
4
|
+
|
|
5
|
+
CueLine splits decision authority from local execution:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
ChatGPT web conversation (controller)
|
|
9
|
+
^ |
|
|
10
|
+
observation| |<CueLineControl>
|
|
11
|
+
| v
|
|
12
|
+
Codex + CueLine (intermediary and policy enforcement)
|
|
13
|
+
|
|
|
14
|
+
v
|
|
15
|
+
registered local workers and filesystem state
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The ChatGPT web page is the top-level controller. It decides whether the run should dispatch work, wait, inspect evidence, complete, or stop as blocked. It has no direct local tools or filesystem access. Codex supplies the built-in in-app Browser (IAB); CueLine converts persisted local evidence into controller observations and converts a validated controller command into a local action.
|
|
19
|
+
|
|
20
|
+
CueLine is standalone. Its runtime does not import Omnilane or GPT Relay, and it does not read either project's state or configuration.
|
|
21
|
+
|
|
22
|
+
## Components
|
|
23
|
+
|
|
24
|
+
### Browser adapter
|
|
25
|
+
|
|
26
|
+
`src/browser/codex-iab/` implements a text-only adapter over Codex's IAB client. It claims an existing ChatGPT tab when possible, otherwise opens the requested ChatGPT URL. It fills the composer, sends one turn, waits for a stable completed assistant message, and records the resulting conversation URL.
|
|
27
|
+
|
|
28
|
+
The adapter can receive an injected browser or resolve `globalThis.iab` / `agent.browsers.get("iab")` from Codex's runtime. Plain Node does not provide these globals.
|
|
29
|
+
|
|
30
|
+
### Controller protocol
|
|
31
|
+
|
|
32
|
+
`src/protocol/` extracts the last complete `<CueLineControl>` envelope and validates it against the exact pending `run_id`, `round`, and `request_id`. Invalid output is returned to the same controller for a bounded repair attempt. This rejects stale replies and unrelated JSON from earlier parts of a conversation.
|
|
33
|
+
|
|
34
|
+
### Controller loop
|
|
35
|
+
|
|
36
|
+
`src/core/controller-loop.ts` owns the run:
|
|
37
|
+
|
|
38
|
+
1. Persist the intended controller turn.
|
|
39
|
+
2. Send an observation through the browser adapter.
|
|
40
|
+
3. Persist the assistant response.
|
|
41
|
+
4. Validate and persist the accepted command.
|
|
42
|
+
5. Execute the command through the local supervisor.
|
|
43
|
+
6. Snapshot the derived state.
|
|
44
|
+
7. Repeat until `complete`, `blocked`, or the round limit is reached.
|
|
45
|
+
|
|
46
|
+
The default limits are 12 controller rounds and two repair attempts per pending command.
|
|
47
|
+
|
|
48
|
+
### Routing and runners
|
|
49
|
+
|
|
50
|
+
`src/router/` chooses an enabled, available candidate before any process starts. `src/runners/` requires an explicitly registered `argv[0]`, uses `spawn` with `shell: false`, and never performs post-spawn fallback. `src/jobs/` coordinates foreground/background execution and persists job status.
|
|
51
|
+
|
|
52
|
+
### Durable state
|
|
53
|
+
|
|
54
|
+
`src/state/` writes a per-run JSONL event log and an atomic materialized snapshot. The event log is authoritative; a snapshot is a replay optimization. Job status files are atomically replaced.
|
|
55
|
+
|
|
56
|
+
## Authority and trust
|
|
57
|
+
|
|
58
|
+
The controller can request local work, but a request is not equivalent to process access. CueLine applies these gates:
|
|
59
|
+
|
|
60
|
+
- exact run/round/request identity
|
|
61
|
+
- structurally valid command and unique `job_key`
|
|
62
|
+
- configured lane and pre-spawn candidate availability
|
|
63
|
+
- config-derived registered executable allow-list
|
|
64
|
+
- no shell interpolation
|
|
65
|
+
- deterministic job identity and duplicate-dispatch suppression
|
|
66
|
+
- no nested CueLine routing (`CUELINE_DEPTH`)
|
|
67
|
+
- no retry after a worker has started
|
|
68
|
+
|
|
69
|
+
These gates reduce accidental execution ambiguity; they do not make an allowed worker harmless. The local Codex/operator environment remains responsible for filesystem, network, credential, and side-effect permissions granted to each registered executable.
|
|
70
|
+
|
|
71
|
+
## Data flow
|
|
72
|
+
|
|
73
|
+
1. The original user request becomes part of every controller observation.
|
|
74
|
+
2. Job outputs and errors are stored locally and included in later observations (individual fields are bounded before browser submission).
|
|
75
|
+
3. ChatGPT returns a command; only the control envelope is machine-executed.
|
|
76
|
+
4. On `complete`, CueLine returns `final_delivery_text` to Codex.
|
|
77
|
+
5. On `blocked`, CueLine preserves the controller's reason and optional delivery text.
|
|
78
|
+
|
|
79
|
+
CueLine does not intentionally inspect or export cookies, tokens, environment secrets, or browser session material. The IAB uses the user's already authenticated page.
|
|
80
|
+
|
|
81
|
+
## Dependency model
|
|
82
|
+
|
|
83
|
+
The published JavaScript has zero runtime npm dependencies and uses Node built-ins. TypeScript and Node type definitions are development dependencies only. Live ChatGPT orchestration additionally depends on Codex's IAB runtime and ChatGPT's current web UI; the bundled default local route also expects the `codex` CLI on `PATH`. The core state, protocol, router, and fake tests run in plain Node.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Brand assets
|
|
2
|
+
|
|
3
|
+
Original CueLine artwork. Plain SVG, no external fonts, no embedded raster images, no third-party material.
|
|
4
|
+
|
|
5
|
+
| File | Use |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `cueline-mark-{light,dark}.svg` | Square mark, 48×48 grid. Readable down to 16 px. |
|
|
8
|
+
| `cueline-wordmark-{light,dark}.svg` | Wordmark alone, for headers and docs. |
|
|
9
|
+
| `cueline-banner-{light,dark}.svg` | README banner, 1280×320. |
|
|
10
|
+
| `cueline-loop-{en,zh-TW,zh-CN,ja,ko}.svg` | The run figure, 1000×590, one per README language. |
|
|
11
|
+
|
|
12
|
+
The mark, wordmark, and banner ship as a light/dark pair; pick one with a `<picture>` block so GitHub serves the right file:
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<picture>
|
|
16
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/cueline-banner-dark.svg">
|
|
17
|
+
<img alt="CueLine" src="docs/assets/cueline-banner-light.svg">
|
|
18
|
+
</picture>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The run figure is a single file per language instead: it carries its own `@media (prefers-color-scheme: dark)` block and a transparent ground, so one `<img>` serves both themes and sits directly on the reader's canvas.
|
|
22
|
+
|
|
23
|
+
## The mark
|
|
24
|
+
|
|
25
|
+
A stage manager marks a cue in the margin of the promptbook: a vertical rule down the page, a caret at the exact line where the cue lands. That is the whole product in one drawing — the controller calls the cue, the line it points at is the work, and everything around it stays quiet.
|
|
26
|
+
|
|
27
|
+
The vertical rule is the control loop. The caret is the accepted command. Three horizontal lines are the run; only the cued one is at full weight.
|
|
28
|
+
|
|
29
|
+
## The run figure
|
|
30
|
+
|
|
31
|
+
The figure is not a flowchart. It is the promptbook itself: two columns with the cue line down the middle, the controller speaking on the left, the machine working on the right, and one round per group of lines. Commands enter the line as a cue caret; observations leave it. Everything is monospaced, because the whole exchange is a printed log.
|
|
32
|
+
|
|
33
|
+
## Geometry
|
|
34
|
+
|
|
35
|
+
Everything sits on a 48-unit grid with a 3-unit stroke and butt caps. The wordmark is monoline geometric — drawn as paths, so it renders identically without a font. Cap height 32, stroke 3, uniform 10-unit letter gaps. Do not re-set the wordmark in a system font.
|
|
36
|
+
|
|
37
|
+
## Palette
|
|
38
|
+
|
|
39
|
+
| Role | Light | Dark |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| Ink | `#0F1720` | `#E6EDF3` |
|
|
42
|
+
| Muted | `#5B6672` | `#8B949E` |
|
|
43
|
+
| Rule | `#D5DBE2` | `#262C34` |
|
|
44
|
+
| Ground | `#FBFBFC` | `#0D1117` |
|
|
45
|
+
| Cue | `#C8553D` | `#E0674C` |
|
|
46
|
+
|
|
47
|
+
The cue colour is the only accent, and it is only ever applied to the caret and the single cue tick. It is a tally-light red held back to a print vermilion. If a second accent is ever needed, the answer is no.
|
|
48
|
+
|
|
49
|
+
## Not this
|
|
50
|
+
|
|
51
|
+
Gradients, glow, glass, neon, circuitry, brains, robots, isometric clouds, decorative emoji. CueLine is a control surface, not a launch page.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 320" width="1280" height="320" role="img" aria-label="CueLine — ChatGPT directs. Your machine executes.">
|
|
2
|
+
<title>CueLine — ChatGPT directs. Your machine executes.</title>
|
|
3
|
+
<rect width="1280" height="320" fill="#0D1117"/>
|
|
4
|
+
|
|
5
|
+
<g transform="translate(96 92) scale(1.5)">
|
|
6
|
+
<g fill="none" stroke-linecap="butt">
|
|
7
|
+
<path d="M12 8V40" stroke="#E6EDF3" stroke-width="3"/>
|
|
8
|
+
<path d="M26 15H40" stroke="#8B949E" stroke-width="3"/>
|
|
9
|
+
<path d="M26 24H40" stroke="#E6EDF3" stroke-width="3"/>
|
|
10
|
+
<path d="M26 33H40" stroke="#8B949E" stroke-width="3"/>
|
|
11
|
+
</g>
|
|
12
|
+
<path d="M14 18.5 23 24l-9 5.5z" fill="#E0674C"/>
|
|
13
|
+
</g>
|
|
14
|
+
|
|
15
|
+
<g transform="translate(200 110) scale(0.75)">
|
|
16
|
+
<g fill="none" stroke="#E6EDF3" stroke-width="3" stroke-linecap="butt" stroke-linejoin="miter">
|
|
17
|
+
<path d="M21.81 14.68A11.5 14.5 0 1 0 21.81 33.32"/>
|
|
18
|
+
<path d="M31.5 8V24A11.5 14.5 0 0 0 54.5 24V8"/>
|
|
19
|
+
<path d="M64.5 8V40"/>
|
|
20
|
+
<path d="M63 9.5H83"/>
|
|
21
|
+
<path d="M63 24H79"/>
|
|
22
|
+
<path d="M63 38.5H83"/>
|
|
23
|
+
<path d="M93.5 8V38.5"/>
|
|
24
|
+
<path d="M92 38.5H112"/>
|
|
25
|
+
<path d="M120.5 8V40"/>
|
|
26
|
+
<path d="M132.5 40V8L155.5 40V8"/>
|
|
27
|
+
<path d="M167.5 8V40"/>
|
|
28
|
+
<path d="M166 9.5H186"/>
|
|
29
|
+
<path d="M166 24H182"/>
|
|
30
|
+
<path d="M166 38.5H186"/>
|
|
31
|
+
</g>
|
|
32
|
+
</g>
|
|
33
|
+
|
|
34
|
+
<text x="96" y="214" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="19" fill="#8B949E" textLength="434" lengthAdjust="spacingAndGlyphs">ChatGPT directs. Your machine executes.</text>
|
|
35
|
+
|
|
36
|
+
<g stroke="#262C34" stroke-width="1">
|
|
37
|
+
<path d="M96 252.5H1184"/>
|
|
38
|
+
<path d="M96 253v6M160 253v6M224 253v6M288 253v6M416 253v6M480 253v6M544 253v6M608 253v6M672 253v6M736 253v6M800 253v6M864 253v6M928 253v6M992 253v6M1056 253v6M1120 253v6M1184 253v6"/>
|
|
39
|
+
</g>
|
|
40
|
+
<path d="M352 253v13" stroke="#E0674C" stroke-width="2"/>
|
|
41
|
+
</svg>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 320" width="1280" height="320" role="img" aria-label="CueLine — ChatGPT directs. Your machine executes.">
|
|
2
|
+
<title>CueLine — ChatGPT directs. Your machine executes.</title>
|
|
3
|
+
<rect width="1280" height="320" fill="#FFFFFF"/>
|
|
4
|
+
|
|
5
|
+
<g transform="translate(96 92) scale(1.5)">
|
|
6
|
+
<g fill="none" stroke-linecap="butt">
|
|
7
|
+
<path d="M12 8V40" stroke="#0F1720" stroke-width="3"/>
|
|
8
|
+
<path d="M26 15H40" stroke="#5B6672" stroke-width="3"/>
|
|
9
|
+
<path d="M26 24H40" stroke="#0F1720" stroke-width="3"/>
|
|
10
|
+
<path d="M26 33H40" stroke="#5B6672" stroke-width="3"/>
|
|
11
|
+
</g>
|
|
12
|
+
<path d="M14 18.5 23 24l-9 5.5z" fill="#C8553D"/>
|
|
13
|
+
</g>
|
|
14
|
+
|
|
15
|
+
<g transform="translate(200 110) scale(0.75)">
|
|
16
|
+
<g fill="none" stroke="#0F1720" stroke-width="3" stroke-linecap="butt" stroke-linejoin="miter">
|
|
17
|
+
<path d="M21.81 14.68A11.5 14.5 0 1 0 21.81 33.32"/>
|
|
18
|
+
<path d="M31.5 8V24A11.5 14.5 0 0 0 54.5 24V8"/>
|
|
19
|
+
<path d="M64.5 8V40"/>
|
|
20
|
+
<path d="M63 9.5H83"/>
|
|
21
|
+
<path d="M63 24H79"/>
|
|
22
|
+
<path d="M63 38.5H83"/>
|
|
23
|
+
<path d="M93.5 8V38.5"/>
|
|
24
|
+
<path d="M92 38.5H112"/>
|
|
25
|
+
<path d="M120.5 8V40"/>
|
|
26
|
+
<path d="M132.5 40V8L155.5 40V8"/>
|
|
27
|
+
<path d="M167.5 8V40"/>
|
|
28
|
+
<path d="M166 9.5H186"/>
|
|
29
|
+
<path d="M166 24H182"/>
|
|
30
|
+
<path d="M166 38.5H186"/>
|
|
31
|
+
</g>
|
|
32
|
+
</g>
|
|
33
|
+
|
|
34
|
+
<text x="96" y="214" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="19" fill="#5B6672" textLength="434" lengthAdjust="spacingAndGlyphs">ChatGPT directs. Your machine executes.</text>
|
|
35
|
+
|
|
36
|
+
<g stroke="#D5DBE2" stroke-width="1">
|
|
37
|
+
<path d="M96 252.5H1184"/>
|
|
38
|
+
<path d="M96 253v6M160 253v6M224 253v6M288 253v6M416 253v6M480 253v6M544 253v6M608 253v6M672 253v6M736 253v6M800 253v6M864 253v6M928 253v6M992 253v6M1056 253v6M1120 253v6M1184 253v6"/>
|
|
39
|
+
</g>
|
|
40
|
+
<path d="M352 253v13" stroke="#C8553D" stroke-width="2"/>
|
|
41
|
+
</svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 590" width="1000" height="590" role="img" aria-label="A CueLine run read as a promptbook: the machine reports an observation, the controller calls one command, the registered runner executes it, until the controller calls complete.">
|
|
2
|
+
<title>A CueLine run, read as a promptbook</title>
|
|
3
|
+
<style>
|
|
4
|
+
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace }
|
|
5
|
+
.hd { fill: #0F1720; font-size: 17px; letter-spacing: .02em }
|
|
6
|
+
.sub { fill: #8B949E; font-size: 13.5px }
|
|
7
|
+
.rule { stroke: #E4E8EC; stroke-width: 1 }
|
|
8
|
+
.spine{ stroke: #0F1720; stroke-width: 2 }
|
|
9
|
+
.tick { stroke: #C3CAD2; stroke-width: 1 }
|
|
10
|
+
.say { fill: #C8553D; font-size: 15px }
|
|
11
|
+
.obs { fill: #4A5561; font-size: 15px }
|
|
12
|
+
.note { fill: #8B949E; font-size: 13.5px }
|
|
13
|
+
.rnd { fill: #B6BEC7; font-size: 12px; letter-spacing: .14em }
|
|
14
|
+
.foot { fill: #8B949E; font-size: 13.5px }
|
|
15
|
+
.cue { fill: #C8553D }
|
|
16
|
+
@media (prefers-color-scheme: dark) {
|
|
17
|
+
.hd { fill: #E6EDF3 }
|
|
18
|
+
.sub, .note, .foot { fill: #7D8590 }
|
|
19
|
+
.rule { stroke: #21262D }
|
|
20
|
+
.spine { stroke: #C9D1D9 }
|
|
21
|
+
.tick { stroke: #30363D }
|
|
22
|
+
.say { fill: #E0674C }
|
|
23
|
+
.obs { fill: #ADBAC7 }
|
|
24
|
+
.rnd { fill: #484F58 }
|
|
25
|
+
.cue { fill: #E0674C }
|
|
26
|
+
}
|
|
27
|
+
</style>
|
|
28
|
+
|
|
29
|
+
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT web conversation</text>
|
|
30
|
+
<text x="505" y="64" class="sub" text-anchor="end">the controller — plans, calls, judges</text>
|
|
31
|
+
<text x="555" y="44" class="hd">your machine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">CueLine — validates, routes, executes, records</text>
|
|
33
|
+
|
|
34
|
+
<path d="M40 84H505" class="rule"/>
|
|
35
|
+
<path d="M555 84H960" class="rule"/>
|
|
36
|
+
<path d="M530 84V520" class="spine"/>
|
|
37
|
+
|
|
38
|
+
<text x="40" y="126" class="rnd">ROUND 1</text>
|
|
39
|
+
<path d="M505 122H524" class="tick"/>
|
|
40
|
+
<text x="555" y="126" class="obs">observation · your request, no jobs yet</text>
|
|
41
|
+
<path d="M524 118 517 122 524 126z" class="cue"/>
|
|
42
|
+
|
|
43
|
+
<path d="M536 158 545 162 536 166z" class="cue"/>
|
|
44
|
+
<text x="505" y="166" class="say" text-anchor="end">dispatch · review · lane default · advise</text>
|
|
45
|
+
<path d="M545 162H565" class="tick"/>
|
|
46
|
+
<text x="575" y="166" class="note">routed before anything starts</text>
|
|
47
|
+
|
|
48
|
+
<text x="555" y="200" class="note">codex exec (read-only) → succeeded</text>
|
|
49
|
+
|
|
50
|
+
<text x="40" y="264" class="rnd">ROUND 2</text>
|
|
51
|
+
<path d="M505 260H524" class="tick"/>
|
|
52
|
+
<text x="555" y="264" class="obs">observation · the evidence, verbatim</text>
|
|
53
|
+
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
|
+
|
|
55
|
+
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · patch · mode work</text>
|
|
57
|
+
<path d="M545 300H565" class="tick"/>
|
|
58
|
+
<text x="575" y="304" class="note">argv[0] must already be allowed</text>
|
|
59
|
+
|
|
60
|
+
<text x="555" y="338" class="note">codex exec (workspace-write) → succeeded</text>
|
|
61
|
+
|
|
62
|
+
<text x="40" y="402" class="rnd">ROUND 3</text>
|
|
63
|
+
<path d="M505 398H524" class="tick"/>
|
|
64
|
+
<text x="555" y="402" class="obs">observation · updated evidence</text>
|
|
65
|
+
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
|
+
|
|
67
|
+
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
68
|
+
<text x="505" y="442" class="say" text-anchor="end">complete · final_delivery_text</text>
|
|
69
|
+
<path d="M545 438H565" class="tick"/>
|
|
70
|
+
<text x="575" y="442" class="note">returned to you, verbatim</text>
|
|
71
|
+
|
|
72
|
+
<text x="555" y="476" class="note">run sealed · events.jsonl is the record</text>
|
|
73
|
+
|
|
74
|
+
<path d="M40 520H960" class="rule"/>
|
|
75
|
+
<text x="40" y="546" class="foot">Five actions only — dispatch · wait · inspect · complete · blocked.</text>
|
|
76
|
+
<text x="40" y="568" class="foot">Nothing outside the envelope is executed. No worker is retried once it has started.</text>
|
|
77
|
+
</svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 590" width="1000" height="590" role="img" aria-label="CueLine の 1 回の実行をプロンプトブックとして読む:マシンが観測を送り、コントローラーがコマンドを 1 つ出し、登録済みの runner が実行し、complete が出るまで続く。">
|
|
2
|
+
<title>CueLine の実行を、プロンプトブックとして読む</title>
|
|
3
|
+
<style>
|
|
4
|
+
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Hiragino Sans", "Noto Sans CJK JP", "Yu Gothic", monospace }
|
|
5
|
+
.hd { fill: #0F1720; font-size: 17px; letter-spacing: .02em }
|
|
6
|
+
.sub { fill: #8B949E; font-size: 13.5px }
|
|
7
|
+
.rule { stroke: #E4E8EC; stroke-width: 1 }
|
|
8
|
+
.spine{ stroke: #0F1720; stroke-width: 2 }
|
|
9
|
+
.tick { stroke: #C3CAD2; stroke-width: 1 }
|
|
10
|
+
.say { fill: #C8553D; font-size: 15px }
|
|
11
|
+
.obs { fill: #4A5561; font-size: 15px }
|
|
12
|
+
.note { fill: #8B949E; font-size: 13.5px }
|
|
13
|
+
.rnd { fill: #B6BEC7; font-size: 12px; letter-spacing: .14em }
|
|
14
|
+
.foot { fill: #8B949E; font-size: 13.5px }
|
|
15
|
+
.cue { fill: #C8553D }
|
|
16
|
+
@media (prefers-color-scheme: dark) {
|
|
17
|
+
.hd { fill: #E6EDF3 }
|
|
18
|
+
.sub, .note, .foot { fill: #7D8590 }
|
|
19
|
+
.rule { stroke: #21262D }
|
|
20
|
+
.spine { stroke: #C9D1D9 }
|
|
21
|
+
.tick { stroke: #30363D }
|
|
22
|
+
.say { fill: #E0674C }
|
|
23
|
+
.obs { fill: #ADBAC7 }
|
|
24
|
+
.rnd { fill: #484F58 }
|
|
25
|
+
.cue { fill: #E0674C }
|
|
26
|
+
}
|
|
27
|
+
</style>
|
|
28
|
+
|
|
29
|
+
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT ウェブ会話</text>
|
|
30
|
+
<text x="505" y="64" class="sub" text-anchor="end">コントローラー — 計画し、指示し、判断する</text>
|
|
31
|
+
<text x="555" y="44" class="hd">あなたのマシン</text>
|
|
32
|
+
<text x="555" y="64" class="sub">CueLine — 検証・ルーティング・実行・記録</text>
|
|
33
|
+
|
|
34
|
+
<path d="M40 84H505" class="rule"/>
|
|
35
|
+
<path d="M555 84H960" class="rule"/>
|
|
36
|
+
<path d="M530 84V520" class="spine"/>
|
|
37
|
+
|
|
38
|
+
<text x="40" y="126" class="rnd">ラウンド 1</text>
|
|
39
|
+
<path d="M505 122H524" class="tick"/>
|
|
40
|
+
<text x="555" y="126" class="obs">observation · あなたの依頼、ジョブはまだない</text>
|
|
41
|
+
<path d="M524 118 517 122 524 126z" class="cue"/>
|
|
42
|
+
|
|
43
|
+
<path d="M536 158 545 162 536 166z" class="cue"/>
|
|
44
|
+
<text x="505" y="166" class="say" text-anchor="end">dispatch · review · lane default · advise</text>
|
|
45
|
+
<path d="M545 162H565" class="tick"/>
|
|
46
|
+
<text x="575" y="166" class="note">プロセス起動の前にルートが決まる</text>
|
|
47
|
+
|
|
48
|
+
<text x="555" y="200" class="note">codex exec(読み取り専用)→ 成功 · 出力を保存</text>
|
|
49
|
+
|
|
50
|
+
<text x="40" y="264" class="rnd">ラウンド 2</text>
|
|
51
|
+
<path d="M505 260H524" class="tick"/>
|
|
52
|
+
<text x="555" y="264" class="obs">observation · 証拠をそのまま</text>
|
|
53
|
+
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
|
+
|
|
55
|
+
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · patch · mode work</text>
|
|
57
|
+
<path d="M545 300H565" class="tick"/>
|
|
58
|
+
<text x="575" y="304" class="note">argv[0] は事前の許可が必要</text>
|
|
59
|
+
|
|
60
|
+
<text x="555" y="338" class="note">codex exec(workspace-write)→ 成功</text>
|
|
61
|
+
|
|
62
|
+
<text x="40" y="402" class="rnd">ラウンド 3</text>
|
|
63
|
+
<path d="M505 398H524" class="tick"/>
|
|
64
|
+
<text x="555" y="402" class="obs">observation · 更新された証拠</text>
|
|
65
|
+
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
|
+
|
|
67
|
+
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
68
|
+
<text x="505" y="442" class="say" text-anchor="end">complete · final_delivery_text</text>
|
|
69
|
+
<path d="M545 438H565" class="tick"/>
|
|
70
|
+
<text x="575" y="442" class="note">そのままあなたに返す</text>
|
|
71
|
+
|
|
72
|
+
<text x="555" y="476" class="note">ラン確定 · events.jsonl が記録そのもの</text>
|
|
73
|
+
|
|
74
|
+
<path d="M40 520H960" class="rule"/>
|
|
75
|
+
<text x="40" y="546" class="foot">アクションは 5 つだけ — dispatch · wait · inspect · complete · blocked。</text>
|
|
76
|
+
<text x="40" y="568" class="foot">エンベロープの外は実行されない。起動後のワーカーは再試行しない。</text>
|
|
77
|
+
</svg>
|