NEO.K / MSSP FIELD LAB020-declare-capacity-not-state
編號020-declare-capacity-not-state
語言javascript
版本v1.0
日期2026-08-20
行數507
執行node src/main.mjs

020 — Declare what you can observe, not what you are

candidate. The twentieth entry, and the last of the archaeology run. It answers the question the Board host asked on 2026-08-19, which was the one thing 改良點 13–17 left standing.

What this program does

Three readers meet one stream. What each declares is not its state but what it is able to see — and that claim is answered by a challenge.

node src/main.mjs              # the run under the policy SCL names
node src/main.mjs --challenge  # just the challenge table
node src/main.mjs --strict     # exit 1 when a reader failed its challenge
node src/island_test.mjs       # 40 checks across 7 sections, and it prints the count itself
  the challenge - two streams whose answers the harness already knows:
    reader           claims   complete->silent   truncated->spoke   verdict
    claims-framing   true     true               false              failed
    framed           true     true               true               passed
    opaque-pipe      false    true               false              failed

    claims-framing: REFUSED: capacity claimed and not demonstrated
    framed: capacity claimed and demonstrated
    opaque-pipe: capacity disclaimed, and the challenge agrees

  reader           records   completeness
  ~~ framed          3         no - declared (no terminator record)
  ?? opaque-pipe     3         not known otherwise, and this reader CANNOT tell

The structural decision

改良點 15 forbids a unit from declaring itself complete, because nothing outside can check that. The Board host put the question that leaves open:

How does the report tell "this reader has an internal cursor check and saw no further pages" from "this reader is an opaque pipe that swallowed whatever bytes arrived", without re-introducing a forbidden positive assertion?

Both are silent. Example 017 put them in the same column, and warned that if most real readers land there, not known to be otherwise quietly becomes "complete" in the reader's head — the very trust the rule exists to remove.

The move is to change what is declared. Not the state — the capacity:

A unit declares what it is able to observe. That claim is not about the outcome, and unlike an outcome claim it can be tested — the harness hands it a case whose answer it already knows.

Silence then splits in two, and no positive assertion is added:

value meaning
no - declared the reader said so
not known otherwise, and this reader can tell silent, and it demonstrated the capacity to speak
not known otherwise, and this reader CANNOT tell silent, and it could not have spoken

There is still no complete.

The island test — the challenge needs both arms, or a constant passes it

A reader that always answers "truncated" is right about the truncated stream. A one-armed challenge passes it. So passed is the conjunction, and the island test drills both constants:

  PASS  a reader that always says truncated IS right about the truncated stream
  PASS  and wrong about the complete one
  PASS  so a one-armed challenge would have passed it
  PASS  and the two-armed one does not
  PASS  the mirror image fails too

Refusal keys on the claim, not the outcome. opaque-pipe fails the challenge and is accepted — it never claimed to pass. claims-framing fails identically and is refused. Section 4 asserts that the two have the same passed and opposite acceptance.

The control pair — two silences that must not share a column

On the complete stream framed is silent, exactly as opaque-pipe is silent on the truncated one. Silence alone therefore separates nothing, and only the completeness column does. Without the pair, the third value would be a relabelling rather than a distinction.

Five mutations were run and each turns the suite red, including one aimed precisely at the one-armed challenge.

Upstream, the same day

Archaeology 020 is this argument made structural, and it is the last entry of the run:

    route                compiles   must_use warning   error
    bare call            yes        yes                -
    let _ = ...          yes        -                  -
    let v: i32 = ...     NO         -                  E0308
    match { Ok, Err }    yes        -                  -

Result<T, E> is a declared capacity to be wrong, and extraction is forced: using the T without naming the Err case is a type error, no lint needed. Discarding is not forcedlet _ = ... compiles clean even under #![deny(unused_must_use)], the loudest setting the language offers. The strength of what remains is the consumer's setting, which is 改良點 16 appearing inside a type system.

What this example does not solve

A demonstrated capacity is not a proved one. Passing on this pair of streams says nothing about every shape a reader may meet. Section 7 states that as a check rather than a sentence.

A disclaimer is believed. A reader that says it cannot discriminate is trusted, and one that disclaims falsely is treated as blind. That is the conservative direction and the same unverified trade as 改良點 15 — named, not closed.

The challenge only reaches what the harness can construct. A reader whose framing is real but whose inputs cannot be synthesised gets no challenge at all; SCL names that gap rather than implying coverage.

Source

FMS

FMS/contract.json
{
  "name": "020-declare-capacity-not-state",
  "what_it_is": "Three readers over one stream, where what each unit declares is not its state but what it is able to observe — and that claim is answered by challenge.",
  "the_structural_decision": "改良點 15 forbids a unit from declaring itself complete, because nothing outside can check it. That leaves a reader which genuinely checked its framing indistinguishable from an opaque pipe that swallowed whatever arrived: both are silent. The move is to change WHAT is declared. A capacity claim — 'I am able to tell truncation from completion' — is not a claim about the outcome, and unlike an outcome claim it is testable: the harness hands the unit a case whose answer it already knows.",
  "why_this_one": "The Board host asked exactly this on 2026-08-19, and it is the last open thing in the 改良點 13-17 line. It is also the twentieth entry, so it closes the archaeology run.",
  "status": "candidate",

  "the_three_completeness_values": {
    "no - declared": "the reader said so",
    "not known otherwise, and this reader can tell": "silent, and it demonstrated the capacity to speak",
    "not known otherwise, and this reader CANNOT tell": "silent, and it could not have spoken - which is a different fact"
  },
  "there_is_still_no_complete_value": "改良點 15 is unchanged. What is new is that silence is split in two by whether the reader could have broken it.",

  "the_challenge": {
    "how": "the harness builds one complete stream and one truncated stream and asks the reader to classify both",
    "why_both_arms": "a reader that always answers 'truncated' is right about the truncated case. A one-armed challenge passes a constant, so `passed` is the conjunction and the island test drills both constants.",
    "what_it_keys_on": "the CLAIM, not the outcome. opaque-pipe fails the challenge and is accepted, because it never claimed to pass; claims-framing fails identically and is refused."
  },

  "readers": {
    "framed":         {"claims": true,  "note": "the frame ends with a terminator, so its absence is observable"},
    "opaque-pipe":    {"claims": false, "note": "the honest half of the control pair — it declares its own blindness and the challenge agrees"},
    "claims-framing": {"claims": true,  "note": "reads exactly like the opaque pipe. In the tree deliberately: 改良點 18 is worth nothing unless a false capacity claim is caught by RUNNING the unit."}
  },

  "the_control_pair": "On the COMPLETE stream, `framed` is silent — exactly as `opaque-pipe` is silent on the truncated one. Silence alone therefore separates nothing, and only the completeness column does. Without that pair, the third value would look like a relabelling rather than a distinction.",

  "sets": {
    "FMS": "this file: the three completeness values, the challenge and why it needs both arms, and the units map",
    "SCL": "what a failed challenge means here, what happens to records from a blind reader, and what the challenge cannot reach",
    "SMS": "building the challenge streams, running each reader against both, and placing the result in one of three columns",
    "TMS": "one file per reader — each declares what it can OBSERVE and how, never what its state is, and imports nothing",
    "DMS": "the three columns kept apart, the challenge table, and a floor that now counts blind records separately"
  },

  "units": {"TMS/readers": ["claims_framing.mjs", "framed.mjs", "opaque_pipe.mjs"]},

  "non_goals": [
    "Proving a capacity. Passing on one pair of streams demonstrates the claim on that pair; it does not establish it for every shape a reader may meet.",
    "Checking a disclaimer. A reader that says it CANNOT discriminate is believed, and a reader that disclaims falsely is treated as blind — the conservative direction, and the same unverified trade as 改良點 15.",
    "Reaching a reader whose framing is real but whose challenge inputs the harness cannot construct. SCL names that gap rather than implying coverage."
  ]
}

SCL

SCL/policy.json
{
  "deployment": "audit-ingest",
  "a_reader_that_fails_its_challenge_is": "refused",
  "records_from_a_blind_reader_are": "served, and marked",
  "why": "An audit ingest may accept records from a reader that cannot see its own framing - most real readers cannot - but it may not let that reader's silence sit in the same column as a reader that checked. Refusing the blind reader entirely would exclude most of the world; refusing the LIAR costs nothing, because its claim was never true.",
  "what_this_cannot_reach": "A reader whose framing is real but whose challenge inputs the harness cannot construct. The challenge only works where the harness can build a case whose answer it already knows.",
  "not_a_general_rule": "A pipeline where every reader is framed would never see the third column. SCL is where the position lives."
}
SCL/policy.mjs
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const here = path.dirname(fileURLToPath(import.meta.url));
export const POLICY = JSON.parse(fs.readFileSync(path.join(here, "policy.json"), "utf8"));

export const refusesLiars = () => POLICY.a_reader_that_fails_its_challenge_is === "refused";
export const servesBlind = () => POLICY.records_from_a_blind_reader_are.startsWith("served");
export const describe = () =>
  `${POLICY.deployment}: a reader that fails its challenge is ${POLICY.a_reader_that_fails_its_challenge_is}, `
  + `records from a blind reader are ${POLICY.records_from_a_blind_reader_are}`;

SMS

SMS/challenge.mjs
// The challenge, and the read pipeline that depends on it.
//
// 改良點 15 forbids a unit from declaring itself complete, because nothing
// outside it can check that. But the Board host asked the question that rule
// leaves open: how does a report tell "this reader checked its framing and saw
// no further pages" from "this reader is an opaque pipe that swallowed
// whatever arrived", without letting the first one make a positive assertion?
//
// The answer is to move what is declared. A unit does not declare its STATE.
// It declares its CAPACITY — what it is able to observe — and a capacity claim
// is answerable, because the harness can hand it a case whose answer it
// already knows.
//
// The challenge needs BOTH arms. A reader that always answers "truncated" is
// right about the truncated case, so a one-armed challenge passes a constant.
import * as claimsFraming from "../TMS/readers/claims_framing.mjs";
import * as framed from "../TMS/readers/framed.mjs";
import * as opaquePipe from "../TMS/readers/opaque_pipe.mjs";

export const COMPLETE_STREAM = "r-1|r-2|r-3|<end>";
export const TRUNCATED_STREAM = "r-1|r-2|r-3";

// The three states a completeness column may hold. There is still no
// verified-complete value (改良點 15); what is new is that silence is split in
// two, by whether the reader could have spoken.
export const DECLARED_INCOMPLETE = "no - declared";
export const SILENT_AND_CAN_TELL = "not known otherwise, and this reader can tell";
export const SILENT_AND_CANNOT = "not known otherwise, and this reader CANNOT tell";

export function load(extra = []) {
  const readers = {};
  const problems = [];
  for (const module of [framed, opaquePipe, claimsFraming, ...extra]) {
    const name = module.NAME;
    if (!name) {
      problems.push("a reader module does not declare NAME");
      continue;
    }
    for (const attribute of ["CAN_FAIL_WITH", "HOW", "read"]) {
      if (module[attribute] === undefined) problems.push(`${name} does not declare ${attribute}`);
    }
    if (typeof module.CLAIMS_CAN_DISCRIMINATE !== "boolean") {
      problems.push(`${name}: does not claim a discrimination capacity either way - the report `
        + `would have nowhere to put its silence`);
    }
    for (const vouch of ["COMPLETE", "IS_COMPLETE", "RETURNS_EVERYTHING"]) {
      if (module[vouch] === true) {
        problems.push(`${name}: declares ${vouch} - a unit may declare what it can OBSERVE, `
          + `never what its state is (改良點 15)`);
      }
    }
    if (problems.some((p) => p.startsWith(`${name}:`) || p.startsWith(`${name} `))) continue;
    readers[name] = module;
  }
  return { readers, problems };
}

// Hand the reader two streams whose answers the harness already knows, and see
// whether it separates them. Both arms are required: `passed` is the
// conjunction, so a reader that answers the same way every time fails.
export function challenge(module) {
  const onComplete = module.read(COMPLETE_STREAM).incomplete_because;
  const onTruncated = module.read(TRUNCATED_STREAM).incomplete_because;
  const rightAboutComplete = onComplete === null;
  const rightAboutTruncated = onTruncated !== null;
  return {
    reader: module.NAME,
    claimed: module.CLAIMS_CAN_DISCRIMINATE,
    rightAboutComplete,
    rightAboutTruncated,
    passed: rightAboutComplete && rightAboutTruncated,
    // A reader that got exactly one arm right answered the same way twice.
    constant: rightAboutComplete !== rightAboutTruncated,
  };
}

export function verdict(result) {
  if (result.claimed && result.passed) return "capacity claimed and demonstrated";
  if (result.claimed && !result.passed) return "REFUSED: capacity claimed and not demonstrated";
  if (!result.claimed && result.passed) return "capacity disclaimed but demonstrated - accepted, "
    + "and the report treats it as blind because that is the conservative direction";
  return "capacity disclaimed, and the challenge agrees";
}

export const accepted = (result) => !(result.claimed && !result.passed);

export function run(module, stream, challengeResult) {
  const result = module.read(stream);
  let completeness;
  if (result.incomplete_because) completeness = DECLARED_INCOMPLETE;
  else if (challengeResult.claimed && challengeResult.passed) completeness = SILENT_AND_CAN_TELL;
  else completeness = SILENT_AND_CANNOT;
  return {
    reader: module.NAME,
    records: result.records,
    incomplete_because: result.incomplete_because,
    completeness,
  };
}

export function readAll(readers, stream) {
  return Object.keys(readers).sort().map((name) => {
    const result = challenge(readers[name]);
    return { ...run(readers[name], stream, result), challenge: result };
  });
}

// The floor, now with the part example 017 could not name: how many records
// came from a reader that could not have told us either way.
export function floor(rows) {
  const total = rows.reduce((n, row) => n + row.records.length, 0);
  const declared = rows.filter((r) => r.completeness === DECLARED_INCOMPLETE)
    .reduce((n, row) => n + row.records.length, 0);
  const blind = rows.filter((r) => r.completeness === SILENT_AND_CANNOT)
    .reduce((n, row) => n + row.records.length, 0);
  return { total, declared, blind };
}

TMS

TMS/readers/claims_framing.mjs
// It declares that it can discriminate. It reads exactly like the opaque pipe.
//
// This unit is in the tree deliberately: 改良點 18 is worth nothing unless a
// false capacity claim is caught, and it has to be caught by RUNNING the unit,
// not by reading the constant above.
export const NAME = "claims-framing";
export const CAN_FAIL_WITH = ["unreadable-chunk"];
export const CLAIMS_CAN_DISCRIMINATE = true;
export const HOW = "it says the frame is checked; the challenge disagrees";

export function read(stream) {
  const chunks = stream.split("|").filter(Boolean).filter((c) => c !== "<end>");
  return {
    records: chunks.map((id) => ({ from: NAME, id })),
    incomplete_because: null,
  };
}
TMS/readers/framed.mjs
// A reader over a framed stream. The frame carries a terminator, so this
// reader can tell a truncated stream from a complete one.
//
// What it declares is NOT that it is complete — that remains forbidden by
// 改良點 15. It declares what it is CAPABLE of observing, and that claim is
// answerable by challenge: hand it a case whose answer is already known.
export const NAME = "framed";
export const CAN_FAIL_WITH = ["unreadable-chunk"];
export const CLAIMS_CAN_DISCRIMINATE = true;
export const HOW = "the frame ends with a terminator record, so its absence is observable";

const TERMINATOR = "<end>";

export function read(stream) {
  const chunks = stream.split("|").filter(Boolean);
  const terminated = chunks.at(-1) === TERMINATOR;
  const records = chunks.filter((c) => c !== TERMINATOR).map((id) => ({ from: NAME, id }));
  return {
    records,
    // The only assertion it is allowed to make: the negative one.
    incomplete_because: terminated ? null : "no terminator record",
  };
}
TMS/readers/opaque_pipe.mjs
// A reader over an unframed byte pipe. It takes whatever arrived and hands it
// over. It cannot tell a clean end from a connection that closed early,
// because nothing in what it receives says which.
//
// It is the honest half of the control pair: it declares that it CANNOT
// discriminate, and the challenge confirms it. Its silence about completeness
// therefore means nothing, and the report has to say so rather than letting it
// sit in the same column as `framed`'s silence.
export const NAME = "opaque-pipe";
export const CAN_FAIL_WITH = ["unreadable-chunk"];
export const CLAIMS_CAN_DISCRIMINATE = false;
export const HOW = "nothing in an unframed pipe distinguishes a clean end from an early close";

export function read(stream) {
  const chunks = stream.split("|").filter(Boolean).filter((c) => c !== "<end>");
  return {
    records: chunks.map((id) => ({ from: NAME, id })),
    incomplete_because: null,
  };
}

DMS

DMS/report.mjs
// What a person is shown.
//
// The rule this report exists for: two readers that both said nothing about
// completeness must not appear in the same cell. One of them could have
// spoken; the other could not.
const pad = (value, width) => String(value).padEnd(width);

export function rows(entries) {
  const lines = ["  reader           records   completeness"];
  for (const entry of entries) {
    const mark = entry.completeness.includes("CANNOT") ? "??"
      : entry.incomplete_because ? "~~" : "ok";
    lines.push(`  ${mark} ${pad(entry.reader, 15)} ${pad(entry.records.length, 9)} `
      + `${entry.completeness}${entry.incomplete_because ? ` (${entry.incomplete_because})` : ""}`);
  }
  return lines.join("\n");
}

export function challenges(entries) {
  const lines = [
    "  the challenge - two streams whose answers the harness already knows:",
    "    reader           claims   complete->silent   truncated->spoke   verdict",
  ];
  for (const { challenge, reader } of entries) {
    lines.push(`    ${pad(reader, 16)} ${pad(challenge.claimed, 8)} `
      + `${pad(challenge.rightAboutComplete, 18)} ${pad(challenge.rightAboutTruncated, 18)} `
      + `${challenge.passed ? "passed" : "failed"}`);
  }
  return lines.join("\n");
}

export function floor({ total, declared, blind }) {
  return [
    `  at least ${declared} of ${total} records come from a reader that declared itself incomplete.`,
    `  and ${blind} of ${total} come from a reader that could not have told us either way.`,
    "  The second number is what example 017's floor could not name: there, a blind reader",
    "  and a checking reader shared one column.",
  ].join("\n");
}

export function refusals(refused) {
  if (refused.length === 0) return "  no reader was refused.";
  return ["  REFUSED:", ...refused.map((r) => `    ${r.reader} - claimed a capacity the challenge `
    + `did not demonstrate (right about complete: ${r.rightAboutComplete}, `
    + `right about truncated: ${r.rightAboutTruncated})`)].join("\n");
}

root

island_test.mjs
// The island test.
//
//   node src/island_test.mjs
//
// Section 2 is the one that matters most: the challenge needs both arms,
// because a reader that answers the same way every time is right about one of
// them. Section 3 is the control pair — two silences that must not share a
// column.
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

import * as harness from "./SMS/challenge.mjs";
import * as policy from "./SCL/policy.mjs";
import * as claimsFraming from "./TMS/readers/claims_framing.mjs";
import * as framed from "./TMS/readers/framed.mjs";
import * as opaquePipe from "./TMS/readers/opaque_pipe.mjs";

const here = path.dirname(fileURLToPath(import.meta.url));
const CONTRACT = JSON.parse(fs.readFileSync(path.join(here, "FMS", "contract.json"), "utf8"));
const failures = [];
let ran = 0;
const check = (label, ok, detail = "") => {
  ran += 1;
  process.stdout.write(`  ${ok ? "PASS" : "FAIL"}  ${label}${detail ? ` - ${detail}` : ""}\n`);
  if (!ok) failures.push(label);
};
const say = (line = "") => process.stdout.write(`${line}\n`);

const { readers, problems } = harness.load();
const results = Object.fromEntries(
  Object.keys(readers).map((name) => [name, harness.challenge(readers[name])]));

say("\n== 1. every reader is an island, and FMS matches the tree");
check("loading raised no problems", problems.length === 0, problems.join("; "));
for (const [unit, declared] of Object.entries(CONTRACT.units)) {
  const dir = path.join(here, ...unit.split("/"));
  const onDisk = fs.readdirSync(dir).filter((n) => n.endsWith(".mjs")).sort();
  check(`${unit}: FMS declares what is on disk`,
    JSON.stringify(onDisk) === JSON.stringify([...declared].sort()),
    `disk ${onDisk.join(", ")} | FMS ${[...declared].sort().join(", ")}`);
  for (const file of onDisk) {
    const body = fs.readFileSync(path.join(dir, file), "utf8");
    check(`${unit}/${file} imports nothing at all`, !/^\s*import\s/m.test(body));
  }
}
check("every reader states a capacity either way",
  [framed, opaquePipe, claimsFraming].every((m) => typeof m.CLAIMS_CAN_DISCRIMINATE === "boolean"));
check("and says HOW, so the claim is inspectable as well as testable",
  [framed, opaquePipe, claimsFraming].every((m) => Boolean(m.HOW)));

say("\n== 2. the challenge needs both arms - a constant answer must not pass");
const alwaysTruncated = {
  NAME: "drill-always-truncated", CAN_FAIL_WITH: ["x"],
  CLAIMS_CAN_DISCRIMINATE: true, HOW: "it answers the same way every time",
  read: (stream) => ({ records: [{ from: "drill-always-truncated", id: "d-1" }],
    incomplete_because: "no terminator record" }),
};
const alwaysComplete = {
  NAME: "drill-always-complete", CAN_FAIL_WITH: ["x"],
  CLAIMS_CAN_DISCRIMINATE: true, HOW: "it answers the same way every time",
  read: (stream) => ({ records: [{ from: "drill-always-complete", id: "d-1" }],
    incomplete_because: null }),
};
const cheatTruncated = harness.challenge(alwaysTruncated);
const cheatComplete = harness.challenge(alwaysComplete);
check("a reader that always says truncated IS right about the truncated stream",
  cheatTruncated.rightAboutTruncated === true);
check("and wrong about the complete one", cheatTruncated.rightAboutComplete === false);
check("so a one-armed challenge would have passed it", cheatTruncated.constant === true);
check("and the two-armed one does not", cheatTruncated.passed === false);
check("the mirror image fails too", cheatComplete.passed === false
  && cheatComplete.rightAboutComplete === true && cheatComplete.rightAboutTruncated === false);
check("the harness knows both answers because it built both streams",
  harness.COMPLETE_STREAM.endsWith("<end>") && !harness.TRUNCATED_STREAM.endsWith("<end>"));
check("and the two streams differ only by the terminator",
  harness.COMPLETE_STREAM.replace("|<end>", "") === harness.TRUNCATED_STREAM);

say("\n== 3. the control pair - two silences that must not share a column");
const truncated = harness.readAll(readers, harness.TRUNCATED_STREAM);
const row = (name) => truncated.find((r) => r.reader === name);
const onComplete = harness.readAll(readers, harness.COMPLETE_STREAM);
check("on the truncated stream, framed speaks", row("framed").incomplete_because !== null);
check("and opaque-pipe does not", row("opaque-pipe").incomplete_because === null);
check("they return the same number of records",
  row("framed").records.length === row("opaque-pipe").records.length,
  `${row("framed").records.length}`);
const framedOnComplete = onComplete.find((r) => r.reader === "framed");
check("on the COMPLETE stream, framed is silent too - the control",
  framedOnComplete.incomplete_because === null);
check("so silence alone does not separate them",
  framedOnComplete.incomplete_because === row("opaque-pipe").incomplete_because);
check("and the completeness column does",
  framedOnComplete.completeness !== row("opaque-pipe").completeness,
  `${framedOnComplete.completeness} | ${row("opaque-pipe").completeness}`);
check("there are three values, and none of them is `complete`",
  new Set([harness.DECLARED_INCOMPLETE, harness.SILENT_AND_CAN_TELL, harness.SILENT_AND_CANNOT]).size === 3
  && ![harness.DECLARED_INCOMPLETE, harness.SILENT_AND_CAN_TELL, harness.SILENT_AND_CANNOT]
    .includes("complete"));

say("\n== 4. the liar is caught by running it, not by reading it");
check("claims-framing declares it can discriminate",
  claimsFraming.CLAIMS_CAN_DISCRIMINATE === true);
check("its source is identical in behaviour to the opaque pipe",
  claimsFraming.read(harness.TRUNCATED_STREAM).incomplete_because
  === opaquePipe.read(harness.TRUNCATED_STREAM).incomplete_because);
check("the challenge refuses it", results["claims-framing"].passed === false
  && harness.accepted(results["claims-framing"]) === false);
check("framed's identical claim is accepted", results.framed.passed === true
  && harness.accepted(results.framed) === true);
check("and opaque-pipe, which claimed nothing, is not refused for failing",
  harness.accepted(results["opaque-pipe"]) === true
  && results["opaque-pipe"].passed === false);
check("so refusal keys on the CLAIM, not on the outcome",
  results["claims-framing"].passed === results["opaque-pipe"].passed
  && harness.accepted(results["claims-framing"]) !== harness.accepted(results["opaque-pipe"]));

say("\n== 5. the floor now names what example 017's could not");
const kept = truncated.filter((entry) => harness.accepted(entry.challenge));
const numbers = harness.floor(kept);
check("the refused reader contributes nothing", kept.length === 2);
check("the floor counts what was declared", numbers.declared === 3, `${numbers.declared}`);
check("and separately counts what came from a blind reader", numbers.blind === 3, `${numbers.blind}`);
check("the two are different populations", numbers.declared + numbers.blind === numbers.total);
check("neither number is offered as a total of anything complete",
  !JSON.stringify(numbers).includes("complete"));

say("\n== 6. a capacity claim is not a state claim");
const vouching = {
  NAME: "drill-vouch", CAN_FAIL_WITH: ["x"], CLAIMS_CAN_DISCRIMINATE: true,
  HOW: "x", COMPLETE: true, read: () => ({ records: [], incomplete_because: null }),
};
check("DRILL: a reader declaring COMPLETE is still refused (改良點 15)",
  harness.load([vouching]).problems.some((p) => /declares COMPLETE/.test(p)));
const mute = {
  NAME: "drill-mute", CAN_FAIL_WITH: ["x"], HOW: "x",
  read: () => ({ records: [], incomplete_because: null }),
};
check("DRILL: a reader that claims no capacity either way is refused",
  harness.load([mute]).problems.some((p) => /does not claim a discrimination capacity/.test(p)));
check("but claiming FALSE is perfectly acceptable",
  harness.load().problems.length === 0 && opaquePipe.CLAIMS_CAN_DISCRIMINATE === false);
check("and no reader anywhere asserts it is complete",
  [framed, opaquePipe, claimsFraming].every((m) => m.COMPLETE === undefined));

say("\n== 7. what the challenge cannot do, asserted so it stays measured");
check("it only works where the harness can build a case it knows the answer to",
  policy.POLICY.what_this_cannot_reach.includes("challenge inputs the harness cannot construct"));
check("a reader that passes on THESE two streams has not been shown to pass on others",
  harness.COMPLETE_STREAM.split("|").length === 4,
  "one pair, one shape - the claim is demonstrated, not proved");
check("and a reader that disclaims capacity is trusted about its own blindness",
  results["opaque-pipe"].claimed === false && harness.accepted(results["opaque-pipe"]),
  "that direction is unchecked, and it is the conservative one - the same trade as 改良點 15");
check("the report never renders a blind reader's silence as informative",
  row("opaque-pipe").completeness === harness.SILENT_AND_CANNOT);

say("");
if (failures.length > 0) {
  say(`  ${failures.length} FAILED: ${failures.join(" | ")}`);
  process.exitCode = 1;
} else {
  say(`  ${ran} checks passed - ${Object.keys(readers).length} readers, 3 completeness values`);
}
main.mjs
// Three readers over one stream, and a capacity claim that gets challenged.
//
//   node src/main.mjs              the run under the policy SCL names
//   node src/main.mjs --challenge  just the challenge table
//   node src/main.mjs --strict     exit 1 when a reader failed its challenge
import * as report from "./DMS/report.mjs";
import * as policy from "./SCL/policy.mjs";
import * as harness from "./SMS/challenge.mjs";

const say = (line = "") => process.stdout.write(`${line}\n`);

function main(argv) {
  const { readers, problems } = harness.load();
  if (problems.length > 0) {
    for (const problem of problems) say(`  REFUSED: ${problem}`);
    return 1;
  }

  const entries = harness.readAll(readers, harness.TRUNCATED_STREAM);
  const failed = entries.map((e) => e.challenge).filter((c) => c.claimed && !c.passed);

  say(`\n  ${policy.describe()}\n`);
  say(report.challenges(entries));
  say("");
  for (const entry of entries) say(`    ${entry.reader}: ${harness.verdict(entry.challenge)}`);
  say("");

  if (argv.includes("--challenge")) return failed.length > 0 && argv.includes("--strict") ? 1 : 0;

  const kept = entries.filter((e) => harness.accepted(e.challenge));
  say(`  reading the truncated stream (${harness.TRUNCATED_STREAM}):\n`);
  say(report.rows(kept));
  say("");
  say(report.floor(harness.floor(kept)));
  say("");
  say(report.refusals(failed));

  if (argv.includes("--strict") && failed.length > 0 && policy.refusesLiars()) {
    say(`\n  --strict: ${failed.length} reader(s) claimed a capacity the challenge did not `
      + `demonstrate, and that is fatal here`);
    return 1;
  }
  return 0;
}

process.exitCode = main(process.argv.slice(2));