Repository navigation
Conversation
…count (#2168) * factory: each repository says its open issues apart from pull requests factory.repos available[] and the factory's /v1/repos rows gain open_issues: open issues WITHOUT pull requests. open stays GitHub's open_issues_count, which counts both. The count comes from one batched GraphQL request per 100 listed repositories (aliases over repository(owner,name){issues(states:OPEN){totalCount}}), so discovery costs one request per REST page it already made. A batch GitHub refuses, or a repository it does not answer, leaves open_issues absent: never 0 and never a guess. * changes: open issues apart from pull requests (#2154) * factory: a live read-only lane for the repository list's open issues Opt-in (CODEAF_LIVE_REPOS_OPEN_ISSUES=1, GH_TOKEN): the picker's own lister reads the real account's repositories, every request counted and anything but the REST list's GET or the GraphQL count refused. * factory: the setup's open issues count issues alone The first-run setup's repository rows sent open_issues as GitHub's open_issues_count, issues and pull requests together, though the read the setup shows progress against counts issues alone. Discovery now asks the same batched GraphQL count the repository list uses (one request per page of 100, forge.OpenIssueCounts shared by both) and sends issues alone with open_issues_exact true. A repository GraphQL does not count keeps the combined number with open_issues_exact false: open_issues stays a required number, so no reader loses it. The read's own count is marked exact. The test guards that refuse GitHub writes treat a GraphQL query as the read it is; a mutation is still refused. * factory: the test write guards pass one GraphQL query and nothing else The guards that refuse GitHub writes took any POST /graphql whose query began with "query", so a second operation chosen by operationName, or a case-variant duplicate key read last by encoding/json, could carry a mutation past them. graphQLRead now passes a body only when its real keys, read token by token, are exactly "query" and optionally "variables" (no operationName, no duplicates, no other key), and a small lexer that skips strings, block strings and comments finds exactly one top-level operation opened by the keyword query and no mutation or subscription anywhere. The product's own open-issue count request, generated by its own code, passes. * factory: setup's open issues test pins 18 issues beside 12 pull requests and every failed count A setup repository row with 18 open issues and 12 open pull requests (GitHub's open_issues_count 30) shows 18 with open_issues_exact when the batched GraphQL count answers, and keeps 30 without the flag when the request is refused, answers GraphQL errors with no data, leaves the repository's alias null, or answers something that is not JSON. * changes: setup's open issues tests (#2168) * changes: shorter title for #2168
) * manual: a cost range writes both dollar signs and a look's price reads ≈ $0.02, as the app shows them * changes: factory cost words entry (#2194)
* factory: an opt-in per-endpoint log of GitHub requests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changes: entry for the GitHub request log Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * config: register CODEAF_GITHUB_LOG as operator plumbing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…th who) (#2125) * factory: the pipeline editor adds an approval (add_step kind gate, with who) add_step takes kind gate: a person put in one pipeline, with an optional prompt and who it waits on (@handle, operator, or the job's person). A gate takes no until, rounds, effort or fanout, and an existing gate may be listed in another pipeline when its words match. Behind the new hello word factory.pipeline_edit_gates; who on the add_step also needs factory.pipeline_edit_approvers. Both kind and who are runtime keys, so the preview takes them only for a file its factory attested. * factory: tidy the gate edit and number its change entry
…2126) * factory: the pipeline editor adds an approval (add_step kind gate, with who) add_step takes kind gate: a person put in one pipeline, with an optional prompt and who it waits on (@handle, operator, or the job's person). A gate takes no until, rounds, effort or fanout, and an existing gate may be listed in another pipeline when its words match. Behind the new hello word factory.pipeline_edit_gates; who on the add_step also needs factory.pipeline_edit_approvers. Both kind and who are runtime keys, so the preview takes them only for a file its factory attested. * factory: tidy the gate edit and number its change entry * factory: the pipeline editor renames a step (rename_step {name, to}) One step under a new name in every pipeline that lists it, in the required list and in its definition, whose words and who move with it. The new name is spelled as a step is and runs as a stage the runner can run; approve and proof are never renamed from or into, and no other edit in the preview names either name. The preview's structure carries renamed. Behind the new hello word factory.pipeline_edit_rename. * changes: number the rename_step entry --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: start and create take the pipeline a job runs (a kind of the repository's file) factory.job_start and factory.job_create take pipeline, a kind the repository's file lists, behind the new hello word factory.start_pipeline. The app sends it to the factory, which already took it on create; start_now now takes it too and decides it in the start's one write, from the file the start decides on the job. pr and ci stay refused, as at creation; a job that ran or waits in the queue keeps its steps; every refusal comes before any write. An older factory refuses the unknown field, so a pick is never dropped. * changes: number the start pipeline entry --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…word (#2128) * factory: the pipeline editor adds an approval (add_step kind gate, with who) add_step takes kind gate: a person put in one pipeline, with an optional prompt and who it waits on (@handle, operator, or the job's person). A gate takes no until, rounds, effort or fanout, and an existing gate may be listed in another pipeline when its words match. Behind the new hello word factory.pipeline_edit_gates; who on the add_step also needs factory.pipeline_edit_approvers. Both kind and who are runtime keys, so the preview takes them only for a file its factory attested. * factory: tidy the gate edit and number its change entry * factory: the pipeline editor renames a step (rename_step {name, to}) One step under a new name in every pipeline that lists it, in the required list and in its definition, whose words and who move with it. The new name is spelled as a step is and runs as a stage the runner can run; approve and proof are never renamed from or into, and no other edit in the preview names either name. The preview's structure carries renamed. Behind the new hello word factory.pipeline_edit_rename. * changes: number the rename_step entry * factory: adapt per pipeline; the pipeline editor sets one pipeline's word adapt: in .codeaf/factory.yaml may now be a map of pipeline to word (adapt: {issue: ask, docs: fixed}); one word is still read as before. set_adapt takes an optional pipeline (feature factory.pipeline_edit_adapt_kind) and the source carries adapt_kinds. A map is a runtime key: an older factory would drop it, so it is read and previewed only for a file its factory attested. * changes: entry for #2128 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… kind (#2254) * test: reproduce duplicated tool names and home paths in run logs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: make factory tool log captions readable and identifiable Tool event hints already include the tool name. Normalize tool captions before clipping and retain identity through the existing report tone so strict older factories accept reports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…mote's stamp answers (#2047) * tests: the last test-only Mac assumptions (T3-T7) Twelve tests assumed Linux and failed on a Mac with nothing wrong in the product: - BSD mktemp ignores TMPDIR without a template, so the five scratch-routing probes now name "${TMPDIR:-/tmp}/probe.XXXXXX" (session, executor); - the three cellstore socket fixtures resolve /tmp to /private/tmp, clean the temp prefix and keep a short base, as the product's socket rules do; - the release-surface probe guards an empty array, which bash 3.2 calls unset under nounset (the workflow itself runs on Linux bash); - the teams doors' unchanged answer is asserted to carry exactly the stamp and the flag, since a Mac's device and inode numbers make the stamp longer; - tui3's Memory switch is expected in the app's own chord spelling, which is opt+u on a Mac. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: the change entry for #2047 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…d the job bound work there (#2039) * processgroup: read macOS process groups and job subtrees without cgo Members lists a group through kern.proc.pgrp with a bounded retry, and Group.Usage walks the recorded leader's descendants through the kernel's proc_info interface, converting task time with hw.tbfrequency. The new darwinproc package owns the raw trap, the SDK layouts and the argv and listening-socket readers the executor uses next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * executor: name and port left-running services on macOS cmdline reads kern.procargs2 and the ports come from each member's TCP listeners. describe reads each member's sockets once for both the naming member and the port set. The two service tests run on Linux and macOS, and the listening-service test polls the record until the backgrounded shell has exec'd its server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: the job subtree bound, and that macOS now applies it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * processgroup, darwinproc: bound the macOS walk and keep strangers out Review fixes: - A queued parent is re-read after its children are listed and its start time compared, so a pid handed to another process cannot bring that process's children into the job's reading. - A child listing that fills the largest buffer, and a walk that reaches 1024 processes, count as lower bounds; any unexpected listing failure makes the reading unknown instead of partial. - kern.procargs2 is parsed at the kernel's eight-byte boundary after the executable path, so an empty argv[0] can never shift an environment string into argv (checked for path lengths 1-40 on arm64 and under Rosetta). - The listening-service test's shell now waits for the server's port before it exits, so the record the call returns is asserted directly; the membersOf helpers it no longer needs are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * processgroup, session: a partial CPU sum yields no rate Review fix: a reading that left part of the tree out (the walk limit, a truncated child listing, a process that could not be read) still counts processes as a lower bound, but its CPU sum is marked partial. The job bound takes no rate from it and does not use it as the next baseline, so a process missing from one reading and present in the next cannot read as a burst of its whole lifetime's CPU and invent a strike. Linux readings are always complete, so nothing changes there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * processgroup: a parent that cannot be re-read makes the sum partial Review fix: when a queued parent read once but its re-read after the child listing fails for a reason other than having exited, its children are left out of this reading only, so the CPU sum is marked partial and no rate is taken from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: number the change entry for #2039 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * processgroup: a child counts only while its parent is still the same Review fix: the macOS walk now reads a parent's listed children first and re-reads the parent after them. A pid is never handed on while its process lives, so a parent with the same start time after its children were read was their parent while they were read; a parent and child whose pids both changed hands just after the parent's own re-read can no longer bring a stranger's busy child into the job's reading. The partial-sum regression now starts from one complete, quiet reading, so it also fails if a partial reading ever keeps that earlier baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: specify marking a job pull request ready Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mark job pull requests ready through the app Reuse the GitHub ready mutation with the caller credential and persist its confirmed draft state before returning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover GitHub ready conflicts and permission refusals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve definite ready-for-review refusals Keep automatic publication idempotent while explicit ready requests conflict on an already ready PR and preserve GitHub permission refusals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pr-ready is a server-owned verb in the client contract Its own serve tests cover it against the real store. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a draft's merge block now names what readiness waits for Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take the gated copy of the union merged docs --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ls (factory.effort_models) (#2148) * factory: a cheap step runs on the small work model, a strong one on the checks model A step's effort word now goes with its conversation, and with no model of the step's or the job's the step opens on the model its effort runs on: models.tiers.low for cheap, models.tiers.high for strong. One model for every task keeps its one model. The app announces factory.effort_models. * changes: name PR 2148 * factory: effort tiers keyed by the one list of effort words * factory: live check of a cheap step on the small work model * factory: a step's effort word comes before the factory's default model Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…b_protected) (#2145) * factory: a Backlog job says which protected paths it names The queue judges every Backlog job against the rules it would start under, read once per repository and show-only, and carries the protected paths its issue, comments, plan or files name. Absent is not judged. The app announces factory.job_protected. * changes: name PR 2145 * factory: live check of the protected key against a real repository * changes: name PR 2145 in the entry * factory: a cheap step runs on the small work model, a strong one on the checks model A step's effort word now goes with its conversation, and with no model of the step's or the job's the step opens on the model its effort runs on: models.tiers.low for cheap, models.tiers.high for strong. One model for every task keeps its one model. The app announces factory.effort_models. * changes: name PR 2148 * factory: judge protected paths only for jobs the canvas shows in Backlog * factory: effort tiers keyed by the one list of effort words * factory: live check of a cheap step on the small work model * factory: a step's effort word comes before the factory's default model Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… can't succeed doesn't spend (#2256) * factory: a raised budget resumes an Auto job its runner parked at the cap A worker's runner parks at the budget through its ask, and its report puts that question on the desk copy as Asking. raise_budget resumed only when Asking was nil, so for a held job it never resumed. Its Yes on the budget signal was a second answer path that the gate never reached. The raise now treats the open ask as the cap question when QKind is cap and any Asking is that same question. When the new cap clears the spend on an Auto job, the raise answers "continue" through the answer door a person's answer uses (continueCap, taken out of the answer handler). The ask comes down, the ledger keeps budget_changed then answered, and the timeline says the budget was raised. The budget signal now carries only the cap and goes first, so the runner never doubles the old cap. An unheld cap continue had the same gap: KeepAnswer cleared Asking but left the job needing you. AnswerUnheld now queues it through run.ReleaseCap, which the answer handler's own fallback uses as well. Manual jobs, any other open ask, and a raise to the spend or lower stay parked. The new worker tests run against the rig's worker-backed desk. The old test ran on a Manual job through a second handler. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: say the raise resumed only once the continue is answered Review of the raise found two problems. First, the timeline said "carrying on" in the same write as the cap, before the answer door ran. A refused answer then left the job parked with a timeline that said otherwise. The note is now written after the continue is accepted. Second, the answer door's fallback for a cap no runner waits on queued the job whatever it waited on at that moment. A job that moved on to another question between the read and the release lost that question. The release now takes down only a cap question. This commit also adds the change entry and removes a stray test comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changes: the raised budget entry carries its PR number Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a person's continue at the cap queues an unheld job again (test) Pins the second half of the fix: on an unheld Auto job whose copy still carries the cap question as an open ask, a person's continue takes the ask down and queues the job. On the base (39cec14) the job was left needing you with its question; on this branch it is queued. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(factory): preserve ordered budget answers and spending stops Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(factory): a Manual budget raise reaches the next approval Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(factory): a budget raise answers Manual's cap question The Auto-only resume predicate stranded Manual jobs after a raise above spend. Keep Take over and other decisions parked while allowing Manual to reach its next step approval. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce no-change feedback report escaping correction Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: correct no-change feedback reports in the same conversation Tracked feedback requires a structured current-head assessment. Return omissions at the reporting door while the model can correct them, retaining the clean published-head verifier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: use the required change entry schema Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse unchanged no-change feedback retries before spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: refuse unchanged feedback verification retries before spending Bind the no-change verification refusal to its PR observations in the saved result. Answer and rerun paths retain the question and budget until those facts change; Stop and fresh feedback remain available. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: exercise no-change feedback with a live factory model Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: preserve unpaid retry when a refused checkout is restored Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recheck refused checkout state before another model call A PR snapshot alone cannot tell whether a rejected checkout was restored. Preserve its content receipt and validate it on the worker without spending; changed contents permit a fresh assessment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain current-head feedback review fences Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: preserve the running state in the live feedback fixture Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: require explicit Model Pool opt-in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep Model Pool off until explicitly enabled Default the shared resolver to off, including CI, while preserving saved choices and environment overrides. Align settings and manual copy and opt pool fixtures in explicitly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: exercise pool default through production app boot Use the production app opener so the provider and record assertions cover the real pool startup sweep without one-model mode masking it. Explicitly enable the two pool push fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: explicitly enable pool for exec pending records The restart-sweep fixture intentionally tests pool records; opt it in now that untouched profiles stay off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * config: Model Pool off says only what the switch does Off stops pool judging and sharing. It does not hold task roles to the chat model: in Auto the router still picks from the allowed models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…at 1 s ticker (#2255) * knowledge: capture wakes on the chat's own journal writes After #2042 an idle chat's capture tick opened no database, but it still woke every second and opened, read and closed the chat's journal. It was the largest per-chat timer left in an idle engine. The journal writer's hook now wakes capture after each line reaches the file (an in-process signal; no file watch). Each write is followed by one trailing look a second later, a look that moves the cursor is followed by another, so a backlog still moves one batch a second, and a five-second safety tick covers lines another process writes to the same journal and consent changed elsewhere. A look a write woke uses a consent answer at most a second old (CaptureConsentWithin), so a turn written just after consent changed elsewhere is captured on the trailing look. An idle chat now runs one five-second tick and nothing else. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: change entry for #2048 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * knowledge: a new capture scanner always takes one trailing look Review found that a rebind could leave a write without its trailing look: the retired scanner may consume the wake and answer from a consent view under a second old, and the replacement's first look moved nothing, so it armed no trailing look and capture waited for the safety tick. Every scanner now looks once when it starts and once more a second later with fresh consent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…for branch publication (#2032) Rebased onto app/v3, where #2178 and #2183 already cover most of this branch: the engine-backed fixtures and the hosted take-back's resumed-hold proof. What is left: - the hosted move rig and the drive rig's default daemon keep their homes under /tmp on Unix, because macOS's temporary folder leaves a workspace socket only a few bytes under the address limit; - the L12 death-branches test waits for A's branch row to hold its three orphan turns before it reads them. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) * remote: an app chat's streamed text is folded before it is framed Every streamed delta of an in-process app chat crossed the remote framing, the in-memory pipe and about eight goroutine handoffs on its own. At 40 tok/s the deltas are 25 ms apart, so the app outbox's 16 ms window never folded anything. Engine.DeltaWindow (opt-in, set by the app's in-process and lent conversations to DefaultDeltaWindow, 33 ms) lets each stream's pump send the first chunk at once and fold the text that follows until the window ends or 4 KiB. Every non-text event sends the held text first and goes out at once; the channel closing flushes before "closed". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * remote: the delta window's tests cover swap, a real reconnect and a steady stream A swap while text is held lets none of the old conversation through; a real client cut mid-burst and resumed sees each character once; with the production window a quiet tail arrives and a steady producer is never starved. The 4 KiB value is documented as the flush threshold it is, and the latency check keeps its median bound without a per-sample maximum that scheduler pauses could break. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: change entry for #2043 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * remote: the delta window's swap and steady-stream tests stand on their own The swap test drives its own pump and joins only that one, so it no longer depends on the fake agent opening no other lanes. The steady-producer test bounds frames by the time the producer actually took and checks that text reaches the surface before the producer finishes, keeping the largest gap as a diagnostic. The change entry names the conversations it applies to: the ones the desktop's engine holds in process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take the gated copy of the union merged docs --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: force task notes to arrive before the final answer ends Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: hold the worker request rather than its helper Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep task directions queued until a worker request reads them Turn cleanup recorded late directions and emptied the queue before the runner checked it. The task could finish with saved notes that no worker request had read. Keep those directions queued for the runner to take another turn and stamp the keyed reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: clarify the final-answer note regression fixture Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: distinguish a missing note receipt from lost words Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: expose later person requests to the job brief Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: judge job briefs against later person requests Carry gate answers and saved notes into the writer input so requested work is judged against the person’s current request. Preserve bounded requests through input cuts and include them in freshness checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: prepare paired live brief request probe Compare the same scripted work with and without person requests using the pinned live model. Print checked verdicts and blocks, and reject the false-fault vocabulary seen in the report. The probe is opt-in and left for the caller to run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: log why a live brief reply ended Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a live brief names the request in its text The verdict is at most fourteen words and may refer to the request by name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * manual: say Brief, not the writer's word for its headline Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#2264) * test: force action reads while a light crew owner opens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: wait for crew readiness before requiring live process actions Reads deliberately answer saved history while a light owner is opening. Check that nonblocking answer during a forced open, then require live actions after agent.changed instead of depending on scheduler timing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce preview refusal digits in a factory identity Pin the fixture identity to include 820 so the whole-error wording check fails consistently despite a clean displayed message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: prove the preview wording guard catches a displayed numeric leak Check only the displayed message and deliberately inject 820 there for the negative control. The following commit removes this test-only mutation after the remote guard verdict. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep preview refusal wording checks on the displayed message Remove the negative-control message injection after confirming that the guard rejects 820 in displayed words. Factory identity digits remain deterministic and typed refusal details are still checked separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing memory spend through the vault interface Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank memory receipts and bind job compilation to finished turns The compiler used the provider transport without a ledger consumer, while the process worker owned its lifetime independently of jobs. Bank decoded receipts before validation and keep job sources out of independent compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: isolate memory snapshots and verify cancellation during compilation Keep compilation boundaries per owner, drain finished-turn journals, and classify older factory conversations from persisted memberships. Preserve projection upgrades and reject a structural bypass that discards the billed context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover retained job sources and large memory snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse memory admission on paused and published jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drain owned memory snapshots and fence unchanged failed input Reclassify retained job events independently of journal cursors, check stored pause and publication state at admission, and finish every extraction batch in the turn snapshot. New source input or an explicit Build is required to retry failed background compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reject repeated refinement of unchanged memory input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require new evidence or explicit build for further memory refinement Record the Build request consumed by each publication so forced flushes on unchanged sources stay idle. Preserve recovery when extraction produced new unpublished evidence, and let an explicit Build advance retained guide work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: old job ownership excludes background memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain old factory ownership in memory inventory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: compile delegated reports with their owning turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: use the persisted place layout for delegated memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: compile delegated evidence on the owning job turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live job memory cost and stage tail delays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory cannot turn successful work into a cap stop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve successful stage results after deferred spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: bound stage memory waits and retain cancelled charges Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: enforce memory cap only at the next unfinished step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: record completed phases before checking the next budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish memory delay and stop timed-out live jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bound stage memory waits to the owning job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain skipped stage evidence across job memory handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recover skipped stage evidence in the next owned memory pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure late memory receipts after job completion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep an empty owned source selection empty Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count overlapping memory waits as wall time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: attribute memory tail wait to its initiating stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify live memory starts stay inside the job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: stop live measurements with a fresh job version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count measured memory calls independently of late prices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read measured job spending through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: settle cancelled live calls before checking measured spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: open live factory brief chats through the in-process app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: deliver late memory receipts through the real factory worker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: observe the public ready flag and bound worker fixture cleanup Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep job reporting alive for late memory receipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test late memory pricing after stopping a factory job Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Observe finished steps before settling final prices and pin live helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reconcile paid memory after a stopped job loses its lease Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep one accounting anchor per run and retry final settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test final memory settlement preserves previously counted job spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure stage answers separately from automatic brief calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Report per-job memory dollars and bound delays by the next step start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test paid memory survives reopening a finished stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preserve paid usage in a closed stage journal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test leased memory receipts during actual factory quit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow bounded accounting settlement after worker cancellation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce the memory tail fixture accounting observation race Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for both memory ledger and job accounting in lifecycle fixture The ledger is published before the independent job meter update. Poll both observable totals and name standalone session closure accurately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test quitting while final worker accounting is already settling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep bounded accounting alive when quit interrupts settlement Detach the existing settlement context from execution immediately, then cancel it five seconds after quit. This also covers cancellation arriving during the existing receipt wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Recognize late journal usage in the append funnel guard The journal is a separate store from artifact indexes. Account for both journal append owners while retaining the guard against unknown append paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce stage budget exemptions and unowned batch draining Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Distinguish memory cap crossings and restore bounded ordinary Flush Keep memory in total job spend while excluding only newly charged memory from completed-round cap checks. Preserve model and tool stops, and retain finite draining only for owned turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce duplicate factory brief charges through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8f8015c20a5e74cd8c73ec68d8fe22b4feb5118e) * fix: charge factory brief calls only at the session billing boundary The session already books each provider receipt to the job and ledger. Keeping a brief charged the job again, including rejected drafts. Preserve session booking so failed saves retain their cost and worker spending remains additive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c2938deaf4b3e6ec8eb9c865a58c229663def4ac) * test: audit manager and title charges beside factory briefs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bb52801b802fd29a1b6889d55461eeeb69e66f87) * test: exercise title billing on an unnamed job-owned conversation Factory managers have a saved title and correctly skip model naming. Use an unnamed stage for the separate title receipt audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit eee242d5899dd62c6d89e3186a1f83d853a67cda) * test: align the factory keep contract with receipt-based billing Keeping a brief preserves its cost metadata without charging the already billed call again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3af433d90bf6809c42152de9b480be3ab3b9e99a) * test: reserve the leased brief fixture for its simulated worker The local factory starts a worker too. Pin the fixture to the remote machine so a local runner cannot win its queued lease when the surrounding suite supplies a runnable configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4ff25c49ffc450b770045ee8a861156447001cd4) * Declare local memory provenance at the reader boundary Check late memory receipts retain their classified share as well as their total charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the existing lane import alias for memory accounting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check live brief charges against the job header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: one entry for the brief charge fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the call log's served field names the provider, not the model The recorder already checks the model that answered each call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory crossing the cap does not hide a daily refusal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a daily refusal is never read as a memory charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce pause after a memory stage tail detaches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check memory admission when Pause returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: complete the paid memory response with valid JSON Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain paused memory for a later resumed turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live Pause memory and provider receipt totals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check settled provider sums and detached memory lifecycle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pause live memory after a provider generation starts Document paused memory admission, normal resume, and process-owned shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: admit local job memory against the owning factory state A worker mirror can still say running after Pause returns. Read the owning local factory for memory admission and cancellation while retaining mirror-based receipt settlement. The job conversation checks that owner before worker mirrors too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cap resumed memory at one normal scripted pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure only stages that started before Pause A paused job correctly has no conversation identity for its unstarted stages. Skip those stages when measuring memory rather than requiring identities from future work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count a finished memory generation and its receipt once A response can finish at the same time cancellation queues its receipt. Both observations describe the same provider charge, so share the existing once-only charge counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain unfinished memory after a completed extraction Pending counts unextracted source events. When the already-paid extraction finishes at Pause, those events can be consumed while NeedsUpdate retains the remaining compilation work. Keep the stricter source assertion for interrupted calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: name its call tag for the replay law and pass the new scan argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory fixtures use a step that isn't held for an unchanged checkout A job's write step with no change now waits for a person. These tests are about memory, so their step is plain work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take the gated copy of the union merged docs --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing memory spend through the vault interface Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank memory receipts and bind job compilation to finished turns The compiler used the provider transport without a ledger consumer, while the process worker owned its lifetime independently of jobs. Bank decoded receipts before validation and keep job sources out of independent compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: isolate memory snapshots and verify cancellation during compilation Keep compilation boundaries per owner, drain finished-turn journals, and classify older factory conversations from persisted memberships. Preserve projection upgrades and reject a structural bypass that discards the billed context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover retained job sources and large memory snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse memory admission on paused and published jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drain owned memory snapshots and fence unchanged failed input Reclassify retained job events independently of journal cursors, check stored pause and publication state at admission, and finish every extraction batch in the turn snapshot. New source input or an explicit Build is required to retry failed background compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reject repeated refinement of unchanged memory input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require new evidence or explicit build for further memory refinement Record the Build request consumed by each publication so forced flushes on unchanged sources stay idle. Preserve recovery when extraction produced new unpublished evidence, and let an explicit Build advance retained guide work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: old job ownership excludes background memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain old factory ownership in memory inventory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: compile delegated reports with their owning turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: use the persisted place layout for delegated memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: compile delegated evidence on the owning job turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live job memory cost and stage tail delays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory cannot turn successful work into a cap stop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve successful stage results after deferred spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: bound stage memory waits and retain cancelled charges Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: enforce memory cap only at the next unfinished step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: record completed phases before checking the next budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish memory delay and stop timed-out live jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bound stage memory waits to the owning job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain skipped stage evidence across job memory handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recover skipped stage evidence in the next owned memory pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure late memory receipts after job completion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep an empty owned source selection empty Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count overlapping memory waits as wall time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: attribute memory tail wait to its initiating stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify live memory starts stay inside the job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: stop live measurements with a fresh job version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count measured memory calls independently of late prices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read measured job spending through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: settle cancelled live calls before checking measured spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: open live factory brief chats through the in-process app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: deliver late memory receipts through the real factory worker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: observe the public ready flag and bound worker fixture cleanup Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep job reporting alive for late memory receipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test late memory pricing after stopping a factory job Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Observe finished steps before settling final prices and pin live helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reconcile paid memory after a stopped job loses its lease Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep one accounting anchor per run and retry final settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test final memory settlement preserves previously counted job spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure stage answers separately from automatic brief calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Report per-job memory dollars and bound delays by the next step start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test paid memory survives reopening a finished stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preserve paid usage in a closed stage journal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test leased memory receipts during actual factory quit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow bounded accounting settlement after worker cancellation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce the memory tail fixture accounting observation race Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for both memory ledger and job accounting in lifecycle fixture The ledger is published before the independent job meter update. Poll both observable totals and name standalone session closure accurately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test quitting while final worker accounting is already settling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep bounded accounting alive when quit interrupts settlement Detach the existing settlement context from execution immediately, then cancel it five seconds after quit. This also covers cancellation arriving during the existing receipt wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Recognize late journal usage in the append funnel guard The journal is a separate store from artifact indexes. Account for both journal append owners while retaining the guard against unknown append paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce stage budget exemptions and unowned batch draining Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Distinguish memory cap crossings and restore bounded ordinary Flush Keep memory in total job spend while excluding only newly charged memory from completed-round cap checks. Preserve model and tool stops, and retain finite draining only for owned turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce duplicate factory brief charges through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8f8015c20a5e74cd8c73ec68d8fe22b4feb5118e) * fix: charge factory brief calls only at the session billing boundary The session already books each provider receipt to the job and ledger. Keeping a brief charged the job again, including rejected drafts. Preserve session booking so failed saves retain their cost and worker spending remains additive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c2938deaf4b3e6ec8eb9c865a58c229663def4ac) * test: audit manager and title charges beside factory briefs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bb52801b802fd29a1b6889d55461eeeb69e66f87) * test: exercise title billing on an unnamed job-owned conversation Factory managers have a saved title and correctly skip model naming. Use an unnamed stage for the separate title receipt audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit eee242d5899dd62c6d89e3186a1f83d853a67cda) * test: align the factory keep contract with receipt-based billing Keeping a brief preserves its cost metadata without charging the already billed call again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3af433d90bf6809c42152de9b480be3ab3b9e99a) * test: reserve the leased brief fixture for its simulated worker The local factory starts a worker too. Pin the fixture to the remote machine so a local runner cannot win its queued lease when the surrounding suite supplies a runnable configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4ff25c49ffc450b770045ee8a861156447001cd4) * Declare local memory provenance at the reader boundary Check late memory receipts retain their classified share as well as their total charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the existing lane import alias for memory accounting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check live brief charges against the job header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: one entry for the brief charge fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the call log's served field names the provider, not the model The recorder already checks the model that answered each call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory crossing the cap does not hide a daily refusal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a daily refusal is never read as a memory charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce pause after a memory stage tail detaches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check memory admission when Pause returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: complete the paid memory response with valid JSON Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain paused memory for a later resumed turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live Pause memory and provider receipt totals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check settled provider sums and detached memory lifecycle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pause live memory after a provider generation starts Document paused memory admission, normal resume, and process-owned shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: admit local job memory against the owning factory state A worker mirror can still say running after Pause returns. Read the owning local factory for memory admission and cancellation while retaining mirror-based receipt settlement. The job conversation checks that owner before worker mirrors too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cap resumed memory at one normal scripted pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure only stages that started before Pause A paused job correctly has no conversation identity for its unstarted stages. Skip those stages when measuring memory rather than requiring identities from future work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count a finished memory generation and its receipt once A response can finish at the same time cancellation queues its receipt. Both observations describe the same provider charge, so share the existing once-only charge counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain unfinished memory after a completed extraction Pending counts unextracted source events. When the already-paid extraction finishes at Pause, those events can be consumed while NeedsUpdate retains the remaining compilation work. Keep the stricter source assertion for interrupted calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: require explicit memory consent through settings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require explicit consent for automatic memory Use memory.enabled for both noticing and knowledge compilation. Empty history no longer grants consent; saved choices remain live across open chats and jobs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover fresh app memory calls through job and chat Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop memory requests while keeping saved knowledge available Gate compiler requests and noticing retries on the live setting. Keep saved pages readable while off and retain pending builds across a switch. Prepare explicit-on billing fixtures and a capped live off test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: require zero new memory requests after switching off Align remaining manual references with the shared learning switch and count request starts exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify fresh app leaves knowledge consent unset Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: cost words say it varies, and the manual names the job's switch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: name its call tag for the replay law and pass the new scan argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory fixtures use a step that isn't held for an unchanged checkout A job's write step with no change now waits for a person. These tests are about memory, so their step is plain work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the live memory measure waits for the last brief before reading the header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: fixtures that exercise automatic memory turn it on Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the switch test reads the one cost note, and its job step is plain work Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: a store that can't open says why, not that memory is off The switch makes off a real state, so this refusal must not read as the person's choice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a first start with memory off must still be able to join Red: the off pass records its job as unbuilt, and the join check only knows waiting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * identity: a memory-off first start counts as a first start A person who starts fresh with memory off could not join an organization, because the home read as holding work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * settings: memory's detail says again that nothing saved is deleted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: reproduce tombstone lookup panic on vault read failure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: return vault read errors before checking tombstones Deleted dereferenced a nil document when a valid vault handle failed to read its backing file. Return the read error so sync can retry instead of terminating its worker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: clarify previous and current vault read failure behavior Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * manual: name the vault read failure section by what it covers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: two engines on one home must not both start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * app: one engine on a home; a second waits for the first to end Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a waiting engine starts nothing, and a child doesn't hold the home Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing memory spend through the vault interface Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank memory receipts and bind job compilation to finished turns The compiler used the provider transport without a ledger consumer, while the process worker owned its lifetime independently of jobs. Bank decoded receipts before validation and keep job sources out of independent compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: isolate memory snapshots and verify cancellation during compilation Keep compilation boundaries per owner, drain finished-turn journals, and classify older factory conversations from persisted memberships. Preserve projection upgrades and reject a structural bypass that discards the billed context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover retained job sources and large memory snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse memory admission on paused and published jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drain owned memory snapshots and fence unchanged failed input Reclassify retained job events independently of journal cursors, check stored pause and publication state at admission, and finish every extraction batch in the turn snapshot. New source input or an explicit Build is required to retry failed background compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reject repeated refinement of unchanged memory input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require new evidence or explicit build for further memory refinement Record the Build request consumed by each publication so forced flushes on unchanged sources stay idle. Preserve recovery when extraction produced new unpublished evidence, and let an explicit Build advance retained guide work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: old job ownership excludes background memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain old factory ownership in memory inventory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: compile delegated reports with their owning turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: use the persisted place layout for delegated memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: compile delegated evidence on the owning job turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live job memory cost and stage tail delays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory cannot turn successful work into a cap stop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve successful stage results after deferred spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: bound stage memory waits and retain cancelled charges Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: enforce memory cap only at the next unfinished step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: record completed phases before checking the next budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish memory delay and stop timed-out live jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bound stage memory waits to the owning job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain skipped stage evidence across job memory handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recover skipped stage evidence in the next owned memory pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure late memory receipts after job completion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep an empty owned source selection empty Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count overlapping memory waits as wall time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: attribute memory tail wait to its initiating stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify live memory starts stay inside the job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: stop live measurements with a fresh job version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count measured memory calls independently of late prices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read measured job spending through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: settle cancelled live calls before checking measured spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: open live factory brief chats through the in-process app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: deliver late memory receipts through the real factory worker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: observe the public ready flag and bound worker fixture cleanup Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep job reporting alive for late memory receipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test late memory pricing after stopping a factory job Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Observe finished steps before settling final prices and pin live helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reconcile paid memory after a stopped job loses its lease Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep one accounting anchor per run and retry final settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test final memory settlement preserves previously counted job spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure stage answers separately from automatic brief calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Report per-job memory dollars and bound delays by the next step start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test paid memory survives reopening a finished stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preserve paid usage in a closed stage journal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test leased memory receipts during actual factory quit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow bounded accounting settlement after worker cancellation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce the memory tail fixture accounting observation race Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for both memory ledger and job accounting in lifecycle fixture The ledger is published before the independent job meter update. Poll both observable totals and name standalone session closure accurately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test quitting while final worker accounting is already settling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep bounded accounting alive when quit interrupts settlement Detach the existing settlement context from execution immediately, then cancel it five seconds after quit. This also covers cancellation arriving during the existing receipt wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Recognize late journal usage in the append funnel guard The journal is a separate store from artifact indexes. Account for both journal append owners while retaining the guard against unknown append paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce stage budget exemptions and unowned batch draining Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Distinguish memory cap crossings and restore bounded ordinary Flush Keep memory in total job spend while excluding only newly charged memory from completed-round cap checks. Preserve model and tool stops, and retain finite draining only for owned turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce duplicate factory brief charges through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8f8015c20a5e74cd8c73ec68d8fe22b4feb5118e) * fix: charge factory brief calls only at the session billing boundary The session already books each provider receipt to the job and ledger. Keeping a brief charged the job again, including rejected drafts. Preserve session booking so failed saves retain their cost and worker spending remains additive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c2938deaf4b3e6ec8eb9c865a58c229663def4ac) * test: audit manager and title charges beside factory briefs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bb52801b802fd29a1b6889d55461eeeb69e66f87) * test: exercise title billing on an unnamed job-owned conversation Factory managers have a saved title and correctly skip model naming. Use an unnamed stage for the separate title receipt audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit eee242d5899dd62c6d89e3186a1f83d853a67cda) * test: align the factory keep contract with receipt-based billing Keeping a brief preserves its cost metadata without charging the already billed call again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3af433d90bf6809c42152de9b480be3ab3b9e99a) * test: reserve the leased brief fixture for its simulated worker The local factory starts a worker too. Pin the fixture to the remote machine so a local runner cannot win its queued lease when the surrounding suite supplies a runnable configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4ff25c49ffc450b770045ee8a861156447001cd4) * Declare local memory provenance at the reader boundary Check late memory receipts retain their classified share as well as their total charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the existing lane import alias for memory accounting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check live brief charges against the job header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: one entry for the brief charge fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the call log's served field names the provider, not the model The recorder already checks the model that answered each call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory crossing the cap does not hide a daily refusal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a daily refusal is never read as a memory charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce pause after a memory stage tail detaches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check memory admission when Pause returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: complete the paid memory response with valid JSON Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain paused memory for a later resumed turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live Pause memory and provider receipt totals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check settled provider sums and detached memory lifecycle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pause live memory after a provider generation starts Document paused memory admission, normal resume, and process-owned shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: admit local job memory against the owning factory state A worker mirror can still say running after Pause returns. Read the owning local factory for memory admission and cancellation while retaining mirror-based receipt settlement. The job conversation checks that owner before worker mirrors too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cap resumed memory at one normal scripted pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure only stages that started before Pause A paused job correctly has no conversation identity for its unstarted stages. Skip those stages when measuring memory rather than requiring identities from future work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count a finished memory generation and its receipt once A response can finish at the same time cancellation queues its receipt. Both observations describe the same provider charge, so share the existing once-only charge counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain unfinished memory after a completed extraction Pending counts unextracted source events. When the already-paid extraction finishes at Pause, those events can be consumed while NeedsUpdate retains the remaining compilation work. Keep the stricter source assertion for interrupted calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing factory charge settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: settle factory charges from final provider receipts Interim stream usage suppressed reconciliation even when no session billing sink could consume it. Factory calls now recover the final receipt and retain unknown-price ownership. Write through ledger overflow without holding a turn indefinitely. Memory keeps its existing billing path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: snapshot pending overflow writes across ledger flushes Capture completion barriers without racing WaitGroup reuse. A full queue cannot certify a successful flush; it reports false under the existing deadline instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep unpriced factory receipts visibly unknown Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep factory token-only receipts unbilled A receipt with token counts but no provider price cannot establish a dollar charge. Final-price consumers now retain the existing unknown-price marker instead of treating those counts as a settled bill. Other receipt consumers remain unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: name its call tag for the replay law and pass the new scan argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory fixtures use a step that isn't held for an unchanged checkout A job's write step with no change now waits for a person. These tests are about memory, so their step is plain work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: a full usage queue never makes a turn wait The 100 ms per overflow row added up on a stalled disk and broke the ledger's turn law. One background writer takes overflow rows instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: the ledger's one writer takes overflow rows, in order Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: format the ledger writer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: a full queue's flush waits for the kept rows instead of reporting false Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: wake the ledger writer when a row is kept after it emptied the queue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: an answer with no usage doesn't hold the job's next step for its receipt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Take the gated copy of the union merged docs --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#2275) * factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing memory spend through the vault interface Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank memory receipts and bind job compilation to finished turns The compiler used the provider transport without a ledger consumer, while the process worker owned its lifetime independently of jobs. Bank decoded receipts before validation and keep job sources out of independent compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: isolate memory snapshots and verify cancellation during compilation Keep compilation boundaries per owner, drain finished-turn journals, and classify older factory conversations from persisted memberships. Preserve projection upgrades and reject a structural bypass that discards the billed context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover retained job sources and large memory snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse memory admission on paused and published jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drain owned memory snapshots and fence unchanged failed input Reclassify retained job events independently of journal cursors, check stored pause and publication state at admission, and finish every extraction batch in the turn snapshot. New source input or an explicit Build is required to retry failed background compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reject repeated refinement of unchanged memory input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require new evidence or explicit build for further memory refinement Record the Build request consumed by each publication so forced flushes on unchanged sources stay idle. Preserve recovery when extraction produced new unpublished evidence, and let an explicit Build advance retained guide work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: old job ownership excludes background memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain old factory ownership in memory inventory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: compile delegated reports with their owning turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: use the persisted place layout for delegated memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: compile delegated evidence on the owning job turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live job memory cost and stage tail delays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory cannot turn successful work into a cap stop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve successful stage results after deferred spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: bound stage memory waits and retain cancelled charges Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: enforce memory cap only at the next unfinished step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: record completed phases before checking the next budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish memory delay and stop timed-out live jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bound stage memory waits to the owning job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain skipped stage evidence across job memory handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recover skipped stage evidence in the next owned memory pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure late memory receipts after job completion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep an empty owned source selection empty Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count overlapping memory waits as wall time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: attribute memory tail wait to its initiating stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify live memory starts stay inside the job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: stop live measurements with a fresh job version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count measured memory calls independently of late prices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read measured job spending through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: settle cancelled live calls before checking measured spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: open live factory brief chats through the in-process app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: deliver late memory receipts through the real factory worker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: observe the public ready flag and bound worker fixture cleanup Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep job reporting alive for late memory receipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test late memory pricing after stopping a factory job Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Observe finished steps before settling final prices and pin live helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reconcile paid memory after a stopped job loses its lease Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep one accounting anchor per run and retry final settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test final memory settlement preserves previously counted job spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure stage answers separately from automatic brief calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Report per-job memory dollars and bound delays by the next step start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test paid memory survives reopening a finished stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preserve paid usage in a closed stage journal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test leased memory receipts during actual factory quit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow bounded accounting settlement after worker cancellation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce the memory tail fixture accounting observation race Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for both memory ledger and job accounting in lifecycle fixture The ledger is published before the independent job meter update. Poll both observable totals and name standalone session closure accurately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test quitting while final worker accounting is already settling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep bounded accounting alive when quit interrupts settlement Detach the existing settlement context from execution immediately, then cancel it five seconds after quit. This also covers cancellation arriving during the existing receipt wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Recognize late journal usage in the append funnel guard The journal is a separate store from artifact indexes. Account for both journal append owners while retaining the guard against unknown append paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce stage budget exemptions and unowned batch draining Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Distinguish memory cap crossings and restore bounded ordinary Flush Keep memory in total job spend while excluding only newly charged memory from completed-round cap checks. Preserve model and tool stops, and retain finite draining only for owned turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce duplicate factory brief charges through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8f8015c20a5e74cd8c73ec68d8fe22b4feb5118e) * fix: charge factory brief calls only at the session billing boundary The session already books each provider receipt to the job and ledger. Keeping a brief charged the job again, including rejected drafts. Preserve session booking so failed saves retain their cost and worker spending remains additive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c2938deaf4b3e6ec8eb9c865a58c229663def4ac) * test: audit manager and title charges beside factory briefs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bb52801b802fd29a1b6889d55461eeeb69e66f87) * test: exercise title billing on an unnamed job-owned conversation Factory managers have a saved title and correctly skip model naming. Use an unnamed stage for the separate title receipt audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit eee242d5899dd62c6d89e3186a1f83d853a67cda) * test: align the factory keep contract with receipt-based billing Keeping a brief preserves its cost metadata without charging the already billed call again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3af433d90bf6809c42152de9b480be3ab3b9e99a) * test: reserve the leased brief fixture for its simulated worker The local factory starts a worker too. Pin the fixture to the remote machine so a local runner cannot win its queued lease when the surrounding suite supplies a runnable configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4ff25c49ffc450b770045ee8a861156447001cd4) * Declare local memory provenance at the reader boundary Check late memory receipts retain their classified share as well as their total charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the existing lane import alias for memory accounting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check live brief charges against the job header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: one entry for the brief charge fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the call log's served field names the provider, not the model The recorder already checks the model that answered each call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory crossing the cap does not hide a daily refusal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a daily refusal is never read as a memory charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce pause after a memory stage tail detaches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check memory admission when Pause returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: complete the paid memory response with valid JSON Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain paused memory for a later resumed turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live Pause memory and provider receipt totals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check settled provider sums and detached memory lifecycle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pause live memory after a provider generation starts Document paused memory admission, normal resume, and process-owned shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: admit local job memory against the owning factory state A worker mirror can still say running after Pause returns. Read the owning local factory for memory admission and cancellation while retaining mirror-based receipt settlement. The job conversation checks that owner before worker mirrors too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cap resumed memory at one normal scripted pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure only stages that started before Pause A paused job correctly has no conversation identity for its unstarted stages. Skip those stages when measuring memory rather than requiring identities from future work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count a finished memory generation and its receipt once A response can finish at the same time cancellation queues its receipt. Both observations describe the same provider charge, so share the existing once-only charge counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain unfinished memory after a completed extraction Pending counts unextracted source events. When the already-paid extraction finishes at Pause, those events can be consumed while NeedsUpdate retains the remaining compilation work. Keep the stricter source assertion for interrupted calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing factory charge settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: settle factory charges from final provider receipts Interim stream usage suppressed reconciliation even when no session billing sink could consume it. Factory calls now recover the final receipt and retain unknown-price ownership. Write through ledger overflow without holding a turn indefinitely. Memory keeps its existing billing path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: snapshot pending overflow writes across ledger flushes Capture completion barriers without racing WaitGroup reuse. A full queue cannot certify a successful flush; it reports false under the existing deadline instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep unpriced factory receipts visibly unknown Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep factory token-only receipts unbilled A receipt with token counts but no provider price cannot establish a dollar charge. Final-price consumers now retain the existing unknown-price marker instead of treating those counts as a settled bill. Other receipt consumers remain unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: name its call tag for the replay law and pass the new scan argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory fixtures use a step that isn't held for an unchanged checkout A job's write step with no change now waits for a person. These tests are about memory, so their step is plain work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a ledger row with no turn must move today's figure Red: spend.changed fires only when a chat turn ends, so Factory triage, scouts and page AI never reach the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: today's figure moves when any ledger row lands, not only when a turn ends Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: a full usage queue never makes a turn wait The 100 ms per overflow row added up on a stalled disk and broke the ledger's turn law. One background writer takes overflow rows instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: overflow rows move today's figure too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: the ledger's one writer takes overflow rows, in order Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: finish the merge of the ledger writer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: format the ledger writer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: format the ledger writer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: drop the merge's duplicated writer loop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: a full queue's flush waits for the kept rows instead of reporting false Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: spend.today names Factory AI, so triage, scouts and page AI aren't called chats Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name what changed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: wake the ledger writer when a row is kept after it emptied the queue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * spend: an answer with no usage doesn't hold the job's next step for its receipt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* factory: a write step that changed nothing is not done A write round that reported done while the job's checkout had no change from the run's base counted as done, so test and review ran on an untouched tree and only publishing found nothing to commit. The runner now reads the checkout after a write round; with no change, the round does not pass, says "the checkout has no change from where the run began", and goes round again or asks. Other steps may still finish with no change, and an unreadable checkout never holds a round back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: changelog entry for #2158 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce missing memory spend through the vault interface Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank memory receipts and bind job compilation to finished turns The compiler used the provider transport without a ledger consumer, while the process worker owned its lifetime independently of jobs. Bank decoded receipts before validation and keep job sources out of independent compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: isolate memory snapshots and verify cancellation during compilation Keep compilation boundaries per owner, drain finished-turn journals, and classify older factory conversations from persisted memberships. Preserve projection upgrades and reject a structural bypass that discards the billed context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover retained job sources and large memory snapshots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: refuse memory admission on paused and published jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: drain owned memory snapshots and fence unchanged failed input Reclassify retained job events independently of journal cursors, check stored pause and publication state at admission, and finish every extraction batch in the turn snapshot. New source input or an explicit Build is required to retry failed background compilation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reject repeated refinement of unchanged memory input Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: require new evidence or explicit build for further memory refinement Record the Build request consumed by each publication so forced flushes on unchanged sources stay idle. Preserve recovery when extraction produced new unpublished evidence, and let an explicit Build advance retained guide work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: old job ownership excludes background memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain old factory ownership in memory inventory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: compile delegated reports with their owning turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: use the persisted place layout for delegated memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: compile delegated evidence on the owning job turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live job memory cost and stage tail delays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory cannot turn successful work into a cap stop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve successful stage results after deferred spending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: bound stage memory waits and retain cancelled charges Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: enforce memory cap only at the next unfinished step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: record completed phases before checking the next budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish memory delay and stop timed-out live jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bound stage memory waits to the owning job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain skipped stage evidence across job memory handoff Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: recover skipped stage evidence in the next owned memory pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure late memory receipts after job completion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep an empty owned source selection empty Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count overlapping memory waits as wall time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: attribute memory tail wait to its initiating stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: verify live memory starts stay inside the job lifetime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: stop live measurements with a fresh job version Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count measured memory calls independently of late prices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read measured job spending through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: settle cancelled live calls before checking measured spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: open live factory brief chats through the in-process app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: deliver late memory receipts through the real factory worker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: observe the public ready flag and bound worker fixture cleanup Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep job reporting alive for late memory receipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test late memory pricing after stopping a factory job Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Observe finished steps before settling final prices and pin live helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reconcile paid memory after a stopped job loses its lease Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep one accounting anchor per run and retry final settlement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test final memory settlement preserves previously counted job spend Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure stage answers separately from automatic brief calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Report per-job memory dollars and bound delays by the next step start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test paid memory survives reopening a finished stage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preserve paid usage in a closed stage journal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test leased memory receipts during actual factory quit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow bounded accounting settlement after worker cancellation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce the memory tail fixture accounting observation race Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for both memory ledger and job accounting in lifecycle fixture The ledger is published before the independent job meter update. Poll both observable totals and name standalone session closure accurately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test quitting while final worker accounting is already settling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep bounded accounting alive when quit interrupts settlement Detach the existing settlement context from execution immediately, then cancel it five seconds after quit. This also covers cancellation arriving during the existing receipt wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Recognize late journal usage in the append funnel guard The journal is a separate store from artifact indexes. Account for both journal append owners while retaining the guard against unknown append paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reproduce stage budget exemptions and unowned batch draining Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Distinguish memory cap crossings and restore bounded ordinary Flush Keep memory in total job spend while excluding only newly charged memory from completed-round cap checks. Preserve model and tool stops, and retain finite draining only for owned turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce duplicate factory brief charges through the app wire Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8f8015c20a5e74cd8c73ec68d8fe22b4feb5118e) * fix: charge factory brief calls only at the session billing boundary The session already books each provider receipt to the job and ledger. Keeping a brief charged the job again, including rejected drafts. Preserve session booking so failed saves retain their cost and worker spending remains additive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c2938deaf4b3e6ec8eb9c865a58c229663def4ac) * test: audit manager and title charges beside factory briefs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bb52801b802fd29a1b6889d55461eeeb69e66f87) * test: exercise title billing on an unnamed job-owned conversation Factory managers have a saved title and correctly skip model naming. Use an unnamed stage for the separate title receipt audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit eee242d5899dd62c6d89e3186a1f83d853a67cda) * test: align the factory keep contract with receipt-based billing Keeping a brief preserves its cost metadata without charging the already billed call again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3af433d90bf6809c42152de9b480be3ab3b9e99a) * test: reserve the leased brief fixture for its simulated worker The local factory starts a worker too. Pin the fixture to the remote machine so a local runner cannot win its queued lease when the surrounding suite supplies a runnable configuration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4ff25c49ffc450b770045ee8a861156447001cd4) * Declare local memory provenance at the reader boundary Check late memory receipts retain their classified share as well as their total charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the existing lane import alias for memory accounting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check live brief charges against the job header Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: one entry for the brief charge fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the call log's served field names the provider, not the model The recorder already checks the model that answered each call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory crossing the cap does not hide a daily refusal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * factory: a daily refusal is never read as a memory charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cover factory write retries against the job base Exercise committed earlier work on rerun, retry after failure and resume after Stop, and retain the refusal for an empty first attempt and rerun. Include the waiting question when the retry fixture misses its failed check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep write retry checks at the Test approval gate Include the following test step so the manual approval is reached, and stop the current step so its recorded attempt can be resumed. Check the retained commit and change through the job reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: distinguish stopped writes before and after reporting Compare immediate Stop with Stop after the first running receipt, using the same committed change and wire actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: retain the factory write base across stopped attempts Stop can revoke a lease before its first report carries ChangeBase. Keep the original pin on the job branch before edits so its replacement counts earlier committed work instead of comparing against the edited HEAD. Make the three retry fixtures perform their promised write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: synchronize stopped write reports and refuse an unpinned base Hold periodic reporting on the real lease worker until Stop, then run the replacement with normal reporting. Verify a locked repository config prevents Write from editing before its comparison base is preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: stop a factory round when its base cannot be preserved A repository config lock must not let edits start without their durable comparison pin. Surface the save error before calling the executor. Keep the deterministic replacement worker on the same fixture machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: assert the factory preparation failure receipt A failure to preserve the base is an execution preparation error, so read its failed-step detail rather than an out-of-rounds result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep read-only factory checks independent of Git metadata Exercise the exported runner with a real command in a directory without Git metadata, matching the leased-worker fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: discard failed Git reads before preserving a factory base Git errors include stderr as output. Do not mistake that text for a branch or commit and try to persist it. Keep the existing behavior when Git metadata is unavailable, while refusing an actual base save failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: reproduce pause after a memory stage tail detaches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pin one next budget for cap questions and answers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check memory admission when Pause returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: complete the paid memory response with valid JSON Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: give cap questions and answers one allowed next budget Select the smallest allowed cap above recorded spend instead of doubling the old cap. Share budget choices with the runner, job reads and budget edits, and refuse a continue when no higher budget remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain paused memory for a later resumed turn Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure live Pause memory and provider receipt totals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: keep budget continuation available above thirty dollars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check settled provider sums and detached memory lifecycle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: pause live memory after a provider generation starts Document paused memory admission, normal resume, and process-owned shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: admit local job memory against the owning factory state A worker mirror can still say running after Pause returns. Read the owning local factory for memory admission and cancellation while retaining mirror-based receipt settlement. The job conversation checks that owner before worker mirrors too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: cap resumed memory at one normal scripted pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: offer matching budget continuation beyond thirty dollars The fixed budget ladder returned zero after thirty dollars, trapping jobs. Derive the next cap from the job and accept that exact amount at the factory budget door. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: measure only stages that started before Pause A paused job correctly has no conversation identity for its unstarted stages. Skip those stages when measuring memory rather than requiring identities from future work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: align cap metadata expectations with the next budget rule The whole-package run found two expectations left on the former doubling and zero-limit rules. Expect the next standard five dollar cap at both public seams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: count a finished memory generation and its receipt once A response can finish at the same time cancellation queues its receipt. Both observations describe the same provider charge, so share the existing once-only charge counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: retain unfinished memory after a completed extraction Pending counts unextracted source events. When the already-paid extraction finishes at Pause, those events can be consumed while NeedsUpdate retains the remaining compilation work. Keep the stricter source assertion for interrupted calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: expose lost Factory page charges on failed generations Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: give Factory scout a real checkout in spending fixture Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: bank Factory page charges before handling failed generations Record provider billing events because failed generations may return no response. Use the returned response only when no event was banked, so success counts once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: require an exact ledger-owner inventory for production model sends Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: inventory current ledger owners and explicit model-spend audit debt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: preserve returned usage and include model sends in initializers Keep the returned response price-presence fact instead of synthesizing an explicit zero. Enumerate declaration initializers as well as named functions and prove package-scope mutations are rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: a failed scout reply counts in its limit, and charges may arrive concurrently Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * memory: name its call tag for the replay law and pass the new scan argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: memory fixtures use a step that isn't held for an unchanged checkout A job's write step with no change now waits for a person. These tests are about memory, so their step is plain work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: name the pull request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#2545) * engine: an idle job chat and an unchanged vault cost nothing per look The person-Stop watch every job chat runs ten times a second listed and decoded every job on the floor (twice) per look; it now answers from a per-floor manager index rebuilt only when the floor folder changes and re-reads the managed job only when its document is replaced. A vault whose sealed bytes are unchanged is no longer decrypted again on every slot read. 100 idle looks over 60 jobs: 12,000 documents decoded -> 0. 400 reads of an unchanged vault: 400 decrypts -> 0. * changes: idle-cpu entry (#2545) * factory: unlock the manager index from a defer
…an AgentField node (#2478) General intake (inbox, Jira, the routing table with an AI filter and priority order), the factory as an AgentField node whose triggers are its intake, AgentField runs as factory steps, named pipelines and a pipeline library, the engine idle-cost rounds, codeaf --events/--steer for watched harness runs, and app/v3 (#2524 go-aheads, #2505 Claude Code, #2544, #2545) merged in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… per file (#2551) On macOS the presence watch handed each held chat's session folder to fsnotify, whose kqueue backend opens a descriptor for every file in a watched folder. A darwin-only watcher now holds one handle per folder, plus one for answers.jsonl only while an answer waits to be drained (since #2478 a quiet session relies on the watch for answer appends). Other platforms keep fsnotify behind the same seam. Holds, viewOpen and the idle sweep are unchanged. Mac proof (macOS 15.6): engine fds per held chat +6 -> +2; takeover reaction unchanged (1-3 ms); 20 darwin and presence tests pass 3/3. Fixes most of #2471. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…en by the opening stamp (#2556) Fixes #2549. stampMeta now settles the owed user stamp before its snapshot, so an effort set right after a conversation opens is no longer overwritten by the opening stamp (a product bug, old since #876). A deterministic seam test fails 10/10 without the fix and passes 50/50 with it; the real-engine test ran 196 loaded iterations without a failure. The unknown-effort check sets up its own rung, so the classifier can retry one rung alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings dev's twelve commits that app/v3 lacked (#2426, #2491, #2509, #2536, #2537, #2540, #2543, #2548, #2553, #2555, #2557, #2558) onto app/v3 (a687c92), so app/v3 can land on dev as one trunk. 28 files conflicted; every behaviour from both sides is kept, and both sides' tests pass. Decisions a reviewer should know: - #2556 (app/v3) and #2557 (dev) are the same stamp-overwrite fix; one implementation is kept in internal/session/placemeta.go. - Git auto-maintenance (#2400 vs #2548): dev's rule wins. Maintenance is suppressed only in owned copies, not on a person's own repository (#2548's TestTaskCommitSuppressesMaintenanceOnlyInOwnedCopies); #2400's finishing- commit tests still pass, since they run in owned copies. craft keeps #2400's attached maintenance. One flag list lives in internal/gitpolicy. - A device's own directory record keeps app/v3's read-first write, so waiting messages (Outbox, Took) and an unchanged record survive. dev's TestLiveDriveRefusedStartupRetriesAndUploads asserted one relay call per refused startup, which a read-first write makes two; it now asserts no call beyond one startup attempt per wait, measured from the first attempt. - dev's per-drive driveNotices keeps its name; app/v3's desktop callbacks become appDriveNotices. - The desktop's local publication loop starts dev's storage refresh while hosted storage is off, as engine.go and syncsetup/state.go already do. - Closing chats stop following ownership and checking their lease once displaced or stopped, so they never read /cells/ after /release. - The two syncsetup TestMain functions are one; two manual headings gained the asker's words where merging both corpora moved their retrieval. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…low app/v3's engine law Two findings from the landing candidate's first CI run (#2561): - app/v3's law TestEngineCleanupUsesEngineDir rejects registering cellstore.StopSpawned directly. dev's storage-off tests (#2509, #2536) did it in nine files; they now take celltest.EngineDir, so LIFO cleanup stops spawned engines before their temporary folders go. Assertions unchanged. - TestAServedFactoryStartsAGoAheadsJobWithNoAppAttached left a writer in its temporary home ("directory not empty"). The served factory's GitHub poll was cancelled but never joined, so a pass could still commit a live event or a go-ahead receipt after serveFactory returned. app/v3 had the same race (17 of 20 there). startFactoryServerPoll now returns a stop that cancels and joins the current pass, and serveFactory defers it (20 of 20). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a first run that works (#2546) * processgroup: launch each Windows process tree inside its own Job Object Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jobs, services, checks: stop whole launch trees and report stopped only once confirmed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * shell: tell the model the Windows facts for python, .cmd shims and stopping servers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fsreplace: open held state files with delete sharing and retry state removal on Windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * automation: publish presence locks with shared handles so reminders fire on Windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * session: record spend through a lock-capable reader so Windows keeps every charge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * store: count charges made at the current clock tick in current spending windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * session: permanently delete conversations on Windows while keeping the deletion lock Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * storage: publish sync, service and task state through fsreplace Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * setup and doctor: shared default model, a key check at launch, and machine readiness checks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * opener: open URLs and files on Windows so sign-in can reach the browser Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * install.sh: put codeaf on the Windows user PATH when run from Git Bash Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * exec: headless commands skip the login shell; edits keep UTF-16 BOMs and line endings; the model sees LF output Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * paths: the folder picker and report references accept native Windows paths Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * checkout: preview new files and offer Open/Reveal on Windows through the same contained open The contained open behind checkout.diff's untracked preview and checkout.locate was Unix-only, so on Windows every new file read as 'could not be opened safely' and no changed file could be opened or revealed. os.Root works on Windows; only the leaf's open flags differ (no O_NOFOLLOW or O_NONBLOCK there), and the same-file check after the open still refuses a leaf swapped for a link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fsreplace: replace a file another handle holds open on Windows with a POSIX-semantics rename Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * tests: give Windows a moment to close a stopped listener's socket before rebinding its port Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: run the tests that pass natively on Windows on every pull request (advisory) No engine test ran on Windows before; the engine only cross-built for it. The new job runs 306 named tests in 29 packages on windows-latest: process-tree stops, state replacement while held, reminders, spending, native paths, UTF-16 and line endings. It is not part of check yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changes: one entry for the Windows stability PR (#2546) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * setup: check the provider key when setup or health is first read, never at launch A launch-time probe made a quiet engine send /key and /auth/key before anyone asked (TestC27NewChatByDefaultStaysQuiet), and the CLI started one on every command. Starting the engine now only enables key health; the first setup.get or health.check (or a key handover) starts one background check per key, and reads never wait for it. doctor still checks directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * keyhealth: unlock the cache from a defer, as the guard law requires Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * exec: macOS and Linux keep their login shell, output bytes, file-tool bytes and health checks The non-login foreground shell, CRLF-to-LF output, line-ending coercion on rewrites and pipefail health checks are Windows-only. On macOS and Linux a headless command loads the login profile again (bash -lc), captured output keeps its bytes, ordinary rewrites write what they are given, and a health check's status is its last command's, as before this PR. The PR's text and shell contract tests now state each OS's rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * session: macOS and Linux keep their job stop receipt and ledger lock order Proof that the whole tree is gone before a kill reports stopped, and locking the usage ledger through its read handle, are Windows-only leaves. Unix keeps the original signal receipt and writer flock order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * head, tui3: macOS and Linux keep report pointers and folder parents as before Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * seniordev/patch: intercept only bash -lc, as before Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * verification: macOS and Linux keep the bounded snapshot diagnostics Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * setup: key check, fresh-setup default and doctor on every OS; desk readiness probes on Windows only The lazy key check, the default model for a fresh setup and codeaf doctor's new checks run on every OS; their wire fields are optional, so older payloads still decode. The desk's setup and health reads run gh and git probes only on Windows: on macOS gh reads its token from the login Keychain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: say what each OS does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
PRODUCT BUG. Retire's departure check (waitForGone) and DialStartingHost's probe (hostLockHeld) both took the workspace's host lock exclusively. Two readers checking at once could each see the other's probe as a host still holding the workspace, so Retire reported a host saving with the lock held after it had given the workspace up, and a dial could wait on a host that had already left. Probes now take a shared, non-blocking lock; only a host takes it exclusively. The test now holds a second reader through the save. Loaded reproduction (GOMAXPROCS=2, synchronous disk writer, CPU spinner, -count=2000): 12 failures before, 0 after; app/v3 a687c92 failed 16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TEST TIMING: an earlier queued writer could enter its run loop only after the baseline stack count, making the process appear to own two writers. Flush existing usage before measuring and retain every close assertion. Seed an earlier writer so the original ordering fails under load. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TEST TIMING: a background publish can display displacement before /quit reaches the writer. Wait for real writer close before forcing the final publish; preserve every restored-receipt assertion. PRODUCT BUG: the last seal watch retires before drive close starts, and news in that gap had no recipient. Retain it for the closing receipt. Cover the gap separately so the fixture ordering cannot hide it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev's pre-release hand-test fixes (#2567) meet app/v3 in 23 files. Every behaviour from both sides is kept; where both sides fixed the same thing, one implementation remains (provider retry admission after waits, the late spending save, the shared daily-limit gate, compiler billing). The knowledge compiler needed a ruling, because the two sides' retry contracts disagreed: - The retry policy is app/v3's: a five-second backoff doubling to 120 seconds, and a persisted three-attempt cap per input that survives reopening the vault. Build or a new source resets the cap; a job-owned failure is retried only by its owner. A persisted total bound is a stronger money guard than a time pause. - dev's persisted 30-second paid-failure pause becomes a two-second repeat guard held in memory by the open vault. It keeps the refusal dev's test asserts (an identical request right after an unusable paid answer is not bought again) without blocking app/v3's deliberate retries. - The cap's key is now each ordinary source's id and content hash. The old key hashed max(arrived), which a revisit moves to now, so the cap could reset silently. - The compiler asks with reasoning disabled (EffortOff, dev's fix for a provider that ignored effort "none" and billed 8000 reasoning tokens for nothing), with the request identity unchanged so cached answers stay cached. - One billing path: the daily gate runs before every compiler call and provider attempt, and each billed answer writes one ledger line and one receipt, usable or not. Proofs, by name: P1 TestKnowledgeOrdinaryBuildCapsEveryBilledAnswer P2 TestKnowledgeOrdinaryBuildRetryCapSurvivesRepeatedHandovers P3 TestKnowledgeDailyLimitBlocksEveryRetry, TestKnowledgeDailyLimitBlocksTransportRetry P4 TestKnowledgeMixedPaidAnswersMatchCallLogLedgerAndReceipts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…computer" The section added with the final publish notice was headed "Quitting after another computer continued the chat". Its words matched the general question so closely that it ranked first and pushed the page that explains moving a chat (availability, pairing, platforms) out of the results, which TestMovingChatIntroductionsStateAvailabilityAndLegacyLimits caught in the full suite. The heading now speaks the asker's words for this case: the line printed after quitting when another device took the chat over. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One rule now recognises a paid call already in the spending ledger: - session.UsageCallID decides it everywhere, and UsageLine.ChargeID delegates to it. - A carried explicit id wins: CallID, "remote:"+RemoteEvent, or the row ID. - Otherwise dev's eight-field fingerprint decides: At, Session, Model, Role, Calls, Input, Output and USD. - A line with neither is still counted against its session's uncovered rows, as both parents did. A row with no identity is never another call's duplicate. - Two different explicit ids are two calls, even when their fingerprints match. This is app/v3 #2332's take law. PRODUCT BUG fixed (from the earlier landing merge, and also present on app/v3 alone): reopening a chat with no receipts booked its paid turns and folded task spend again. All four TestReopeningFoldedTaskSpendNeverRebillsWorkerCalls variants now pass. Seven contract tests in usage_remerge_contract_test.go pin the rule. Conflicts resolved, keeping both sides: - cellindex/usage.go, cellstore/receipt.go, cellstore/types.go, executor/modelcall.go - session/digest.go, loop.go, task_remote_money.go, usage_identity.go (add/add), usage_ledger.go, usage_receipt_test.go - tui3/commands.go keeps app/v3's slashcat table, and dev's "Memory tab" wording moves into slashcat/catalog.go - manual/chat/settings.md and what-i-remember.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PRODUCT BUG (a regression against dev, from the landing merge): the first landing merge kept app/v3's take road in chatContinuer and dropped dev's 255-byte component cap in takeCopyBucket, leaving an inline "copy-"+encodeWorkspace(origin) BucketFor that fails with "file name too long" once a chat's origin path exceeds the filesystem component limit. Root dev's capped copy-bucket helper at an explicit home directory via takeCopyBucketAt(dir, origin), keep takeCopyBucket(origin) delegating to takeCopyBucketAt(home.Dir(), origin), and wire chatContinuer's BucketFor to takeCopyBucketAt(s.Home, origin). Contract: - C1. Three round trips (six takes) of one chat between two homes all succeed and the chat opens on each side after each take, with every created path component at most 255 bytes and a stable bucket per origin. - C2. A chat the taker already has keeps its existing local root (takeRootForAt), unchanged. - C3. app/v3's take road is otherwise unchanged: its two-field takeover, its s.Home-relative paths, and every existing take, move and older-chats test on both sides, unedited. Fixes #2579 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PRODUCT BUG from the dev ace7888 merge. dev #2577 and app/v3 fixed the same defect, a late charge missing from Home's figure, in different places: - dev stamped at the end of every bank; - app/v3 stamped after each late door (reconciled, memory billing, aux usage). Keeping both stamped a turn's own calls as they were banked, and again when the turn sealed. An interrupted turn therefore saved its spend twice (TestLateRecoveredCancellationSavesCumulativeSpendOnce). Now bank stamps every bill that is not a step of a live turn, and nothing else does. The redundant stamps in reconciled and the memory billing are gone. Both laws hold: - TestPostSealChargesStampTheHomeTotal (dev); - TestLateRecoveredCancellationSavesCumulativeSpendOnce (app/v3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wice PRODUCT BUG from the dev ace7888 merge. Rebuilding the usage index: - flushes queued live rows before reading the ledger (dev); - flushes again after importing (app/v3). When the writer could not settle, the rebuild waited out both deadlines. That spent a take's whole hook budget, and the take failed with "handoff: i/o timeout" (TestTakeLedgerQueuedOrSettledLiveCall/queued). The second wait now happens only if the first one settled. An unsettled queue still refuses a row whose identity is already queued (usageIdentityCursor), so the import cannot double-book while it waits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One conflict, in cmd/codeaf/poolrecord.go: app/v3 stands the pool judge down while the pool is being handed over (poolJudgeStandsDown), and dev's #2583 stops it once its owner's context is cancelled. Both reasons to stay quiet are kept, in both the per-landing judge and the sweep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… their owner closes The people loader read profiles on a detached goroutine under context.Background(), and the CODEOWNERS and pipeline asks ran the same way, so a read could still be calling GitHub, or caching an answer, after the factory that wanted it had closed. In tests that call landed in whichever test had swapped http.DefaultTransport next. PeopleLoader and PipelineLoader now have a Close that cancels the read in flight, keeps a cancelled read's answer out of the cache, and waits at most a second for it to finish. factoryPeople returns no client when there is no GitHub token, as factoryRules already did, so a tokenless factory starts no read at all. stopFactoryLoaders detaches a profile's loaders and closes them, and the factory service calls it when it closes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se waits for the first Several things the app backend starts could outlive its Close: - the solo factory's poll and people readers; - a brief write already past its debounce; - the provider-model warm-up; - a catalog warm-up opened by the clock process or the profile road. A second concurrent Close also returned at once, while the first was still tearing down. Now: - The brief debounce has a context. stop cancels the write in flight and waits for it within the pool's close budget. - The local factory forbids its read loops before cancelling the host. - The host's solo handler refuses to rebuild once the host is closing. - The local factory's starts refuse once the backend is closing. - The backend's Close waits for the provider-model warm-up and stops the pool errands. It also closes the factory loaders, and closes the engine process it assembled, the same close RunApp makes after the wire ends. - closeEngineProcess clears the process slot before closing it. - The clock process releases through closeAll. - The profile road closes its catalogs. - A second Close, of the backend, the local factory or the factory host, waits for the first to finish. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These tests tore down their HTTP fakes or temp directories while something they had started was still running, which is how one test's leftover calls reached the next test's fake transport. The leftovers were: - a backend; - a pipe fleet's catalog; - a profile road; - the usage-ledger writer. - The offline local factory fixture gets a poll source that polls nothing, so it no longer polls GitHub through http.DefaultTransport. - The memory tests register their HTTP fakes before newLocalSetup, so under t.Cleanup's last-in-first-out order the backend closes first. - wireOver waits for its server to return. - Every onePipeFleet and profileRoad a test opens is closed in its cleanup. - moneyVault and the session daily-limit tests stop the usage writer they started. - The touched cmd/codeaf tests use testHome(t), so a late write names its file. No assertion was removed or loosened. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r cannot hold it The waits the leak fixes added to Close must not lengthen a quit without limit. - closeWait in internal/factory/github is a variable now (still one second). - The brief debounce waits on briefStopWait (the pool's close budget). - stopFactoryLoaders closes its loaders concurrently, so it spends one bound in total rather than one per loader. - A read that ignores cancellation can no longer cache its answer or start another read after its loader closed. Tests show that a profile read, a CODEOWNERS ask, a pipeline read and a brief write that each ignore cancellation cannot hold their Close past its bound, and that two stuck loaders still close within one. The profile road keeps the per-service catalogs it opens and closes them with the road. Closing them when the readiness wait returned cancelled a stale custom catalog's refresh before it could finish. testHome(t) now reports only for a failed test. When a test calls TempDir before it, its walk runs before the shared removal and would list every file the test legitimately left. Worst case added to a desktop quit by these waits: briefStopWait + closeWait, two seconds, reached only when a write or a GitHub read ignores cancellation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No conflicts. #2588 keeps a settled task's row in the conversation after an answered landing, gives a just-settled node its result page, and stops the pool's index pull at close; it touches internal/tui3, the pool pull code and the chat manual, none of which the landing branch had changed since the last merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guard laws refuse a Lock whose Unlock is not deferred directly under it, because an absorbed panic inside the section would leave the lock held and turn into a deadlock, and they refuse a bare go statement for the same reason. The leak fixes had added ten such sections and one bare goroutine. Each section is now its own small function with its Unlock deferred: the factory host's close claim, the brief debounce's stop and re-arm, the local factory's teardown claim and its release, the profile road's catalog set, the engine process slot, and the two loader caches. The brief stop's waiter starts through guard.Go. Behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…down once The PR gate on 392b2b0 found three faults in the Close changes. - A second Close waited on the backend's closing flag. Tests that only simulate a quit set that flag themselves, so their cleanup's Close waited for a teardown nobody had started, and cmd/codeaf hung for 15 minutes in TestAppCrewProposalLaterWhileClosingRefuses. The teardown claim now has its own flag: every Close tears down once, and only a genuinely concurrent second Close waits for the first. - solo() refused once the host's context was cancelled. A host built to serve only is given a context that is already cancelled, so TestAppFactoryMountTakesOverWhenTheSoloHostCloses and TestAppFactoryProxyKeepsIssuedRunnerCredentials failed. The refusal now reads a flag that close sets. - The backend's Close closed the engine process it had assembled, and stopped the engine's pool errands. But the app wire calls Close before it waits for the calls still in flight, and before RunApp's CloseUsage. The engine's receipt wait therefore ran inside Close, ahead of a receipt that lands after the quit. Both are backed out: the engine closes after the wire has finished, where RunApp always closed it. The quit-path receipt test, TestMemoryLateReceiptReachesFactoryHeaderAfterQuit, went red here with provider=0.0400 memory=0.0000 ledger=0.0200 header=0.0200. That is the same line #2566 records failing about one run in three on app/v3 itself. So that red is not shown to be caused by this branch, and #2566 stays open; the back-out stands on the ordering argument above. The worst case the remaining Close waits add to a quit is unchanged: two seconds, briefStopWait + closeWait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestUsageMillionRowLedgerFlush timed the writer's first write over a 1,000,000-row ledger on this machine, three alternating runs a side. app/v3 a687c92 took 592.9, 575.4 and 582.1 ms. The landing head 392b2b0 took 595.2, 611.8 and 603.6 ms: every landing run slower than every app/v3 run, by about 3.4%. The merge made ChargeID delegate to UsageCallID, and UsageCallID to UsageExplicitID. So each row of the scan copied the whole UsageLine twice and called strings.TrimSpace three times, where app/v3 read two fields. ChargeID now reads CallID, RemoteEvent and ID in place, and copies the row only when it has to fingerprint it. The trim answers first for an id whose first and last bytes are visible ASCII, which has nothing to trim. UsageExplicitID and UsageCallID give the same answers as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
This lands
app/v3(the desktop engine line) ondev, sodevbecomes the one trunk.app/v3retires afterwards. The plan's G0 gate is this branch:app/v3(a687c92) withdev's twelve newer commits merged in (0fa1b5d).dev, 0 behind.Draft until the hand gates pass. The plan's G1 (this PR's checks), G2 (
ci-full.ymlon this sha), G3–G4 (race and end-to-end), G5 (data both ways, including rollback), G6 (the desk on the merged engine) and G7 (the WorkAF loop live) all run before this leaves draft. It lands after Friday 13 Nov's staging cutoff, so it gets a full week ondevbefore reaching staging.How the 28 conflicts were resolved
Every behaviour from both sides is kept, and both sides' tests pass unchanged except where noted below. Decisions a reviewer should check:
app/v3) and An effort, place or working copy recorded right after a message is no longer overwritten by its stamp #2557 (dev) fix the same stamp-overwrite race. One implementation is kept, ininternal/session/placemeta.go.dev's rule wins.TestTaskCommitSuppressesMaintenanceOnlyInOwnedCopiesasserts.craftkeeps codeaf's own git commands start no automatic maintenance #2400's attached maintenance, and one flag list lives ininternal/gitpolicy.app/v3's read-first write. That is what preserves waiting messages (Outbox,Took) and skips an unchanged record.dev'sTestLiveDriveRefusedStartupRetriesAndUploadsasserted exactly one relay call per refused startup, and a read-first write makes it two.dev's per-drivedriveNoticeskeeps its name, andapp/v3's desktop callbacks becomeappDriveNotices.dev's storage refresh while hosted storage is off, asengine.goandsyncsetup/state.goalready do. It adds no requests once storage is open./cells/after/release.syncsetupTestMainfunctions are now one.Later dev merges, and the rules they settled
devmoved four times after the first merge. Each move came in as its own merge commit.8511037 merges
devb0dfe97 (Fix what the pre-release hand test of dev found #2567).app/v3's retry policy: backoff from 5 to 120 s, and a stored cap of 3 attempts that survives reopening. A new build or a new source resets the cap. Only the owner retries owned work.dev's stored 30-second retry pause becomes an in-memory, per-vault repeat guard of 2 s.TestKnowledgeOrdinaryBuildCapsEveryBilledAnswer,TestKnowledgeOrdinaryBuildRetryCapSurvivesRepeatedHandovers,TestKnowledgeDailyLimitBlocksEveryRetryandTestKnowledgeMixedPaidAnswersMatchCallLogLedgerAndReceipts.6ed333e merges
devace7888 (Fix what the second pre-release hand test of dev found #2577), and leaves one rule for recognising a paid call already in the spending ledger.session.UsageCallIDdecides everywhere, andChargeIDdelegates to it:CallID,remote:+RemoteEvent, or the rowID. Two different explicit ids are two calls, even when everything else about them matches (A take no longer loses or double-counts cost #2332's take law).At(UTC, RFC3339Nano),Session,Model,Role,Calls,Input,OutputandUSD.dev's rule. A chat with receipts keeps A take no longer loses or double-counts cost #2332's strict matching.app/v3alone and on this branch's earlier merge. The proofs areTestReopeningFoldedTaskSpendNeverRebillsWorkerCalls(all four variants) and the seven contract tests ininternal/cellindex/usage_remerge_contract_test.go.3cb458b: the take road files a moved chat's copy through
dev's capped bucket name. The first merge had dropped the cap, so a chat moved back and forth failed withfile name too long. The proof isTestThreeRoundTripsBetweenTwoHomesStillOpen.528122a merges
dev15d40fd (The model pool's writers stop with their owner, and the tmux suite runs on the engine road #2583). It has one conflict, incmd/codeaf/poolrecord.go.app/v3stands the pool judge down while the pool is being handed over (poolJudgeStandsDown).devstops the judge once its owner's context is cancelled. Both checks are kept, in the per-landing judge and in the sweep.6e4d317 merges
devb8c5f26 (A settled task keeps its row in the conversation, and the pool's index pull stops at close #2588), with no conflicts.Fixes #2579
Fixes #2585
Closing the desktop engine: what it waits for
On the landing head, the full suite went red in scattered, order-dependent ways. The cause was one family: work a test's backend, engine or factory had started kept running after that test returned. Through
http.DefaultTransportit then reached the next test's fake. The fix makes each owner's Close stop what it started.5499dbf: the factory's GitHub people, CODEOWNERS and pipeline readers get a bounded Close. A factory with no GitHub token starts no profile reads.
679544c: the app backend's Close joins:
A second Close waits for the first.
6992c46: tests only. Owners close before their fakes, and every pipe fleet and profile road a test opens is closed. No assertion is loosened.
fd949df: every new wait has a named bound of a second or less. Tests show that a reader or writer that ignores cancellation cannot hold its Close past that bound.
392b2b0: every new critical section unlocks from a
defer(the guard laws).Worst case these changes add to a desktop quit: 2 s (
briefStopWait+closeWait). That is reached only when a brief write or a GitHub read ignores cancellation; otherwise they add about nothing. The engine-stop and window-quit times, measured onapp/v3a687c92 and on this head, will be added here from the landing hand checks.briefDebounce.stop: cancels the write in flight, then waitsbriefStopWait, 1 sstopFactoryLoaders: people and pipeline loaders close concurrentlycloseWait, 1 s in totalappLocalStopWait, 10 sapp/v3<-h.doneand the read-loop join (THE READ LOOPS END BEFORE THE FLOOR IS LET GO)app/v3, unchangedapp/v3, unchangedappReleaseWait, 5 s, sharedapp/v3closeAll: knowledge, credits (10 s HTTP), catalogs (15 s fetch), place sweepcloseAll: receiptsappQuitReceiptWait, 3 scloseAll: sync drivesdriveCloseWithin, 2 scloseAll: usage ledger and the SQLite closesThe engine process still closes where
RunApphas always closed it: after the wire has finished its calls in flight, and afterCloseUsage.solo()a refusal that does not mistake a serve-only host's cancelled context for a closing one.TestUsageMillionRowLedgerFlush(#1749) is the other number this landing owes. Its first write took 3.1 s on one CI runner. It will be timed on this machine, three alternating runs each on a687c92 and on this head, before the merge.Who it reaches
dev-channel build and thedevrelay.app/v3todevon landing day.app/v3are re-pointed todev. Their diffs do not change. Superseded ones are closed.🤖 Generated with Claude Code