Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d4f4eac
Use one observed private lifetime for physical Toad runs
trissim Nov 1, 2026
d67941c
Freeze run operations and retain exact child retirement evidence
trissim Nov 1, 2026
2c86205
Give physical runs an explicit framebuffer and reject clipped windows
trissim Nov 1, 2026
5340278
Record the debugger context repair and private functional journey
trissim Nov 1, 2026
4782917
Detach pager retirement joins from the cancelled worker context
trissim Nov 1, 2026
134c56b
Record the qualified pager retirement app controls
trissim Nov 1, 2026
9d8eccd
Compare recorded runtime inputs before physical UI input
trissim Nov 1, 2026
f436d76
Verify physical runtime builds at the frontend resource lifetime
trissim Nov 1, 2026
72dedf4
Ask the storage rule to verify physical-run isolation
trissim Nov 1, 2026
e9b9ae7
Append followed saved history without replacing its painted prefix
trissim Nov 1, 2026
8b3f7ff
Require actual append publication and complete closed-prefix acquisition
trissim Nov 1, 2026
01755b3
Use the declared thread project path in append controls
trissim Nov 1, 2026
6132897
Establish commit admission before exercising the known source gap
trissim Nov 1, 2026
390785d
Own physical observations from frontend startup, delete debugger atta…
trissim Nov 1, 2026
21fa51b
Execute physical operations only at the explicit module entrypoint
trissim Nov 1, 2026
0910819
Observe saved publication instead of demanding a running agent
trissim Nov 1, 2026
39be538
Keep failed append acquisition coupled to replacement publication
trissim Nov 1, 2026
33059e8
Wait for source publication at the observation boundary
trissim Nov 2, 2026
50f340c
Enter prompt insertion before physical text input
trissim Nov 2, 2026
cfec52a
Separate installed resource observation from candidate build admission
trissim Nov 2, 2026
5bbc58e
Record installed capture08/09 limits and caller-owned lease
trissim Nov 2, 2026
3f123d4
Qualify active replies from their source and published body
Nov 2, 2026
7c80d9b
Compose frame measurement with the existing startup and admission lif…
trissim Nov 2, 2026
132aea3
Use the declared transcript exception in source rewrite controls
trissim Nov 2, 2026
874dc52
Derive transcript preparation identity from the declared content view
trissim Nov 2, 2026
fdafb77
Retain transcript suppliers through the existing preparation owner
trissim Nov 2, 2026
02a3ee1
Bind prepared suppliers to the current transcript read
trissim Nov 2, 2026
79f560c
Correct the overlay-sensitive paint oracle and record capture15 limits
trissim Nov 2, 2026
09d7ecc
Declare observer boundary names and preserve the selected tab identity
trissim Nov 2, 2026
207e698
Keep physical frontend contracts in the Textual test layer
trissim Nov 2, 2026
f136347
Check read blocking and native paint instead of publication completion
trissim Nov 2, 2026
d8ed02e
Own observer imports at startup and delete the retired injection coll…
trissim Nov 2, 2026
e07f479
Derive observation module identities from their imported packages
trissim Nov 2, 2026
7039ec7
Publish the status check required by main protection
trissim Nov 2, 2026
db8a6aa
Keep NRA gate aligned with the directed protection setting
trissim Nov 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 33 additions & 109 deletions docs/performance/bounded-history-capture.md

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions docs/performance/cpython-debugger-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Remote debugger context: functional candidate, not an installed fix

The accompanying `cpython-debugger-context.patch` belongs to CPython's
`Python/ceval_gil.c`, not Toad's renderer or its runner. It is retained here so
this runner's platform dependency, exact proposed repair and demonstrated scope
are reviewable. It is **not** an alternate launcher, import preload, retry or
permission bypass. No live Python binary/library was replaced.

## Failure and owner

On CPython3.14.8, retained physical run11 and independently read mobile06 fail
before opening the helper:

```
Can't open debugger script .../operation.py
File "<string>", line 1, in <lambda>
KeyError: '__import__'
```

`run_remote_debugger_script` audits/opens/reads/closes source under the
interrupted frame. Only afterward does `run_remote_debugger_source` create its
fresh namespace. The default `PyFile_OpenCodeObject` imports `_io.open`;
`PyImport_Import` consults the interrupted frame's builtins. A legitimate empty
builtin mapping therefore breaks the debugger itself. The interrupted constructor
is unidentified; run14's separate timeout remains unexplained.

Exact source: v3.14.8, commit
`8e6e75d9102e39bed2a2b279203a396741180f12`. The debugger owner file is identical
on the checked compatible3.14.9/3.14.10 tags;3.14.10's file-open/import owners are
also unchanged. NRA's Python AST does not parse these C files; the C call chain
was read manually and checked against installed disassembly.

## Repair and audit difference

The original remote-debugger audit refusal remains first. The existing loader
body becomes one private C callable, invoked through a real Python frame with
interpreter-owned builtins. The original application frame stays in the normal
frame/GC chain. The embedder's open-code hook is still called; global import
behavior, source reading/closing and payload execution are not replaced.

**The complete audit trace is not equivalent.** Successful execution now emits:

1. `cpython.remote_debugger_script(path)`;
2. `compile` / `exec` for the context lambda, filename `<string>`;
3. the existing `compile` / `exec` for payload source, filename `<string>`.

The initial proposal incorrectly put context preparation ahead of the original
audit. Review caught this; the published patch restores that audit gate first.
The extra context events remain explicit. A policy refusing them prevents source
opening and reports a context-entry error. A close error still reports the error
then executes already-read source, matching the original loader body.

## Functional build and native controls

A separately owned3.14.8 build used existing GCC16.1.1/make, no new toolchain,
PGO/LTO/BOLT/JIT/tail-call chase, and at most two make/compileall jobs. Configure,
make and private altinstall completed0 in18.4s/109.6s/13.0s. Built patch SHA256:
`5a679cd8875271a4c7eace7ce088b5f93f261076b929987e1276b6161ef9857d`;
functional binary SHA256:
`e18b6c81a63f9683beca2d20c9e56225da3207b68530bae2eaa26b6bf351e4fe`.
These identify measured artifacts, not a runtime publication. Existing `BoundedRun`
owned process retirement and deadlines; no output for180s failed the stage.
This nonmatching compiler build is **not release-performance evidence**.

One native batch completed0:

- one fresh unpatched empty-builtins child reproduced the source-open failure;
- 18 patched controls: nine cases under full and empty interrupted builtins;
- normal execution; refusing request/compile/exec audit hooks; real embedder-hook
acceptance/refusal; read/close failure; payload failure;
- executing cases retained the original frame and cyclic guard through
`gc.collect`; every case preserved its active exception and builtin mapping;
- all19 typed target identities independently absent after retirement.

These are exercised counterexamples/controls, not a proof over every CPython state.
The guard has other strong references; this is not a sole-root liveness proof.
The fresh control target deliberately runs a busy select loop, not a production
workload. The separate actual Toad run below exercises the unchanged application.
The disposable control extension/script targets never loaded into a user app.

## Actual private Toad

The unchanged shared runner then completed one real default-launcher journey0:
saved history, held PageUp/PageDown, reversal, End, wheel scrolling and normal
retirement. It obtained31 observed callbacks,17 explicit startup-pending results
and one exec result. The screenshot shows saved message bodies and STANDARD
mode; no physical timeout or source-open failure occurred in this run.

Admission checked1013 module locations; HOME/XDG/database/palette, selected and
opened root, and saved-source identities were private. There were **zero ACP
bindings**: this does not qualify bound-ACP behavior, mobile1391 or errors1389.
The controller used the installed source owner to copy history. The target used
the functional interpreter with a byte-compared copy of5295 regular installed
package files, declaration-derived console scripts and an existing Neovim payload
verified through its archive owner. No native download or fabricated build.json.
A setup assertion initially confused Core's package root with site-packages;
that failure is retained, and only script generation was completed afterward.

st/Xvfb/encoder retired0, all four frontend/resource identities were independently
absent, and the copied root was stopped. Original sessions, input dispositions,
phone/editor processes, desktop/pointer and scientific data were untouched.
The separately approved metadata/profile capture remains unused.

## Receipts and remaining work

Owned retained evidence under `/home/ts/.cache/agent-scratch/pi-ui-performance/`:

- `cpython-functional-build.log`, `cpython-functional-startup.log`;
- `cpython-native-controls.log`, `cpython-native-control-absence.log`;
- `cpython-functional-toad-{prepare,finish}.log` and native-payload log;
- `cpython-functional-toad-01/{admitted.json,frontend/end-return.png}`,
typed retirement/copy-stop records and `cpython-functional-toad-absence.log`.

Native case inputs/results and the functional source/prefix are retained under
the allocated Core checkout's `platform-source/` pending review. One-shot build
code was retired after its successful result. Input hashes are observations,
not a new runtime stamp. Integration still needs a qualified interpreter/build
selection: `RuntimeStack.build` currently keys reuse by Core commit and lock
hash only. The runner's repository-identity work must use the existing
`RecordedBuildIdentity`/`RuntimeResolution`/`RuntimePackage` owners; a mutable
prefix/module location is not a repository commit. Installed acceptance and
measured production source-lifetime/performance repair remain open.
79 changes: 79 additions & 0 deletions docs/performance/cpython-debugger-context.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -1216,22 +1216,16 @@
return 0;
}

-// Note that this function is inline to avoid creating a PLT entry
-// that would be an easy target for a ROP gadget.
-static inline void run_remote_debugger_script(PyObject *path)
+// This private callback is invoked only inside the debugger's Python frame.
+// It remains static: there is no new exported or PLT entry point.
+static PyObject *
+run_remote_debugger_script_body(PyObject *Py_UNUSED(self), PyObject *path)
{
- if (0 != PySys_Audit("cpython.remote_debugger_script", "O", path)) {
- PyErr_FormatUnraisable(
- "Audit hook failed for remote debugger script %U", path);
- return;
- }
-
- // Open the debugger script with the open code hook, and reopen the
- // resulting file object to get a C FILE* object.
+ // Preserve the existing open-code hook, read/close ordering and errors.
PyObject* fileobj = PyFile_OpenCodeObject(path);
if (!fileobj) {
PyErr_FormatUnraisable("Can't open debugger script %U", path);
- return;
+ Py_RETURN_NONE;
}

PyObject* source = PyObject_CallMethodNoArgs(fileobj, &_Py_ID(read));
@@ -1253,6 +1247,47 @@
}
Py_DECREF(source);
}
+ Py_RETURN_NONE;
+}
+
+// Note that this function is inline to avoid creating a PLT entry
+// that would be an easy target for a ROP gadget.
+static inline void run_remote_debugger_script(PyObject *path)
+{
+ // Keep the existing debugger refusal before context compilation/execution.
+ if (0 != PySys_Audit("cpython.remote_debugger_script", "O", path)) {
+ PyErr_FormatUnraisable(
+ "Audit hook failed for remote debugger script %U", path);
+ return;
+ }
+ static PyMethodDef body_definition = {
+ "_run_remote_debugger_script_body",
+ run_remote_debugger_script_body,
+ METH_O,
+ NULL
+ };
+ PyObject *ns = PyDict_New();
+ if (!ns) {
+ PyErr_FormatUnraisable("Can't prepare debugger namespace for %U", path);
+ return;
+ }
+ // PyRun_String initializes this namespace from the interpreter's builtins.
+ // A real Python call frame then owns audit/open/read/close as well as exec;
+ // it neither borrows the interrupted frame's builtins nor detaches its GC roots.
+ PyObject *entry = PyRun_String("lambda load, path: load(path)", Py_eval_input, ns, ns);
+ if (entry) {
+ PyObject *body = PyCFunction_New(&body_definition, NULL);
+ if (body) {
+ PyObject *result = PyObject_CallFunctionObjArgs(entry, body, path, NULL);
+ Py_XDECREF(result);
+ Py_DECREF(body);
+ }
+ Py_DECREF(entry);
+ }
+ Py_DECREF(ns);
+ if (PyErr_Occurred()) {
+ PyErr_FormatUnraisable("Can't enter debugger execution context for %U", path);
+ }
}

int _PyRunRemoteDebugger(PyThreadState *tstate)
Loading
Loading