Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ including prior context, B's own edit and busy/stop checks. A new
[public-entry checkpoint](docs/09-reviews/2026-09-07-native-public-entry.md) verifies
anonymous workflow retrieval; title-based activation, novice task selection and
normal plugin activation remain open. The live readiness attempt returned empty
current-turn evidence despite host-reported completion; resolve result visibility
before repeating it. Sending is not race-free. External adapter/hook adoption is
current-turn evidence despite host-reported completion; an official App Server
read recovered the original results and identified invalid inventory limits.
That parameter is corrected, but a valid bounded inventory still omitted the
pair. Resolve selected-task lookup before claiming entry success. Sending is
not race-free. External adapter/hook adoption is
a separate portability route, not a prerequisite for trying native guidance.

The [desktop-first plan](docs/10-planning/desktop-entry-2026-09-07.md) supersedes
Expand Down
10 changes: 7 additions & 3 deletions docs/06-guides/codex-native-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ or terminal command is needed in this prompt.

```text
Use the ThreadMesh workflow at this pinned public URL. Read the complete file:
https://raw.githubusercontent.com/fyaic/threadmesh/592014782d10a8c4b88f46ea23b7cf588ff78355/plugins/threadmesh-codex/skills/threadmesh-codex/SKILL.md
https://raw.githubusercontent.com/fyaic/threadmesh/7ea4d407b719f0241f1eccbe2e5d95c15a72c72c/plugins/threadmesh-codex/skills/threadmesh-codex/SKILL.md

Pair only this task with "OTHER TASK TITLE". Each keeps its own current job and
earlier decisions. Allowed shared topic: SHARED TOPIC.
I allow one task-list lookup to resolve that title, understanding that the list
also exposes other task titles/summaries. Do not read unrelated conversations.
Use list_threads with limit: 50 at most; the host rejects 100.
If the title is missing or ambiguous, ask me; do not guess or scan more history.

I authorize automatic, relevant peer advice after setup. I understand an idle
Expand Down Expand Up @@ -60,8 +61,11 @@ each task to cancel it; no separate control panel is required.

If the app shows “completed” but supplies no readable setup confirmation, keep
collaboration off. Do not assume pairing worked or repeatedly rerun it. This
occurred in our [readiness attempt](../09-reviews/2026-09-07-native-public-entry.md#authorized-live-readiness-attempt);
its cause is unresolved, and a completed indicator alone is not acceptance.
occurred in our [readiness attempt](../09-reviews/2026-09-07-native-public-entry.md#read-only-diagnosis-and-correction):
a separate official read recovered the results, which reported a rejected list
limit. The corrected limit is not a complete task search: our subsequent bounded
inventory still did not contain the selected pair. Missing titles require an
app-provided reference or a clearer selection, not a guessed destination.

This is an explicit workflow request in the existing conversation, **not proof
that installing a plugin hot-loads old tasks**. The model must actually retrieve
Expand Down
83 changes: 75 additions & 8 deletions docs/09-reviews/2026-09-07-native-public-entry.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Native desktop public entry: retrieval and readiness boundary

Date: 2026-09-07. Status: **public retrieval checked; live name-based readiness
attempt not accepted because current-turn evidence is empty**. This record does not replace the earlier
Date: 2026-09-07. Status: **readiness failure recovered through official App Server
read: both inventory calls used an invalid limit; pairing still not accepted**.
The earlier empty desktop-read observations are retained below, not erased.
This record does not replace the earlier
[controlled native business case](2026-09-07-native-desktop-acceptance.md).

## What changed for a user
Expand Down Expand Up @@ -90,12 +92,77 @@ traces and cannot fill the missing tool evidence.

## Disposition

The bounded readiness gate **did not pass**. The bilingual guide now explicitly
says that a completed indicator without a readable confirmation is not ready.
Resolve current-turn result visibility before another acceptance run; do not
paper over it with a new CLI pair, repeated quota-consuming dispatches or a
claim based on the earlier successful native case. Independent GUI onboarding
and public-source activation remain open.
The bounded readiness gate **did not pass**. The subsequent diagnosis below
recovered the results, not a passing pair. Independent GUI onboarding and
public-source activation remain open. Do not substitute a new CLI pair or the
earlier successful native case for this missing acceptance.

## Read-only diagnosis and correction

A later native `read_thread` recheck still returned zero items for both current
turns and readable preceding turns. The official
[App Server `thread/read` interface](https://learn.chatgpt.com/docs/app-server)
supports reading a stored task without resuming it. Using the installed desktop
runtime, Codex CLI 0.153.1, over a new **stdio diagnostic connection**, the manager
read the same task IDs with `includeTurns: true` and selected the exact same
readiness turn IDs. **Both contained five items and a final “not ready” result.**
No new task, `thread/resume`, `turn/start`, messaging, private socket or direct
transcript/database access was used. Diagnostic processes exited after reads;
no model was invoked. This identifies a discrepancy between the two read
surfaces, not its internal implementation cause or a repair of the desktop tool.

| Recovered evidence | A | B |
|---|---|---|
| Public retrieval operation | Web open of the pinned raw URL | Successful curl of the same URL |
| Inventory call | `list_threads`, `limit: 100` | `list_threads`, `limit: 100` |
| Actual tool result | Invalid arguments: limit must be at most 50 | Same |
| Model's final disposition | Not ready; matching unverified; collaboration OFF | Same |
| Outgoing peer send / native file-change items in this turn | 0 / 0 | 0 / 0 |

The inbound `send_message_to_thread` function output is the manager's check
message, not an outgoing peer send. A's web-open item and final response support
retrieval being attempted/reported; they do not expose the full web response.
B's completed curl item retains the workflow text. Neither model retried its
rejected inventory call. There is now evidence for their reported stopped
behavior in these turns; the initial empty-export observation could not provide it.

Private App Server turn records have SHA-256 commitments:
A `bd0b7733d39b380400b28b834c650fa8757f70d209313320bb011e3ac8d955d5`;
B `f3c60f7680c5c683042a71038fffebb486e485c85967e768ea63db0ba499aeb6`.
They are retained separately from the original empty native-tool responses.

The manager then made one native `list_threads` call with `limit: 50`. It was
accepted and returned 50 entries with no unavailable-host/source warnings, but
**neither selected task was present**. Exact-title App Server `thread/list`
diagnostics also returned no matches; a separately checked `appServer` source
filter likewise returned none, while each task's own metadata reports `vscode`.
A scoped exact-title archived-`vscode` query also returned no matches for either
task; it did not unarchive or alter anything.
Do not infer deletion, rename, global absence or a proven source-filter cause.
This diagnostic does not establish successful title resolution.

Two bounded fixes follow from the evidence:

- The skill and both copyable prompts cap native inventory at 50, include
pinned/unpinned results and explicitly treat a bounded list as incomplete.
The revised public workflow is pinned to
`7ea4d407b719f0241f1eccbe2e5d95c15a72c72c`; the failed run used the earlier revision.
- The structural evidence auditor now rejects any empty completed turn. An
earlier valid handoff must not hide a later unknown turn and produce misleading
total-send counts. A regression exercises empty turns on either side and empty
prior context; the retained original nonempty native proof still passes.

Post-fix regression: 460 tests passed, one optional native test skipped; all
55 schema cases and seven transition cases passed, and 146 Markdown files linted
cleanly. These are deterministic checks, not a rerun of the repaired model workflow.
The new pinned public workflow returned HTTP 200, matched the source exactly
(7,031 bytes), and has SHA-256
`2d3822d5c609f091ff29e49aaef33f8ea432a13661b67b5112b7144379865c18`.

The original limited call approval was not reused to restart either model or
enable collaboration. Next resolve supported selected-task lookup and validate
the repaired public entry end to end. Keep that separate from this no-model
diagnostic and from a claim that the desktop read tool itself has been fixed.

Official [skill documentation](https://learn.chatgpt.com/docs/build-skills)
describes reusable instructions and host loading. It does not itself prove this
Expand Down
2 changes: 1 addition & 1 deletion docs/09-reviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ not count as live-product or independent external-verifier evidence.

## Live attempt audits

- [Native desktop public entry: retrieval checked, live readiness evidence unavailable](2026-09-07-native-public-entry.md)
- [Native desktop public entry: recovered readiness results and invalid-limit repair](2026-09-07-native-public-entry.md)
- [Codex-first installed-package acceptance and retained failures](2026-09-07-codex-first-use-release.md)
- [Codex native desktop: prior context, original receiver edit and busy/stop checks](2026-09-07-native-desktop-acceptance.md)
- [Codex native-task skill: earlier packaging/tabletop checkpoint](2026-09-07-codex-native-skill.md)
Expand Down
16 changes: 13 additions & 3 deletions docs/10-planning/community-followup-2026-09-07.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ complete, not passed. The reply explicitly retained that limitation rather than
delaying the contributor's already-delivered priorities behind native retries.
The earlier draft is superseded by the linked posted text and remains in Git history.

At 12:49:11 UTC, the same comment was corrected in place after a no-model
diagnosis. Official App Server `thread/read` recovered both original five-item
turns: the models reported not ready after `list_threads(limit: 100)` exceeded
the host's maximum of 50. The recovered records contain no outgoing peer send
or file-change items. The source workflow now caps the limit, while a later
valid inventory still omitted both tasks. This does not repair the desktop read
tool or prove title-based onboarding. No extra comment or model retry was sent.

### Next work, not another status-only reply

Subsequent native desktop evidence is now retained as [actual excerpts and diff](../evidence/codex-native-2026-09-07/README.md).
Expand All @@ -126,9 +134,11 @@ again. Do not post another acknowledgement-only message, roadmap promise, test
request or issue closure. Continue implementation, review and verification
inside the authorized task rather than stopping after each small step.

Next resolve why the supported native read path exposes no current-turn result
in the readiness attempt, without private storage or unauthorized UI workarounds.
Then validate the public-source name-based entry with a readable confirmation
Read-only recovery now distinguishes missing desktop-tool output from a missing
model result; the desktop tool's internal discrepancy remains outside this repo.
Next resolve supported selected-task lookup: the bounded native list did not
contain the pair, and exact-title diagnostic searches also returned no matches.
Then validate the public-source entry with a readable confirmation
before claiming activation. Keep the original goals: a user's existing Codex
pair, retained decisions, useful receiver-owned work and less manual relaying.
Do not add harnesses or a benchmark platform to avoid this first-use blocker.
Expand Down
8 changes: 6 additions & 2 deletions docs/10-planning/project-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ source parity passed; readiness checking is separate from activation. The
desktop matching and end-to-end activation open. Two user-authorized read-only
checks were dispatched: both host-reported completed, but current-turn histories
were empty while preceding turns were readable. Sample hashes were unchanged;
readiness and absence of peer sends cannot be verified. No enable command or
repeat dispatch was issued. Resolve result visibility before another live gate.
readiness and absence of peer sends could not initially be verified. A subsequent
official App Server read recovered five items per original turn: both models
reported not ready because `list_threads(limit: 100)` exceeds the host's maximum
of 50. The skill now caps it at 50 and the evidence auditor rejects empty turns.
A valid manager inventory still omitted the selected pair, so name resolution
remains open. No enable command or repeat model dispatch was issued.

**Value and evidence correction:** the native demo uses Codex's own communication
and continuation; the skill adds guidance, not transport. [English responsibility
Expand Down
2 changes: 1 addition & 1 deletion docs/evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ adoption or proof of incremental value over the host's native capability.
| Recent case | Public record | Retained private originals |
|---|---|---|
| Codex desktop prior-context pair | [Actual exchange, B's diff and reduced audit](codex-native-2026-09-07/README.md) | Complete A/B native exports, original tasks and files |
| Codex public-entry readiness attempt, not accepted | [Empty current-turn evidence and unchanged artifacts](../09-reviews/2026-09-07-native-public-entry.md) | Native read responses retained separately; not full execution traces |
| Codex public-entry readiness attempt, not accepted | [Recovered results, rejected inventory limits and unchanged artifacts](../09-reviews/2026-09-07-native-public-entry.md) | Empty desktop reads and recovered official App Server turn records retained separately |
| Codex default installed-package pass, 272.604 s | [Acceptance](../09-reviews/2026-09-07-codex-first-use-release.md) | Events, report, transcripts and sample artifacts copied to a dated non-temporary archive |
| Codex diagnostic pass, 184.050 s | [Same record, separate budget](../09-reviews/2026-09-07-codex-first-use-release.md) | Same archive categories; not counted as the default gate |
| Codex old-runtime failure | [Failure retained alongside passes](../09-reviews/2026-09-07-codex-first-use-release.md#failures-that-changed-the-implementation) | Events and failed-run report copied to the dated archive |
Expand Down
9 changes: 6 additions & 3 deletions docs/zh-CN/codex-native-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ clone 仓库或终端命令。

```text
使用这个固定版本公开链接中的 ThreadMesh 工作流,请完整读取文件:
https://raw.githubusercontent.com/fyaic/threadmesh/592014782d10a8c4b88f46ea23b7cf588ff78355/plugins/threadmesh-codex/skills/threadmesh-codex/SKILL.md
https://raw.githubusercontent.com/fyaic/threadmesh/7ea4d407b719f0241f1eccbe2e5d95c15a72c72c/plugins/threadmesh-codex/skills/threadmesh-codex/SKILL.md

只把当前任务与“对方任务名称”配对。双方保留自己正在做的工作和此前约定。
允许交流的话题:允许交流的话题。
我允许读取一次任务列表来匹配这个名称,理解列表也会显示其他任务的标题和摘要。
list_threads 的 limit 不超过 50,宿主会拒绝 100。
不要读取无关对话正文。找不到或遇到重名就问我,不猜测、不继续扫描历史。

我授权设置完成后自动发送相关的同伴建议,理解空闲检查不能保证绝不与新输入竞争。
Expand All @@ -48,8 +49,10 @@ https://raw.githubusercontent.com/fyaic/threadmesh/592014782d10a8c4b88f46ea23b7c
要取消,可以分别在两个任务里说“停止 ThreadMesh 协作”,不需要额外控制面板。

如果应用显示“已完成”,却没有可读的设置确认,请保持协作关闭,不要当作配对成功,
也不要反复重跑。这是我们在[只读就绪检查](../09-reviews/2026-09-07-native-public-entry.md#authorized-live-readiness-attempt)
中实际遇到的问题,原因尚未确定;“已完成”的状态不能代替验收结果。
也不要反复重跑。我们在[只读诊断](../09-reviews/2026-09-07-native-public-entry.md#read-only-diagnosis-and-correction)
中通过另一条官方读取接口取回了结果,实际错误是列表参数超限。修正参数仍不等于
完整搜索:后续有限列表里依然没有选中的两个任务。找不到名称时,需要应用提供的
任务引用或进一步确认选择,不能猜测目标。

这是在已有对话中明确请求使用流程,**不是证明安装插件能热加载旧任务**。
模型应实际读取流程,核对已有原生工具,并确认选择范围。若读取失败或缺少工具,
Expand Down
6 changes: 6 additions & 0 deletions plugins/threadmesh-codex/skills/threadmesh-codex/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Resolve targets from user-provided native task references or already observed
host IDs, preserving the host ID when present. Do not ask users to find IDs in
files. If names alone are provided, explain that the host's task-list operation
also exposes other task titles/summaries; obtain permission for one inventory.
For this Codex desktop host, call `list_threads` with `limit: 50` at most
(or a smaller documented host limit), never 100. The observed tool rejects
values above 50 even when its displayed schema omits that bound. Include both
pinned and unpinned results when matching. This is a bounded inventory, not a
complete search of every stored task; a missing title does not mean no such
task exists. Do not spend a one-call authorization retrying rejected parameters.
Never read unrelated task turns. Confirm ambiguous names instead of guessing.
If the authorized inventory does not contain the target, ask for an app-provided
reference or a more specific selection; do not repeatedly expand the inventory.
Expand Down
2 changes: 1 addition & 1 deletion scripts/audit-native-evidence.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function auditNativeEvidence(a, b) {
const reject = () => { throw new Error("Native evidence is incomplete or does not establish one attributed receiver-owned handoff."); };
for (const d of [a, b]) {
if (!d?.thread?.id || !d.thread.cwd || !d.thread.hostId || d.page?.hasMore !== false || !Array.isArray(d.turns) ||
d.turns.some(t => t.status !== "completed" || !Array.isArray(t.items) ||
d.turns.some(t => t.status !== "completed" || !Array.isArray(t.items) || t.items.length === 0 ||
t.items.some(i => i.output?.truncated || i.changes?.some(c => c.diff?.truncated)))) reject();
}
if (a.thread.id === b.thread.id) reject();
Expand Down
13 changes: 12 additions & 1 deletion test/native-evidence-audit.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function pair() {
arguments: { threadId: "SECRET-B", hostId: "local", prompt: "PRIVATE-CONTENT" } }] },
] };
const b = { thread: { id: "SECRET-B", hostId: "local", cwd: "/private/b" }, page: { hasMore: false }, turns: [
{ status: "completed", completedAt: 1, items: [] },
{ status: "completed", completedAt: 1, items: [{ type: "agentMessage", text: "Prior user constraint retained." }] },
{ status: "completed", startedAt: 2, items: [
{ type: "functionCallOutput", name: "send_message_to_thread", output: { text: "<codex_delegation>\n <source_thread_id>SECRET-A</source_thread_id>\n <input>PRIVATE-CONTENT</input>\n</codex_delegation>", truncated: false } },
{ type: "fileChange", status: "completed", changes: [{ path: "/private/b/landing.json", diff: { text: "PRIVATE-DIFF", truncated: false } }] },
Expand All @@ -33,6 +33,17 @@ test("native evidence rejects incomplete, truncated or non-completed histories",
]) { const p = pair(); mutate(p); assert.throws(() => auditNativeEvidence(...p)); }
});

test("empty completed turns cannot hide later sends behind an earlier valid handoff", () => {
for (const side of [0, 1]) {
const p = pair();
p[side].turns.push({ status: "completed", items: [] });
assert.throws(() => auditNativeEvidence(...p));
}
const p = pair();
p[1].turns[0].items = [];
assert.throws(() => auditNativeEvidence(...p));
});

test("native evidence rejects wrong destination, wrong source, duplicate sends and missing context", () => {
for (const mutate of [
([a]) => { a.turns[0].items[0].arguments.threadId = "other"; },
Expand Down
Loading