Desktop over SSH: inspect, load and verify rollback of managed hooks for native task tools
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary and requested outcome
We use Codex Desktop connected to a remote Linux workspace over SSH. A custom,
versioned managed hook protects owner-authorized operations on newly registered
tasks. We need a supported way to identify the effective hook configuration
for the caller executing native codex_app task tools, load a reviewed
configuration at the correct lifecycle boundary, and verify both selection
and rollback through actual native hook events.
In a previous bounded test, a candidate configuration was selected and read
back on the remote filesystem, but one native codex_app.read_thread probe
was denied by our older guard. We have not established whether that is due to
process lifetime, execution on a different host/process, a different config
layer, or a local integration mistake. Editing files was not established as
a supported reload operation, so we are not claiming that Codex violated
a documented hot-reload guarantee.
Our own policy keeps cross-task mutation disabled until the integration is
verified. Ordinary independent project work remains available. We are not
requesting bypasses, access to private sessions, or a guarantee that hooks
form a universal security boundary.
Environment and evidence limits
| Item | Recorded state |
|---|---|
| Frontend | Codex Desktop using a saved remote SSH workspace |
| Remote environment | Linux VM; exact distribution/kernel release not captured in this report |
| Remote Codex binary | codex-cli 0.153.4, recorded by scoped diagnostics on 2026-09-10 and the machine inventory on 2026-09-18 |
| Desktop application build | Not captured; the remote CLI version must not be treated as the desktop build |
| Native task-tool execution host/process | Not established; shell ancestry is not proof of the host/process running a native app tool |
| Hook source tested | Root-managed requirements.toml, absolute commands under an immutable managed directory |
| Hook events configured in the local integration | SessionStart, SubagentStart, PreToolUse, PostToolUse |
| Baseline custom guard | transient_thread_guard_v3_6, custom artifact schema 10 |
| Historical candidate under test | transient_thread_guard_v3_11, custom artifact schema 14 |
| Custom MCP plugin | monasys-ctb 0.4.0+codex.20260731095857; prior scoped inspection found no bundled hook in that plugin |
| Test mode | deny_all_thread_mutations throughout; no real task targeted or created |
These custom guard/schema/plugin identifiers belong to our integration, not
Codex product releases. A later local candidate exists but has not passed a
native lifecycle canary and is not presented as installed or working here.
What was observed
A. Historical native probe — 2026-09-10
The retained structured result records:
- A bounded maintenance window selected the candidate's managed-hook
configuration. Candidate selection was verified by filesystem read-back. - One direct native
codex_app.read_threadcall used a deliberately
synthetic, non-task identifier, withturnLimit=1. The candidate hook was
designed to deny this exact diagnostic shape before task lookup and return
a minimal version/challenge receipt. The request did not select a real
conversation. - A native pre-tool denial was observed from our v3.6 baseline, not the
v3.11 candidate. The observed tool spelling wascodex_appread_thread.
The bounded denial reason was:
read_thread targets a pre-existing or unregistered user chat. - No candidate receipt was observed. No retry, task creation, or mutation
followed. Full CTB lifecycle and candidate SessionStart were not proved. - The window was ended after approximately 17 seconds. An independent
restoration path restored the previous files and their checksums.
This proves disk restoration only, not effective native-hook reload.
The full 600-second deadline expiry was not exercised in that test.
Redacted call shape, provided for triage only; this is not a new reproduction:
{
"tool": "codex_app.read_thread",
"arguments": {
"threadId": "ctb-native-hook-probe-v1:<redacted-fresh-nonce>",
"turnLimit": 1
}
}
The synthetic identifier and denial contract are specific to our guard.
We do not claim this is a standalone stock-Codex reproducer. A new isolated
reproducer would need the supported setup/load procedure clarified first.
B. Current caller-surface observation — 2026-09-18
- Native saved-project listing succeeded for the expected remote workspace.
- The active agent surface describes direct
create_thread,read_thread,
set_thread_title, andset_thread_archivedtools. This is an inventory,
not proof that these operations or their hooks work. - Direct
wait_threads, effective-hook inspection, hook load/reload control,
and subscriptions to native hook events are not exposed to this agent. - A subsequent single direct
codex_app.read_threadcall used a fresh
synthetic non-task identifier andturnLimit=1, without changing any
configuration. The tool boundary returned a PreToolUse hook denial
identifyingtransient_thread_guard_v3_6, with the same bounded reason as
the historical probe and tool spellingcodex_appread_thread. - This establishes a guard-family denial on this caller's read path at that
moment. It does not attest an exact source commit, the candidate,
SessionStart, PostToolUse, or create/title/archive coverage. There was no
challenge receipt, retry, real conversation read, task creation or mutation. - Managed configuration and mode-file checksums remained unchanged. No
configuration switch or rollback was attempted in this fresh observation.
The absence of a model-callable tool does not imply that the corresponding
app-server API does not exist, or that it ought to be exposed to the model.
We would accept a supported operator/UI diagnostic route instead.
C. Settings UI and bounded configuration inspection — 2026-09-18
The owner opened Desktop Settings > Hooks. The page displayed "No hooks
found"; the owner confirmed the same result after pressing its refresh icon.
No host/project selector was visible in the supplied view. The screenshot is
retained privately and is not attached. We have not established which host or
project context this page queried, or whether it issued a hooks-list request.
In the remote workspace, the managed requirements file contained five entries:
SessionStart, SubagentStart, two PreToolUse entries, and PostToolUse. Their
absolute commands pointed to the immutable baseline directory. The checked
user, system and ancestor/project configuration paths contained no additional
hook definitions; absent files were recorded as absent. The current shell's
Codex configuration root matched its default. This bounded check did not
enumerate cloud/MDM/session sources or prove the native caller's configuration
root. No authentication values or unrelated configuration content were read
into the report.
Together, the UI observation and actual native denial show that the empty
page cannot be used as proof that this caller has no executing hook. They do
not establish a root cause or a safe candidate-loading procedure.
Related reports, not assumed duplicates
- #30701 reports an empty Hooks
page despite an executing plugin hook when no projects are saved. It is
closed; its report and comments do not establish a fix applicable here. - #43123 reports a Windows
Hooks UI discovery problem with no local projects. Our saved workspace is
remote, but the local-project inventory was not established in this check.
Those reports concern UI discovery. Our additional request is the supported
inspection/load/rollback contract for managed hooks on native task tools in
Desktop over SSH. We have not reproduced their empty-project conditions or
confirmed a shared cause.
Relevant documented contract
The App Server documentation
lists hooks/list for discovering lifecycle hooks and synchronous
hook/started / hook/completed notifications. Their presence in protocol
documentation does not establish access from this desktop/SSH caller.
We need the supported client/operator route.
The Hooks documentation says managed
hooks are trusted by policy, while other hooks have a trust-review flow. It
also states that some specialized tool paths can bypass the usual hook path.
We therefore do not assume that native task tools receive both hook events,
or treat plugin installation, a file hash, MCP refresh, or CLI /hooks in a
different process as proof about this desktop caller. Sources checked
2026-09-18.
Questions for the Codex team
- Execution ownership: In Desktop over SSH, which host/process and config
layers governcodex_app.create_thread,read_thread,set_thread_title
andset_thread_archived? Is this different from the remote shell tool? - Effective inspection: What supported UI/API/export lets the operator
inspect resolved hook sources for that exact caller and correlate an
invocation with the selected hook command/version? Ishooks/lista
discovered-config view only, or does it reflect the active engine? Which
host/project does Desktop Settings > Hooks inspect for an SSH task? - Load boundary: When are changes to managed
requirements.tomland
managed hook commands read by a Desktop SSH session? Is a supported reload
available? If restart/new session is required, which component and what
procedure preserve unrelated active work? We do not assume hot reload. - Coverage: For each native task tool above, are PreToolUse and
PostToolUse guaranteed, conditional, or intentionally unsupported? What
tool names/aliases are documented, and iscodex_appread_threadexpected? - Runtime evidence: How can a desktop operator obtain the corresponding
synchronous hook events without scraping transcripts/session databases or
privately attaching to the application-owned app-server? - Rollback: How can the operator verify that the running caller uses the
restored hook after restoring files? Are in-flight turns pinned to their
initial configuration?
A precise statement that a route is unsupported would also resolve the
integration question. We could then change our architecture explicitly,
instead of repeating configuration switches that cannot prove readiness.
What has not been established
- No confirmed cached-config defect, hook bypass, or host-routing defect.
- No evidence that all configured sources or cloud/MDM layers were enumerated.
- No proof of the candidate hook on create/title/archive or a complete native
create → execute → receive → archive workflow. - No current desktop build, independent clean-profile reproduction, or full
deadline-expiry test. These gaps should remain explicit during triage. - Local source tests validate our guard logic, not the native app integration.
Separate local binding/version/whole-window rollback gaps also remain;
an answer to this report alone would not certify our complete system.
Safe next reproduction, only after clarification
Use a disposable workspace and exact client/remote versions; establish the
documented load boundary; collect only a harmless synchronous diagnostic event
bound to a versioned handler; restore the baseline and verify that handler
again. Use no existing user task, secrets, raw transcripts or business job.
Task mutations need their own bounded approval and subsequent coverage test.
This procedure is proposed and NOT RUN, not an executable authorization.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the App Server and Hooks documentation, then trace hooks/list and hook/started/hook/completed for the Desktop Settings > Hooks SSH context. Compare those documented surfaces with native codex_app.create_thread, read_thread, set_thread_title, and set_thread_archived behavior. Done means a supported inspection, load boundary, event-evidence, and rollback procedure is documented, or the route is explicitly declared unsupported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, rust
- Domain
- backend-api-design, desktop, devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100