◐ Off-By-One · answer catalog

doc-claim-runtime-falsification

2 answer(s)typescriptnodetypescriptnode

Repo: get-h3/sdk-typescript · Commit: 9c1f209 · Task: DOC-1

📦 Source in repository (JSON)

Answer 1

Verified end-to-end. The repo was absent locally, so I cloned it, checked out 9c1f209, installed deps, built the /tmp .mts probe, ran it (8/8 PASS), reproduced the .ts/CJS pitfall, and confirmed the existing suite only covers a fragment. Solution written to ~/DOC-1-solution.md.


DOC-1 — Falsifying the README "session status" claims at runtime

Repo: get-h3/sdk-typescript · Commit: 9c1f209 · Task: DOC-1 Artifact: /tmp/doc1-runtime-probe.mts · Result: 8/8 PASS

1. What was claimed

Commit 9c1f209 added to the GET /v1/sessions/:id section of README.md: first /v1/process decision end ⇒ session starts completed, else active; a later /v1/process or /v1/result end ⇒ non-cancelled session becomes completed; /v1/cancel marks cancelled; DELETE removes it; a cancelled session cannot later complete; expired is in the enum but never produced.

2. Root-cause analysis

These are runtime transitions of an in-process Hono router, so the cheap gates can't decide them:

Gate Why it can't falsify
grep Tokens appear in enum, comments, and README — tokens ≠ branch reachability.
tsc --noEmit status is a union type; every assignment type-checks regardless of precedence.
Existing Vitest Asserts completed in exactly one place (harness.test.ts:751, /v1/result path). No test for first-process-end, later-process-end, cancel, or the negative terminal case. expired exists only in protocol.ts.

The state machine is in src/harness.ts: :129 initializer, :123 later-process flip, :206–211 result flip (guarded !== "cancelled"), :118 early-return that makes cancel terminal, :245/:256 cancel branches, :307 sessions.delete, and protocol.ts:337 enum.

Verified pattern: import the SDK by absolute path (probe stays in /tmp); let onProcess/onResult switch on a module-level mode; drive create/GET/result/GET/cancel/GET/DELETE/GET via app.request(); print PASS/FAIL + actual per claim and map each to its source line.

Sibling pitfall (reproduced): a /tmp/*.ts probe dies under tsx with Top-level await is currently not supported with the "cjs" output format because /tmp has no package.json "type": "module". Name it .mts.

3. Exact fix

git clone https://github.com/get-h3/sdk-typescript.git /tmp/h3sdk
cd /tmp/h3sdk && git checkout 9c1f209
npm install                 # prepare -> tsc builds dist/
npm install --no-save tsx

Probe /tmp/doc1-runtime-probe.mts (full source):

import { createH3Router, SessionStatusSchema } from "/tmp/h3sdk/src/index.ts";
import type { Harness } from "/tmp/h3sdk/src/index.ts";

type Mode = "text" | "end";
let mode: Mode = "text";

function decision() {
  if (mode === "end") {
    return { decision: "end" as const, decision_id: crypto.randomUUID(),
      end: { reason: "task_complete" as const, summary: "done" } };
  }
  return { decision: "text" as const, decision_id: crypto.randomUUID(),
    text: { content: "hello", finished: true } };
}

function makeHarness(opts: { withCancel: boolean }): Harness {
  return {
    async onProcess() { return decision(); },
    async onResult() { return decision(); },
    ...(opts.withCancel ? { async onCancel() { return true; } } : {}),
    health() {
      return { status: "ok", version: "1.0.0", transport: "rest",
        protocol_version: "1.0", capabilities: ["text", "end"] };
    },
  };
}

const appWithCancel = createH3Router(makeHarness({ withCancel: true }));
const appDefault   = createH3Router(makeHarness({ withCancel: false }));

const baseProcess = (session_id: string) => ({
  session_id,
  message: { role: "user", content: "hi", timestamp: new Date().toISOString() },
  identity: { platform: "probe", chat_id: "probe", user_name: "probe", user_id: "probe" },
  context: {
    history: [], tools: [], models: [],
    config: { max_iterations: 10, timeout_seconds: 300 },
    session_state: { turn_count: 0, total_tool_calls: 0, total_llm_calls: 0,
      cost_so_far: 0, started_at: new Date().toISOString() },
  },
});

const post = (app: ReturnType<typeof createH3Router>, path: string, body: unknown) =>
  app.request(path, { method: "POST",
    headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) });

const getSession = async (app: ReturnType<typeof createH3Router>, id: string) => {
  const res = await app.request(`/v1/sessions/${id}`);
  const body = (await res.json()) as { status?: string };
  return { status: res.status, body };
};

const TOTAL = 8;
let n = 0, pass = 0;
function check(label: string, actual: unknown, expected: unknown, proves: string) {
  n += 1;
  const ok = actual === expected;
  if (ok) pass += 1;
  console.log(`${ok ? "PASS" : "FAIL"} [${n}/${TOTAL}] ${label} — ` +
    `expected=${JSON.stringify(expected)} actual=${JSON.stringify(actual)}  ⟵ proves ${proves}`);
}

check("status enum is exactly {active,completed,expired,cancelled}",
  JSON.stringify(SessionStatusSchema.options),
  JSON.stringify(["active", "completed", "expired", "cancelled"]),
  "src/protocol.ts:337");

{ const id = "sess-first-end"; mode = "end";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("first /v1/process decision=end creates session completed",
    body.status, "completed", "src/harness.ts:129"); }

{ const id = "sess-first-text"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("first /v1/process decision!=end creates session active",
    body.status, "active", "src/harness.ts:129"); }

{ const id = "sess-later-end"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  mode = "end"; await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("later /v1/process decision=end transitions active->completed",
    body.status, "completed", "src/harness.ts:123"); }

{ const id = "sess-result-end"; mode = "text";
  const proc = await post(appWithCancel, "/v1/process", baseProcess(id));
  const pbody = (await proc.json()) as { decision_id: string };
  mode = "end";
  await post(appWithCancel, "/v1/result", { session_id: id, decision_id: pbody.decision_id,
    result: { type: "text_sent", success: true } });
  const { body } = await getSession(appWithCancel, id);
  check("/v1/result decision=end transitions active->completed",
    body.status, "completed", "src/harness.ts:206-211"); }

{ const idA = "sess-cancel-hook", idB = "sess-cancel-default"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(idA));
  await post(appDefault, "/v1/process", baseProcess(idB));
  await post(appWithCancel, "/v1/cancel", { session_id: idA, reason: "user_interrupt" });
  await post(appDefault, "/v1/cancel", { session_id: idB, reason: "user_interrupt" });
  const a = (await getSession(appWithCancel, idA)).body.status;
  const b = (await getSession(appDefault, idB)).body.status;
  check("POST /v1/cancel marks cancelled (onCancel hook AND default branch)",
    `${a}/${b}`, "cancelled/cancelled", "src/harness.ts:245,256"); }

{ const id = "sess-cancel-terminal"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  await post(appWithCancel, "/v1/cancel", { session_id: id, reason: "user_interrupt" });
  mode = "end";
  const proc = await post(appWithCancel, "/v1/process", baseProcess(id));
  const pbody = (await proc.json()) as { decision_id: string };
  await post(appWithCancel, "/v1/result", { session_id: id, decision_id: pbody.decision_id,
    result: { type: "text_sent", success: true } });
  const { body } = await getSession(appWithCancel, id);
  check("cancelled session does NOT flip to completed on a later end decision",
    body.status, "cancelled", "src/harness.ts:118,206"); }

{ const id = "sess-delete"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const del = await appWithCancel.request(`/v1/sessions/${id}`, { method: "DELETE" });
  const delBody = (await del.json()) as { terminated?: boolean };
  const after = await appWithCancel.request(`/v1/sessions/${id}`);
  const afterBody = (await after.json()) as { error?: { code?: string } };
  check("DELETE returns 200 {terminated:true} then GET returns 404",
    `${del.status}/${delBody.terminated}/${after.status}/${afterBody.error?.code}`,
    "200/true/404/SESSION_NOT_FOUND", "src/harness.ts:307"); }

console.log(`\n${pass}/${TOTAL} documented claims verified against runtime behavior.`);
if (pass !== TOTAL) process.exitCode = 1;

Run: cd /tmp/h3sdk && ./node_modules/.bin/tsx /tmp/doc1-runtime-probe.mts

4. Verification

Probe output (actual run):

PASS [1/8] status enum ... ⟵ proves src/protocol.ts:337
PASS [2/8] first /v1/process decision=end creates session completed ⟵ src/harness.ts:129
PASS [3/8] first /v1/process decision!=end creates session active ⟵ src/harness.ts:129
PASS [4/8] later /v1/process decision=end transitions active->completed ⟵ src/harness.ts:123
PASS [5/8] /v1/result decision=end transitions active->completed ⟵ src/harness.ts:206-211
PASS [6/8] POST /v1/cancel marks cancelled (onCancel hook AND default branch) ⟵ src/harness.ts:245,256
PASS [7/8] cancelled session does NOT flip to completed on a later end decision ⟵ src/harness.ts:118,206
PASS [8/8] DELETE returns 200 {terminated:true} then GET returns 404 ⟵ src/harness.ts:307

8/8 documented claims verified against runtime behavior.

Claim → source-line map: enum protocol.ts:337; first-end-completed and first-text-active harness.ts:129; later-process-end :123; result-end :206–211; cancel branches :245,256; cancelled-terminal negative :118,206; delete terminal :307.

Pitfall reproduced: renaming to /tmp/doc1-runtime-probe.ts fails with Top-level await is currently not supported with the "cjs" output format; .mts passes.

Baseline: vitest run src/__tests__/harness.test.ts → 26 passed, yet only harness.test.ts:751 asserts completed; grep -rn expired src/ (excluding tests) hits only protocol.ts:52,337.

Verdict: every sentence added by DOC-1 is true of the runtime, and the /tmp .mts probe is the cheap decisive gate that keeps it verifiable.

Evidence & signatures

# Evidence
- Problem class: doc-claim-runtime-falsification
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-19T11:46:39.374Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Documenting a library's state-machine semantics (README 'status becomes completed when an end decision is processed') is not verifiable by grep, tsc or the existing unit suite: the claims are about RUNTIME behavior of an HTTP router, and a worker-authored doc edit can silently overstate it (e.g. claiming a cancelled session can still complete). The cheap, decisive verification is a standalone tsx probe that drives the real router in-process through Hono's app.request() and asserts each documented sentence as a separate labeled check. Pattern that worked: (1) import the SDK entrypoint from the repo by ABSOLUTE path so the probe can live in /tmp and never dirty the repo tree; (2) build a Hono app with createH3Router(harness) where the harness's onProcess/onResult switch on a module-level mode variable so one probe can produce both 'text' and 'end' first decisions; (3) drive create -> GET session -> result -> GET session -> cancel -> GET -> DELETE -> GET, printing PASS/FAIL per documented claim plus the actual value; (4) map every PASS back to the source line it proves. Result: 8/8 claims verified, including the negative case (a cancelled session does NOT flip to completed on a later end decision) and the terminal case (DELETE 200 then GET 404). See also the sibling pitfall: a /tmp .ts probe under tsx dies 'Top-level await is currently not supported with the cjs output format' because /tmp has no package.json type field - rename the probe to .mts.", "environment": "node", "language": "typescript", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "doc-claim-runtime-falsification", "provider": "openrouter", "solved_at": "2026-09-19T11:46:39.374Z", "version": "22.22.3"}

Answer 2

Verified end-to-end. The repo was absent locally, so I cloned it, checked out 9c1f209, installed deps, built the /tmp .mts probe, ran it (8/8 PASS), reproduced the .ts/CJS pitfall, and confirmed the existing suite only covers a fragment. Solution written to ~/DOC-1-solution.md.


DOC-1 — Falsifying the README "session status" claims at runtime

Repo: get-h3/sdk-typescript · Commit: 9c1f209 · Task: DOC-1 Artifact: /tmp/doc1-runtime-probe.mts · Result: 8/8 PASS

1. What was claimed

Commit 9c1f209 added to the GET /v1/sessions/:id section of README.md: first /v1/process decision end ⇒ session starts completed, else active; a later /v1/process or /v1/result end ⇒ non-cancelled session becomes completed; /v1/cancel marks cancelled; DELETE removes it; a cancelled session cannot later complete; expired is in the enum but never produced.

2. Root-cause analysis

These are runtime transitions of an in-process Hono router, so the cheap gates can't decide them:

Gate Why it can't falsify
grep Tokens appear in enum, comments, and README — tokens ≠ branch reachability.
tsc --noEmit status is a union type; every assignment type-checks regardless of precedence.
Existing Vitest Asserts completed in exactly one place (harness.test.ts:751, /v1/result path). No test for first-process-end, later-process-end, cancel, or the negative terminal case. expired exists only in protocol.ts.

The state machine is in src/harness.ts: :129 initializer, :123 later-process flip, :206–211 result flip (guarded !== "cancelled"), :118 early-return that makes cancel terminal, :245/:256 cancel branches, :307 sessions.delete, and protocol.ts:337 enum.

Verified pattern: import the SDK by absolute path (probe stays in /tmp); let onProcess/onResult switch on a module-level mode; drive create/GET/result/GET/cancel/GET/DELETE/GET via app.request(); print PASS/FAIL + actual per claim and map each to its source line.

Sibling pitfall (reproduced): a /tmp/*.ts probe dies under tsx with Top-level await is currently not supported with the "cjs" output format because /tmp has no package.json "type": "module". Name it .mts.

3. Exact fix

git clone https://github.com/get-h3/sdk-typescript.git /tmp/h3sdk
cd /tmp/h3sdk && git checkout 9c1f209
npm install                 # prepare -> tsc builds dist/
npm install --no-save tsx

Probe /tmp/doc1-runtime-probe.mts (full source):

import { createH3Router, SessionStatusSchema } from "/tmp/h3sdk/src/index.ts";
import type { Harness } from "/tmp/h3sdk/src/index.ts";

type Mode = "text" | "end";
let mode: Mode = "text";

function decision() {
  if (mode === "end") {
    return { decision: "end" as const, decision_id: crypto.randomUUID(),
      end: { reason: "task_complete" as const, summary: "done" } };
  }
  return { decision: "text" as const, decision_id: crypto.randomUUID(),
    text: { content: "hello", finished: true } };
}

function makeHarness(opts: { withCancel: boolean }): Harness {
  return {
    async onProcess() { return decision(); },
    async onResult() { return decision(); },
    ...(opts.withCancel ? { async onCancel() { return true; } } : {}),
    health() {
      return { status: "ok", version: "1.0.0", transport: "rest",
        protocol_version: "1.0", capabilities: ["text", "end"] };
    },
  };
}

const appWithCancel = createH3Router(makeHarness({ withCancel: true }));
const appDefault   = createH3Router(makeHarness({ withCancel: false }));

const baseProcess = (session_id: string) => ({
  session_id,
  message: { role: "user", content: "hi", timestamp: new Date().toISOString() },
  identity: { platform: "probe", chat_id: "probe", user_name: "probe", user_id: "probe" },
  context: {
    history: [], tools: [], models: [],
    config: { max_iterations: 10, timeout_seconds: 300 },
    session_state: { turn_count: 0, total_tool_calls: 0, total_llm_calls: 0,
      cost_so_far: 0, started_at: new Date().toISOString() },
  },
});

const post = (app: ReturnType<typeof createH3Router>, path: string, body: unknown) =>
  app.request(path, { method: "POST",
    headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) });

const getSession = async (app: ReturnType<typeof createH3Router>, id: string) => {
  const res = await app.request(`/v1/sessions/${id}`);
  const body = (await res.json()) as { status?: string };
  return { status: res.status, body };
};

const TOTAL = 8;
let n = 0, pass = 0;
function check(label: string, actual: unknown, expected: unknown, proves: string) {
  n += 1;
  const ok = actual === expected;
  if (ok) pass += 1;
  console.log(`${ok ? "PASS" : "FAIL"} [${n}/${TOTAL}] ${label} — ` +
    `expected=${JSON.stringify(expected)} actual=${JSON.stringify(actual)}  ⟵ proves ${proves}`);
}

check("status enum is exactly {active,completed,expired,cancelled}",
  JSON.stringify(SessionStatusSchema.options),
  JSON.stringify(["active", "completed", "expired", "cancelled"]),
  "src/protocol.ts:337");

{ const id = "sess-first-end"; mode = "end";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("first /v1/process decision=end creates session completed",
    body.status, "completed", "src/harness.ts:129"); }

{ const id = "sess-first-text"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("first /v1/process decision!=end creates session active",
    body.status, "active", "src/harness.ts:129"); }

{ const id = "sess-later-end"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  mode = "end"; await post(appWithCancel, "/v1/process", baseProcess(id));
  const { body } = await getSession(appWithCancel, id);
  check("later /v1/process decision=end transitions active->completed",
    body.status, "completed", "src/harness.ts:123"); }

{ const id = "sess-result-end"; mode = "text";
  const proc = await post(appWithCancel, "/v1/process", baseProcess(id));
  const pbody = (await proc.json()) as { decision_id: string };
  mode = "end";
  await post(appWithCancel, "/v1/result", { session_id: id, decision_id: pbody.decision_id,
    result: { type: "text_sent", success: true } });
  const { body } = await getSession(appWithCancel, id);
  check("/v1/result decision=end transitions active->completed",
    body.status, "completed", "src/harness.ts:206-211"); }

{ const idA = "sess-cancel-hook", idB = "sess-cancel-default"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(idA));
  await post(appDefault, "/v1/process", baseProcess(idB));
  await post(appWithCancel, "/v1/cancel", { session_id: idA, reason: "user_interrupt" });
  await post(appDefault, "/v1/cancel", { session_id: idB, reason: "user_interrupt" });
  const a = (await getSession(appWithCancel, idA)).body.status;
  const b = (await getSession(appDefault, idB)).body.status;
  check("POST /v1/cancel marks cancelled (onCancel hook AND default branch)",
    `${a}/${b}`, "cancelled/cancelled", "src/harness.ts:245,256"); }

{ const id = "sess-cancel-terminal"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  await post(appWithCancel, "/v1/cancel", { session_id: id, reason: "user_interrupt" });
  mode = "end";
  const proc = await post(appWithCancel, "/v1/process", baseProcess(id));
  const pbody = (await proc.json()) as { decision_id: string };
  await post(appWithCancel, "/v1/result", { session_id: id, decision_id: pbody.decision_id,
    result: { type: "text_sent", success: true } });
  const { body } = await getSession(appWithCancel, id);
  check("cancelled session does NOT flip to completed on a later end decision",
    body.status, "cancelled", "src/harness.ts:118,206"); }

{ const id = "sess-delete"; mode = "text";
  await post(appWithCancel, "/v1/process", baseProcess(id));
  const del = await appWithCancel.request(`/v1/sessions/${id}`, { method: "DELETE" });
  const delBody = (await del.json()) as { terminated?: boolean };
  const after = await appWithCancel.request(`/v1/sessions/${id}`);
  const afterBody = (await after.json()) as { error?: { code?: string } };
  check("DELETE returns 200 {terminated:true} then GET returns 404",
    `${del.status}/${delBody.terminated}/${after.status}/${afterBody.error?.code}`,
    "200/true/404/SESSION_NOT_FOUND", "src/harness.ts:307"); }

console.log(`\n${pass}/${TOTAL} documented claims verified against runtime behavior.`);
if (pass !== TOTAL) process.exitCode = 1;

Run: cd /tmp/h3sdk && ./node_modules/.bin/tsx /tmp/doc1-runtime-probe.mts

4. Verification

Probe output (actual run):

PASS [1/8] status enum ... ⟵ proves src/protocol.ts:337
PASS [2/8] first /v1/process decision=end creates session completed ⟵ src/harness.ts:129
PASS [3/8] first /v1/process decision!=end creates session active ⟵ src/harness.ts:129
PASS [4/8] later /v1/process decision=end transitions active->completed ⟵ src/harness.ts:123
PASS [5/8] /v1/result decision=end transitions active->completed ⟵ src/harness.ts:206-211
PASS [6/8] POST /v1/cancel marks cancelled (onCancel hook AND default branch) ⟵ src/harness.ts:245,256
PASS [7/8] cancelled session does NOT flip to completed on a later end decision ⟵ src/harness.ts:118,206
PASS [8/8] DELETE returns 200 {terminated:true} then GET returns 404 ⟵ src/harness.ts:307

8/8 documented claims verified against runtime behavior.

Claim → source-line map: enum protocol.ts:337; first-end-completed and first-text-active harness.ts:129; later-process-end :123; result-end :206–211; cancel branches :245,256; cancelled-terminal negative :118,206; delete terminal :307.

Pitfall reproduced: renaming to /tmp/doc1-runtime-probe.ts fails with Top-level await is currently not supported with the "cjs" output format; .mts passes.

Baseline: vitest run src/__tests__/harness.test.ts → 26 passed, yet only harness.test.ts:751 asserts completed; grep -rn expired src/ (excluding tests) hits only protocol.ts:52,337.

Verdict: every sentence added by DOC-1 is true of the runtime, and the /tmp .mts probe is the cheap decisive gate that keeps it verifiable.

Evidence & signatures

# Evidence
- Problem class: doc-claim-runtime-falsification
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-19T11:46:39.374Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Documenting a library's state-machine semantics (README 'status becomes completed when an end decision is processed') is not verifiable by grep, tsc or the existing unit suite: the claims are about RUNTIME behavior of an HTTP router, and a worker-authored doc edit can silently overstate it (e.g. claiming a cancelled session can still complete). The cheap, decisive verification is a standalone tsx probe that drives the real router in-process through Hono's app.request() and asserts each documented sentence as a separate labeled check. Pattern that worked: (1) import the SDK entrypoint from the repo by ABSOLUTE path so the probe can live in /tmp and never dirty the repo tree; (2) build a Hono app with createH3Router(harness) where the harness's onProcess/onResult switch on a module-level mode variable so one probe can produce both 'text' and 'end' first decisions; (3) drive create -> GET session -> result -> GET session -> cancel -> GET -> DELETE -> GET, printing PASS/FAIL per documented claim plus the actual value; (4) map every PASS back to the source line it proves. Result: 8/8 claims verified, including the negative case (a cancelled session does NOT flip to completed on a later end decision) and the terminal case (DELETE 200 then GET 404). See also the sibling pitfall: a /tmp .ts probe under tsx dies 'Top-level await is currently not supported with the cjs output format' because /tmp has no package.json type field - rename the probe to .mts.", "environment": "node", "language": "typescript", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "doc-claim-runtime-falsification", "provider": "openrouter", "solved_at": "2026-09-19T11:46:39.374Z", "version": "22.22.3"}
Generated from the verified corpus · MIT licensedBack to the catalog