mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
394da0a313b574c3e233287cdfc21d4f408a7245
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
394da0a313 |
refactor: the kernel's packages live in the layer they belong to
internal/ was 141 packages side by side, so nothing but a reader's memory
said which were foundations and which assembled the rest. Each now sits in a
layer directory, and the directory is the declaration:
base L0 foundation with no domain in it
contract L1 types and interfaces the layers above agree on
model, tools, safety, ext, state, platform
L2 subsystems, peers of one another
runtime L3 the turn engine
session L4 the controller
assembly L5 the composition root
frontend L6 cli, serve, acp and the host adapters
Only paths change: package names, code and behaviour do not. Imports,
repolint and coverage baselines, sensitive paths, CI package lists and docs
follow the new paths; release notes keep the paths they were written with,
and sample paths inside tests and fixtures keep theirs.
repolint gains layer-order: a package may import its own layer and those
below it, read from where it lives. The 47 imports that point upward today
are recorded as that rule's opening debt (-allow-widen, a new rule's first
baseline) and can only go down. Most of it is config, which still reaches
into eight subsystems and is the next thing to take apart; the rest is
event, history and a few tools reaching into runtime for types that belong
in contract.
|
||
|
|
22bff74de6 |
bench(runtime-resume): ask what names a host-started execution
9a measures one surface and its name says so: a person typing /<skill> into a live session, routed through Submit to the controller's slash path. The headless counterpart is deliberately not measured beside it — caller-owned, with its own cancellation and session ownership — because reading one for the other is how a real number gets the wrong subject, which has happened twice in this series. The fourth arm is queued rather than restart. Restart is an axis every arm already has; what no other arm can answer is whether an identity exists before the child does, and only work the scheduler is holding back asks that. Four identities are printed apart, because this is the first surface where they may not coincide: the synthetic dispatch id the host mints so a child's activity can nest on screen, the store's own artifact ref, the provider-visible parent call, and the execution a journal would open. For a model-delegated run the last two are one string, and that has only ever held because a tool call produced every durable execution there was. What it found is narrower and sharper than "a slash skill records nothing". The store is not empty: since the runner converged, a slash-started child is marked running before it acts and carries a correct terminal afterwards — completed, interrupted, cancelled, each measured. What is missing is the execution. Nothing was ever opened, so nothing places that child, and the arms say exactly that: record-only, a reader can see a child of this name was cut and cannot say which invocation it belonged to. LOST-SILENT is reserved for the queued arm, where work the scheduler had admitted into its domain and then refused leaves nothing at all. That is what makes the queued arm decide a linearization. An identity for this class would have to exist before a child artifact does, and the three candidates fail by exhaustion rather than by assertion: the synthetic dispatch id may never be persisted as lineage, the child ref does not exist while the work is queued, and the parent call must stay empty because there is none. Both oracles held in every arm — no persisted lineage named a host event id, and every parent was empty. Two labels were corrected while building this, both mine. A restart that still holds a child record is not silence, and calling it LOST-SILENT would have reported a surviving record as a total loss; and the rebuilt column credited the holder fleet's nodes to the invocation until it was filtered to the execution it belongs to. Nothing is implemented. These arms establish what the candidate identities cannot do; what replaces them is the next cut's question. |
||
|
|
6dac296ad6 |
bench(runtime-resume): ask what kind of execution a subagent skill is
8d-2 classifies rather than compares. Whether a runAs=subagent skill belongs to the delegation class the task and fan-out arms established, or is an execution class of its own, leads to opposite work — converge it onto the shared owner, or declare an exclusion — and the answer cannot come from which plumbing happens to exist today. Two runners are measured apart instead of averaged. The tool a model calls prepares a transcript, supports continuation and saves a terminal; the read-only entry point builds a session in memory, refuses continuation and stores nothing. Asking the second for durability would be demanding it break its own contract, so those arms ask what it is instead, and answer in a classification — ephemeral-seen or ephemeral-unseen — rather than a pass. Seven dimensions, one row each, because a skill can share one domain and not another: scheduler, graph, journal, store, cancel, restart, identity. The scheduler has no refusal hook to read, so admission is established as an A/B — the call is out, unanswered, the ceiling occupied and no child of its own has reached the provider, against the same dispatch with capacity free whose child is inside it. Only the slots check is reached that way, and the README says so rather than letting a writer claim be read as measured. Identity reads the two entry points apart. A model-invoked skill has a call to join to; the controller's own drops that id deliberately, so an empty one there is top-level provenance and not a lost join — both run in one death so the row compares two lineages rather than a value against an expectation. The cancel row judges the terminal against an observed cause, never wording: the child's own context closed, which is what a cancellation does to it and a failure does not. The queued arm is the negative control and bounds any convergence: an execution the scheduler never admitted produced nothing, so a change that satisfied the running arm by preparing a transcript at dispatch would break it. Three labelling faults were caught while building this and are fixed here rather than reported later: a journal and a store that were empty on both sides read as persisted-direct, a restart row credited the holder fleet's interruption to the skill, and the stop row named a guarded turn caller-owned. Absence now has its own verdict, evidence is filtered to the execution it belongs to, and the graph row carries the whole graph's node count so "the filter found nothing" cannot be read as "there was nothing to find". |
||
|
|
1a9076abf8 |
bench(runtime-resume): stop each surface with the stop that owns it
The last cut reported a cancellation defect. It was measuring the wrong owner, and this A/B retracts it. A turn the controller admits itself — what Send opens, and what a person's Stop reaches — carries the cancel the gate holds. A synchronous Run is never admitted through that gate: the controller holds no cancel for it, and the caller's own context holds the only one. The probe had been driving Run and then calling Controller.Cancel, which claims nothing there, and reading Running(), which answers for a gate that was never told about the turn — so "the turn ended while its work ran on" was two facts about two different things. Read the right way round, the interactive surface is correct. An ordinary shell the turn is waiting on ends the moment the stop arrives. A delegation stopped while the scheduler still held it back settles with no store record, and one stopped while its child was executing settles with the child's own cancelled terminal — the table this step was aiming for, on the path a person actually uses. On the other surface both halves hold too: the controller leaves the caller's work alone, and the caller's own cancel ends it. One arm is red, and it is the one that matters most. Work already handed to a background job — which the tool result tells the caller runs across turns — is gone the instant the parent turn is cancelled, with the probe confirming it was live when the stop was issued. That contradicts the ownership boundary the handoff exists to draw. The mechanism is not located here: a job's context is rooted in the manager, not the turn, so something else in the child's chain is carrying the cancellation, and finding which edge is the next cut's job rather than a guess in this one. The readings now say what surface they came from, so neither answer can be read as the other's again. |
||
|
|
c6313e58d2 |
bench(runtime-resume): ask where a stop goes
8c left one reading unexplained: a cancelled turn ended while its foreground delegation stayed open and its child kept running. That could have been three different defects, so this is the probe that tells them apart rather than a fix aimed at the first guess. Four readings, and they localize it. A plain shell — `bash sleep 30`, a tool that derives its context the way every tool does — is still running three seconds after the stop, with the turn already ended. So the fault is not in how a delegation derives its context: an ordinary tool loses the same cancellation. The delegation arms agree from both sides of the slot: one stopped while queued and one stopped while executing are both left open after the turn is over. The fourth is the negative control and bounds any fix. Work already handed to a background job keeps running when a stop is aimed at the turn — which is correct, and is what a cancel that reached everything the session knows about would destroy. A fix passes this arm only by cancelling what the turn owns and nothing further. The delegation arms now carry this as an invariant instead of a premise: once the turn has ended, nothing it owned may still be open. An open record implies a live owner, since nothing else closes one, so the child's liveness rides in the reading as evidence rather than standing in as the test — a delegation still waiting for a slot has no child at all and is just as much still owned. That also fixes a hole in the first version of the row, which read a queued delegation's absent child as work that had ended. No production change: this says where to look, and the next cut says what to do about it. |