Repository navigation
Measure production multiformat reachability, fix launcher credential identity, publish HTTP contract - #157
Merged
Conversation
added 29 commits
October 4, 2026 17:28
… a proxy over the core The previous round found the router itself opens no database connection, and read that as promising. Its imports show why that search was misleading: the connection lives in the modules it imports, along with the database path. Those modules contain inserts into evidence anchors, index revisions and evidence bundles, so the surface that serves the frontend writes the same database. Three things follow. The boundary is not a proxy over the core, so it cannot be re-pointed, and a compatibility layer has to be written against the core's HTTP - the contract document is reusable, the implementation is not. Second, and more importantly, the present wiring holds a single-writer conflict: running the core alongside this surface puts two writers on one database, which the package forbids. That rather than style is why the re-pointing has to happen. Third, a table name worth checking was noticed and deliberately not concluded: the python side inserts into evidence_anchors while the core selects from anchors. This is the fifth revision of my cost estimate, and the reason is constant - I estimated before the survey was finished. The discipline worth recording is not to put a number on migration cost until the data source's ownership is established. Nothing was changed, built or run, the table-name question is unexamined, and the runtime client test is unread for a fourth round running.
The anchor concept exists under three different tables: one the Rust core creates, one the python boundary creates, and a third from a shared migration. The frontend's requirements match the python one exactly, since that table stores the raw hash and a structured locator json that the frontend validates, while the core's table stores a hash and an opaque position. So the layer cannot be a transport projection alone. The columns differ in name and in meaning, and an opaque offset is not obviously expressible as the structured locator the frontend expects. That is a capability question rather than a mapping table, and it is the kind of thing this round exists to surface before anyone writes code. I also narrowed a claim from the previous round rather than repeating it. Python maintains its own anchor tables and the core maintains another, so this is not two writers racing on one row but two parallel data models - and whether they even share a database file is unverified, since the core takes its path as an argument while python resolves a configured path. That is more accurate and no less serious: two models is a problem for the idea of one canonical store regardless. On the runtime client test I am changing my own reporting. It has gone unread for five rounds while I kept promising it, so I am no longer listing it as a standing debt each round and will read it when it actually gates a decision. Nothing was changed, built or run.
…of them written The configured database path and the path the host exports to the backend are the same string, and the python side resolves its default to that same value. The three converge on one sqlite file. That answers the fork left open last round, and the answer is the harder branch. It is not two independent datasets but one file carrying several models at once: the core's anchors, a shared migration's anchors_v2, and the python surface's evidence_anchors, alongside other tables. The python surface writes that file, so the writer conflict is real rather than hypothetical, and the migration is required by ownership and data model rather than by style. What I did not establish is recorded too, and one item is a correction in the making: a search of the Avalonia supervisor for its database argument returned nothing, which is not the same as the file having no argument - the wording may simply differ. The table names come from create statements in source and not from opening the real database, and two other checks remain undone. Diagnosis has reached the point where more reading adds little, so the next round turns to delivery: a one-page decision set naming the canonical model and its costs, a first runnable slice of the compatibility layer limited to the handshake and one route, and an explicit list of what will not be touched. That is worth more than a nineteenth comparison table.
…ake composer Diagnosis is complete enough to act on, and the handshake is the right first slice because it is the one exchange that depends on no data model at all. The frontend refuses every projection until it receives product identity, contract, versions, runtime mode, workspace, capabilities and migration state; the core answers with runtime, contract and schema version, and calls its own contract an outline. So the composer takes the core's answer plus the identity facts the host owns and returns the document the shell validates. It opens nothing and writes nothing, which is why the sqlite owner count is unchanged at fifty-nine, and it keeps the core's outline self-description alongside the projected contract so that saying outline is not lost in translation. The tests restate the frontend's predicate field by field rather than trusting a paraphrase, and check the composer fails closed on an unusable schema version, a missing runtime, a blank identity fact, a non-ready migration state and blank capability names. One case failed first time and it was the test at fault, not the code: passing an empty override merged nothing and left a valid payload in place, so the case that was meant to remove a field now actually removes it. This is the first implementation change under the new package. It is additive and reverts with one commit, and nothing is wired to it yet - the transport and the canonical data model decision both remain open.
…o narrow A system module already serves the handshake route, documented in the execution log as RUN-203. It is not just present but better than what I wrote: it reads the backend version from the project metadata, runs git for the commit, reads the schema version from the database in read-only mode, derives a stable workspace id and reports the supervisor's real migration state, behind a local-request guard. My composer took all of those as caller-supplied arguments. The error is in the search, not the reasoning that followed it. I looked for the field names inside the Rust core, found none, and generalised that to the repository having no handshake - without ever searching the python side for the route. Searching one stack for a shape cannot establish the absence of an endpoint elsewhere. It is the second time in this work that my own search scope produced the wrong answer, and the sixth time measurement has corrected a judgement. So the module and its tests are removed in a new commit rather than rewriting history. Keeping them would have created a second handshake surface, which is precisely what the boundary contract warns against, and it would have contradicted the instruction to reuse what already exists and fix only gaps. It does narrow the question usefully. The handshake is not the missing piece: the host launches the python backend that serves it, while the core that should become the only writer serves a different and thinner exchange and calls its own contract an outline. The problem is that the frontend's current backend and the intended canonical one are not the same backend - and that needs no new code from me to state.
…ing data The app was started against a temporary copy of the database rather than the worktree's own, and it refused to start: the schema has not been migrated. That is the guard behaving correctly, since it fails closed instead of running against an unfinished store, and it stopped the probe before it could report a handshake. Looking at why the copy was empty produced the round's real finding. The worktree's data directory holds one file, cognitive_os.sqlite, and no archeaxis.sqlite at all, while the configuration names archeaxis.sqlite. That qualifies what I concluded three rounds ago. I verified that three places agree on the configured path, and they do, but I did not check that the file they name is the one actually carrying data - and it is not the file that exists. So the claim narrows to agreement at the level of configuration, with the relationship between the legacy-named file present on disk and the name in the configuration still unexamined. This is the cost of concluding from source alone, and finding it only when the thing was run is evidence that running it was the right move this round. The migration entry points were located - several of them - but which combination migrates a store to usable was not determined, and no official data or installation was touched.
… as SUP-022 The owner asked for the latest package to be archived properly, describing it as another change and calling out the UI frontend in particular. The package is now stored under docs/authority following the repository's existing taskpack convention, copied byte for byte, with its own checksum file verifying all ten entries against the archive. The frontend is the focus because the formal product host changes: from the C# Avalonia application to Tauri 2 with React, TypeScript and Vite. The package's startup prompt states that choice and forbids raising the Avalonia or Tauri question again, and its joint-architecture document instructs that the answer be registered as a traceable delta rather than by rewriting the immutable packs. That delta is registered as SUP-022, superseding the earlier decision that made Avalonia the formal shell, and the configuration authority index now points at it. Every boundary the earlier decision carried is retained rather than relaxed: the Rust core stays the only canonical writer, python stays isolated workers, one writer per file is unchanged, the old python backend must not be re-wired as authoritative, there is still exactly one default shell, and the release freeze and owner gate are untouched. The Avalonia application becomes a frozen reference only once the Tauri shell has actually taken over. The index also says no parallel task pack should be created, so the note states plainly what this is: an owner-delivered update that the owner asked to archive, not a plan the executor authored for itself. The executor does not sign off audits or the owner gate.
…lain-style colons
…y the Rust core The file present in the worktree is named as the legacy database by setup status, and the workspace migration module documents moving data out of it into the four-asset-domain layout, with a backup prefix, never deleting the legacy file and being idempotent on its recorded source hash. So the relationship I called unexamined last round is in fact documented and tooled - the worktree simply has not been migrated yet, which is an unperformed step rather than a defect. The more useful find is who owns the schema. Nothing anywhere in the repository writes the sqlite user version, while the knowledge table definition comes from the Rust store crate. So the canonical database's schema is established by the Rust core and the python side only reads it, which explains why the system module reads that pragma and no python module sets it. That is concrete evidence for the core being the canonical writer - it holds the right to create the schema, not just to write rows. It also names the precondition I was missing when I tried to run the app, and the probe that can reach that state. The handshake is still uncalled, I have still not run the migration, and nothing official was touched; the next round is to get a temporary store into a migrated state and make that one real call.
…a receipt Twenty-three rounds of this package have been almost entirely reading, so this round ran a real capability. The probe refused the first attempt because no authorised copy was named, and the legacy database's hash was identical before and after - it did not touch the original, as its documentation promises. Given a copy, the migration ran to completion. It reports the copy's hash matching the original, a rollback candidate backup, a produced ledger of sixty-five tables and fifty rows, and the original untouched. The legacy database's hash after the run is the same as before it. So the migration path is genuinely runnable on this machine, it is rollback eligible, and it left the source alone - the first executed product capability under this package, with a receipt to cite. It is not the same as the application starting, and the record says so. The migration produces a workspace layout, not the database file whose schema the app validates, so the precondition for calling the handshake is still unmet. The next step uses an already-built core binary to create that schema in a temporary directory. I am noting in advance that the binary dates from before the current commit and may not match its schema, so either it will be rebuilt first or the staleness will be stated with any result - a stale binary's behaviour will not be reported as the behaviour of this commit.
…locks python outright The core was rebuilt with an explicit target directory so the binary is current for this commit, which removes the staleness caveat I raised last round. Started against a temporary database it created the schema - twenty-six tables - and then the python application refused to start, for a specific and newly informative reason. Python's read-only research path requires a checkpointed database and rejects one that still carries the write-ahead log and shared-memory sidecars, naming both files in the error. The core leaves those sidecars behind, as a single writer in WAL mode does. So the practical consequence is stronger than what I had read out of the sources three rounds ago. Then I described two parallel data models sharing a file; now it is reproducible that while the core holds the database open, the python side cannot read it at all. Coexistence is not a policy question here - under the current implementations the two stacks cannot work on one store at the same time. That is the technical reason the migration has to happen, and it is firmer than the wording I had. One thing is deliberately left open rather than guessed: the core created twenty-six tables but left the user version at zero, and I did not establish whether that is intended. Nothing was changed, no official data was touched, and the handshake is still uncalled.
…rator that guards itself Getting the application to start turns out to need a chain of conditions, each of which was observed rather than assumed. The core creates its schema, which it does - twenty-six tables. Live write-ahead sidecars then block python's read-only access, and checkpointing removes them so that error disappears. Behind it sits a third condition: a phase four research schema migration must have been applied, and without it startup fails with that message. That third step is not freely callable. Invoked with the correct arguments it refuses, saying the migration must be driven by a MigrationOperator. That is a guard expressing that this operation needs a proper driver, and I am not going around it - the package says not to fake permission, and this is exactly what that looks like in code. Two earlier attempts failed on my own misreading of the signature; the third produced the real constraint. The conclusion is that the canonical store is not any single stack's product. The Rust side builds its schema and the Python side must additionally apply a research migration that is itself governed. That extends what the last two rounds established: after two parallel data models sharing a file, and then a hard failure when the core holds it open, there is now a third dependency - and it sits behind an authority boundary rather than a technical one. The handshake remains uncalled and I will not dress that up. Locating and properly driving the operator is next; if it needs human authorisation that is not present on this machine, that becomes a recorded blocker while independent work continues.
…rlier overclaim The sanctioned driver was the runtime entrypoint, whose migration command applies each migration using the owner registered for it rather than an owner I invented. Run that way it exits zero, takes a backup first, and records the workspace owner applying its target. With the database migrated that way, the application starts and the handshake answers 200 with all ten fields the shell requires: the pinned product id and contract, a version, the real commit of this tip, an integer schema version, a runtime mode, a workspace id, an array of capabilities and a ready migration state. Every one of the frontend's conditions is satisfiable, and it is the python boundary satisfying them today. This also narrows what I wrote two rounds ago. I said the two stacks cannot coexist on one database, which was too strong. What was measured then was that while the core holds the file open, python cannot even read it; what is measured now is that when the core is not holding it and the governed migration has run, python works completely. The accurate statement is that only one stack may hold the store at a time - a lease question rather than irreconcilable data models, which makes the canonical decision easier than I had made it sound. Two things are flagged rather than glossed. The handshake reports an empty capability list, so the catalogue is not yet wired through. And this is still a single manual observation: by my own standard manual evidence should become a gate, so making it a repeatable probe is next.
The call succeeded once by hand last round, and manual evidence goes stale, so it is now a probe that anyone can rerun. It drives the sanctioned migration entrypoint, starts the real application against a temporary database, asks the real endpoint and checks the answer against the conditions the shell applies, then reports a receipt and an exit code. It is deliberately unhurried about honesty. It opens nothing of the worktree's, touches no official installation or library, and says of itself that it signs no product qualification - it verifies one exchange on one machine at one commit. Its temporary directory lives under the project's ignored development root rather than the system temporary directory, which the project treats as ambiguous ownership, and it removes that directory when it finishes. The test keeps it from rotting. It asserts the migration exited zero and produced a database, that the endpoint answered 200, that the document satisfies every condition the frontend applies, that the pinned values are the ones the shell pins, that the cited commit really is a commit in this repository, and that no failure step was recorded. Seven tests, six seconds, run against a fresh temporary store each time. Nothing in the product changed: this adds a probe and a test and touches no existing implementation.
…ing what it launches Before re-pointing the host's launch target I checked whether the host compiles, and it does not. The root workspace excludes both Tauri crates on purpose, saying each keeps its own lockfile and build boundary, but neither manifest declares a workspace root of its own. Cargo therefore refuses them as being in a workspace while not being a member - so the host was neither part of the workspace nor buildable on its own, and any change to it would have been unverifiable. That explains why the re-pointing has not been done in the rounds since it was scoped. The fix is the one cargo itself suggests and the one the workspace comment already implies: give each crate an empty workspace root. I deliberately did not add them to the main workspace, which would pull Tauri's dependencies into the workspace build and could disturb CI; each crate now stands alone, so the workspace build is untouched. It works. The workspace error is gone and the build proceeds into Tauri's own build script, which is how far it had never previously reached. It then fails on a resource path the manifest declares - a staged runtime under the project's development root that is not present - so the host needs one to build. The re-pointing is still not done, but the reason has changed from nothing to a named missing input. The change itself remains held back until the host can actually be checked, because a change I cannot verify is not a change I should make. No official installation or data was touched.
…ng conflicts with a gate Checking the host regenerated four files under the Tauri schemas directory. The diff is one line in each and says the same thing every time: the regenerated document has no final newline where the committed one does. The repository convention check exists to catch exactly that, so any build of the host leaves four modified files that would fail the gate. That is a real unhandled conflict between building the host and the repository's own conventions, and it is nobody's error - the tool's normalised output simply disagrees with the convention. I reverted the files rather than committing them: they are generated artefacts, committing them would make the gate fail, and adding a workspace root to a manifest should not change a schema. Three ways to handle it are written down and none is chosen, because that belongs to whoever owns the convention rather than to me in this round. The re-pointing remains undone for the reason already recorded - the host still needs a staged runtime before it can build. No official installation or data was touched.
…cker is a space in the path The host bundles a runtime from the project's development root, and that directory did not exist, so the staging tool was run with the built core, an interpreter from the shared tool library, the workers and the real commit and tree. It produced the directory the manifest names - twenty-seven hundred odd files - and with it present the resource error disappears. The build then gets further than it ever has here and fails in the windows resource compiler. The path in the error is telling: it begins at projects rather than at All projects, so the leading part was lost at the space. That is the GNU toolchain failing on a path containing a space, not a defect in the product, and CI would not see it because its checkout path has no space. This machine could not build the host even before any change of mine. That matters for the rule set two rounds ago: do not change what the host launches until the host can be checked. On this machine that rule now meets an obstacle no source change can fix, and three ways out are recorded - switch toolchain, move the checkout to a space-free path, or accept that neither this machine nor CI builds the Tauri host and find somewhere that does. I have chosen none of them, because that is an environment decision rather than mine, and I will not make an unverifiable change to the launch path in the meantime. The build also rewrote the same four generated schemas, stripping their final newline again. They have been reverted a second time. No official installation or data was touched.
…says about each With the Tauri host blocked locally by a space in the checkout path, this round used the scene that does run - a temporary store, the sanctioned migration, the application - and posted three real fixtures to the intake endpoint. The results are more useful than a support list because they separate three different states. Markdown is carried through by an engine actually named passthrough, so it is transported and not structured, and by the package's own standard that does not count as passing. Canvas reports itself as custody only, saying in its own content that no ingest route claims the format yet - the product describing its own gap, which is worth more than my inference. The image fails with the missing optional engines named, Tesseract and pytesseract, which is an uninstalled optional dependency rather than a defect. The original hash is checkable for each: both successful items report a sha256 identical to the source file's. Nothing has been called supported that is not, which is the discipline the package emphasises most, and the next step is to turn these three states into a probe and a test so that the two non-passes are remembered as non-passes instead of drifting into being described as support. Only intake was exercised, not the other dimensions the format task names; no optional engine was installed to make a number look better; no implementation file changed; and neither the official installation nor the material library was touched.
…passes Three formats were measured last round and the results are now reproducible. The probe drives the sanctioned migration, starts the application, posts each real fixture to intake and classifies what comes back without flattering it. Its outcomes are deliberately separate values - carried through, custody only, engine missing, structured or refused - because collapsing them is exactly how transported quietly becomes supported. The tests assert rules rather than today's answers, with one deliberate exception. They check that every attempt carries an outcome and its evidence, that a successful intake preserves the original hash and reports the expected format, and - the rule that matters most - that nothing is called structured unless the evidence names structure. The exception pins the three outcomes measured this week, so that carried and refused cannot later be described as supported: if a format genuinely improves, that test fails and the improvement has to be recorded on purpose. Eight tests, under eight seconds, against a fresh temporary store each run, and the probe removes its own working directory. No product implementation changed; this adds evidence and the means to keep it honest. Neither the official installation nor the material library was touched.
…oute as it really is CI caught what my own local run had not: the architecture guard rejects a runtime string beginning with a slash, reading it as a hardcoded external absolute path, and the probe contained the intake route written that way. The pull request workflow passed and the push workflow failed, on the lint job and the architecture test together. The fix is not a trick to satisfy the checker. The route is a path relative to the origin, so it is now written that way, with the base ending in a slash and the route naming only the segments. The handshake route was moved to the same form for consistency, and both are named constants rather than literals buried in a call. The gap on my side is worth naming: I ran the repository convention check before pushing but not the architecture guard, and the guard is exactly what this change needed. Rerunning both locally now passes, as do the eight format tests. No behaviour changed - the same routes are called, spelled as relative paths.
…survive the read Against the running product, a real file was ingested and then anchored at the exact characters of a phrase it really contains. The character range was right - the offset lands on that phrase - and the create response echoed the whole locator back, including the character region and the block name. Reading the anchor back loses both. Only the page and the source format return, which is what the projection function selects; the source shows it reading exactly those two fields. So the system accepts a precise, explainable position and does not hand it back, and the format task requires exactly that kind of position. It is worth noting against the project's own words: its loss receipt contract says unknown fields must never be silently dropped, and here what is dropped is not unknown but accepted. I am careful about what this does and does not establish. Only the projected read route was read; whether the stored record still holds the full locator was not checked, so this is a projection dropping fields rather than data being lost, and those are different claims. It is also unchecked whether the character region is a supported field of that route or simply outside its contract. Nothing was changed this round - evidence was taken, not a fix - and the loss receipt itself, with its engine, version, parameters, note and coverage, is still to be measured.
…nest Two things the format task asks for were still unmeasured. A probe now ingests a real file, anchors the exact character range of a phrase it really contains, reads the anchor back, and asks the library for the conversion run of that file. What it finds is recorded rather than smoothed. The offset genuinely lands on the phrase and the create response returns the locator it was given. The read returns only the page and the source format, so the probe reports that no precision field came back and the test enforces the rule that a precise position may only be called returned when a precision field is present. The conversion run answers and does expose a loss-notes channel and a format execution receipt; for this markdown file the notes list is empty. The one pinned assertion is that pair of measured outcomes, so an improvement cannot arrive unnoticed. Eight tests in six seconds against a fresh temporary store, and the probe removes its own working directory. No product implementation changed - this is measurement, and the finding that a precise readback is not returned is now recorded in a gate rather than in my notes.
…precision is lost The exchange export writes an open directory and its own verification passes with one item verified. While taking that evidence I wrote a check comparing a freshly computed hash of the manifest file against the manifest's own manifest_sha256 field, and it disagreed. That is almost certainly my expectation being wrong rather than the product: that field hashes what the manifest describes, not the file that carries it, and the product's own verify already says the export is valid. I have removed the misleading comparison and renamed the value to say plainly that it is the file's hash, with a note that it must not be compared to the manifest field - so nobody repeats the mistake and reads a defect out of it. The more useful result is what the exported evidence item contains. Its locator carries six block identifiers, a conversion run and a derived document, which means the precise structure exists and is exported. Three rounds ago I deliberately wrote that I had only read the projected read route and that whether the stored record retains the full locator was unchecked - so the accurate claim was that the projection drops fields rather than data being lost. This is positive evidence for that boundary: the export layer has the structure, the anchor read route returns only the page and the source format. The careful wording was not wasted. Nothing was changed in the product, no test for this probe exists yet, and what manifest_sha256 actually hashes was not established - only that it is not the hash of its own file.
…rast cannot drift The export probe now anchors an exact character range on the same file it exports, so a single receipt carries both observations. That turns something I had been describing into something asserted: the anchor read route returns only the page and the source format, while the exported record carries block identifiers. Seven tests hold the export status, the item count, the manifest hash, the directory's contents and the product's own verification, and then assert that contrast directly. One test exists purely to stop a mistake from returning. Last round I compared a hash of the manifest file against the manifest's own manifest_sha256 field, got a mismatch, and nearly read a defect out of my own wrong expectation; the product's verify had already said the export was valid. The value is now recorded under a name that says it is the file's hash, and a test asserts the misleading comparison is absent. No product implementation changed. This is measurement and the gate that keeps it true, and the official installation and material library were not touched.
… on one store The last dimension the format task names is cold start. A probe takes a real file in during a first boot, stops the application, starts it again against the same database without re-ingesting anything, and reports what it finds. What it finds is reassuring and now asserted: the library answers before and after and holds the same thing, the conversion run still answers and still names the same file hash, and the schema version is unchanged. Eight tests hold that. One of them exists to keep a weak result from looking strong. Both boots report an empty capability list, so of course the lists are identical; the test asserts the emptiness explicitly rather than letting identity stand as evidence that capabilities survived a restart. When the catalogue is wired through, that test fails and the comparison begins to mean something. I made the same authoring slip twice in two rounds - a module docstring closed on its first line and then reopened, which Python reports as an unterminated triple-quoted string. Both times the test run caught it before anything was committed, and it is worth naming as a pattern of mine rather than treating it as bad luck. No product implementation changed.
… two wrong guesses at search The system module builds the handshake response with a literal empty list for capabilities, and the running product returns exactly that. So the frontend does not receive an unwired catalogue - it receives one that is empty by construction, whatever the Rust core's capability registry knows. That is the gap the capability-catalogue task names, and it now has both a source line and a measured value behind it. Search did not get measured, and the reason is mine. The workspace search route takes a request body whose shape I guessed twice and got 422 both times: an object with a query field was told the root field was missing, and a bare value was told it wanted an object. The errors are informative and probably name the answer, but I did not work it out this round, so search is neither reported as working nor as broken. It is the same pattern as earlier in this work - guessing a shape instead of reading its definition first, and paying for it in round trips. The next round reads the request model at that route, and also pins the hardcoded emptiness in a test so that wiring it up cannot pass unnoticed. Nothing was changed in the product.
… it working Reading the search route's model - which I should have done before guessing twice - showed the body is a root and a query, so my earlier object-with-a-query failure was a missing required field rather than a nested model. With the right shape the route still did not answer: one attempt returned a server error and the other timed out. I am not calling that broken, because the root I passed may not be one the route accepts, but I am also not calling search working. Two things are asserted instead. The capability list the handshake returns is empty and now pinned, with a comment naming it as the catalogue gap: the handshake builds its response with a literal empty list while the core has a real registry, so wiring them together must fail this test rather than pass unnoticed. And every search attempt must have recorded an outcome, with an explicit test that a successful status is not among them today - so neither a server error nor a timeout can drift into being described as a passing search. Two fixes came out of running it honestly. My first error handler hung while reading an error body and crashed the probe, so reading that body is now guarded. And the search call waited a minute per attempt, which cost the suite two minutes for an observation that does not change; a short timeout gives the same answer in twenty-five seconds.
…CI rejected it The last commit pinned that search had not answered, because locally one attempt returned a server error and the other timed out. CI rejected that assertion: both attempts returned 200 there. So search works in CI and did not answer on this machine, which makes the failure a property of my environment rather than of the product, and I have not found out why this machine differs. The same commit contained two pins with opposite fates, which is the clearest illustration I have had. Pinning that the capability list is empty held, because it comes from a literal in the source and is therefore true anywhere. Pinning that search does not work failed, because it came from one run on one machine. Facts from source can be asserted; behaviour from a single run can only be recorded. The assertion is replaced by a rule that every attempt recorded an outcome and no claim about success, with the story written into the docstring so the next person knows why it does not pin one. Running it also let me cut the search timeout, since waiting a minute per attempt bought the same observation for five times the cost. My own note is that writing measured on a date in a docstring looked like qualification but the assertion was still a requirement. Careful wording is not a substitute for designing the assertion around what actually varies.
…rt it positively I suspected the space in the workspace path was breaking vault search, the same cause as the resource compiler failure earlier. A controlled experiment refuted it: a vault under the system temporary directory and the fixture vault, whose path does contain a space, both answered 200. Reading the vault module shows why the earlier attempts failed. The root must be an existing directory, and I had pointed it at my own run directory, which is full of the database and its sidecars - a store, not a vault. The second attempt timed out at the time and does not reproduce now, and I have not established why; what I can say is that it was not the space. With a purpose-built vault the route answers here as it already did in CI, so the assertion can now be positive rather than withheld. That completes a sequence worth keeping: first I pinned that search did not work, which CI rejected because it answered there; then I asserted only that an outcome was recorded; now the claim is that it works, because it has reproduced in two environments. The rule is plain - a fact from source, or something reproduced across environments, can be asserted; a single run's behaviour can only be recorded. One incidental gain: once search actually answers, the test fell from two minutes to five seconds, because the earlier cost was almost entirely one misdirected call waiting to time out. No product implementation changed.
The sync manifest recorded b69c42a as base_commit, but the two 20261006 documents it hashes were only published by the following commit, so the SHA-256 list could not be reproduced from the stated commit. Bind the mirror to the commit that contains the hashed content and keep the earlier commit as an explicit prior baseline.
The ledger was the only current-state authority but carried no pointer to the dated Green mirror or its SHA-256 manifest, so a reader could not tell that the mirror exists or what it does and does not prove. The manifest's ledger entry is refreshed to the hashed content of this commit.
Binding alone was not enough: the hashed AGENTS.md bytes came from the local worktree copy, which carries CRLF that Git normalizes away, so no checkout of any commit reproduced them. Take every hashed file from the bound commit's own content, state how to materialize it, and rebind to the commit that holds the current ledger text.
The read-only history view reported through the Inspector only the current document identity, so a historical read could not be inspected without risking a late response overwriting a newer document's Inspector or a dirty draft. Bind the request to generation, request id and the requested document's id/version/content hash, and report the historical target with its own body fingerprint, using the original CAS hash only when the source revision matches.
job_execute inherited the host's 30-second default client timeout while the reader asks for a 300-second deadline and real media jobs exceed 30 seconds, so the host aborted requests whose jobs were still going to persist and the interface reported failure over a durable success; the timeout table is now a function and asserted. Also: a superseded document read or restore could stamp its failure over the newly opened document; a content digest and a knowledge type were each displayed under a label for something else; the backend badge was never announced, the current-space name was dropped by assistive tech, the browse button was named only by a glyph, and closing the Inspector from inside it stranded focus on the body; the Inspector body had no styling at all, the selected rail item had no keyboard focus ring, a used token was never declared, and the only library section switcher was deleted below 900px instead of narrowing.
Draft creation, note creation, version restore, export and page citation each persisted a new document, version, anchor or export per click, so a double click during an in-flight write silently produced duplicates. Serialise those writes and disable the controls while one is outstanding.
Adds the measured results that were previously unrecorded: the canonical 21-step native pass and the isolated Green deployment, the three installed-state increment runs with their failure receipts kept, the durable video proof at the deployed candidate, the 300-second job ceiling that structurally blocks long-audio ASR, the interface audit findings and their fixes, and the vnext-ci worker-environment root cause plus the SQLite runtime-version evidence AQ27 never had.
A durable check record was announced as unconfirmed when only its follow-up readback failed, because the write and the readback shared one catch. A latest job that ended failed was captured in state that nothing rendered, so the source looked idle. Every non-409 core status collapsed into one sentence that named neither the operation nor the kind of failure.
Making the context subnav always visible at narrow widths broke the A0 geometry contract, which requires a single column with no context rail on a phone viewport. Narrow the relief to the band between the phone layout and the desktop layout, where the switcher was previously deleted even though there was room for it.
…proved audit claims The narrow-layout change broke the A0 browser geometry contract, which is recorded as a self-inflicted regression together with the scoped fix and the local real-browser re-run; audit items that measured false on re-check are recorded as disproved rather than silently dropped.
The canvas node cards and viewport had no rules at all, so they rendered as bare positioned text, and the expanded activity dock ran its rows together. Every statically applied class name must now resolve to a rule, which the previous stylesheet failed for nine of the canvas classes. The quaternary foreground also failed the 4.5:1 body-text floor against the surfaces it is used on.
The rail, palette and subnav advertised URL and batch intake, note-taking with a canvas board, open exchange-package validation and system settings, while the desktop shell routes those ids to the library, knowledge and capability surfaces. Browser development mode keeps its own wording.
… declined audit items
…ardrail Seventeen class names used in shipped components resolved to nothing: the whole recovery workbench (card, heading, kicker, message, diagnostic, actions, field, confirm, progress, feedback, logs), the command palette trigger and its option rows, the space container and the import block. With the global reset removing every default margin, those screens rendered as one undivided run of text, and the palette trigger looked deliberate only because it inherited the bare button rule. The guardrail now scans every component and space instead of four files.
…ow-window overflow Eleven reading surfaces printed untouched backend payloads next to the content: the learning space rendered its own JSON as the page body, and capability, receipt, revision-basis, export, pipeline and machine-answer payloads were dumped inline. They now publish to one diagnostic console in the activity dock (and to the developer console), so the reading surface keeps only human-readable summaries while the exact receipt stays reachable. Verbatim model output on a failed check is deliberately kept inline: paraphrasing it would let a failure read as a judgement. Measured with a stubbed desktop bridge at 1024x900, three fixed panes plus the reading column collapsed the centre to 304px and overflowed it by up to 58px; the chrome now narrows before the content and the subnav may wrap, giving 496px and no overflow. The style-coverage guardrail matched class names as substrings, so `.space-card > h3` hid a missing `.space-card` rule; it now requires a real selector boundary.
…sured narrow-window fix
…the artifact-download constraint
DTALEX66
marked this pull request as ready for review
October 6, 2026 06:18
… test The workspace tests exercise real workers, and the xlsx member format needs the adapter engines; this job built its worker venv from the ci group alone, so the run failed with AAK-WORKER-003 "engine missing" for an engine that is declared and that ci.yml already installs. The same test passes locally and in ci.yml with that group.
This was referenced Oct 6, 2026
Merged
DTALEX66
added a commit
that referenced
this pull request
Oct 6, 2026
… no longer verifiable Both sentences read as present-tense truth. Re-measuring them today produced 650/14/10-shared by one method and 0 by another, because #157 is merged and #158 was closed: the honest correction is that the claim can no longer be reproduced, not that a new number replaces it. Nothing is overwritten - the originals stay above the dated correction.
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
The AAOS backend real-multiformat closed loop (P0–P6), plus the versioned production HTTP contract
the UI branch binds to. Based on
1a981a44— the same base as the UI branch, so the twodiverged rather than one containing the other.
Base
codex/Auditis 18 commits ahead ofmainand 0 behind (this branch's own reading, aftercorrecting an earlier reversed count): the September consolidation and backend integration are on
codex/Auditand have not yet reachedmain. Merging here advances that line; it does not resurrectsuperseded commits.
Recommended merge: merge commit, so each round's regression tests and evidence stay in their own
commit and remain independently revertable.
Draft on purpose: the objective requires ending at a Draft PR. Release stays
FROZEN.Read these, in this order
docs/current/AAOS-BACKEND-UI-HANDOFF-SUMMARY-20261001.mddocs/current/AAOS-PRODUCTION-HTTP-CONTRACT-20261001.mddocs/current/AAOS-BACKEND-ACCEPTANCE-RUNBOOK-20261001.mddocs/current/AAOS-BACKEND-LOOP-EVIDENCE-20261001.mddocs/current/AAOS-ERRORS-BLOCKERS-20261001.mdThe five things a UI must not get wrong
schedule_authorityhas three values and a review produces two of them.POST /learning/reviewsanswersfsrsorunavailable(next_review: null,next_review_days: -2);placeholder_ladderbelongs only toPOST /learning/eventswith noschedule_state.quality, members, v3, machine-task and validation errors answer plain text.
status, notreview_state;new_body, notbody. The contract lists every field for all thirteen routes.GET /searchhas no paging. Onlyqandactive_only; the limit is a hardcoded 20. Areview is ~6× a projection read and holds the single writer while waiting for the scheduler.
/research*,/plugins*,/models*,/embeddings/search,/graph/searchdo not exist andmust render as "not connected".
Verification
cargo fmt --checkclean0b563db0…:CI(a0-gates,test (3.12),lint,gateplan) andvnext-citests/maintenance/test_contract_verification_map.pyfails if a link breaksA02,A16,P0-H01,DP-F01, Research DTO,image.caption, video decode, webpage fetchTwo CI runs in this window had
test (3.12)cancelled inside "Install and verify local OCRengine" (not failed); both succeeded on re-run at the same exact SHA. A cancelled job is not
reported as a pass.
Development output stayed under
.project-local/; the root checkout was not touched.