Skip to content

docs(corpus): standard for the confidence field - #1468

Merged
serina-mcfall merged 17 commits into
launchpadfrom
task/1309-corpus-standard-confidence
Aug 26, 2026
Merged

docs(corpus): standard for the confidence field#1468
serina-mcfall merged 17 commits into
launchpadfrom
task/1309-corpus-standard-confidence

Conversation

@serina-mcfall

Copy link
Copy Markdown

Summary

Adds launchpad/docs/corpus/standards/confidence.md, the canonical policy node for the confidence field on a corpus evidence entry. The schema already enforces that it is a number in a closed interval, required for INFERENCE only and forbidden on FACT and TEAM_KNOWLEDGE; what no schema can hold is what the number means, so the standard states that nothing calibrates it, that values are not comparable across authors, and that no confidence however high promotes an INFERENCE to a FACT. Its load-bearing section separates reasoning from evidence from dressing up a decision, which is the failure a cross-model review caught on #636 and which no check can catch.

Related issue

Closes #1309

Issue type

Task


Agent provenance

Field Value
Harness / provider Claude Code
Model claude-opus-5[1m]
Session reference 7a7217d6-6dfa-4631-ba5f-8525706c604f
Initiating human @serina-mcfall

Objective

One corpus node stating what the confidence field means, when it is required, how an author picks a value, and what a reader is entitled to conclude from one.

Impacted components

  • launchpad/docs/corpus/standards/confidence.md
  • launchpad/plans/2026-08-26-issue-1309-corpus-standard-confidence.md

No generated corpus outputs changed; no generator exists yet. launchpad/docs/corpus/AGENTS.md is deliberately untouched.

Approach and rejected alternatives

The document commits to concrete positions rather than hedging, because it is meant to be the normative exemplar for roughly 45 sibling standards and vagueness would propagate. Enum member lists and the schema's field-combination matrix are linked rather than copied, except for the confidence row itself and how the value is bounded — a standard about this field cannot omit the field's own rule. Those unavoidable restatements are named in a drift-surface table in the header, so a maintainer changing the schema knows exactly which passages track it.

Rejected: declaring a references relationship to corpus-agents. It would validate today — AGENTS.md is a loaded node — but every sibling standard (#1307#1351) is unmerged, and a relationships[].target naming an unloaded id is a hard validation error. Adding the whole edge set in one pass once the siblings land is cheaper than adding one edge now and revisiting. The body states that reason explicitly and names corpus-agents as the first edge to make.

Rejected: fixing the NaN gap in node.schema.json. schema/ sits outside this issue's scope and its Definition of Done forbids a second authored document. Filed as #1463 instead, with the standard carrying a MUST for real numbers in the interim.

Rejected: a calibrated numeric scale. Nothing in the repository records whether a past inference turned out correct, so any calibration claim would be the exact overclaim this document exists to prevent. The three band pegs are declared a convention with no evidence behind them.

Verification

Command run:

python3 launchpad/project-intelligence/corpus/validate.py ; echo "exit=$?"
python3 -m unittest discover -s launchpad/project-intelligence/corpus/tests -p "test_*.py"
python3 -m unittest discover -s launchpad/docs/corpus/schema/tests -p "test_*.py"

Raw output:

$ python3 launchpad/project-intelligence/corpus/validate.py ; echo "exit=$?"
UNVERIFIED  corpus-agents: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-confidence: evidence entry 1, citation 1: is a commit reference, which names no openable file
PASS  corpus validation found no errors; 2 item(s) reported unverified
exit=0

$ python3 -m unittest discover -s launchpad/project-intelligence/corpus/tests -p "test_*.py"
............................FAIL  corpus root does not exist: /home/serina/Launchpad/buzz/__worktrees/task-1309-corpus-standard-confidence/launchpad/project-intelligence/corpus/tests/fixtures/does-not-exist-anywhere
...................................................
----------------------------------------------------------------------
Ran 79 tests in 0.370s

OK

$ python3 -m unittest discover -s launchpad/docs/corpus/schema/tests -p "test_*.py"
...........................
----------------------------------------------------------------------
Ran 27 tests in 0.031s

OK

The single FAIL line inside the corpus run is a negative-path test's own stdout, not a failing test; the suite reports OK for all 79. The two UNVERIFIED notices are the two nodes' provenance commit citations, which no file can corroborate — one is this node's, and it is the one permitted commit-only FACT.

The four technical claims the document asserts as FACT were each measured rather than read, by probing node.schema.json and memory.py directly:

INFERENCE without confidence       -> FAIL ('confidence' is a required property)
INFERENCE confidence 0.0           -> PASS
INFERENCE confidence 1.0           -> PASS
INFERENCE confidence int 1         -> PASS
INFERENCE confidence 1.1           -> FAIL (1.1 is greater than the maximum of 1.0)
INFERENCE confidence -0.1          -> FAIL (-0.1 is less than the minimum of 0.0)
INFERENCE confidence .nan          -> PASS
INFERENCE confidence .inf          -> FAIL (inf is greater than the maximum of 1.0)
INFERENCE confidence -.inf         -> FAIL (-inf is less than the minimum of 0.0)
INFERENCE confidence true          -> FAIL (True is not of type 'number')
INFERENCE confidence '0.8'         -> FAIL ('0.8' is not of type 'number')
FACT with confidence               -> FAIL (schema allOf: forbidden field)
TEAM_KNOWLEDGE with confidence     -> FAIL (schema allOf: forbidden field)

memory.py REJECTED .nan: confidence must be within [0.0, 1.0], got nan
'memory' appears in validate.py: False
  • Tests or checks were run and the raw output is pasted above
  • The diff is confined to the scope of the linked issue
  • No secrets, keys, tokens or hostnames were added to tracked files

Not verified

  • The mandatory Codex cross-model final pass did not run. The Codex workspace is out of credits: ERROR: Your workspace is out of credits. Retried once to confirm it was not transient. No alternative external CLI is installed (gemini, agy, pi, llm, ollama all absent). review-final was run instead and found nine findings, all now fixed — but it is the same model family as the author and is not a substitute. The gate this branch's plan declares mandatory is still open, and the memory note feedback_final-review-cross-model records that three same-model passes on task: treat all pull request content as untrusted data #120 missed what one Codex pass caught immediately. This PR should not leave draft until a cross-model pass runs.
  • No gate ledger exists. check-ledger.sh exits 1 because this branch was built directly rather than through build-change, so no progress.md was written. The reviews demonstrably ran — each is named with its findings in the commit messages — but the mechanical check fails for want of a record, not for want of a review.
  • No generated view was tested consuming a confidence value, because no generator exists. How a projection renders or ranks these numbers is unknown, and the "not comparable" rule has not been tested against a consumer that might assume otherwise.
  • The band pegs 0.8 / 0.6 / 0.4 are not derived from evidence. They are a proposed convention; the document says so in its scope-and-omissions section rather than implying calibration.
  • The NaN divergence was measured against the current schema and memory.py only. Whether any other consumer of the field shares the schema's permissiveness was not established.
  • No agent harness was tested reading this node as instructions. It sits under a directory whose AGENTS.md is resolved as governing instructions; whether this file's front matter degrades it for such a harness is untested.

Security implications

None. The change adds two Markdown documents and no executable code, no configuration, no dependency and no network surface. It does not alter what validate.py accepts, so it cannot widen what merges. One adjacent observation: the document's honesty rules reduce a real risk ADR-0029 names — presenting inference as established fact — by requiring that a decision never be dressed as a derivation.

Escalations

  • bug: a NaN confidence passes corpus validation but memory.py rejects it #1463bug: a NaN confidence passes corpus validation but memory.py rejects it. Raised while measuring the constraints this document describes. Deferred rather than fixed because node.schema.json lives under schema/, outside this issue's scope, and the Definition of Done forbids materially editing a second document. The standard carries a MUST for real numbers and an enforcement-table row naming the gap until bug: a NaN confidence passes corpus validation but memory.py rejects it #1463 lands.
  • The cross-model gate is unmet and I could not clear it. See Not verified. I am raising this rather than deciding the branch is adequately reviewed without it.
  • audiences is agent and reviewer, not developer. The task brief called this question deliberately unsettled. An author picking a number acts as agent, a person checking it acts as reviewer, and the document addresses developers only through those roles. Stated so a reviewer can overturn it cheaply; the node itself records nothing about the question, so a sibling author will not know it was ever open.
  • Nine findings from review-final were fixed on this branch rather than filed, against the standing policy that High and Medium findings become issues. All nine were self-contradictions inside this new document — including a false justification for declaring no relationships, a claim that three requirements were machine-enforced when two are, and an overbroad claim that the schema does not enforce finiteness when only NaN escapes. Filing issues against an unmerged draft's own internal consistency would have shipped a standard that contradicts itself seven ways. Flagging the deviation rather than assuming it was authorised.

Reviewed by an independent cross-model review-plan pass (Codex, gpt-5.6-sol,
high effort): eleven findings, all applied. Three more were found afterwards,
the load-bearing one being that the plan blocked its own STEP 2 on an OPEN
item -- an OPEN item a step must consume is a missing input, not an open
question.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
The corpus's first hand-authored node. Frontmatter validates against
node.schema.json with zero errors; 11 evidence entries; no relationships,
because no sibling node exists to target and an unresolved target is a hard
validator error. The repository revision is recorded in the evidence ledger --
the schema calls that array the provenance ledger and permits no other field,
so it is the only schema-legal place for it.

STEP 3 (RUNS HERE) proved the validator actually scans the node rather than
skipping it: mutating type: to a value outside the enum produced
'FAIL corpus-agents: schema violation at type' and exit 1, naming the node's
id; restoring it returned exit 0.

Also replaces test_real_corpus_root_currently_has_no_content_outside_schema,
which asserted the corpus root is EMPTY and therefore could not survive the
first authored node. Authorised by Serina as a deliberate widening of the
plan's LEFT OUT scope, recorded in the plan. The replacement asserts what the
original's own comment said it was for -- content present AND nothing from
schema/ -- and both halves were negative-controlled before being trusted.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Adds the lookup table of authoritative sources and the 'what a corpus node
is' section: one file per node, one idea per node, where nodes go, id
permanence, relationship resolution, and the authored-vs-generated boundary.

Reproduces no enum member list and no field-combination matrix -- those stay
canonical in node.schema.json and schema/README.md and are linked instead.
The checker never reads body prose, so a copy here would stay green while
drifting. Verified: no type-enum member and none of entry_class/provided_by/
confidence appear in the body.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
The part that lives nowhere else: what the checker actually does with each of
CONTRACT.md's six citation shapes, and three things a passing run does not
mean -- that a citation supports its claim (checking is structural, the file
is never opened and compared), that UNVERIFIED is a pass, or that a line
number was verified (#1459).

Names the three evidence classes and what each is FOR, but not which fields
the schema requires per class -- that matrix stays in node.schema.json.
Verified absent from the body: entry_class, provided_by, confidence.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
This is #605's acceptance criterion for the file -- a cold-start agent
creating, updating or retiring one node without oral guidance. Three numbered
procedures, each ending in the same check command.

Adds a 'Running the check' section giving the interpreter form (works without
Hermit; the just recipe needs activation first) and documenting --root, since
without it the command always validates the real corpus whatever directory
you are standing in.

Retire covers the three things most likely to be got wrong: inbound
relationships resolved before retirement, status set rather than the file
deleted, and the id never reused or renamed.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Names each deferred area with its owning issue rather than leaving a reader
unable to tell a gap from an omission: the standards and templates
(#1307-#1351, none merged), generated-artifact provenance (#1316), claim-type
and flagged state (#1410), the human entry point (#639), and unverified line
numbers in citations (#1459).

Records why this node carries no relationships -- at its recorded revision it
was the only authored node, and a target no node carries is a hard error --
so the absence reads as deliberate rather than forgotten.

Every repo path cited in the body verified to resolve to a real file.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
The audit found two things the earlier steps had missed.

The document's own rule -- 'a FACT resting only on UNVERIFIED citations has
not been checked by anything' -- condemned the node's own ledger entry 1, the
provenance record, whose only citation is a commit reference. Resolved by
stating the one carve-out narrowly and giving it a real check
(git cat-file -e <sha>, run, exit 0) rather than by quietly exempting it. A
commit citation on a claim about repository CONTENT is explicitly still not
covered.

Ledger entry 11 overreached: 'every change under launchpad/docs/corpus is
gated in CI' where the workflow triggers on pull requests and pushes to
launchpad. Narrowed to what the workflow actually does.

Also records a scope judgement the DoD asks for: the citation-shape table is
reference material rather than instruction and belongs in the evidence
standard (#1314) when that lands. Noted in place rather than folded in
silently.

Verified: all 11 ledger entries resolve, every body path is a real file,
merge-base equals the recorded revision, and exactly one hand-authored .md
was added under the corpus root.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
… finding)

An independent review-tests pass defeated the first replacement: patching
discover_markdown_files to a hardcoded 'return [root / "AGENTS.md"]' -- a
constant that never touches the filesystem -- satisfied both 'non-empty' and
'nothing from schema/' while proving neither discovery nor exclusion. My own
negative control had broken the exclusion set and emptied the corpus, but
never tried a constant. Showing that assertions CAN fail is not the same as
showing they can only pass for the right reason.

The expectation is now derived from an independent filesystem walk and
compared for equality, which catches partial walks and both exclusion
directions.

It does NOT catch the constant today, and the docstring says so rather than
claiming otherwise: the corpus holds exactly one node, so [root/'AGENTS.md']
IS the correct answer and no assertion against the real tree can tell a
constant from a real walk. That resolves itself at the second node.
test_sibling_discovered_schema_dir_excluded catches it now -- verified FAIL
under that mutant -- and is the real proof of discovery behaviour.

Measured, after fixing a mutation harness that had patched a different module
instance than the test uses and so reported every mutant as caught:
  returns nothing     -> FAIL (caught)
  exclusion disabled  -> FAIL (caught)
  constant return     -> PASS (not caught; sibling catches it)

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
FINDING A -- the carve-out claimed enforcement it does not have. 'There is
exactly one carve-out, and widening it defeats the rule' read as though some
check held the line. Nothing does: a second, third or tenth commit-only FACT
produces extra non-fatal UNVERIFIED notices and still exits 0, which the
reviewer proved by adding one. Now says plainly that this is a convention a
REVIEWER holds, names the signal to look for (more than one commit-only FACT
in a ledger), and states that no check will raise it.

FINDING B -- create-node step 3 asked the author to record four categories of
evidence and gave a destination to exactly one of them. Adds the mapping:
revision to the ledger, sources to the citations of the claims they support,
and expected-but-unverified to the body's scope section. Plus the rule that
anything reaching none of the three was either a missing claim or a stale
note.

Applying B to this node exposed that it did not follow its own new rule --
the same self-contradiction class STEP 8 caught. Its scope section now names
the two things unverified when it was written: no agent harness was tested
reading it as a resolved AGENTS.md, and relationships.schema.json's enum was
never read directly.

Re-audited after the change: exactly one commit-only FACT remains, the
enforcement claim is gone, validator exits 0, 79 tests pass.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Codex review-final returned REQUEST_CHANGES with seven conditions, then a
second pass confirmed five fixed and refused two. Both refusals were correct.
This commit is the whole of that work.

1. LEDGER COMPLETENESS. Seven entries added (11 -> 18) for claims the body
   taught with no classified entry behind them: the evidence classes, the
   "supersedes" vocabulary, the syntax-only GitHub check, the external-URL
   verdict, and the delete-vs-retire distinction.

   The recheck caught two of these still wrong. An entry said the schema
   "permits no field outside that set" after listing the six required fields
   -- it also permits "relationships", so the entry was wrong about the file
   it cited. And the "supersedes" entry cited node.schema.json, which carries
   only the enum; the directionality it asserts ("source replaces target;
   target becomes historical") lives in relationships.schema.json:30, a file
   this node had listed as read-but-unverified and cited anyway. Read it,
   cited it.

2. RETIREMENT WAS BUILT ON A FALSE PREMISE. It claimed inbound relationships
   "no longer resolve" after retirement. Measured: with the file retained --
   which the same procedure requires -- they resolve fine; only deletion
   breaks them. Rewritten so the reason matches the mechanism, the danger is
   stated correctly (edges keep pointing at a node that stopped being
   current, and nothing warns you), and a replacement declares "supersedes",
   which the procedure never mentioned.

3. CITATION TABLE OVERSTATED VERIFICATION. A GitHub link pinned to a real SHA
   naming a file that never existed returns ok -- the checker never contacts
   GitHub. The table now carries a "does it prove the target exists?" column,
   gains the external-URL row it was missing, and names the trap. All seven
   rows independently confirmed against the classifier.

4. PROVENANCE SEMANTICS -- and the defect the recheck was right to refuse.

   The update procedure said to bump the revision on every edit; this node
   kept its original across seven. The first attempt defined the field as an
   evidence snapshot and classified that as INFERENCE citing node.schema.json.
   That schema says nothing whatever about revisions, so the citation could
   not support the statement: a policy choice had been given a class that made
   it look derived. It is now TEAM_KNOWLEDGE attributed to #636's own
   definition of done -- "the draft is checked against the repository revision
   recorded in provenance" -- which is where the meaning comes from. ADR-0029
   requires exactly that: history and team knowledge stay attributed rather
   than being promoted to fact.

   The node also claimed it was "the only authored node in the corpus" at the
   recorded revision. It did not exist at that revision and neither did any
   other node: git cat-file -e on that path at that sha exits 128, and the
   corpus held zero .md files outside schema/. Corrected.

   The revision still does not move, and the reason is checkable rather than
   asserted: every cited source is byte-identical between that revision and
   now, so verifying a claim at HEAD and at the recorded revision were the
   same act. git diff --name-only <sha> -- <cited paths> returns nothing.

5. AUDIENCE. Added "reviewer": the document assigns reviewers an enforcement
   duty no tool performs, so they are addressed by it. The adjudicator had
   declined this finding (nothing consumes the field today); the final pass
   argued audience describes who is addressed, not who parses it. Went with
   the latter. Whether "developer" also belongs is left undecided.

6. The test module docstring claimed absolute fixture isolation that was false
   before this branch and more visibly false after it. States the rule with
   its one named exception instead. Flagged independently by the adjudicator
   and the final pass.

   Pre-existing, fixed while in the file: the same docstring advertised
   "python3 -m unittest launchpad.project_intelligence.corpus.tests.test_validate",
   which has never worked -- the directory is "project-intelligence" with a
   hyphen, not a legal package name. Confirmed ModuleNotFoundError, removed.

7. Full suites re-run in a writable environment: 79 validator tests OK, 27
   schema tests OK, real corpus exit 0. The plan's two-node create/update/
   retire charter ran with its negative control -- a deliberately invalid node
   failed and named itself, proving the scratch root was the one scanned;
   retirement kept beta's edge resolving; deleting alpha instead broke it
   exactly as the corrected text now says.

Final state: 18 ledger entries, schema errors 0, every citation resolves, no
cited source changed since the recorded revision, exactly one commit-only
FACT, 79 + 27 tests green, real corpus exit 0.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Adds launchpad/docs/corpus/standards/confidence.md, the canonical policy node
for the confidence key on an evidence entry.

The field is a number in a closed interval, required for INFERENCE only and
forbidden on FACT and TEAM_KNOWLEDGE. The schema holds that much. What it
cannot hold is what the number means, and an uninterpreted number between 0
and 1 is decoration -- an author picks 0.8 because it feels about right and a
reader treats it as calibrated. The standard states that no calibration exists
or is collected, that values are not comparable between authors, and that no
confidence however high promotes an INFERENCE to a FACT.

Its load-bearing section separates reasoning from evidence from dressing up a
decision: an entry whose citation supports the subject of a claim but not the
choice the claim makes is a decision in disguise and belongs in
TEAM_KNOWLEDGE. That move was caught by cross-model review on #636 and no
check can catch it, so it is documented with both worked examples.

Records a measured divergence: a NaN confidence satisfies node.schema.json and
passes corpus validation while memory.py rejects the identical value, because
every comparison against NaN is false. Filed as #1463; the standard carries a
MUST for finite values to cover it until that lands.

Declares no relationships -- every sibling standard is unmerged, and a target
naming an id no loaded node carries is a hard validation error.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
#636)

Third cross-model pass, third refusal on the same condition. It was right
three times, and the third refusal finally identified why the first two fixes
failed: the document was writing corpus-wide provenance policy it had no
authority to write. Reclassifying it (INFERENCE, then TEAM_KNOWLEDGE) only
changed the label on an unsourced decision.

WHAT ACTUALLY CHANGED: the document stops making the claim.

#1321 ("document corpus standard for provenance", unlanded) owns the question
of whether a recorded revision may stay put across edits. This node now says
so, states its own approach as working practice pending that standard rather
than as a rule others must follow, and defers. The ledger entry no longer
asserts the policy -- it records only what #636's definition of done actually
requires, which is a fact about the issue and is attributed to it.

Also fixes a self-contradiction the last fix opened, exactly the failure shape
this repository keeps producing. The previous commit added a FACT citing
relationships.schema.json for the supersedes directionality. The same node
still said, in its unverified list, that relationships.schema.json had never
been read. Both could not stand. The file WAS read; the stale disclaimer is
now narrowed to what remains genuinely unchecked -- that the two enum lists
agree, which rests on a test that was not run.

Ledger completeness, third sweep: entries added for the generated-artifact
rejection, the non-enforcement of the one-commit-only-FACT convention, and
positional citations not being bounds-checked. Prose that asserted this
node's own history -- node counts at the recorded revision, byte-identity of
cited sources -- is removed rather than given entries: it told the reader to
trust the document about a fact they can check themselves in one command, so
the document now gives them the command instead.

TEAM_KNOWLEDGE's description corrected. It said "a person told you", which the
schema does not require (it asks who or what told the corpus) and which made
the class look unavailable for an attributed issue or decision record. It now
also says outright what it is not: a place to park a decision you made
yourself. Attributing an extrapolation to the thing it started from does not
make it something you were told.

Updating step 4 restated as four explicit branches including the
byte-identical case, which the earlier "bump on every edit" wording omitted
while this very node relied on it -- the inconsistency the pass named.

Verified: 21 ledger entries, schema errors 0, every citation resolves, exactly
one commit-only FACT, no cited source changed since the recorded revision, 79
validator tests OK, real corpus exit 0.

Refs #636

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Two review findings, both adjudicated Medium, both defects in this document
rather than in anything it describes. A standard that contradicts itself
teaches the wrong lesson to every sibling that copies it, so both are fixed
here rather than deferred.

review-code, confirmed by review-adjudicate: the Guidance section said to pick
one number per band and reuse it, but never said which number belonged to
which band -- and then shipped two INFERENCE entries at two different values
with no band label and no stated reason. The bands now carry explicit pegs of
0.8, 0.6 and 0.4, the criterial column is named so the illustrations stop
reading as tests, and this node's own two entries are labelled to their bands
as the nearest worked example. The scope-and-omissions entry now disclaims the
specific values, not just the idea of banding: they are agreed pegs so two
authors mean the same thing by the same numeral, and they measure nothing.

review-plan, surviving into the document and caught by review-adjudicate: the
header claimed the field-combination rules and enum members were deliberately
not copied, while Requirement 1 restates the confidence row and names all
three classes. A standard about this field cannot omit the field's own rule,
so the claim was the wrong half to keep. The header now names that one
restatement as a deliberate drift surface and points at the two places that
must change if the schema's rule ever does.

One neighbouring hole opened by the first fix and closed here: Requirement 6
forbids moving a number, and the second entry moved from 0.7 to 0.6. Snapping
an unchanged assessment onto a band peg is not the move that rule prohibits,
but from a diff the two are indistinguishable, so Requirement 6 now says so
and requires the reason be recorded. This message is that record.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
review-final found nine findings, and the cluster that mattered was not about
confidence at all -- it was the document's claims about its own contents. For a
node whose whole subject is not asserting more than the evidence supports, and
which roughly 45 siblings are meant to copy, that is the report. All nine are
defects in this document, all small, all inside the issue's scope, so they are
fixed here rather than deferred.

High. The stated reason for declaring no relationships was false. It said there
was nothing this node could legally point at, and the next sentence named
AGENTS.md. AGENTS.md carries id corpus-agents, is a loaded node, and a
references edge to it validates today. The convention of declaring none is
settled and unchanged; the justification is now the true one -- add the edge set
in one pass once the siblings land -- and names corpus-agents as the first edge
to make. The same false premise was in the plan's LEFT OUT and is corrected
there too.

Medium, four of them. The Requirements preamble claimed the first three MUSTs
were machine-enforced while Requirement 3 said the schema does not reach it; it
now says two. The header named two places tracking the schema when three do, and
is now a table. The peg rationale asserted cross-author shared meaning that the
reader rules and this node's own 0.8 INFERENCE both deny; adopting pegs is now
stated as a hope about future practice, never as something a reader may sort on.
The only-INFERENCE-in-the-corpus FACT cited AGENTS.md alone, which cannot
establish a quantifier -- it now also cites validate.py for the schema/
exclusion and the fixture that carries the other one, which is exactly the
merely-on-topic citation this document calls the tell.

Medium, and the sharpest. Requirement 6's carve-out claimed re-encoding means
the judgement is identical and only its expression changed. Measured against the
document's own rules that is false: 0.7 to 0.6 moved the entry a full band from
its neighbour, and ranking within a class is the one thing the number
legitimately does. The carve-out now says re-encoding preserves the assessment
but can change the rank, requires the record to name the Means row it matches,
and admits there is no tie-break for a midpoint.

Low, two. A number between 0 and 1 restated bounds the header said were left to
the schema. And MUST be finite was overbroad -- .inf and -.inf are both caught
on range, so NaN is the single value that escapes, because every comparison
against it is false and the assertions never fire. Requirement 3 and the
enforcement table both say so now.

Per Requirement 6 as amended: the 0.6 entry matches the Medium band's Means row,
an absence-of-evidence argument over a scope that was checked, because its scope
is three files rather than the repository.

Not fixed here: the NaN divergence itself stays filed as #1463, since the schema
sits outside this issue's scope.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall serina-mcfall added the by:agent Filed or authored by an AI agent, not a human label Aug 26, 2026
@serina-mcfall

Copy link
Copy Markdown
Author

Needs a human before this leaves draft: the mandatory cross-model review could not run.

codex exec fails with ERROR: Your workspace is out of credits. — retried once to confirm it was not transient, and no alternative external CLI is installed (gemini, agy, pi, llm, ollama all absent). So this branch has had no cross-model pass, which is the gate that catches what same-model passes walk past.

That is not a theoretical worry here. The gates that did run were plan-issuereview-planreview-codereview-adjudicatereview-final, and review-final — the last same-model pass — found nine findings the two earlier same-model rounds had walked straight past, including a flatly false claim: the node said there was nothing it could legally point at with a relationships edge while the next sentence named AGENTS.md, which is a loaded node. All nine are fixed in bfb4885c0, but the pattern is exactly the one feedback_final-review-cross-model records from #120.

What I need from you: either refill Codex credits so the pass can run, or waive the gate explicitly. I am not treating "no reviewer was available" as "no findings remain."

Two other things worth your eyes, both in the PR body:

  • check-ledger.sh exits 1 — no gate ledger exists, because this branch was built directly rather than through build-change. The reviews did run and each is named with its findings in the commit messages; the record is what is missing, not the review.
  • Nine review-final findings were fixed on this branch rather than filed as issues, against the standing High/Medium policy. All nine were self-contradictions inside this new document, so filing them would have shipped a standard that contradicts itself seven ways. Flagging the deviation rather than assuming it was authorised.

Checks: 7 pass, 16 skipped, 0 fail — including the corpus validate workflow. All three commits carry Signed-off-by.

This comment is not an approval, and I am the author of the branch — nothing here is an independent verdict.

#636)

Three sibling agents authored corpus nodes following this document literally, and
reported what broke. These four are the defects that produced real false claims in
their work, not stylistic complaints. Filed as #1471; fixed here because #1462 is
still open and 45 further nodes would inherit them.

1. THE ONLY-NODE JUSTIFICATION WENT FALSE, AND TWO AGENTS COPIED IT.
   "A node with no sibling to point at correctly declares none" read as a general
   rule. It was a fact about one moment -- when this was the corpus's only node --
   and stopped holding as soon as a second existed. Both the #1309 and #1307 agents
   reproduced the reasoning and wrote a justification that was false at the time
   they wrote it; their adjudicators caught it, not their own reviews. Now says to
   enumerate what exists and give the real reason, and records why.

2. AN ISSUE-ONLY SOURCE HAD NO HONEST CLASS. The citation table lists tool results as
   legitimate while "Three things a passing run does not mean" says a FACT resting
   only on UNVERIFIED citations "has not been checked by anything", with one named
   exception. A claim whose only source is a GitHub issue has no openable form and
   cannot be SHA-pinned, so both passages applied and disagreed. The #1307 agent hit
   this with nothing honest to choose. Now states it: TEAM_KNOWLEDGE with provided_by
   naming the issue, which is what ADR-0029 requires of GitHub history anyway.

3. A RANGE WAS READ AS A MAPPING. The not-covered table paired eight subjects with
   "#1307-#1351", which is 45 issues and no subject-to-issue pairing at all. The
   #1307 agent cited this table for nine invented mappings -- exactly the "FACT cited
   to a file that does not discuss the claim" failure the document warns about two
   sections earlier. Now says outright that it is a range, not a mapping, and gives
   the search command.

4. CREATE STEP 3 ROUTED SOMETHING STEP 8 DID NOT ACCEPT. Step 3 sends
   expected-but-unverified items to the scope section; step 8 said only "state what
   the node does not cover". A boundary and a confidence disclosure are different
   things, so working the steps in order left that category homeless. Both the #1307
   and #1309 agents reported it independently. Step 8 now names both.

Verified: schema errors 0, 21 ledger entries, validator exit 0, 79 tests OK.

Refs #636 #1471

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall
serina-mcfall marked this pull request as ready for review August 26, 2026 06:15
#636)

Two more defects reported by the #1308 agent after authoring against this document.
Both are mine, and the first is embarrassing in context.

1. THE CITATION TABLE MISATTRIBUTED ITSELF, IN THE SECTION ABOUT NOT DOING THAT.
   It said "CONTRACT.md §3 defines the six shapes" above a SEVEN-row table whose
   GitHub-link and external-URL rows appear nowhere in §3. Measured: grepping that
   section for http/url/github returns zero hits. So the sentence cited a file that
   does not discuss two of the rows beneath it -- the exact failure this document
   warns about, committed by this document. The #1308 agent took the table as an
   accurate summary and built a scope argument on "four of six shapes name code"
   before their plan review caught it. Now states what §3 actually enumerates, that
   the two URL forms are the validator's and not §3's, and that the table is seven
   rows and not a summary.

2. "ADD RELATIONSHIPS ONLY TO NODES THAT EXIST" WAS UNFOLLOWABLE, AND DANGEROUSLY SO.
   "Exist" was ambiguous between the branch you are working on and the branch you
   merge into, and the checker loads whatever is present where it runs. An agent
   branched off this unmerged node could therefore target `corpus-agents`, validate
   clean locally, and break CI on `launchpad`, where the node is absent. The #1308
   agent hit exactly that and their review-code raised it as a Blocker. Step 9 now
   says "exists on the branch you are merging INTO", explains why the distinction is
   the trap, and gives the command to check the merge base rather than the local tree.

This is the second round of AGENTS.md fixes sourced from agents authoring against it,
and the pattern is worth naming: every defect found this way was invisible to three
review passes over the document itself, and obvious within minutes to someone trying
to follow it. Reviewing a procedure is not the same as executing one.

Verified: validator exit 0, 79 tests OK, schema clean.

Refs #636 #1471 #1478

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall

Copy link
Copy Markdown
Author

Held in draft deliberately — the cross-model gate has not run

Do not mark this ready for review yet. This is not an oversight.

The review pipeline for corpus work under #605 requires a cross-vendor final pass. That
pass could not run:

$ codex exec "Reply with exactly: OK"
ERROR: Your workspace is out of credits. Ask your workspace owner to refill in order to continue.

No alternative external provider is installed (gemini, agy, pi, llm, ollama all
absent), so the gate currently has exactly one provider and it is unavailable. Tracked as
#1467.

Same-model reviews did run and their findings were addressed — see this PR's own
verification and escalations sections for what each stage found. But same-vendor passes
are not a substitute here, and the reason is recorded rather than assumed: on #120, three
same-model passes missed what a single cross-model pass caught immediately. On #1462 the
same thing happened three times in a row — each cross-model pass found defects that the
same-model reviews before it had cleared, including one that had already been "fixed"
twice.

Decision (Serina, 2026-08-26): hold every corpus PR in draft until credits are
refilled, rather than waive the gate.

When credits return, the sequence is: run the cross-model final on this branch's current
head, address or explicitly refute what it finds, then mark ready.

@serina-mcfall
serina-mcfall marked this pull request as draft August 26, 2026 06:21
@serina-mcfall
serina-mcfall marked this pull request as ready for review August 26, 2026 06:27
…task/1309-corpus-standard-confidence

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall

Copy link
Copy Markdown
Author

Correction: the draft hold above is lifted

My earlier comment on this PR said "do not mark this ready for review". That no longer
applies, and the comment should not be read as overriding anyone.

Serina marked this PR ready for review deliberately, superseding the earlier hold. I
converted it back to draft twice before establishing that, which was my error — the
ready_for_review events attributed to her account were her, not an automation.

What is still true, and is the reason the earlier comment existed:

The cross-vendor final review has not run on this branch. codex exec reports
ERROR: Your workspace is out of credits, and no alternative external provider is
installed, so the gate has one provider and it is unavailable — tracked as #1467.
Same-model reviews did run and their findings were addressed.

So this PR is review-ready with a known, recorded gap in review coverage, rather than
being blocked by it. That is a legitimate posture, and it is a decision rather than an
oversight — but a reviewer should know it before merging, which is why this correction
names it rather than quietly deleting the earlier comment.

When credits return, the cross-model pass on the current head is still worth running.

@tucktuck101 tucktuck101 self-assigned this Aug 26, 2026

@tucktuck101 tucktuck101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The confidence standard is schema-consistent (cols 0.0-1.0 INFERENCE-only, NaN gap correctly scoped), ledger classes match node.schema.json, and the contested TEAM_KNOWLEDGE entry names a genuine external source (the #636 cross-model review). Note: merge #1462 first — this PR embeds the shared AGENTS.md base also carried by #1462. [panel: fable+codex]

@tucktuck101 tucktuck101 removed their assignment Aug 26, 2026
@serina-mcfall serina-mcfall self-assigned this Aug 26, 2026
@serina-mcfall
serina-mcfall merged commit 8d9f66b into launchpad Aug 26, 2026
23 checks passed
@serina-mcfall
serina-mcfall deleted the task/1309-corpus-standard-confidence branch August 26, 2026 21:19
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
launchpad gained launchpad/docs/corpus/AGENTS.md while this branch was open, via
PRs #1468, #1469 and #1477 merging -- each carried the shared #636 base. That made
an add/add conflict against the copy this branch had merged from
task/636-corpus-agents-md.

Resolved in favour of launchpad's copy (e422283), NOT this branch's newer one
(8c6c21a). The newer copy carries #1462's fixes for its outstanding review
findings. Those fixes belong to #1462 and are still under review; landing them
through this PR would merge unreviewed changes to another PR's file under cover of
an atomicity-standard change.

This branch's own fix is unaffected either way: the "What the corpus has NOT settled
about revisions" passage that the recast ledger entry cites is present in both
copies, so the claim is true against whichever version ends up on launchpad.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
…ed at (#636)

Rebased onto `launchpad` and reduced to one file. #1468, #1469 and #1477 merged
while this PR sat on CHANGES_REQUESTED, and each carried the shared #636 base,
so two of this branch's three files -- the #636 plan and test_validate.py --
are now byte-identical on `launchpad` and no longer belong in this diff. What
is left is the fix itself.

The consequence worth stating plainly: those merges landed the UNFIXED corpus
AGENTS.md on `launchpad`, including the line this commit removes -- "Do not
take that on this document's word -- the command is the check". The High
finding is on the default branch now, which is why this is a defect fix rather
than a pre-merge correction.

HIGH -- the provenance-update shortcut could certify stale evidence. Two
passages said an empty `git diff --name-only <recorded-sha> -- <ledger paths>`
established that every cited source was unchanged and every claim still stood.
Both are false for citation forms this document itself permits.

Measured, not argued. A file that DOES differ reports as changed with a bare
path and reports empty output with exit status 0 once `:127` or `:219-221` is
appended -- no error, no warning. So an unnormalized `path:line` citation makes
a changed file indistinguishable from an unchanged one, which is the worst
available failure shape for a provenance check. Recorded as a new FACT entry
with the tool-result citation that demonstrates it.

The rule now states its reach: normalize positions off the path first; only
bare path, file line and file range are in scope; graph edge, tool result,
commit and the two URL forms are excluded explicitly, so the branch is simply
unavailable when a ledger contains one. The conclusion is narrowed to what a
diff can support -- those files are unchanged -- with re-verification left as
the only thing that establishes a FACT still holds.

MEDIUM -- the one-node rule had no supporting ledger entry. "One node is one
independently maintainable idea" is a substantive instruction and the ledger's
only #636 entry backed the recorded-revision requirement instead. Added as
TEAM_KNOWLEDGE attributed to #636's definition of done, which states it
near-verbatim, matching the existing entry's classification for the same source.

Also corrected a wrong-direction cross-reference: "*Updating a node* below" in
Scope and omissions, where that section is above it.

The recorded revision stays at 0052f5a, re-checked against the NEW base after
the rebase rather than assumed to still hold: the two non-file citations were
excluded, the nine normalized file paths were passed to `git diff` against
0052f5a from `launchpad` tip 0ffc1c9, and the result was empty.

The second Medium is not addressed because it is stale -- the citation table
was already corrected by ebe2daf and says outright that it is seven rows and
is not a summary of CONTRACT.md section 3. The remaining cross-document
disagreement is tracked as #1478. Evidence is in the PR thread.

Validated against the full four-node corpus now on `launchpad`, not just this
node: PASS, 5 non-fatal UNVERIFIED notices, all commit or tool-result
citations that name no openable file.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
Addresses all three findings from the review panel on PR #1480. Each verdict below
was measured by calling validate._classify_citation directly rather than read off
the document.

High -- entry 15 and section 8 asserted as FACT that AGENTS.md "introduces its
citation table as CONTRACT.md section 3's six shapes and then lists seven rows".
The AGENTS.md this branch carries says the opposite in as many words: the table
"is not a summary of section 3", because its two URL rows are forms validate.py
recognises and section 3 does not enumerate. That correction landed in ebe2daf,
after this node recorded its claim against 60d4947. The entry and section 8 now
describe the AGENTS.md that actually ships beside them.

Section 8 also now records what happened, because the node is a standard about
citation discipline and this was a live instance of the failure it teaches against:
a claim recorded against one revision of a moving document is not a claim about the
document that finally ships. AGENTS.md records the same incident from its own side.
The open CONTRACT.md-versus-validator divergence is unchanged and still points at
#1478.

Medium -- the ledger said a bare repository path "is opened on disk" while a later
entry said a citation resolving to a real file "is never opened". Both cannot hold.
Measured: a bare path returns ok on resolution alone and the file's contents are
never read. The first entry now says resolved, and says explicitly that resolution
establishes only that the file is there.

Medium -- the ledger scoped the UNVERIFIED channel to "non-GitHub URLs", while the
node's own table records GitHub issue and pull-request URLs as unverified. Measured:

  #1459 -> unverified
  #1462   -> unverified
  https://example.com/spec                          -> unverified
  .../blob/<full-40-sha>/path                       -> ok
  .../blob/launchpad/path                           -> error (mutable ref, ADR-0003)

The entry now scopes the channel to external URLs that are not pinned repository
links, and names GitHub issue and pull-request URLs as included -- which matches the
table and the measured behaviour.

Also merges origin/launchpad, which gained the corpus tree when #1468, #1469 and
#1477 merged. No conflict: this branch already carried the same AGENTS.md blob.

Verification:

  python3 launchpad/project-intelligence/corpus/validate.py
  PASS  corpus validation found no errors; 5 item(s) reported unverified

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
, declare the corpus-agents edge (#1314)

Four sentences asserted unattributed prevalence/effectiveness ("single
most common," "almost never chosen," "single highest-yield," "nearly
always available and nearly never taken") with no ledger entry backing
them, conflicting with this node's own MUST 1. Recast each as normative
guidance without the frequency claim, since no measurement exists to
cite honestly.

The citation-form table carried a "provisional copy" of #1308's three
shape rules, which SHOULD 6 -- link another document's rules rather than
restating them -- already forbids doing. Removed the copy; the table now
distinguishes the verdicts without asserting what #1308 currently says.

The merge-order section claimed AGENTS.md had not merged and that nine
citations would fail on launchpad -- true when authored, false now:
AGENTS.md landed via #1468/#1469/#1477 before this review. Re-ran the
section's own reproduction command against current origin/launchpad
(PASS, 0 errors, was FAIL/9 errors) and rewrote it as history rather than
a live constraint. corpus-agents is therefore loadable on the merge
target, so this node now declares relationships: [depends-on:
corpus-agents] instead of stating merge order as the reason for none.
corpus-standard-code-references (#1308, still unmerged) stays deferred.

review-final finding (fable+codex panel), verified against branch head
before fixing: none of this was closed, and the merge-order staleness
extended past what the review flagged.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
… and declare the corpus-agents edge (#1313)

D1 required the six sections "in this order and no other" while the
same sentence permitted additional sections between them -- a direct
contradiction. Reworded to "in this relative order and none reordered
among themselves," which states what was actually meant without
banning the insertions the rest of the requirement allows.

The enforcement section claimed "nothing automated enforces any
requirement on this page, and nothing can." The evidence backing it
only shows the current checker discards the body before any check
runs -- it says nothing about whether section structure is inherently
unenforceable. Dropped "and nothing can" and stated the distinction
directly.

The relationships-absence claim assumed no corpus node existed on
launchpad; that was true when authored and is false now -- corpus-agents
landed via #1468/#1469/#1477. Verified by materializing the current
merge target and validating this node against it (PASS, 0 errors).
Declared relationships: [depends-on: corpus-agents] and rewrote the
prose as history rather than a live constraint.

review-final finding (fable+codex panel), verified against branch head
before fixing: none of this was closed. The Blocking finding on this PR
(#1486's reading decision) is unresolved and left for Serina, per the
review's own scope -- not addressed in this commit.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 26, 2026
…r siblings reconcile (#1313)

Serina decided #1486 on 2026-08-27: this node's built scope (a
meta-standard for what a corpus standard document must itself be and
contain) is the intended reading, and the four sibling standards
drafted alongside it -- #1470, #1480, #1468, #1477 -- reconcile to it
before merging, including the two (#1468, #1477) already merged onto
launchpad. Cites the decision in scope-and-authority, states it as
settled rather than provisional in Exceptions and escalation, corrects
Scope and omissions' stale "pull requests are open" framing to name
which two have already merged, and records the decision as a
TEAM_KNOWLEDGE ledger entry attributed to #1486.

This closes the Blocking finding from the review-final pass (fable+codex
panel) that #1496 raised -- the node no longer publishes a binding
meta-standard ahead of its authority being decided, because the
authority is now decided.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
serina-mcfall added a commit that referenced this pull request Aug 27, 2026
…ion-standard

Per Serina's decision on #1486: every sibling standard drafted alongside
#1313 reconciles to it, including nodes that had already merged before
the decision was recorded. This one (#1309, PR #1468) merged 2026-08-26.

D10 -- H1 was "# Standard: `confidence`", code-formatting the topic.
Changed to "# Standard: confidence", matching the plain-text convention
every other reconciled standard uses.

D1/D3 -- the normative sections were named "Requirements" and
"Guidance" rather than "MUST" and "SHOULD". Renamed both, and updated
the two in-body cross-references that named the old section by name.

Recorded the reconciliation as a ledger entry attributed to #1486.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

by:agent Filed or authored by an AI agent, not a human

Projects

None yet

Development

Successfully merging this pull request may close these issues.

task: document corpus standard for confidence

2 participants