Skip to content

#332 Phase 7 wave 1: reused-instance state, L2 infra crediting, verify wording - #346

Merged
HouMinXi merged 20 commits into
mainfrom
claude/laughing-bohr-y7r65a
Nov 1, 2026
Merged

HouMinXi merged 20 commits into
mainfrom
claude/laughing-bohr-y7r65a

Conversation

@HouMinXi

@HouMinXi HouMinXi commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Base: main 20b4ace (Phase 6 landed as #319). 19 commits; merges cleanly onto current main (only shared file is factories.py, non-overlapping hunks). The full record, including what is deliberately deferred and what needs an owner decision, is in docs/gsd/future-direction/332-host-failure-classification/phase7-plan.md.

What changes

Reused StateMachine instance (PR #319's "planned for the next phase"). A later LOCAL run() on one instance drops the State object the previous run() used before it looks for state.json, so a missing, other-diff or corrupt file leaves it where a new instance starts. A State the instance was built or seeded with, one a caller assigned between runs, and one no run reached are kept. CI is unchanged. The pre-existing L0 advisory buffer is reset per run. Production builds one instance per review, so this is reachable only through the Python API.

L2 infrastructure errors in host-receipt reviews (crash fix). With a diff and active L1 (the normal LOCAL review), any mutation-infrastructure error (raised L2 runner or typed MUTATION_ERROR) made the machine write an interrupted + INCOMPLETE row that its own validator refused, so the review stopped with CorruptedStateError. #114's tests run without host receipts and never saw it. Now:

  • Host rows carry "l2_infra_error": true when this round's L2 returned an infrastructure error; the validator accepts INCOMPLETE with it and refuses the field when not exactly true, when L2 did not return, or beside CLEAN.
  • A completed round is interrupted (window kept, nothing earned, non-PASS, policy: L2 mutation infrastructure errors (MUTATION_ERROR, source=INFRA) reset consecutive clean credit like code findings #114). A round that cannot prove credit (failed attempt, refused receipt gate, survivor breaker) is unavailable, as a CLEAN round is there; only a falsifier protocol stop or an acquisition failure interrupts. Receipt acceptance also runs for a round that would be CLEAN but for its L2 error.
  • The L2 error is cleared when each host attempt begins, so no attempt inherits an earlier round's error.
  • Stricter on purpose: a pure excerpt rejection beside an L2 error is unavailable (fail closed).
  • docs/round-history.md documents the field, compatibility with older versions, and recovery from a state an older version left unloadable.

Verify wording (#70, 2026-10-30 comment). The unresolved-finding reason no longer calls INFRA/UNTRUSTED findings "product findings". It reads "unresolved finding without verified evidence (a product candidate the host could not verify, or an infrastructure failure)", or names a malformed / unrecognized basis. Verdict, failure_kind and unresolved_findings are unchanged; the receipt-gate diagnostic fingerprint changes with the text.

Smaller items from #319's follow-up list. Public read-only accessors for excerpt rejections on _L1Call; the host round-row helpers in a new leaf module state_rows.py (no call-time shims); corrected per-run vs instance-lifetime comments; the plan's missing test combinations; a keep-across-runs mutant sweep of _reset_run_state with every surviving mutant either killed by a new test or shown equivalent (plan section 2).

Compatibility

  • Older versions refuse interrupted / unavailable rows whose INCOMPLETE comes from the L2 error alone (they crashed on those rounds anyway) and ignore the field on protocol, reset and preserved rows.
  • test_provider_capacity_reporting.py was formatted in its own commit (AST unchanged) because a touched file must be left lint-clean.

Verification

  • Behaviour changes were checked red first: each new test fails on the previous code or under a targeted mutant (recorded per commit).
  • Full suite on this tree (453 collected files, 4 shards, pinned ruff first on PATH): the only failures are ones that fail identically on untouched 20b4ace in this container (Vertex credentials, git environment, running as root, gate pytest evidence/waiver tests, 3 projection-isolation pins, doctor live probes, dogfood, test_deleted_scope_consumers.py x2, test_exec_falsify timeout, test_ci_null_baseline_deadline...), plus timing-dependent cases that also fail on the base.
  • ruff check / ruff format --check (pinned 0.17.3) clean on every changed file.
  • Review: five rounds of six independent reviews (security/correctness, code quality, redundancy/style, blast radius, code review, verify-and-dedup); the last round found nothing left to fix.
  • Not run: forge's own LLM review cycles (no backend in this environment) and native mutmut.

Needs an owner decision (not in this PR)

Credit-policy items TD-P6-IV/V/VI, persisting the preserve basis on preserved rows, companion fingerprints in ever_seen, CI State reuse on one instance (W2-9), and the mutation-infra breaker demoting a preserved third round (W2-10). See plan section 3.


Generated by Claude Code

claude added 19 commits November 1, 2026 05:04
…oads

A local review loads .code-forge/state.json only when its source hash
matches the review. Otherwise the run is meant to start empty. A
StateMachine instance whose run() is called a second time did not: when
the state file had been removed, or belonged to another diff, the second
run kept the State the first run left in memory and resumed its rounds,
dispositions and clean credit. With preserved schema/coverage credit
that carried-over State could also reach PASS sooner than a new instance
reviewing the same workspace.

A later local run() on the same instance now drops that in-memory State
before it looks for state.json, so it starts where a new instance starts.
The first run() still starts from the State the instance was built or
seeded with, which callers and fixtures use. CI never reloads state.json
and keeps its in-memory State across runs on one instance, as before.
The comments that described which attributes survive a run() now say
which ones are kept for the instance's lifetime.

New differential tests run the second run on the reused instance and on
a new instance from the same files and compare every file both write;
they fail without this change and pass with it.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…essors

The state machine bound its rejected-evidence snapshot and the schema-fail
companion check to the L1 producer's private invocation token and
rejection tuple, reaching into another module's underscore attributes.
That made the producer's storage part of the machine's contract.

The producer now exposes both as read-only properties that return the
stored objects themselves, so the machine's identity checks against the
current invocation keep holding, and the machine reads only those. The
storage, its reset on every call and the tamper tests that write the
backing attributes are unchanged.

A new test pins identity, the per-call token and that the properties
cannot be assigned. Returning a copy from the rejection accessor makes
27 existing evidence-rejection tests fail.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
Preserved-row validation lives in state_preserved, which state imports at
module level. The validator needs the product row projection, but that
function was defined in state, so state_preserved reached it through a
function-level import on every call, and carried a second unused shim for
is_host_round. Those shims existed only to break the import cycle.

The authority field set, is_host_round and the product row projection now
live in state_rows, which imports nothing from the package. state
re-exports them unchanged, so existing imports keep working, and
state_preserved imports the projection directly. Both modules bind the
same function objects; the call-time shims are gone. Behavior is
unchanged.

The two tests that pinned the shim layout now pin one shared definition:
the same object in all three modules, and both callers reach it.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…tests

The next change edits one assertion in this module. Lint is diff-scoped
and a touched file has to be left clean, and this module predates the
pinned formatter. Formatting it on its own keeps the behavioral change
reviewable. The syntax tree is identical before and after; only layout
changes.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
… product

When receipt verification found an open finding whose basis it could not
accept, the reason always read "unresolved unverified product finding".
Most of these are not product findings: the host gives authority
infra-unavailable to INFRA diagnostics (provider failures, schema-fail,
incomplete coverage) and to UNTRUSTED reviewer output, and the rest have a
malformed or unrecognized basis. Reporting them all as product defects
contradicts the report separation of infrastructure failures from product
defects.

The reason now names what the receipt basis shows: a finding without
verified evidence (an infrastructure failure, or a product candidate in
untrusted reviewer output), or a finding with a malformed or unrecognized
basis. A receipt finding does not carry the source that separates INFRA
from UNTRUSTED, and its file and description can come from the reviewer,
so the wording claims neither a product defect nor a trusted
infrastructure diagnostic, keeps the possible product candidate visible
and echoes nothing from the receipt. The verdict, failure kind and the
recorded unresolved findings are unchanged; the machine compares those,
not the text. The infra-unavailable authority string is now a named
constant shared by the writer and the verifier.

The tests assert the label for every unverified basis shape. Restoring
the old wording makes 13 of them fail.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…infra rounds

Two combinations of the schema/coverage credit preserve had no test: a
schema-fail finding beside literal receipt damage on the receipt gate
path, and a round with both a schema-fail and an incomplete-coverage
finding together with an L2 infrastructure error. The first must take
the full reset, as the coverage variant already does; the second must
preserve, because what remains after removing both findings is clean or
incomplete only through the L2 error, and a new product finding beside
them must still reset.

The gate-path test now runs schema-fail with literal damage in both pass
orders, and two predicate tests cover the mixed round with and without
the L2 error. Dropping the L2-infra arm of the preserve rule makes the
mixed L2 case fail.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…erve

The credit-preserve change listed its deferred follow-ups only in its
merge request. This note collects them in the repository next to the
architecture and plan for the host-failure classification work: which
bounded items have landed (reused-instance state, the excerpt accessors,
the row helper module, the comments, the verify wording and the missing
test combinations), and, for each item that changes credit policy or the
persisted round shape, what happens today, the options and the decision
the owner has to make. Listing an item does not schedule it.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…eason

The previous change described every open finding with authority
infra-unavailable as an infrastructure failure or a product candidate in
untrusted reviewer output. That missed the most common producer: a
product candidate from a validated reviewer reply whose falsification
failed is published to the receipt as INFRA/UNCERTAIN, so it also carries
infra-unavailable. The wording steered a reader towards discounting a
real product candidate.

The reason now reads "unresolved finding without verified evidence (a
product candidate the host could not verify, or an infrastructure
failure)". It names a product candidate first, which covers both a failed
falsification and untrusted output, and still claims no trusted
infrastructure diagnostic. The docstring lists all three producers.

The receipt-gate diagnostic fingerprints its message text, so a receipt
failure recorded by an older version and the same failure recorded now
get different fingerprints; the verdict is unchanged.

The falsifier protocol and transport run test now asserts the exact
reason the real producer gets. The basis tests use an explicit table of
expected labels instead of a helper that mirrored the implementation.
Restoring the previous wording fails 14 tests, including both run cases.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…structure error

An L2 mutation infrastructure error (a raised L2 runner or a typed
MUTATION_ERROR) is meant to earn no clean credit, keep a window already
earned on the same source, and be non-PASS. That held only when the
review wrote no host receipts, which is how the existing tests run it.
With a diff and active L1, the normal local review, every round is a host
attempt: the fixpoint turned CLEAN into INCOMPLETE, the round was
recorded as interrupted, and the round history validator then refused
that row as corrupt, because it accepted INCOMPLETE only beside a
falsifier protocol failure. The review stopped with CorruptedStateError
on the first round whose mutation layer failed.

The machine now records "l2_infra_error": true on a host round whose L2
phase returned an infrastructure error, and the validator accepts an
interrupted INCOMPLETE round with that fact. It refuses the fact when it
is not exactly true or when L2 did not return, and on an earned or
evidence-rejected round, which an L2 error makes INCOMPLETE. Rows without
the field validate as before.

A second leak fed the same refusal: the L2 error was cleared only when
the next L2 phase started, so a round that failed after L1 and before
its own L2 recorded INCOMPLETE from the previous round's error. It is now
also cleared at the start of every round.

New host-mode tests run a raised and a typed L2 failure: the window is
kept, the state reloads, recovery earns the next cycle, three failing
rounds stop at the mutation infrastructure breaker, and a round that
fails before L2 records the CLEAN its L1 observed. Loader tests pin the
new field. Without this change 15 of the 17 tests fail; without only the
per-round clear, the round-B test fails.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…cases

Every per-run attribute is reset when run() starts. For most of them a
reused instance cannot be told apart from a new one anyway, because the
round or attempt rewrites the attribute before anything reads it. Three
can be told apart, and no test did:

- run 1 cannot write its receipts and fails after the round; run 2 fails
  after L1. Run 2's failed path would log run 1's receipt-write error a
  second time.
- run 1 finds another diff's state.json and no receipts, saves its own
  empty state, and stops in the mutation preflight. Run 2 would continue
  the other diff's cycle numbers instead of starting at round 0.
- run 1's L2 runner fails; run 2 fails after L1, before its own L2. Run 2
  would record INCOMPLETE from run 1's L2 error.

Each test runs run 2 on run 1's instance and on a new instance from the
same files and compares every file both write. Dropping the run-entry
reset of the receipt-write errors or of the other diff's state makes the
first or second test fail. The L2 error is now also cleared at the start
of every round, so the third test guards that scenario without depending
on the run-entry reset.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
A later local run() starts empty unless a matching state file loads, while
the first run uses the State the instance was built or seeded with. The
first run was identified by counting run() calls, so a run that raised
before it ever reached the state load (for example while resolving the
trusted gate) still counted, and the next run discarded a seeded State
nobody had used.

The state load now marks the built State as used, and only a later run
after that starts empty. A new test fails the first run before the load
and checks that the second run keeps the seeded State; it fails with the
counter.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
Adds the classification of every per-run reset whose removal no test
noticed: which ones a reused instance can expose (now covered), which one
became redundant once the L2 error is cleared every round, and why the
rest cannot be observed. Records the host-receipt L2 crash found by that
analysis and its fix, the corrected verify wording, the run-entry marker,
and the open question of CI runs reusing an instance's State.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…credit

When the receipt gate refuses a round's evidence (for example a reviewer
excerpt that does not match the diff), the round is recorded as
unavailable: the inherited clean window cannot be proved, and the next
run fails without calling a reviewer. The gate maps an INCOMPLETE
fixpoint to an interruption instead, which keeps the window. An L2
infrastructure error alone makes the fixpoint INCOMPLETE, so since the
previous change the same damaged round beside an unrelated mutation
failure kept its window, and a later healthy round could reach PASS on
it.

On the gate path only a falsifier protocol stop or an acquisition failure
now interrupts; a damaged round whose INCOMPLETE comes from the L2 error
alone is unavailable, as it is with a healthy L2. The validator accepts
an unavailable INCOMPLETE round only with the recorded L2 error.

A new test runs literal receipt damage with a healthy, a raising and a
typed failing L2: all three are unavailable, cannot be restored, and the
next run fails with no reviewer call. Restoring the old gate mapping
fails the two L2 cases. The round-B test now also asserts that its
unavailable round is not restored.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…ation

Describes how a round whose receipts the gate refused stays unavailable
beside an L2 error, records as an open question that the mutation
infrastructure breaker demotes a preserved round now that host-receipt
reviews reach it, and records the full-suite comparison against the base
and the review findings that changed the series.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…e label

The unresolved-finding reason was picked by a helper that parsed and
normalized a finding's basis a second time, separately from the check
that decided the finding was unverified. The two could disagree, and the
label was looked up for a finding tracked beside the unresolved list
rather than from it.

One classifier now returns what a basis is: absent, verified,
infra-unavailable, malformed or unrecognized. The unverified check and
the reason label both read it, and the label of the first unresolved
finding is taken in the same loop that records it. The infra-unavailable
label is keyed by the shared constant. Behaviour is unchanged: the
classifier matches the old check for every basis shape the tests cover,
and the reason text is the same.

The label tests are an explicit table of basis and expected label, and a
new test puts findings of two basis kinds in two passes and checks that
the reason names the first one and its pass. Taking the label or the
cycle and pass from the last unresolved finding instead makes it fail.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…urately

A few comments and test docstrings from the row-helper move and the
excerpt accessors no longer matched the code. The excerpt token
docstring said the token was owned by its rejections, when each
rejection records the token. The leaf-module and preserved-validation
docstrings still described the removed call-time shims. The projection
test claimed to prove a single shared function, which a separate identity
test does, and one assertion guarded a shim name that no longer exists.
Two test docstrings carried planning vocabulary.

The text now says what the code does, the dead assertion is gone, and the
accessor test sits after the reviewer-response group it interrupted.
No behaviour changes.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
…isory buffer

A later local run() on one StateMachine starts empty unless a matching
state file loads. It decided that with a flag set when the state load
was reached, so it also threw away a State a caller assigned between
runs, and a run whose state load raised still marked the seeded State as
used. The pre-existing L0 advisory buffer was an instance attribute: a
run that raised after L0 and before the advisory flush left its entries
for the next run, which published them if it returned without an L0
phase of its own.

The machine now records the State object the last run used, once its
state load returned, and a later local run drops exactly that object.
A State the instance was built or seeded with, one a caller assigned
after the previous run, and one no run reached are kept; CI is
unchanged. The buffer is reset with the other per-run state at every
run() entry. Comments that called instance-lifetime attributes per-run,
or the reverse, now say which they are, and the CI docstring says CI
never loads the state file.

New tests cover a State assigned between runs, a run whose state load
raised, and the buffer case; each fails on the previous code. The
reused-instance differentials share one helper, which gained a hook
between the runs and an nth-call failure seam.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
An L2 infrastructure error turns what would be a CLEAN round into
INCOMPLETE. The receipt gate had been fixed to record a damaged round
beside such an error as unavailable, but three other paths still let the
L2 error keep the inherited window:

- An attempt that failed after its L2 returned (a crash before
  publishing receipts, a receipt-gate read error, a state save failure)
  mapped any INCOMPLETE to interrupted, even with damaged receipts, so a
  later healthy round could reach PASS on the kept window.
- Receipt acceptance (hunk witness, coverage floor, completeness) ran
  only for CLEAN rounds, so evidence it would refuse went unchecked when
  an L2 error sat beside it.
- The survivor breaker had its own mapping.

A failed attempt, a refused receipt gate and the survivor breaker now
share one rule: only a falsifier protocol stop or an acquisition failure
interrupts; a round that is INCOMPLETE only through its L2 error is
unavailable, as a CLEAN round is on those paths. The gate and the
breaker use one helper for it, and the protocol cause of INCOMPLETE has
one definition. A round that would be CLEAN but for its L2 error gets the
same receipt acceptance as a CLEAN round.

The L2 error is now cleared when a host attempt begins (also for non-host
local rounds), replacing the clear at the start of each round, so an
attempt that fails before its L2 never reads an earlier round's error.
The validator refuses the L2 fact beside a CLEAN fixpoint, which the
machine never writes, and its message for an unexplained INCOMPLETE now
names both causes. One consequence is stricter on purpose: a pure excerpt
rejection, which alone keeps the window, is unavailable beside an L2
error. docs/round-history.md documents the field, the outcomes,
compatibility with older versions, and recovery from a state an older
version left unloadable.

New tests run each failure after L2, unverifiable evidence, a pure
excerpt rejection, an acquisition failure, the survivor breaker beside an
L2 error and beside a protocol stop, and an attempt failing before its
round, against a healthy, raising and typed L2; each behaviour change
fails at least one of them on the previous code or under a targeted
mutant.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
The plan described an earlier state of the series: the per-round L2
clear, the survivor breaker test it no longer runs, verification counts
from before the last fixes, and commit hashes that changed. It also
claimed the gate-path protocol-plus-damage outcome was unpinned when a
test pins it.

It now describes the reused-instance and L2 rules as implemented, with
the compatibility and recovery notes, the full test coverage, the
mutant-sweep classification, the open owner decisions (including the
breaker demoting a preserved round and CI State reuse), the deferred
refactors, and the final verification and review record.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix reused LOCAL state and L2 infrastructure credit in host reviews

🐞 Bug fix ✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Prevent reused LOCAL reviews from carrying state when no matching state file loads.
• Record and validate L2 infrastructure errors without granting unproved clean credit or crashing.
• Clarify unverified-finding diagnostics and cover recovery, receipt failures, and state-loading
 boundaries.
Diagram

graph TD
  A["LOCAL run"] --> B["State load"] --> C["Host attempt"] --> D{"L2 error?"} --> E{"Credit provable?"} --> F["Host row"] --> G["Row validator"] --> H["Persisted state"]
  D -- "No" --> E
  H -- "Next run" --> B
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Return explicit causes with fixpoint results
  • ➕ Give the credit decision, row writer, and validator a shared account of why a round is INCOMPLETE.
  • ➖ Broadens a targeted crash fix into a cross-cutting change to fixpoint handling and persisted-state policy.

Recommendation: Use the PR's optional L2 observation and bounded credit-rule changes for this wave. They address the crash while preserving existing policy; consider explicit fixpoint causes separately if the owner approves a broader persisted-shape change.

Files changed (15) +2296 / -298

Enhancement (1) +14 / -0
factories.pyExpose read-only excerpt rejection observations +14/-0

Expose read-only excerpt rejection observations

• Adds accessors for an L1 call's invocation token and stored rejection tuple, preserving the object identities needed by receipt checks.

src/code_forge/factories.py

Bug fix (3) +183 / -110
machine.pyCorrect reused-state and host credit lifecycles +107/-52

Correct reused-state and host credit lifecycles

• Drops a previous LOCAL run's State before loading, resets the advisory buffer and L2 error at their appropriate boundaries, and records returned L2 infrastructure errors. Distinguishes interrupted rounds from attempts whose evidence cannot prove credit, and checks receipt acceptance for L2-only INCOMPLETE rounds.

src/code_forge/machine.py

state.pyValidate L2 infrastructure observations in host history +24/-32

Validate L2 infrastructure observations in host history

• Accepts causally supported INCOMPLETE host rows while rejecting invalid L2 flags, phase statuses, and fixpoint combinations. Re-exports host-row helpers moved to the leaf module.

src/code_forge/state.py

verify.pyDescribe unresolved findings by basis kind +52/-26

Describe unresolved findings by basis kind

• Classifies verified, infra-unavailable, malformed, and unrecognized bases to produce accurate unresolved-finding reasons. Keeps the underlying unresolved findings and verdict behavior unchanged.

src/code_forge/verify.py

Refactor (3) +49 / -21
basis.pyName the shared infra-unavailable authority +3/-1

Name the shared infra-unavailable authority

• Introduces a constant for the authority assigned to INFRA and UNTRUSTED findings so verification can classify it consistently.

src/code_forge/basis.py

state_preserved.pyUse the shared product-row projection +5/-20

Use the shared product-row projection

• Imports the projection from the new leaf module instead of resolving state helpers through call-time shims.

src/code_forge/state_preserved.py

state_rows.pyCentralize host-row classification and projection +41/-0

Centralize host-row classification and projection

• Defines host authority fields, host-row detection, and product-snapshot projection in one module shared by state validation and preserved-credit logic.

src/code_forge/state_rows.py

Tests (6) +1585 / -167
test_factories.pyPin excerpt accessor identity and immutability +33/-0

Pin excerpt accessor identity and immutability

• Tests that the new accessors expose stored observations by identity, cannot be assigned, and track a new invocation.

tests/test_factories.py

test_l2_infra_host_rounds.pyExercise L2 failures in real host-receipt rounds +452/-0

Exercise L2 failures in real host-receipt rounds

• Covers raised and typed L2 errors, recovery, breakers, failed attempts, receipt and excerpt rejection, acquisition failures, and validator acceptance or refusal of L2 row shapes.

tests/test_l2_infra_host_rounds.py

test_phase6_schema_coverage_credit.pyCover mixed preservation and shared projection +58/-10

Cover mixed preservation and shared projection

• Tests combined schema and coverage findings with and without L2 errors, plus product findings that must reset credit. Updates projection-identity and host-row validation assertions.

tests/test_phase6_schema_coverage_credit.py

test_provider_capacity_reporting.pyFormat capacity tests and update verify wording assertion +627/-125

Format capacity tests and update verify wording assertion

• Formats the existing provider-capacity test file without changing its test scenarios, and aligns an unresolved-finding assertion with the new diagnostic wording.

tests/test_provider_capacity_reporting.py

test_review_interruption_source_controls.pyCompare reused LOCAL reviews with fresh instances +345/-4

Compare reused LOCAL reviews with fresh instances

• Adds file-by-file differentials for missing or mismatched state and tests seeded-state, CI, advisory-buffer, and pre-L2 failure boundaries. Extends receipt-damage coverage to schema failures and pins the wording for a falsification failure.

tests/test_review_interruption_source_controls.py

test_verify_uncertainty_basis.pyPin diagnostic labels for unverified bases +70/-28

Pin diagnostic labels for unverified bases

• Tests wording for infra-unavailable, malformed, and unknown authorities, including the label chosen when multiple unresolved findings occur.

tests/test_verify_uncertainty_basis.py

Documentation (2) +465 / -0
phase7-plan.mdRecord Phase 7 wave-one scope and deferred decisions +429/-0

Record Phase 7 wave-one scope and deferred decisions

• Documents delivered behavior, test and mutation-sweep evidence, compatibility limits, and owner decisions needed for later credit-policy work.

docs/gsd/future-direction/332-host-failure-classification/phase7-plan.md

round-history.mdDocument L2 infrastructure host rows and recovery +36/-0

Document L2 infrastructure host rows and recovery

• Defines the optional row field, credit outcomes, validation constraints, older-reader compatibility, and recovery from previously unloadable state.

docs/round-history.md

Brings in the fixpoint state-invariance tests (#337), the fixval JUnit
evidence rule (#331) and the isolate startup diagnostic (#329). Both
sides appended tests at the end of
tests/test_review_interruption_source_controls.py; the resolution keeps
both blocks unchanged. The touched test files and the neighbouring
machine, state and verify suites pass on the merged tree.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
Claude-Session: https://claude.ai/code/session_01Rf2jBZrtS24e7qpWUBy3uo
@HouMinXi
HouMinXi merged commit ef5ef54 into main Nov 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants