Skip to content

fix: keep what the engine said, so the log can say why it fell - #94

Draft
test1card wants to merge 42 commits into
masterfrom
fix/keep-the-engine-stderr
Draft

test1card wants to merge 42 commits into
masterfrom
fix/keep-the-engine-stderr

Conversation

@test1card

Copy link
Copy Markdown
Owner

The engine explained itself and the log kept none of it

_pump_engine_stderr read every line the engine wrote and logged a fixed string instead of it. Measured on the laboratory machine, one soak run:

lines in log-engine-stderr.txt:   104
distinct message texts:             1
log_capture.json:                  "allowlist": []

Every record for the whole run was engine child stderr record received; phase=runtime. At the one moment the engine says what is wrong with it, nothing it said survived.

The direction

Owner, 2026-08-20, asked directly whether to keep it and whether to redact:

"конечно сохранять, ничего не чистить. секреты хранятся на том компе, их нужно чистить только если происходит вынос с компа, а не внутри работы программы"

So redaction belongs to export off the machine, not to running on it, and nothing here scrubs anything.

Two properties that were already there, kept and now tested

Keeping the content must not become keeping an unbounded amount of it, and it must not make the pump fragile:

property why it matters
the forwarding bound holds an over-long line is still drained and reported as over-long, never forwarded whole
the decode replaces, never raises a pump that dies on one bad byte loses every line after it

Both were already in the function and both now have a test, because a property nothing exercises is a property that can quietly go.

Evidence

Four tests in a new sibling module, and all four fail when the fixed placeholder is put back:

put the fixed placeholder back
4 failed in 0.95s
   test_the_line_the_engine_wrote_is_what_is_logged
   test_nothing_is_scrubbed_on_the_way_through
   test_an_undecodable_byte_does_not_kill_the_pump
   test_an_over_long_line_is_reported_and_not_forwarded_whole
restored the production file

tests/launcher/ is 144 passed. The changed-Python count is re-derived as a set difference in both directions: 706 here, 705 at master, one path entered and none left.

Why this lands before the restart change

The owner also asked that a faulted engine be replaced and the reason recorded in the log. That reason does not exist until the engine's own words are kept, so this comes first.

The restart change is deliberately not in this pull request. It touches LAUNCHER-STARTUP-AUTHORITY, whose registered invariant is that process death must not be reported as successful shutdown — five guards hold it. Restarting after an observed exit and claiming the shutdown settled are two different things, and separating them is its own slice.

Written with assistance from Claude (Anthropic).

soak measurement added 5 commits August 20, 2026 09:00
The stderr pump read every line from the engine and logged a fixed string
instead of it. Measured on the laboratory machine: one soak run produced one
hundred and four records, every one of them the identical placeholder, with the
capture's own record showing an empty allowlist. At the one moment the engine
explains itself, nothing it said was kept.

Owner, this morning, on whether to keep it and whether to redact:

    конечно сохранять, ничего не чистить. секреты хранятся на том компе, их
    нужно чистить только если происходит вынос с компа, а не внутри работы
    программы

So redaction belongs to export off the machine, not to running on it, and
nothing here scrubs anything.

Two properties that were already there survive the change and are now tested.
The forwarding bound still holds, so an over-long line is drained and reported
rather than forwarded whole; keeping the content must not become keeping an
unbounded amount of it. And the decode replaces undecodable bytes instead of
raising, because a pump that dies on one bad byte loses every line after it.

The four tests were confirmed by putting the placeholder back, which fails all
four.

This also unblocks the next piece. The owner asked that a faulted engine be
replaced and the reason recorded in the log; the reason does not exist until the
engine's own words are kept, so this lands first.
The new test module imported pytest and never used it; none of its four tests
needs pytest.raises, because each one asserts what reached the log rather than
that something was refused. The linter caught it before the push.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9789569b45

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +80 to +81
said = b"connect failed: token=abcdef123456 host=10.0.0.4\n"
messages = _pump(said, tmp_path, monkeypatch)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exercise the production stderr path before asserting no scrubbing

When the engine logs an actual Telegram-shaped token such as 7701234567:<35 chars>, engine.py first calls setup_logging(), whose _TokenRedactFilter rewrites the value to bot*** on stderr before the launcher pump receives it. This sample is both injected directly into _pump_engine_stderr and unlike the token syntax that the production filter recognizes, so the test passes while the new “nothing is scrubbed” contract remains false for real engine log records. Drive the assertion through the engine's production logging setup with a matching token and move redaction to the export boundary as required.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

Comment thread src/cryodaq/launcher.py Outdated
Comment on lines +1717 to +1720
stderr_logger.error(
"engine child stderr; phase=runtime: %s",
raw_line.decode("utf-8", "replace").rstrip("\r\n"),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fix the child encoding before decoding stderr as UTF-8

On a Windows installation whose redirected Python stderr uses a non-UTF-8 code page (for example CP1251), or whenever PYTHONIOENCODING is inherited with such a value, the engine encodes its Russian diagnostics using that encoding while this unconditional UTF-8 decode replaces their bytes with . _start_engine sets only PYTHONUNBUFFERED and does not establish the child's stderr encoding, so the exact failure explanation this change is intended to retain can remain unreadable on the laboratory target. Set a known UTF-8 child encoding before spawn or decode using the actual child encoding, and cover the subprocess boundary with a non-ASCII diagnostic.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 20, 2026 10:17
P1 -- the child was never told to encode in the encoding the pump decodes.

The pump decodes UTF-8, but the spawn set only PYTHONUNBUFFERED. On a host whose
stream encoding is a single-byte code page, or with PYTHONIOENCODING inherited
from the environment, the engine encoded its Russian diagnostics in that
encoding and the pump replaced every one of those bytes. The exact explanation
this change exists to keep arrived unreadable.

The engine child's base environment now comes from one helper,
_engine_child_environment, which pins PYTHONIOENCODING to utf-8 beside the
existing PYTHONUNBUFFERED, so both ends agree by construction. The helper exists
so the test can drive the real thing rather than rebuild a lookalike beside it:
the new test spawns a real subprocess with a deliberately hostile inherited
encoding, confirms the control genuinely mangles the text, then passes the same
environment through production's builder and requires the Russian line to arrive
intact. Removing the one pinned line turns that test red and leaves the other
six green.

P2 -- the "nothing is scrubbed" test proved less than its name claimed.

Its payload was a shape the production filter would never have matched, so it
passed without touching the question. Worse, the claim itself was too broad. The
pump scrubs nothing, and that is now tested with a token in the exact shape
production DOES recognise, checked against logging_setup._redact first so the
sample cannot be vacuous. But the engine end is a different matter, and it is
stated rather than hidden: setup_logging installs _TokenRedactFilter, which
replaces a Telegram bot token before the bytes leave the engine. Telegram
carries that token in the URL, so a logged URL would put a live credential into
a file that leaves this machine in a support bundle. That one narrow replacement
is the export boundary doing its job, not an operational scrub, and it stays.
A second new test drives the real filter and pins what it does.

The module docstring now says which end each test speaks for.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is 94ae9de70eb8fe42c52c8236d1828a962f7cdacc. Both findings from the previous round are closed. P1: the engine child's base environment now comes from _engine_child_environment, which pins PYTHONIOENCODING to utf-8, and the new test drives that production helper across a real subprocess boundary with a hostile inherited encoding as its control. P2: the over-broad claim is gone. The pump's own no-scrub property is now tested with a token in the shape logging_setup._redact actually matches, checked first so it cannot be vacuous, and a second test pins what the engine end really does, which is that _TokenRedactFilter replaces a Telegram token before the bytes leave the engine. That filter stays, and the reasoning is in the module docstring.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94ae9de70e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +155 to +156
fixed = launcher._engine_child_environment(hostile)
child = subprocess.run([sys.executable, "-c", program], capture_output=True, env=fixed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Drive the real engine spawn in the encoding guard

Fresh evidence in this revision is that the subprocess receives fixed directly from _engine_child_environment, while the separate inspect.getsource assertion only checks that _start_engine contains the helper's name. Both tests therefore remain green if _start_engine later overwrites the encoding, passes another mapping to Popen, or the Windows/frozen invocation ignores it, so the original target-OS failure can recur without the corrective guard failing; exercise the actual _start_engine spawn boundary and inspect the resulting diagnostic instead.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

args=(f"https://api.telegram.org/{_REAL_TOKEN_SHAPE}/getMe",),
exc_info=None,
)
assert logging_setup._TokenRedactFilter().filter(record) is True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exercise setup_logging before claiming engine-end redaction

Fresh evidence in this revision is that the new engine-end test manually invokes a newly constructed _TokenRedactFilter rather than calling setup_logging() and emitting through its stderr handler. It therefore stays green if production stops attaching the filter, attaches it only to the file handler, or otherwise writes the token to stderr before the pump, leaving the previous credential-path finding without a production-path regression guard.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 20, 2026 10:48
…beside them

Closes both review findings on pull request #94. Both were right, and both were
the same weakness: a test that reproduced production's behaviour instead of
running it stays green while production changes underneath it.

The encoding guard now intercepts subprocess.Popen inside the real
_start_engine and reads the environment that was actually on its way to the
operating system. Before, it built the environment through the helper and
spawned its own child, so _start_engine could have overwritten the value, or
handed a different mapping to the spawn, and nothing would have failed. The
inspect.getsource assertion that stood in for this is gone, because it only
checked that a name appeared in the source.

The engine-end redaction guard now runs the production setup_logging in a
child and reads what actually reached that child's stderr, which is the stream
the pump reads. Before, it constructed a _TokenRedactFilter by hand, which
proved the class works and nothing about whether production attaches it. If
setup_logging ever stopped adding it to the console handler, or added it only
to the file handler, a live Telegram token would reach a file that leaves this
machine and the hand-built filter would have gone on passing.

The same child carries a Russian diagnostic beside the token, so one run shows
both halves of the contract: the one credential shape is replaced, and
everything else survives byte for byte, encoding included.

Each property was falsified separately. Removing the pinned child encoding
turns the spawn test and the subprocess test red and leaves the other five
green; removing the redaction filter from the console handler turns only the
engine-end test red.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is 128e40264282045d8efcc929ea4d8ce47d4e9d4c. Both findings are closed by making each test run production rather than reproduce it. The encoding guard now intercepts subprocess.Popen inside the real _start_engine and reads the environment on its way to the operating system; the inspect.getsource stand-in is gone. The engine-end guard now runs the production setup_logging in a child and reads what actually reached that child's stderr, with a Russian diagnostic carried beside the token so one run shows both halves. Each property was falsified separately: removing the pinned child encoding reddens the spawn and subprocess tests only; removing the console handler's redaction filter reddens the engine-end test only. Verified on Ubuntu 22.04 at this commit, tests/launcher 147 passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 128e402642

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".



def test_the_line_the_engine_wrote_is_what_is_logged(tmp_path, monkeypatch) -> None:
"""The defect itself: the content used to be replaced by a constant."""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register both confirmed stderr prevention obligations

Because this module explicitly records a confirmed machine-testable defect and the follow-up false-green review escape, leaving all of its new guards absent from governance/agent_preventions.yaml means neither obligation has a stable prevention ID or a binding to its production-path guard and immutable red/green evidence; ordinary pytest discovery could later be renamed, deselected, or removed without reopening either prevention. Add separate runtime-failure and coverage-escape records before treating this correction as closed.

AGENTS.md reference: AGENTS.md:L361-L369

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 20, 2026 11:27
Continuous integration caught what my test selection did not:
tests/test_launcher_bridge_handshake.py::test_child_environments_always_strip_launcher_only_descriptor_authority
asserted `source.count("env = _without_soak_bridge_environment(os.environ)") >= 3`.
Putting the engine's child environment behind _engine_child_environment removed
one of those literals. The PROPERTY it guards -- that no child environment is
built from a bare os.environ -- was never broken; the proxy for it was.

The guard now runs the helper instead of describing it. It builds an
environment carrying both soak variables, passes it through
_engine_child_environment, and requires both to be gone and the unrelated one
to survive, exactly as the first half of the test already does for
_without_soak_bridge_environment. The source check stays, but counts BOTH
builders, so moving a spawn behind the helper is allowed and dropping the
stripping is not.

The selection I ran before pushing was tests/launcher, and this test is at the
tests/ root. The selection is now derived rather than guessed: every module
naming a symbol this branch touches -- _without_soak_bridge_environment,
_engine_child_environment, _start_engine, PYTHONIOENCODING, _pump_engine_stderr
-- which is eighteen modules, 495 passed and 17 skipped.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is a9829f3f2643d9cd628bd1e5a25d8109236e96ef. Continuous integration caught a guard my selection missed: test_child_environments_always_strip_launcher_only_descriptor_authority counted the literal env = _without_soak_bridge_environment(os.environ), and putting the engine spawn behind _engine_child_environment removed one occurrence. The PROPERTY was never broken, the proxy for it was. The guard now RUNS the helper and requires both soak variables gone, and its source check counts both builders. The pre-push selection is now derived rather than guessed -- every module naming a symbol this branch touches, eighteen of them, 495 passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a9829f3f26

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/test_launcher_bridge_handshake.py Outdated
Comment on lines +341 to +344
builders = source.count("env = _without_soak_bridge_environment(") + source.count(
"env = _engine_child_environment("
)
assert builders >= 3, builders

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard each production child spawn instead of counting helpers

The count is currently four because it includes _engine_child_environment's internal env = _without_soak_bridge_environment(base) as well as the three production spawn builders. If either the assistant or standalone-GUI spawn is changed back to a bare os.environ copy, the count merely falls to three and this test still passes; the helper assertions also remain green because they never exercise those spawn paths, allowing launcher-only descriptor variables into that child's environment undetected. Inspect each Popen environment or otherwise bind the assertion to every production spawn site rather than using this aggregate threshold.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 20, 2026 12:29
…lpers

Closes the review finding on pull request #94, which was right: the count was
four because it included _engine_child_environment's own internal
`_without_soak_bridge_environment(base)`. A spawn regressing to a bare
os.environ merely dropped the total to three and still satisfied `>= 3`, and the
helper assertions could not see it either, because they never touch a spawn.

Two changes, and the weaker one is now only a backstop.

Each production spawn is intercepted at subprocess.Popen and the environment on
its way to the operating system is read directly -- the engine and the assistant,
each with its own literal window state. The launcher-only descriptor variables
grant authority over the runner's evidence stream, so a child that inherits them
can write into it; the test requires all four to be absent and an unrelated
variable to survive, so "strips everything" would fail too.

The count now includes only builders that take os.environ, since the helper
takes `base`. That makes each counted call a production spawn, and the number is
exact rather than a floor.

Proven by regressing each spawn in turn: with the engine's builder replaced by
`dict(os.environ)` the engine case turns red, with the assistant's replaced the
assistant case turns red, and the tightened count catches both as well.

Finding the assistant's spawn state took a throwaway probe that added whatever
attribute the traceback named until Popen was reached; it needed none. The
engine's needed two, which is why they are written down rather than guessed.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is 7f614dc633d427dc6daa37311bb047b6b65bd6b2. The finding was right: the count included _engine_child_environment's own internal _without_soak_bridge_environment(base), so a spawn regressing to a bare os.environ merely dropped the total to three and still passed. Each production spawn -- the engine and the assistant -- is now intercepted at subprocess.Popen and its environment read directly, requiring all four launcher-only descriptor variables absent and an unrelated one to survive. The count is a backstop and now counts only builders taking os.environ, so it is exact rather than a floor. Proven by regressing each spawn in turn: the engine case reddens for one, the assistant case for the other, and the count catches both.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f614dc633

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +365 to +368
[
("engine", launcher.LauncherWindow._start_engine, _engine_window),
("assistant", launcher.LauncherWindow._start_assistant, _assistant_window),
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Intercept the standalone-GUI spawn too

Fresh evidence in this revision is that the parameterization intercepts only the engine and assistant, while LauncherWindow._on_open_full_gui is a third production Popen path at src/cryodaq/launcher.py:5151-5167. If that call passes os.environ directly while leaving its builder assignment in place, both these runtime assertions and the exact textual count remain green, yet the GUI child receives the launcher-only evidence-authority variables. Add this spawn to the direct interception rather than relying on the structural backstop.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 20, 2026 13:28
Third and last of the launcher spawns. It builds its child environment inline,
inherits the same launcher-only descriptor variables if it stops, and was simply
missing from the interception. A count could never have said so, which is the
whole reason the count is only a backstop now.

Regressing that spawn to a bare os.environ reddens exactly its case.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is e2f0eaf8450ed241b8af6904c68dfbf71b154edd. Right again: the standalone GUI is the third production spawn, it builds its child environment inline, and it was simply missing from the interception. It is parametrized now beside the engine and the assistant, and regressing it to a bare os.environ reddens exactly its case. The count stays only as a backstop and says in place why three is the number. Verified on Ubuntu 22.04 at this commit.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: e2f0eaf845

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

soak measurement added 3 commits August 20, 2026 14:26
…-stderr

# Conflicts:
#	docs/CLAIM_CORRECTIONS.md
#	docs/architecture-montana-important.svg
#	docs/current_candidate_metrics.md
@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is a97579b600484191b889966104e26db1dd6856fc. No behaviour change in this push: master is taken in so the protected jobs can run at all. Only three files conflicted, the same three that conflict on every branch -- the two DERIVED documents, resolved by taking one side and regenerating to a fixed point rather than hand-merging hunks, and CLAIM_CORRECTIONS, whose count is read out of the freshness guard afterwards (707) rather than merged. The launcher selection is green at this head.

@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is 6fe896e268c0a9930b2e12e2813852d3fc103955. All four findings are closed, and two of them matter for an unattended week.

  • A final diagnostic without a newline was thrown away. The stderr pump treated a line with no trailing newline as an over-length line and replaced it with engine stderr line exceeded the forwarding bound. So an engine, or a native dependency, that wrote its reason and died before flushing lost exactly that reason — and a message that fits the bound is not an over-length message. Length alone decides now.
  • A credential could reach the log through formatted exception text. The redaction filter sees a record's message and arguments; it does not see what the FORMATTER appends from exc_info, so a traceback quoting a Telegram URL reached the file unredacted. The formatter redacts what it produces, which is the last point before the bytes are written.

Both matter for the same reason: over a week the log is the only witness, and it must keep the last thing said and none of the secrets.

Authored by a worker lane, reviewed by a second model, and verified here rather than taken on either one's word. Two corrections were needed and I would rather name them than let the review look cleaner than it was: the lane wrote CRLF into three LF files, which would have shown as whole-file diffs; and my first falsification of the redaction property ran the wrong test module and briefly looked like an unpinned property. Both properties are pinned — restoring the newline condition, and formatting without redaction, each turn exactly one test red.

tests/launcher/test_engine_stderr_is_kept.py and tests/test_launcher_bridge_handshake.py are green at 20 passed and 14 skipped; ruff is clean; the prevention baseline is regenerated; tests/docs is green at 68 passed with the changed-Python count re-derived from the guard at 708.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 6fe896e268

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

soak measurement added 2 commits August 23, 2026 12:10
# Conflicts:
#	docs/architecture-montana-important.svg
#	docs/current_candidate_metrics.md
@test1card

Copy link
Copy Markdown
Owner Author

@codex review this pull request at head 38d62e50367e9545e19f7f4c9502986d51359a7f.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38d62e5036

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread governance/agent_preventions.yaml Outdated
Comment on lines +583 to +585
guard: tests/launcher/test_engine_stderr_is_kept.py::test_the_engine_end_replaces_a_token_through_its_real_logging_setup
ci_partition: remaining
red_evidence: the_no_scrub_test_used_a_shape_production_never_matched_and_the_builder_count_included_the_helpers_own_call_so_a_spawn_regressing_to_a_bare_environ_stayed_green_2026_08_20_pending_immutable_capture

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register the spawn-coverage escape under its own guard

This record combines two distinct false-green reproductions, but its sole guard exercises only logging redaction. If the aggregate spawn-builder check again permits a production child to inherit the launcher-only descriptor authority, test_every_production_spawn_strips_the_launcher_only_authority may catch it, yet the registered false-green obligation here never runs that test and remains green. Give the spawn-coverage escape its own prevention ID bound to the production-spawn guard rather than combining it with the token-shape escape.

AGENTS.md reference: AGENTS.md:L366-L369

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 23, 2026 18:26
…alse-green pair

The reviewer objected that a single false-green record carried two different
defects: the no-scrub test used a shape production never matched, and the
builder count included the helper's own call. One record cannot be closed by
two independent guards, and while they shared an entry neither could be shown
to have gone red on its own.

Record 501 keeps the first defect and stays bound to the real-logging-setup
guard. New record 502 carries the second and binds to the spawn-authority
guard. Neither claims red-before evidence it does not have; both say pending.

Measured at these bytes: the baseline regenerates to itself, so the floors are
the generator's own count and not a hand-written number, and the governance
suite is 297 passed.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review this pull request at head 4aef260eb73562b39096ce784a49ff5760a80e53.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4aef260eb7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread governance/agent_preventions.yaml Outdated
- id: LAUNCHER-SPAWN-COVERAGE-FALSE-GREEN-502
status: open
scope: product_contract
runtime_prevention_id: LAUNCHER-STDERR-CONTENT-001

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Link the spawn escape to descriptor authority

This false-green record still points to LAUNCHER-STDERR-CONTENT-001, whose classification and consequence cover discarded diagnostics, while the guarded failure lets a child inherit the launcher’s evidence-stream descriptor authority. If this guard regresses, the prevention map therefore reopens the wrong runtime obligation and never tracks the actual authority escape; bind it to LAUNCHER-DESCRIPTOR-EVIDENCE-021 (and add the guard there) or create a matching runtime record with the descriptor-forgery consequence and invariant.

AGENTS.md reference: AGENTS.md:L361-L369

Useful? React with 👍 / 👎.

ci_partition: remaining
- node: tests/launcher/test_engine_stderr_is_kept.py::test_the_engine_end_replaces_a_token_through_its_real_logging_setup
ci_partition: remaining
- node: tests/launcher/test_engine_stderr_is_kept.py::test_the_engine_end_replaces_a_token_in_formatted_exception_text

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register the exception-redaction false green

When formatter-level redaction is removed while the existing message/argument filter remains, the registered normal-record guard at line 583 stays green and only this newly added exception-path guard detects that traceback text leaks the token. The confirmed formatter escape therefore needs its own false_green_pairs entry bound to this exact guard; listing it only under the runtime record does not satisfy the independently enforceable coverage obligation.

AGENTS.md reference: AGENTS.md:L366-L369

Useful? React with 👍 / 👎.

ci_partition: remaining
- node: tests/launcher/test_engine_stderr_is_kept.py::test_the_engine_end_replaces_a_token_in_formatted_exception_text
ci_partition: remaining
- node: tests/launcher/test_engine_stderr_is_kept.py::test_a_bounded_final_stderr_fragment_is_forwarded_at_eof

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register the EOF-fragment false green

If the pump again treats every non-newline read as overlong, the existing overlong-line guard remains green while a bounded final diagnostic is silently discarded; only this newly added EOF guard catches that previously escaped failure. Add a distinct false-green prevention ID bound to this node so renaming, deselecting, or weakening it reopens the coverage obligation rather than leaving the runtime record apparently enforced.

AGENTS.md reference: AGENTS.md:L366-L369

Useful? React with 👍 / 👎.

soak measurement added 2 commits August 23, 2026 19:40
… shows it

Review asked for three corrections and all three are the same mistake: a record
pointing at a guard that does not demonstrate it.

The spawn-coverage pair named the stderr-content runtime record, but the guard it
binds -- the production spawn authority test -- belongs to the descriptor-evidence
record; the node moves with it. Two further false-greens were folded into the
stderr-content record's history rather than registered: an exception's formatted
traceback text leaking a token while the message and argument tests stayed green,
and a bounded final fragment discarded at end of stream while the over-long-line
tests stayed green. Each is now its own record against its own guard.

None of them claims red-before evidence it does not have; all say pending.

The baseline is regenerated at these bytes, which the lane did not do -- it left
the two baseline synchronisation guards red. Governance is 297 passed here.
@test1card

Copy link
Copy Markdown
Owner Author

@codex review this pull request at head 602ef3c2ae3546f0907ba66412ef106a24449971.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 602ef3c2ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +4265 to +4266
- node: tests/launcher/test_engine_stderr_is_kept.py::test_a_russian_diagnostic_survives_the_real_subprocess_boundary
ci_partition: remaining

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bind the actual engine-spawn encoding guard

If _start_engine stops passing _engine_child_environment to Popen, the registered test_a_russian_diagnostic_survives_the_real_subprocess_boundary still stays green because it invokes that helper directly; only the unregistered test_the_spawn_hands_the_operating_system_the_environment_under_test exercises the production handoff. Register that exact test, including the corresponding false-green obligation, so it cannot be renamed or deselected while LAUNCHER-STDERR-CONTENT-001 remains apparently enforced.

AGENTS.md reference: AGENTS.md:L366-L369

Useful? React with 👍 / 👎.

Comment thread governance/agent_preventions.yaml Outdated
status: open
scope: product_contract
runtime_prevention_id: LAUNCHER-STDERR-CONTENT-001
guard: tests/launcher/test_engine_stderr_is_kept.py::test_the_engine_end_replaces_a_token_through_its_real_logging_setup

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point the no-scrub escape at the pump guard

If the pump starts selectively redacting Telegram-shaped text, this registered engine-setup test remains green because setup_logging() already removes the token before the pump receives it. The exact guard for this false-green shape is test_the_pump_adds_and_removes_nothing_even_for_a_real_token_shape, but that node is absent from both this pair and the runtime record, so the pump contract can regress without reopening the prevention; bind the pair to that guard instead.

AGENTS.md reference: AGENTS.md:L387-L390

Useful? React with 👍 / 👎.

status: open
scope: product_contract
runtime_prevention_id: LAUNCHER-DESCRIPTOR-EVIDENCE-021
guard: tests/test_launcher_bridge_handshake.py::test_every_production_spawn_strips_the_launcher_only_authority

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register the capability-bearing assistant spawn guard

If the soak-capability path passes the launcher's original artifact descriptor or broadens pass_fds, this registered generic spawn guard remains green because its assistant fixture has no _soak_artifact_capability. Only the newly added but unregistered test_assistant_spawn_delegates_only_its_bounded_soak_artifact_grant exercises child_grant() and checks the delegated descriptor boundary; register that node under LAUNCHER-DESCRIPTOR-EVIDENCE-021 with its own false-green pair so this distinct authority escape cannot be deselected without reopening the prevention.

AGENTS.md reference: AGENTS.md:L366-L369

Useful? React with 👍 / 👎.

@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Head is 88546dac610c3648f3f6c5085317cefc2237f5d9. A lane closed the live review findings; the coordinator ran the landing gates on this tree -- byte-order-mark, encoding and parse checks on every changed file, a refusal on any tree that deletes more than it adds, ruff check and ruff format --check on the changed Python, the derived documentation pair regenerated to a fixed point, and the documentation gate green.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 88546dac61

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@test1card

Copy link
Copy Markdown
Owner Author

@codex review

Exact head: df1eaf7

This test-only update isolates the two Popen observers from ambient data directories and port occupancy. Coordinator verification on this exact tree: C:\Python314\python.exe -m pytest -q --basetemp .pytest-tmp/pr94-verify-20260831 tests/launcher/test_engine_stderr_is_kept.py tests/test_launcher_bridge_handshake.py completed with 29 passed and 19 skipped. Ruff check passed. Ruff format --check reported both files already formatted. The exact new slice and the pull-request metadata passed the privacy search.

The pull request remains a draft. Hosted CI and a clean exact-head Codex verdict remain open merge gates.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T10:02:57.673304Z df1eaf7 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df1eaf7a55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

monkeypatch.setattr(launcher.LauncherWindow, "_do_shutdown", lambda _host: False)

def fail_after_capturing_engine_stderr() -> None:
launcher._pump_engine_stderr(io.BytesIO(stderr), stderr_logger, tail)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exercise construction diagnosis through _start_engine

When _start_engine reaches _wait_engine_ready and the child exits, production depends on the stderr thread receiving stderr_tail; this guard instead populates the tail manually before invoking _run_construction_step. Removing the tail from the real thread arguments would therefore lose the child’s diagnostic while this registered guard remained green, so drive the failure through the actual engine-start path.

AGENTS.md reference: AGENTS.md:L380-L386

Useful? React with 👍 / 👎.

raise _Stop("spawn intercepted after the environment was fixed")

monkeypatch.setattr(launcher.subprocess, "Popen", _capture)
monkeypatch.setattr("cryodaq.paths.get_data_dir", lambda: tmp_path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Redirect the stderr log alongside the data directory

When CRYODAQ_STATE_ROOT is unset or points outside the test sandbox, _start_engine still calls _create_engine_stderr_logger() before reaching the intercepted Popen, and get_logs_dir() consequently opens the ambient logs/engine.stderr.log. Patching only get_data_dir leaves this observer dependent on and mutating ambient writable state, so it can fail in a read-only checkout or collide with another launcher observer; redirect the logs directory too, or set the complete state root to tmp_path.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant