# Circe PR #11, round 6 implementation and verification

The two round-5 blockers are fixed on PR #11 at 6a89cc9. Two GPT-6 Luna agents implemented bounded fixes; a third audited recovery. The integrated implementation was reviewed and verified independently. All 525 repository tests, 22 strengthened probes and the retained 19-probe suite pass. PR #11 remains open and unmerged.

F101: one shared binding normalizer now governs proposals and corrections; the failing exclusion and contradictory-binding probes pass with valid destination identity.

F102: intent identity survives frame persistence, is paired with the revision at compilation, and is checked again by the kernel before a revision.

Current-version correction recovery is tested against the real HTTP service. Replaying a correction does not create a new revision, changed content under the same command ID is rejected, and redelivering confirmation invokes only the replacement target once.

525 repository tests, typecheck, static and deletion boundary checks, real and continuing demos, and held-out fixtures pass. The 22-probe and 19-probe suites overlap and are not an additive test count.

Upgrade limit: older accepted-turn logs containing corrections may fail replay validation because they lack the newly pinned identity. Old context frames still decode. No automatic migration is provided; preserve old logs and finish outstanding interactions with their original version before starting fresh interactions.

This increment is ready within its stated scope. Live language quality and risk calibration remain unverified, with belief reuse, deliberation, general language controls and retrieval scale still pending. No whole-product completion claim.

F101: Proposals and corrections now call the same binding normalizer. It rejects unresolved exclusions, contradictory summary refs and invalid slot cardinality, using the pending capability for corrections. Corrections retain certified versions; unsupported correction constraints and entity-ref-valued arguments fail closed. The strengthened Q1/Q2 probes include valid identity, so an identity failure cannot mask these checks.

F102: Frames now associate the live transaction with its intent ID, and context-file decoding preserves that field. Corrections check the pending intent identity and revision against that association and emit expectedIntentId. The kernel checks expectedIntentId before changing bindings. Restart coverage verifies persisted identity, exact-command replay, changed-payload rejection, and one invocation of only the replacement target.

---

# Circe PR #11, independent review round 5

Independent review of 4db47a0: 519 repository tests and the retained 19-probe suite pass. Two positive continuation checks also pass. Three new compiler-contract probes expose two remaining correction-boundary findings, so the implementation agent’s round-4 approval is superseded.

The evaluator now genuinely shares ordered dependency validity across proposals and continuations. Frame-certified correction versions, explicit clarification answers and the complete-write service changes are substantive improvements.

The previous six findings’ retained reproductions all pass. Additional positive checks confirm retargeting revokes authorization and later completes only the new target, and an explicit clarification answer stays resolved across restart.

Two correction checks remain incomplete: binding normalization ignores unresolved exclusions and contradictory summary refs; destination selection ignores a supplied targetIntentId. These are public compiler contract tests. The built-in normal correction flow passed.

Verified 519 repository tests, typecheck, static boundary check, demo:real and the retained 19 probes. The new suite contains 3 failures and 19 passes: 17 repeated host checks plus 2 new positive controls. These counts overlap and must not be added together.

No product source changes, GitHub comments or merge. No model credentials were needed. The author reports the deletion check; this pass independently reran the static boundary check only.

## F101 P1 Corrections still skip exclusion and binding-consistency checks

packages/perception/src/proposals.ts:699-717

The ordered evaluator now shares dependency checks and verifies correction evidence, but its correction branch still applies fewer binding checks than proposals. It removes accepted exclusions only. It never rejects a correction target covered by unvalidatedExclusionRefs, and never checks that summary refs agree with executable slot refs.

Q1 supplies a frame-certified correction target and a sibling exclusion whose citation is unaccepted. The planner still emits revise for that target. Q2 supplies summary refs naming one task and a slot naming another; the planner silently revises the slot target. Both are public compiler-contract tests with supplied semantic turns. The current built-in graph’s normal retarget path passes the positive control.

These failures do not mean the ordered evaluator refactor should be undone. They show that common binding validation must also be shared. A valid version token proves which entity snapshot was seen; it does not erase an unresolved exclusion or reconcile contradictory target declarations.

Fix: Apply the same binding normalization and safety checks to proposal and revision inputs: unresolved exclusions, summary/slot agreement, declared slot constraints and frame coverage. Reject or clarify the unsafe correction before issuing revise. Preserve certified expectations and the passing retarget control; avoid copying another partial check list into the correction branch.

Evidence: Q1 and Q2 fail in evidence/round5/host-review.test.ts. Q4 passes: an ordinary certified retarget revokes authorization, then confirmation completes only the new target. Follow-up to the binding contract in F97.

## F102 P1 A correction ignores the intent it explicitly names

packages/perception/src/proposals.ts:679-687

The correction evaluator requires targetIntentRevision but never checks targetIntentId. Command construction at lines 723-726 always targets the frame’s current obligation, so a proposition explicitly naming a different intent can be silently redirected to this transaction. Matching revision numbers do not identify an intent.

Q3 gives a correction a targetIntentId that differs from the pending intent while keeping a valid revision and certified replacement target. The compiler emits revise for the current transaction. The reproduction proves the compiler accepts the wrong destination; it does not claim the built-in graph currently emits that inconsistent proposition.

The original proposal path already treats expected intent identity as meaningful. A correction should either match the intended pending object or fail closed, especially when applications can supply their own proposition builders.

Fix: Validate the named intent and revision together against the exact pending intent/obligation association before constructing the revision. If the frame cannot establish the association, reject or clarify rather than defaulting to the current transaction. Carry explicit destination identity through the command boundary as needed.

Evidence: Q3 fails in evidence/round5/host-review.test.ts. Keep Q4 as the valid-retarget control and add matching-intent, mismatched-intent and stale-revision coverage.

## Preserved original findings

### F85 Excluding every pending target falls through to confirmation, original reproduction fixed

correctionProposition returns undefined for both an unchanged target set and an empty result. The affirmation branch treats either result as permission to fall through to commit. An accepted exclusion can therefore disappear precisely when it excludes everything.

R1 first gates completion of auth rotation, then supplies accepted affirmation and exclusion decisions for "Yes, except auth rotation. Leave that alone." The host emits confirm and the real service completes that excluded task. This fails even with correct model decisions; a better prompt or API key cannot repair the deterministic translation.

### F86 An exclusion converts a new capability into the old operation, original reproduction fixed

The request branch treats any excluded reference overlapping the pending intent as a correction. That inference ignores the newly accepted capability. It preserves the old capability while replacing its targets with the new request targets.

R2 gates complete(auth rotation), then accepts request, resume, include(Billing export), and exclude(auth rotation). The graph emits revise of the old complete intent to Billing export. The requested resume never happens, and a later confirmation would complete the wrong task. Exclusion overlap does not establish that the user is correcting the old operation.

### F87 Continuation commands bypass whole-turn safety checks, original reproduction fixed

planLanguageCommands adds confirm, cancel, and revise commands independently of compileSemanticTurn. Its new verifyPropositionEvidence helper checks citations only. It does not apply the whole-turn structural, exclusion, dependency, frame identity, and evidence checks already centralized for proposals.

R3 supplies a valid confirmation with an accepted sibling exclusion for its target; the planner still emits confirm. R4 supplies a mismatched frame ID; compilation rejects that frame, yet the planner again emits confirm. These exercise the exported planner with caller-supplied semantic turns. The built-in demo need not generate the malformed combination for this entry-point contract to matter. This repeats the earlier alternate-writer safety drift.

### F88 A failed file write reports refusal after changing the service, original reproduction fixed

The action handler mutates the task and inserts a SUCCEEDED operation before persist succeeds. The outer catch at lines 380-383 converts every exception, including a storage error, into HTTP 400 bad-request. The adapter treats that response as a confirmed execution failure.

R8 makes the temporary persistence path unwritable by placing a directory there. The service task changes to paused in memory, while the adapter returns ok:false. The idempotency map also claims success before durable commit. The kernel receives a definitive failure even though the live service applied the operation; a restart can then produce another history.

### F89 Malformed success responses become terminal failure, original reproduction fixed

The adapter turns an undecodable or unexpected response into EXECUTION_ERROR unless the HTTP status is at least 500. A 200 response with invalid JSON is not evidence that the service refused the mutation. The current fallback nevertheless returns ok:false and makes the kernel mark the effect FAILED.

R7 lets the real service apply a pause, then replaces its successful response with malformed JSON while preserving HTTP 200. The task is paused but the effect is FAILED instead of UNKNOWN. The existing lost-response test covers a thrown fetch, so it misses this equivalent loss of authoritative outcome evidence.

### F90 Pinned replay skips unfinished clarification writes, original reproduction fixed

The host pins the interpreted turn before dispatch, but writes the clarification event afterward only when !pinned. A crash or append failure between those writes leaves a durable question in the turn record without a corresponding pending obligation in context. Redelivery reuses the turn and permanently skips the missing write.

R5 interrupts recordEvent on obligation-opened, reopens the file host, and redelivers the same observation. The returned turn still contains its question, but the next frame has no pendingQuestion. This loses the interaction exactly at the restart boundary the milestone claims to cover. The same ordering also leaves a gap for interrupted resolution events.

### F91 Shared context imports another interaction’s clarification, original reproduction fixed

findPendingQuestion looks up events by entity references but never filters evidence.interactionId. Its signature does not even accept the current interaction. Entity overlap is not interaction identity, and the shared semantic store can contain history for more than one interaction.

R9 records another interaction’s open question for a shared task, then runs the current host with that task in context. The current frame receives "Other user secret request" as its pendingQuestion. This mixes discourse and can disclose unrelated interaction content to the model. Per-host file paths in the demo conceal the shared-store case.

### F92 An unrelated query silently consumes an open question, original reproduction fixed

The host resolves previousQuestion whenever the current turn emits any command or an answer. It has no accepted semantic relationship establishing that this turn answered, rejected, or superseded that particular obligation.

R10 opens an ambiguous completion request and then asks a separate status query about Docs refresh. The query is answered, but the following frame has lost the original unresolved clarification. Ordinary conversation cannot safely interleave with a pending question under this rule.

### F93 Relation observations never reach the configured host, original reproduction fixed

The host reads observeRelations by casting each authority to a shape with an optional method. The HTTP adapter instead returns observeRelations beside authority and executor at adapter.ts:472. The demo and tests pass only adapter.authority, so the method the host probes is absent.

R6 asks about a task with blockedBy data and inspects its actual frame. The task attributes contain the raw blocker IDs, but candidate.relations is empty. The demo’s grounded answer reads the attribute fallback, making the output look correct while the promised relation evidence channel remains disconnected.

### F94 Stored continuation commands escape semantic replay validation, original reproduction fixed

The accepted-turn decoder recompiles the stored semantic turn but compares only the propose subset of record.commands. Other command kinds need only a string kind. A confirm, cancel, or revise command can therefore disagree with the stored interpretation and still be accepted for replay.

R11 records a no-op "Thanks" turn while a transaction awaits confirmation, appends a structurally valid confirm command to that turn’s JSONL record, and reopens the host. The decoder accepts the inconsistent record. This is a codec and replay-consistency finding, not a claim that the application must withstand an attacker with arbitrary filesystem control. The existing recompilation guarantee now covers only part of the durable execution plan.

### F95 Confirmation still ignores partial and unverified exclusions, original reproduction fixed

The replacement compiler checks only whether subtracting accepted exclusions leaves zero refs. If any ref remains, it emits confirm for the original transaction and revision. A confirm command cannot carry the smaller target set, so this still authorizes the excluded frozen target. The branch also never checks unvalidatedExclusionRefs.

N1 constructs a confirmation for two gated targets with an accepted sibling exclusion for one; the planner returns confirm. N2 uses a sibling exclusion whose decision is not accepted; the planner again returns confirm. These are exported compiler contract tests with supplied semantic turns, not claims that the current built-in graph emits these exact combinations. The original one-target exclusion probe passes, but it covered only the empty-set case.

### F96 Accepted citations still substitute for a valid prerequisite, original reproduction fixed

continuationIssue checks whether a dependsOn predecessor has accepted citations, but never checks whether the predecessor itself passed command evaluation. evaluateTurn already records rejected prerequisites for proposals; the new continuation loop ignores those results.

N3 supplies a structurally valid prerequisite that compileSemanticTurn rejects for lacking an executable capability, then a confirmation depending on it. The whole-turn planner nevertheless emits confirm. A dependency can therefore be rejected by one part of the supposedly shared compiler and accepted by another. This is the same distinction between accepted evidence and a valid executable proposition that earlier reviews required.

### F97 Corrections bypass certified frame evidence, original reproduction fixed

The correction branch constructs slots and emits revise after citation checks without applying expectedVersionsFromFrame or verifying that every binding ref has frame evidence. The evaluated proposal results above this branch are not used for corrections. Moving the code into proposals.ts has not made the evidence rule shared.

N4 supplies a correction with an accepted citation and a target absent from the certified frame. The planner emits revise for that target. A downstream authority or kernel may reject an unknown entity, but that is not proof that the semantic selection was grounded in this frame. The public compiler should reject this before issuing any command.

### F98 Unrelated commands still consume a clarification, original reproduction fixed

The fix preserves pending questions across queries, but still resolves previousQuestion whenever commands.length is nonzero. Emitting a command does not establish that the current turn answers or supersedes the pending question. The new durable transition faithfully persists that incorrect inference.

N5 opens "Complete the failing one", then submits a separate accepted request to pause Docs refresh. The pause succeeds, but the following frame has lost the unresolved completion question. The original query probe passes; the broader obligation lifecycle remains incomplete.

### F99 The replacement durable writer can acknowledge corrupt or unsynced state, original reproduction fixed

The new writeDurable calls writeSync once and ignores its returned byte count. A partial write is then fsynced and renamed over the state file, and the service returns success. Its directory-sync catch also suppresses every error, including real I/O failures, while the module claims successful responses are durable against power loss.

N6 injects a legal short write at the filesystem boundary. The action returns HTTP 200 and the persisted file is truncated invalid JSON. N7 injects EIO specifically for directory fsync; the service still returns 200. These are deterministic fault-injection tests, not an assertion that an actual power failure was exercised. Staging in-memory state fixes the earlier pre-write fault but does not make this replacement writer complete.

### F100 The 404 path still accepts an unverified refusal, original reproduction fixed

The stricter response decoder handles malformed 2xx and most unrecognized errors correctly, but its 404 branch returns TARGET_INVALIDATED without validating the response body. An arbitrary proxy or malformed 404 therefore becomes a definitive failure despite the stated requirement for contract-valid refusals.

N8 lets the real service apply a pause and replaces the reply with plain-text HTTP 404. The service task is paused while the kernel marks its effect FAILED. This is the same uncertain-outcome failure mode as the original malformed-success reproduction, now isolated to the remaining unchecked status branch.
