[ai] Add two-repository workflow.

This commit is contained in:
John Preston
2026-07-19 14:11:06 +04:00
parent 587e998cbf
commit 61da040370
22 changed files with 2349 additions and 1697 deletions
+73 -59
View File
@@ -1,8 +1,8 @@
# Test Loop Protocol (harness-neutral)
The portable core of autonomous, tested implementation. Both `/implement` (Claude Code) and
`$implement` (Codex) read it. This file defines shared defaults after one task's implementation is
committed; wrappers own setup, splitting, and spawn/wait mechanics. A wrapper may explicitly adapt
The portable core of autonomous, tested implementation. `/perform-task` (Claude Code) and
`$perform-task` (Codex) read it. This file defines shared defaults after one task's implementation
is ready to commit; wrappers own setup, splitting, and spawn/wait mechanics. A wrapper may adapt
commit ownership, task baseline/attempt caps, staging/source restoration, account swapping,
`EVIDENCE_DIR`, or an optional UI driver. Its named rule wins only at that
adapter point; every other rule here still applies.
@@ -21,11 +21,14 @@ adapter point; every other rule here still applies.
## Inputs the wrapper passes in
- `TASK_DIR``.ai/<project>/<letter>/` for this task.
- `TASK_ID` — stable artifact/log identifier (e.g. the project + letter); never a commit trailer.
- `TASK_DIR` external `ai-tdesktop/tasks/<full-task-id>/` directory for this task.
- `WORK_DIR` — tracked resumable artifacts under `TASK_DIR/work/`.
- `TASK_ID` — full dated task identifier and required source-commit locator.
- `BASE_REF` — local pre-task baseline ref derived from `TASK_ID`.
- `GREEN_REF` — local ref for the current retained implementation attempt.
- `EVIDENCE_DIR` — per-run logs and screenshots; defaults to `TASK_DIR` unless the wrapper passes a
run-specific directory.
- **TASK SPEC** — the task's full description block (from `implementing.md`), including its design
- **TASK SPEC** — the task's self-contained `task.md`, including its design
basis when the wrapper records one, plus any referenced images (`images/<file>` mockups /
screenshots / graphic resources). Images are optional evidence: read them when present, but their
absence is never by itself a planning, implementation, or test blocker. The spec and its cited
@@ -38,17 +41,20 @@ adapter point; every other rule here still applies.
## State machine (run by the task-runner)
Precondition: the implementation for this task is committed in the current checkout (impl agents
commit; they do not stash). Record that commit's SHA as **IMPL_SHA** — the reset after each test run
returns the checkout to exactly it. The runner tracks the attempt number as its own state (`attempt`
starts at 1); the commit message carries no attempt marker. Commits follow "Commit message" below.
Precondition: the implementation for this task is ready in the current checkout. The performer
stages exact task-owned paths and commits; leaf implementation agents never stage, commit, or stash.
Move `GREEN_REF` to that commit. The runner tracks the attempt number as its own
state (`attempt` starts at 1); the commit message carries no attempt marker.
Never resolve a local task ref into a hash in any artifact or report. Commits
follow "Commit message" below.
```
TEST_AUTHOR -> RUN -> ASSESS (adversarial — see "Assessing"):
APPROVED -> reset to the impl commit (drop overlay); delete the test binary; return DONE up.
APPROVED -> restore overlay paths to GREEN_REF; delete the test binary; return DONE up.
TEST_FLAW -> fix the overlay only; back to RUN. Does NOT cost an impl attempt.
IMPL_BUG -> spawn impl-fix agent (input = test.md, latest attempt's Root cause / Fix hint);
it commits a NEW attempt; re-apply overlay (--3way, else re-author); RUN. attempt++
performer commits a NEW attempt and moves GREEN_REF; re-apply overlay
(--3way, else re-author); RUN. attempt++
UNRECOVERABLE -> delete the test binary; return BLOCKED up with the reason. Stop.
attempt > MAX -> delete the test binary; return BLOCKED up with test.md + "improve" notes. Stop.
@@ -68,26 +74,25 @@ and debugger.
## Handoff tokens
- **Commit** is the only impl handoff. Impl/impl-fix agents `git add -A && git commit` per "Commit
message" below (and, if submodules changed, commit inside each submodule first, then bump the
superproject pointer in the same logical attempt — real commits, never stash). The runner records
the resulting SHA as that attempt's IMPL_SHA.
- **Owned paths plus phase artifacts** are the implementation-leaf handoff. The performer inspects
them, stages only explicit task-owned paths, and commits per "Commit message" below. If an intended
submodule changed, the performer commits inside it first and then stages the superproject pointer
in the same logical attempt. Use real commits, never stash. The performer moves local
`GREEN_REF` to the resulting commit.
- **Test report** (`test.md`) is the only fix-agent handoff. Give it the latest Attempt/Run section,
especially Root cause / Fix hint and Failure signature. Reserve wrapper-owned `result.md` for the
terminal task result; never create `result<n>.md`.
## Commit message
Impl commits must read like the repository's own history — never marked as autonomous. Match the
style of recent `git log` subjects.
Impl commits must read like the repository's own history and carry only the durable task locator.
Match the style of recent `git log` subjects.
- **Subject:** one concise, plain-language line summarizing the change, ≤ ~50-60 characters. This is
usually the ENTIRE message.
- **Body (rare):** only when the subject can't carry it — a short plain-language note of WHAT was
done (user-facing, not the technical how); a line or two at most.
- **No trailers, ever.** No `Autotask:`/attempt marker; no `Co-Authored-By:` or any tool/assistant
attribution line. This explicitly OVERRIDES any harness default that would append one — a freshly
spawned committing sub-agent may add `Co-Authored-By` unless told not to, so pass this rule to it.
The attempt number is the runner's own state, never part of the message.
the first line.
- **Second line:** empty.
- **Third line:** exactly `Task: <TASK_ID>`.
- **Nothing else:** no explanatory body, `Autotask:`, attempt marker, `Co-Authored-By:`, or any
tool/assistant attribution. The attempt number is runner state, never part of the message.
## Test account (portable data) — hard rules
@@ -101,23 +106,30 @@ The debug build runs in portable mode out of `out/Debug/`. Three sibling folders
**SETUP — run at the START of every test run, with NO app instance alive. Idempotent: it
guarantees a clean test account no matter how the previous run ended.**
1. If `TelegramForcePortable` exists AND `real_TelegramForcePortable` does NOT, rename
`TelegramForcePortable` -> `real_TelegramForcePortable`. (Captures the user's real data exactly
once; guarded so it is never overwritten afterward.)
2. If `TelegramForcePortable` still exists, delete it. (Safe: `real_...` now holds the real data, so
this only discards a leftover live/test copy.)
3. Copy `test_TelegramForcePortable` -> `TelegramForcePortable`. The live folder is now a fresh copy
of the golden test account — ready to launch.
1. Require `test_TelegramForcePortable`. Its absence is the only portable-account setup blocker.
2. If `TelegramForcePortable` exists and `real_TelegramForcePortable` does not, rename the live
folder to `real_TelegramForcePortable`.
3. If both `TelegramForcePortable` and `real_TelegramForcePortable` exist, recursively delete the
live folder completely. Do not inspect or require an ownership marker: coexistence means the real
data is already preserved and the live folder is disposable.
4. Deep-copy `test_TelegramForcePortable` to `TelegramForcePortable`. Never rename, modify, or
delete the golden folder.
**CLEANUP — optional, after a run.** The SETUP steps already self-heal, so cleanup exists only to
leave the user's real data live for manual use:
1. Delete `TelegramForcePortable`.
2. Copy `real_TelegramForcePortable` -> `TelegramForcePortable`.
After SETUP, the live folder is always a fresh deep copy of the golden account, the golden folder is
still present, and the real folder may or may not be present. An existing live folder, an existing
real folder, both folders existing, or any missing/extra ownership marker is never a blocker.
Why this is safe: `real_...` is written exactly once (step 1 is guarded by "real does not exist")
and `test_...` is only ever a copy source, so both the user's real data and the golden test account
are structurally protected — only `TelegramForcePortable` is ever destroyed. Use `robocopy /MIR`
(or `Copy-Item -Recurse` / `Remove-Item -Recurse -Force`) for the folder ops.
**CLEANUP — optional, only after SETUP completed successfully.** The SETUP steps already self-heal,
so cleanup exists only to leave the user's real data live for manual use. If SETUP stopped because
the golden folder was missing, do not touch any of the three folders.
1. Recursively delete `TelegramForcePortable` completely.
2. If `real_TelegramForcePortable` exists, move it to `TelegramForcePortable`.
Why this is safe: SETUP preserves the live folder as `real_...` before the first test run, and once
`real_...` exists every live folder is a disposable test copy or the manual-use copy restored from
that same preserved folder by CLEANUP. A skipped or interrupted CLEANUP therefore self-heals on the
next SETUP. Use the platform's recursive copy/move operations only on these exact resolved sibling
paths; never delete `test_...` or `real_...`.
**Serialize app runs.** Never have two `Telegram.exe` instances alive against this account at once —
concurrent reuse of one auth key can trigger a server-side session reset. Before SETUP, launching, or
@@ -156,7 +168,8 @@ writing any overlay:
1. **Read both sides of the task.** (a) The TASK SPEC — its full description, `Design-Basis:` or
equivalent cited sources, and every referenced image when present. (b) The change under test —
`git show <IMPL_SHA>` (the actual diff) and `<TASK_DIR>/plan.md`. List every concrete thing the
`git diff <BASE_REF>..<GREEN_REF>` (the complete task diff) and
`<WORK_DIR>/plan.md`. List every concrete thing the
diff changed and every surface the task (description + "Observable result") says it affects.
The diff proves what shipped; it is not independent authority for what the design should be.
2. **Turn each into a falsifiable check with an ORACLE** — something that can come out FAIL. A check
@@ -169,7 +182,7 @@ writing any overlay:
judging the render. For an exact asset replacement, verify any expressly required source-file
identity/equality, then render the intended and old files and compare both with the tight crop.
Without target artwork, use the exact task criteria,
`<TASK_DIR>/visual.md`, cited current/legacy analogues, style-token or resource identity, and
`<WORK_DIR>/visual.md`, cited current/legacy analogues, style-token or resource identity, and
the pre-task baseline. Confirm a baseline delta whenever the task requires one. **If the target
still matches the old state when a change is expected, that is a FAIL, not a pass.** A
`Visual: layout` task must also satisfy every numeric design-contract line (sizes, spacings,
@@ -179,14 +192,14 @@ writing any overlay:
3. **Cover every surface the task names.** If the Observable result lists a settings row, a balance
header, a gift field, and a suggestion bar, each must be observed (or explicitly marked N/A with
a reason). Do not stop at one or two.
4. **Write the checks into `<TASK_DIR>/test.md` BEFORE running** (format under "Test report"), so the
4. **Write the checks into `<WORK_DIR>/test.md` BEFORE running** (format under "Test report"), so the
design is explicit and Actual/Result can be filled in per check afterward.
## Visual contract (layout tasks)
When the wrapper marks a task `Visual: layout`, "looks right" is not a vibe — it is a small
computation, and the test MEASURES it. The wrapper's design-spec phase writes the contract to
`<TASK_DIR>/visual.md`; impl builds to it; this loop verifies it. (Tasks marked `Visual: appearance`
`<WORK_DIR>/visual.md`; impl builds to it; this loop verifies it. (Tasks marked `Visual: appearance`
use the ordinary visual/asset check above. Unmarked non-visual tasks use their applicable text or
behavior checks; only legacy unclassified visual changes use the visual/asset branch.)
@@ -305,13 +318,14 @@ actually land; likewise for screenshots.
### Git mechanics for the overlay (no stash)
- After building, save the overlay as a patch: `git diff > <TASK_DIR>/test-overlay.patch`.
Then **reset the checkout back to the implementation commit** so it stays impl-only:
`git reset --hard <IMPL_SHA>` (and `git submodule update --init --recursive` if the overlay
touched submodules). The overlay never enters an impl commit.
- Before authoring, inventory every tracked overlay path in `<WORK_DIR>/test-overlay.paths`; no
unrelated or untracked source path may be used. After building, save the overlay with
`git diff --binary HEAD > <WORK_DIR>/test-overlay.patch` and verify the patch is nonempty and
reapplicable. Restore only the inventoried overlay paths to `GREEN_REF`; never hard-reset the
repository. The overlay never enters an impl commit.
- Next round, re-apply on top of the new implementation: `git apply --3way
<TASK_DIR>/test-overlay.patch`. This succeeds ~90% of the time when the tail change was small.
- On conflict, **re-author the conflicting hunk from the latest Attempt/Run in `test.md`** (which
<WORK_DIR>/test-overlay.patch`. This succeeds ~90% of the time when the tail change was small.
- On conflict, **re-author the conflicting hunk from the latest Attempt/Run in `<WORK_DIR>/test.md`** (which
records injection point, fake values, and assertions) rather than fighting conflict markers.
Scenario steps that only call public APIs should live in their own block so they never conflict;
only true in-situ injections land inside impl files.
@@ -334,8 +348,8 @@ actually land; likewise for screenshots.
`<EVIDENCE_DIR>/test_log.txt` every ~5s -> on each `SCREENSHOT:` read the image and judge it -> detect
`TEST_COMPLETE` (success) or process death (crash) or no new output for the watchdog cap, or the
hard deadline elapsing (hang) -> path-scoped kill of any straggler (Test account → "Serialize app
runs") -> optional CLEANUP -> save the overlay (`git diff > <TASK_DIR>/test-overlay.patch`) ->
THEN `git reset --hard <IMPL_SHA>` (back to impl-only — the patch must be saved before this reset).
runs") -> optional CLEANUP -> save the binary overlay patch -> restore only inventoried overlay
paths to `GREEN_REF` (the patch must be saved before this restore).
On Windows, launch and capture both streams like:
@@ -406,10 +420,10 @@ the same signature → BLOCKED (early-escalation rule).
### Leave no test binary behind
The on-disk `EXE` (`out/Debug/Telegram.exe`) always contains the compiled overlay after a test run
`git reset --hard` only reverts the source, not the built binary. So when the loop reaches a TERMINAL
verdict (APPROVED, BLOCKED, UNRECOVERABLE, or attempt cap), after the final path-scoped kill and
`git reset --hard <IMPL_SHA>`, **delete the built `EXE`** so no overlay-laden test binary is left for
The on-disk `EXE` (`out/Debug/Telegram.exe`) always contains the compiled overlay after a test run.
Restoring source does not rewrite the binary. When the loop reaches a TERMINAL verdict (APPROVED,
BLOCKED, UNRECOVERABLE, or attempt cap), after the final path-scoped kill and exact-path source
restore, **delete the built `EXE`** so no overlay-laden test binary is left for
the user to launch by mistake:
Remove-Item -Force "$EXE"
@@ -443,7 +457,7 @@ correct.
- APPROVED requires every derived check to PASS with evidence; else IMPL_BUG (real defect) or
TEST_FLAW (the test was wrong, not the code).
## Test report (`<TASK_DIR>/test.md`) — human-readable, append per attempt
## Test report (`<WORK_DIR>/test.md`) — human-readable, append per attempt
The file the human opens to see how testing went. The test-author writes checks before running;
ASSESS fills Actual / Result and the verdict. Create one `## Attempt` per implementation commit and
@@ -453,7 +467,7 @@ starts the next Attempt. Never overwrite history.
```
# Test report — <project>/<letter>: <title>
## Attempt <n> — commit <sha>
## Attempt <n>
### Run <m> — strategy <...> — driver <overlay|hybrid> — verdict <APPROVED|TEST_FLAW|IMPL_BUG|UNRECOVERABLE>
- Evidence directory: <EVIDENCE_DIR>
@@ -487,4 +501,4 @@ DISCOVERED: <none|present in result.md|inline concise follow-ups when the wrappe
NOTES: <one or two lines, or none>
```
Detailed reasoning stays in `.ai/` artifacts. The chat reply is only this block.
Detailed reasoning stays in external AI task artifacts. The chat reply is only this block.
+212
View File
@@ -0,0 +1,212 @@
---
name: continue
description: Continue autonomous Telegram Desktop development from the shared ai-tdesktop repository. Use when the user invokes $continue or /continue, asks Codex to keep working through the AI queue, or wants one command to process the local inbox, resume this checkout's active task, consume its claimed queue, and claim new work until nothing eligible remains.
---
# Continue AI Work
Act as the checkout-level scheduler. Keep looping until the inbox is empty and
no eligible work remains. Delegate inbox planning and one-task execution; do not
plan or implement Telegram changes in this scheduler session.
This is the default development command and the successor to the old `task` and
`implement` workflows. Inbox processing owns request splitting and project
routing; `perform-task` owns all mature context, planning, implementation,
review, Debug build, test-loop, evidence, and publication behavior.
## Resolve the workspace
Run from a Telegram Desktop checkout. Read `AGENTS.md`, then use the shared
helper with the host's Python 3 command:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py queue
```
Use `python` or `py -3` when appropriate. Save `checkout_tag`, `ai_main`,
`slot_worktree`, and `source_root` from its JSON. Read `ai_main/AGENTS.md`.
Stop before mutating anything when `violations` is nonempty, AI master is
dirty, or the AI slot has changes outside its one active task. Never clean,
stash, reset, or absorb unrelated changes. Unpublished AI slot commits are
resumable state: retry the helper's `publish` command before selecting new
work.
`status` and `claimed_by` are orthogonal:
- `todo` plus `claimed_by: null` is shared unreserved work;
- `todo` plus this `checkout_tag` is this checkout's reserved queue;
- `in-progress` plus this tag is the one active task;
- `approved` and `blocked` are terminal;
- work claimed by another checkout is invisible to this scheduler.
Do not infer a claim from who processed an inbox receipt. Do not steal or
expire another checkout's claim.
## Interpret scope hints
Treat the invoking request after `$continue` or `/continue` as optional natural
language scheduling guidance, not a required command grammar.
A plain invocation claims one shared task at a time. This minimizes abandoned
reservations and lets parallel checkouts distribute the backlog.
When the user expressly asks to reserve or claim a group, claim the matching
ordered set in one operation. Common scopes include:
- all tasks created from the inbox receipt processed by this invocation;
- all unclaimed tasks for a named project;
- an explicit list of friendly titles or task identifiers.
Preserve receipt order, project index order, or explicit user order when one is
available; otherwise use creation date and task identifier. A batch receives
one `claimed_at` value and ascending `claim_order`. Dependencies do not prevent
reservation, but they do prevent a task from starting.
Scope hints filter new claims only. Always resume this checkout's existing
`in-progress` task and then its already claimed queue before taking more shared
work, unless the user explicitly asks to stop or reassign them.
## Main loop
Repeat these steps. Refresh queue JSON after every delegated operation and
state transition; do not rely on a stale snapshot.
### 1. Process the inbox
When `inbox_nonempty` is true, spawn one inbox worker with `fork_turns: "none"`.
Give it the source checkout path and instruct it to read and use
`.agents/skills/process-inbox/SKILL.md` completely. It owns exactly one inbox
transaction, may use the bounded planner delegation required by that skill,
must not implement tasks, and must return the receipt and created task ids.
Wait in intervals no longer than 60 seconds. A timeout is not failure. Inspect
the saved target after every wake and validate the receipt plus refreshed queue
before proceeding. Never launch a second inbox worker for the same transaction.
If inbox processing cannot publish durable AI state, stop. The inbox skill must
leave the input or active transaction recoverable.
### 2. Resume active work
If this checkout has an `in-progress` task, select it. There must be at most
one. Spawn one stateful performer as described below.
### 3. Start reserved work
Otherwise select the first ready task in this checkout's claimed `todo` queue.
Readiness means every `depends_on` task is `approved`. Transition it atomically:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py start \
--task <YYYY/MM/DD/slug>
```
Then spawn its performer. Leave claimed tasks with unfinished prerequisites as
`todo` and consider later ready tasks.
### 4. Claim shared work
Otherwise inspect unclaimed `todo` work matching the scope. For a plain
invocation select only the first ready task. For an explicit batch reservation,
reserve every matching task in the chosen order, including later tasks whose
dependencies are not approved yet, and pass one `--task` argument per task:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py claim \
--task <first-id> \
--task <second-id>
```
The claim is committed and published before source work starts. Refresh the
queue; then return to step 3. A publish race may mean another checkout won the
task. Do not resolve that by overwriting shared state; refresh and choose again.
### 5. Stop normally
Stop when the inbox is empty and none of these exist:
- this checkout's active task;
- a ready task in this checkout's claimed queue;
- a ready unclaimed task for a plain run, or any unclaimed task matching an
explicit batch-reservation scope.
Claimed tasks belonging to other checkouts do not keep this run alive.
Claimed tasks waiting on prerequisites remain visible in the final summary but
do not cause a busy loop.
## Spawn one performer
Spawn exactly one performer for the selected task with `fork_turns: "none"` and
a unique tool-valid name. Tell it:
```text
Use .agents/skills/perform-task/SKILL.md completely.
Source checkout: <source_root>
AI slot worktree: <slot_worktree>
Checkout tag: <checkout_tag>
Task: <task-id>
Own this task until it reaches approved or blocked. You may use the bounded
leaf delegation required by the skill. Do not select or claim another task.
```
The performer is stateful. Never duplicate it. Poll at no more than 60-second
intervals, distinguish progress from completion using its task artifacts, and
send a follow-up to the same target if it becomes idle without a terminal state.
After it returns, require:
- source checkout clean and at the performer's retained commit;
- task `state.yaml` terminal and published to AI master; or
- a clearly reported global hard stop that makes further work unsafe.
A clean terminal `blocked` task does not stop the scheduler; continue with
independent work. A dirty checkout, file-lock build failure, missing test
account, unresolved AI publication conflict, or other global environment
failure stops the loop.
The missing `test_TelegramForcePortable` golden account is the only
portable-folder state that is a global stop. Live and real portable folders
coexisting, either one being absent, or any ownership-marker state must be
reconciled by `perform-task` according to the shared test-loop protocol and
must never stop `/continue`.
## Route discovered follow-ups
After every terminal performer, read its published `work/result.md`. If it says
`Discovered: present` and has no `work/discovered-routed.md`, route the complete
blocks under `## Discovered tasks` before selecting more shared work.
Spawn one disposable routing worker with `fork_turns: "none"`. Tell it to read
the routing, splitting, task-path, artifact, validation, and publication rules
in `.agents/skills/process-inbox/SKILL.md`, but not to call `prepare`,
`finalize`, or `abort`: its immutable input is the published result, not the
human inbox. It must not edit Telegram source, claim, or implement work.
The worker must:
1. deduplicate against existing tasks and discovery receipts;
2. preserve each independently testable follow-up, its provenance, and valid
dependencies;
3. create dated unclaimed `todo` tasks and any justified project/index updates;
4. create `receipts/YYYY/MM/DD/discovered-<source-slug>.md` mapping every block;
5. write the source task's `work/discovered-routed.md` with the receipt, new or
reused task ids;
6. stage only those explicit paths, commit with
`Route follow-ups from <source-task-id>`, then run the workspace helper's
`publish` command.
The worker must retry an ordinary concurrent-master race using the helper. A
semantic conflict or unavailable remote preserves the slot commit and stops
the scheduler. The routing marker makes later `/continue` runs idempotent.
Refresh queue JSON after routing, then resume the main loop.
## Report
Return one compact run summary: inbox receipt if processed, tasks approved,
tasks blocked with exact unverified behavior, tasks newly claimed or left
queued, routed discoveries, elapsed time, and why the loop stopped. Make any
global hard stop, retained unsafe state, or incomplete verification visually
unmistakable. The human should not need to invoke another command merely to
advance to the next eligible task. Never include source or AI commit hashes;
task ids are the only durable locators.
@@ -0,0 +1,4 @@
interface:
display_name: "Continue AI Work"
short_description: "Drain the shared Telegram AI work queue"
default_prompt: "Use $continue to process the inbox and continue queued Telegram Desktop work."
-499
View File
@@ -1,499 +0,0 @@
---
name: implement
description: Autonomously implement and verify Telegram Desktop changes from an inline request, task-list path, or a prepared project task source under .ai, with or without mockups. Use when Codex should split work into independently testable tasks and drive each through context, planning, implementation, a Debug build, one review pass, artifact-grounded in-app testing with optional Computer Use, resumable artifacts, a lean parent task, and native-Windows CRLF normalization.
---
# Implement Pipeline
You are the top orchestrator. Normalize an inline description or task-list file into a project with
a testability-split task list, then drive each task to test-approval through an isolated per-task
**task-runner**. Keep only the task list and one compact summary per task in the parent. Heavy work
happens in the disposable runner and, when nested delegation is available, fresh leaf phase agents.
This tested superset of `task-think` does not re-specify the implementation phases or the test
loop. Read and reuse:
- `.agents/skills/task-think/PROMPTS.md` — Phase 0-6 prompt templates and the Codex execution-mode
/ wait-ladder / progress-heartbeat / compact-reply rules.
- `.agents/shared/test-loop.md` — the harness-neutral impl⇄test loop (state machine, handoff,
overlay, account swap, watchdog); `references/computer-use-testing.md` adds a Codex-only UI driver.
### Input sufficiency and visual evidence
Treat the task description and repository as sufficient. Visual references are optional unless expressly required; absence alone never causes a stop, question, malformed task, or block.
Use, in order: request facts; supplied references; adjacent UI/code/styles and baseline; repository
history/legacy; then the closest desktop convention and smallest common-sense change. Record
assumptions; never invent a reference. Block only for expressly required exact content or bytes that
cannot be recovered, and continue every independent task.
## Inputs
Set `REQUEST` to the invoking user text, including attached-image references; skills do not receive
the deprecated custom-prompt `$ARGUMENTS` macro. `REQUEST` is one of:
- an inline task description (e.g. `add a dark-mode toggle to settings`)
- a path to a task-list file (e.g. `.ai/communities/tasks.txt` -- a rough list of tasks to refine)
- an existing project name to resume, optionally followed by extra work
- **just a project name with a prepared `.ai/<project>/tasks/about.md`** -- the default task source.
With no other input, `implement <project>` runs it (see Artifacts).
## Config
Run in the **current checkout** without creating a worktree. Resolve platform, build tree, command,
and executable together; never mix native-Windows commands with a WSL tree.
```
NATIVE_WINDOWS_BUILD = cmake --build ./out --config Debug --target Telegram
WSL_BUILD = Telegram/build/docker/centos_env/build_debug.sh
EXE_CANDIDATES = out/Debug/Telegram.exe | out/Debug/Telegram | out/Debug/Telegram.app/Contents/MacOS/Telegram
COMPUTER_USE_APP_TARGET = Windows: absolute EXE | macOS: absolute outer .app containing EXE | other: none unless supported
TEST_ACCOUNT = out/Debug/test_TelegramForcePortable
MAX_ATTEMPTS = 4
MAX_TEST_RUNS = 12
COMPUTER_USE_POLICY = auto | overlay-only | required (default auto; user request overrides)
SUBAGENT_QUALITY = inherit the parent task's selected model and reasoning effort
```
Follow `AGENTS.md` if it names a different command. Build Debug only. Verify `EXE` from the actual
tree. Scope proactive cleanup to its resolved full path; never kill processes by image name.
The test binary is **always launched with `-testagent`** (test-loop.md "Crashes & assertions"). It
suppresses modal assertion dialogs, turns assertions and a frozen main thread into a crash with a
`tdata/working` report, and writes assertion text to captured stderr. Detect crashes from the report,
not the exit code.
Keep the parent model/reasoning selection for all subagents; a GPT-5.6 Sol Ultra parent therefore
keeps that quality. Do not invent model, reasoning, or role fields missing from `spawn_agent`. If a
host exposes overrides, match the parent. Custom agents use `model_reasoning_effort`.
### Codex collaboration contract
- Use `spawn_agent` with a unique lowercase/digit/underscore `task_name`; save its canonical target.
- Use `fork_turns: "none"` with self-contained prompts; fork minimal turns only for thread-only context.
- The top orchestrator spawns the task-runner; the runner selects NESTED only after its first real
phase-leaf spawn succeeds. An immediate depth/capacity/policy rejection before phase work selects
SAME-RUNNER; then execute the same prompt checklists locally. Never switch modes for a wait timeout.
- Every delegated planner or phase worker is a leaf and must not spawn more agents, especially under
Ultra's proactive delegation. Keep implementation phases sequential unless their plan proves
disjoint write sets and the current checkout has safe capacity.
- `wait_agent` can wake for any agent or new user input, not just the intended target. After every
wake, inspect the saved target with `list_agents` and validate its artifact. Follow the detailed
wait/retry contract in `task-think/PROMPTS.md`.
- Never duplicate a task-runner. It owns stateful writes, commits, and test attempts.
Tasks run **sequentially** in this one checkout (the build cache stays warm; app runs must serialize
against the account anyway). To parallelize, run the skill in a different checkout/slot (e.g.
`C:\Telegram\tdesktop`, `D:\Telegram\tdesktop`, `D:\Telegram\twin`). Each run is independent and
single-tree. Never run the **test phase** in two slots against the same account at once; concurrent
clients on one auth key can trigger a session reset, so give parallel slots separate test accounts.
## Artifacts (per project)
- `.ai/<project>/tasks/about.md` — the **default task source**: a human-prepared description or rough
list, with optional mockups beside it. The planner reads it for `implement <project>`. It is distinct
from the project blueprint `.ai/<project>/about.md`
(the `tasks/` subdir is what disambiguates them).
- `.ai/<project>/implementing.md` — the canonical, final, testability-split task list. The planner
creates or rewrites it in Phase B; after the main thread adopts it, only the main thread edits it.
- `.ai/<project>/images/` — illustrations referenced by tasks (`images/01.png`, ...).
- `.ai/<project>/<letter>/` — task context, plan, visual contract, review, test, result, overlay, logs.
- `.ai/<project>/about.md` — project blueprint (task-think convention).
## Terminal state and Goal mode
The pipeline is terminal when every task is `approved` or `blocked: <reason>`, but successful only
when all are approved. A blocked task is a loud terminal result, not goal achievement.
If a Goal mode objective is active, do not create or replace it. Complete it only when every task is
approved; use blocked-state rules only when their threshold is satisfied. Reinvocation continues
`todo` or `in-progress` tasks; a blocked task stays terminal until explicitly requeued or replaced.
## Phase A: Setup & input resolution (main thread)
1. Record `START_TIME` with the host's current-time facility.
2. Detect native Windows vs WSL/Linux vs macOS/other; read `AGENTS.md`; resolve `BUILD`, `EXE`,
`TEST_ACCOUNT`, `COMPUTER_USE_APP_TARGET`, `COMPUTER_USE_POLICY`, and the active Computer Use
skill path (or `none`). On macOS require EXE to realpath under `<target>.app/Contents/MacOS/`, never
use the inner binary as the app target. Strip only a driver-policy directive from `REQUEST`. On WSL use Docker
and LF/no-BOM; on native Windows use the configured Debug tree and later CRLF phase.
Verify path-scoped process control, safe folder ops, launch/capture, and a usable app-run display
(WSLg/Xvfb counts) or stop. Never build Release; Computer Use capability is separate and optional.
3. **Test-account gate (hard precondition — before planning or implementation).** If
`out/Debug/test_TelegramForcePortable` does not exist, STOP the entire skill immediately and tell
the user that the test account is not prepared: create `out/Debug/test_TelegramForcePortable`
(a portable-data folder authed to a throwaway test account) before `implement` can run, because
autonomous testing is impossible without it. Do no implementation work.
4. **Clean-checkout gate.** Require a clean tracked worktree and clean submodules before the first
planner or runner spawn. Ignored `.ai/` artifacts are allowed. If unrelated tracked, staged,
untracked, or submodule changes exist, stop without stashing, committing, or resetting them.
Record `BASE_SHA`; invocation authorizes destructive resets only for changes proven to belong to
this workflow.
5. **Resolve `REQUEST` into (project, SOURCE, mode) — without reading task files or images.**
The main thread never loads task prose or assets; resolving needs only paths and existence checks.
SOURCE ends as EITHER inline text OR a confirmed file path that the planner will read.
- **File input** — if `REQUEST` as a whole or its first quoted token resolves to an existing path,
confirm existence without reading it and set SOURCE to that path. If it is under `.ai/<name>/`,
project = `<name>`; otherwise derive a short kebab name from the filename. Mode = **extend** if
that project already has `implementing.md`, else new.
- **Existing project** — else if `.ai/<FIRST_TOKEN>/` exists: project = `FIRST_TOKEN`.
- If there is a **remainder**: if it is a path to an existing file, SOURCE = that path (confirm
it exists, do NOT read it); otherwise SOURCE = the remainder text. Mode = **extend** only when
`implementing.md` exists; otherwise mode = **new** within this existing project directory.
- If the remainder is **empty**, resolve SOURCE in this priority order (existence checks only,
do NOT read):
1. If `.ai/<project>/tasks/about.md` exists → SOURCE = that file (the **default task
source**); mode = **extend** if `implementing.md` already exists, else **new**. This is the
`implement <project>` with a prepared task source path — it fires the full pipeline.
2. Else if `implementing.md` exists → mode = **resume** (no SOURCE; Phase C finishes the
still-unfinished tasks).
3. Else there is nothing to implement — tell the user to prepare `.ai/<project>/tasks/about.md`
(or pass a description / task-file path) and stop.
- **New inline** — else SOURCE = all of `REQUEST`; pick a unique short kebab-case project name
after consulting `.ai/`.
After this step you always have a project name and either a SOURCE (inline text or a confirmed
path) or mode = **resume** — and you have read neither the file nor any image.
Set `FIRST_TASK_ID` after a narrow heading scan to the next id after the union of task headings
in `implementing.md` and artifact directories (`a`...`z`, `aa`...); never reuse an id.
6. Create `.ai/<project>/` and `.ai/<project>/images/` if new.
7. **Persist supplied visual inputs when present.** Prefer SOURCE or project images. For a chat-only
attachment, fork the smallest necessary turn window and persist its description; ask for an
on-disk copy only when exact unavailable bytes are required. With no image, continue normally.
Never claim a chat-only image was saved; the planner copies filesystem-visible references.
8. If mode = **resume**, skip Phase B and go to Phase C.
## Phase B: Planning & testability split (delegate)
Spawn one planner with a unique tool-valid task name and `fork_turns: "none"`, except for the
smallest recent-turn fork explicitly selected in Phase A for a chat-only visual. It inherits the
parent quality setting and is a leaf: it must not delegate. Use this prompt shape:
```
You are a planning/splitting agent for a large C++ codebase (Telegram Desktop).
You are a leaf worker. Do not spawn or delegate to other agents.
SOURCE — EITHER an inline request OR a path to a task-list file. If it is a PATH, READ it yourself
(and any task files it points to); the main thread has NOT read it. If it is inline text, use it as
the request:
<the inline description, or the file path>
PROJECT: <project> MODE: <new | extend> FIRST_TASK_ID: <next unused id>
IMAGES (optional) — resolve SOURCE-referenced paths relative to its directory; siblings of
`.ai/<project>/tasks/about.md` are candidates. READ each referenced image, COPY it into
`.ai/<project>/images/` with a descriptive name, and attach it to every pertinent task. The main
thread did not read or move it. Treat a chat-only textual description as visual evidence:
<description(s) or none>. With none, continue from the request and repository; never ask for a
mockup or weaken, omit, or block a visual task solely for lacking optional references. The express
exact-content exception in "Input sufficiency and visual evidence" still applies.
Read AGENTS.md. Briefly scan the codebase to gauge scope. Produce the FINAL ordered task list that
satisfies BOTH constraints for every task:
- **Implementable in one pass**: a fresh implementation agent must be able to complete the task with
comfortable context headroom and without relying on compaction — a bounded change across a
handful of related files, not a sweep across dozens. If a unit is too big, split it.
- **Independently testable**: each task must yield an observable behavior the test agent can drive
from an in-app debug overlay and verify via log/screenshot. Split on testable seams, so each task
ends at a point where something concrete can be exercised and checked.
Use the minimal number of tasks subject to both constraints; preserve dependency order (a task comes
before any task that depends on it). If the SOURCE is already a list, respect its intended breakdown
and refine only as needed: split entries that are too big or not independently testable; you may
merge trivially tiny adjacent entries if the result is still one testable unit.
Write `.ai/<project>/implementing.md` in EXACTLY this format:
# Implementing: <project>
## Goal
<one-line overall goal>
## Tasks
### <FIRST_TASK_ID>: <imperative title>
Status: todo
<2-4 line self-contained description: what to implement and the observable, testable result. Enough
that a fresh agent can act on it.>
Depends-On: none | <comma-separated earlier task ids>
Observable: <specific runtime evidence that proves this task works>
Visual: layout | appearance (user-visible visual/asset changes only; omit otherwise)
Design-Basis: <ordered request/image/current/legacy/repository evidence and assumptions; visual tasks only>
Images: images/<file> — <caption> (this line only if the task uses an image)
### <next id>: <imperative title>
Status: todo
<...>
**Images per task (required when supplied).** Attach every pertinent supplied image via `Images:`,
with a precise caption, and account for unused ones. With none on a visual task, omit `Images:`, cite
non-image evidence in `Design-Basis:`, and never create a placeholder. Non-visual tasks omit both.
**Visual classification (required for visual/asset changes).** For every task that changes how
user-visible UI, rendered output, or an asset looks, add `Visual:`; it routes the task-runner:
- `Visual: layout` — reproduce composition: element sizes, proportions, spacing, margins,
alignment, or component geometry. This triggers a dedicated design-spec phase and a
geometry-measuring oracle whether or not a mockup exists.
- `Visual: appearance` — match color, wording, style choice, or glyph identity without changing
proportions or geometry. This uses the lighter visual comparison without a numeric contract.
- Omit `Visual:` only when the task changes no appearance.
Classify from the requested change, never from reference availability. When uncertain, use `layout`
for anything composed from multiple sized or positioned pieces. The user may override the line.
Every task must include `Depends-On:` and `Observable:`. Dependencies may name only earlier tasks.
Use `Depends-On: none` when the task can still run after any earlier task is blocked. The observable
must name the exact log value, action/state transition, or tightly framed visual evidence the test
will verify; "screen opens" is not sufficient. Every task with `Visual:` must also include a
`Design-Basis:`; supplied images are one possible basis, not a prerequisite.
Use spreadsheet-style ids a...z, aa... without reusing an existing task artifact id. Do not plan internals or implement. When done, reply with ONLY a
compact confirmation — `ready — <N> tasks` (extend: `ready — appended <letters>`); do NOT echo the
task list or image contents back, the main thread reads `implementing.md` itself.
```
For **extend** mode, instead instruct the planner to FIRST read the existing `implementing.md`, then
rewrite it as: (1) a TRIMMED completed-history — keep only the **three most recent** `Status: approved`
task blocks (the three nearest the bottom of the file) and drop all earlier approved ones; (2) every
still-unfinished task left untouched, in place and with its status — that is all `todo`, `in-progress`,
and `blocked` blocks (never drop these); then (3) APPEND new tasks starting at FIRST_TASK_ID after
them. FIRST_TASK_ID follows the pre-trim task-heading/artifact union. The trim only removes
already-approved entries from the list — it never touches the per-task `.ai/<project>/<letter>/`
artifacts on disk, so a follow-up letter can still read an earlier letter's `context.md` even after its
block was trimmed out of `implementing.md`. It must append only work from SOURCE not already
represented either in `implementing.md` or in the preserved per-task `context.md`, `result.md`, and
test artifacts. Deduplication must include trimmed history, so re-running `implement <project>`
against an unchanged default `tasks/about.md` appends nothing (the planner replies
`ready — appended (none)`, still applying the completed-history trim). Any
`todo`/`in-progress` leftovers from an interrupted run are picked up by Phase C regardless, so
defaulting to extend never loses an in-flight batch; it is a superset of resume.
After the planner replies `ready`, read `implementing.md` once (the first and only load of task
prose; never read images) and initialize a progress list mirroring the tasks.
For **resume**, read and validate `implementing.md` once here before Phase C and initialize the same
progress list. Treat any status line beginning with `Status: approved` or `Status: blocked` as the
corresponding legacy terminal state, then normalize it to the canonical grammar the next time the
main thread edits that block. For a legacy unfinished block without `Depends-On:` or `Observable:`,
assume `Depends-On: none` and use its self-contained result sentence as the observable rather than
blocking resume on a format migration.
## Phase C: Per-task loop (main thread orchestrates)
For each task whose normalized `Status` is neither `approved` nor `blocked`, in order:
1. If any id in `Depends-On:` is blocked, do not spawn a runner. Set
`Status: blocked: prerequisite <ids> blocked`, record the missing behavior, and continue to the
next independent task. The main thread creates its canonical `result.md` with `STATUS: BLOCKED`,
`Blocker-Type: impl`, HEAD as base, no implementation/test, and prerequisite results as evidence.
2. Record `TASK_BASE_SHA = HEAD`, set `Status: in-progress`, and mark the progress item in progress.
Spawn exactly one **task-runner** with a unique task name and `fork_turns: "none"`, using the
prompt below. It inherits the parent model and reasoning selection.
3. Poll with waits no longer than 60 seconds. Each wake may belong to another agent or user input;
check the runner's canonical target and its progress/result artifacts. Use `send_message` while
it is running and `followup_task` if it is idle but owes the final result. Never fresh-retry the
whole runner. If it becomes irrecoverably unresponsive, interrupt it, audit the checkout and
artifacts, and classify the task as blocked only if the tree is clean and buildable; otherwise
hard-stop.
4. Validate `<TASK_DIR>/result.md`, its referenced commit, `test.md` when applicable, cleanup state,
and a clean worktree. The compact reply is a notification, not proof. Update the canonical task
status to `approved` only for a validated `STATUS: DONE`; otherwise write
`blocked: <specific reason>`.
5. When `Discovered: present`, accept ordered blocks headed `discovered-1`, `discovered-2`, etc. Rescan
current task headings and artifact dirs, assign unused spreadsheet ids, and rewrite earlier placeholder
dependencies before appending. Reject collisions/forward dependencies; send malformed blocks through a leaf planner. Only the main thread assigns ids and writes
`implementing.md` after Phase B.
6. On BLOCKED, **do NOT stop the loop — prioritize continuing development.** This often runs
unattended for hours, so NEVER pause to ask the user whether to go on; record the blocker and
move to the next task as long as further progress is possible:
- **Test-blocked** — the runner committed a building impl and only its in-app verification could
not complete (a harness limit, or the attempt cap hit on a test flaw, not a real bug). The code
is on disk, so CONTINUE; capture EXACTLY what was left unverified for the loud final report.
- **Impl-blocked but checkout clean** — no green impl for this task, but HEAD is left at a prior
committed, buildable commit. CONTINUE — later tasks may be independent; record the missing
behavior.
- **Hard stop ONLY when continuing is truly impossible** — a broken / uncommitted / non-buildable
checkout, or a global environment failure (file lock needing the user to close `Telegram.exe`,
the test-account gate). Only then stop and report.
Before spawning the next task, confirm the tree is clean and HEAD is a known buildable commit.
Never reset an unexpected or unrelated path. If the runner cannot prove and restore only its own
changes to a known-good SHA, hard-stop. Every blocked/unverified task must be surfaced loudly in
Completion with its exact `<TASK_DIR>/test.md` or `<TASK_DIR>/result.md` path.
### task-runner prompt
````
You are a task-runner for ONE task in an autonomous implement-and-test workflow on Telegram
Desktop (C++ / Qt). You own this stateful task end to end; no second runner may operate on it.
Inherit the parent model and reasoning setting. At startup, select one execution mode for the task:
- NESTED: choose only after the first real phase-leaf spawn succeeds. Give every leaf a unique
tool-valid name, `fork_turns: "none"`, and an instruction not to delegate.
- SAME-RUNNER: choose if that first spawn is immediately rejected by depth, capacity, or policy;
execute the same task-think prompts as strict checklists. This is not degraded failure.
After selection, do not switch modes merely because a wait timed out.
PROJECT: <project> TASK: <letter> — <title>
TASK DESCRIPTION:
<the task's full description block from implementing.md>
IMAGES: <referenced .ai/<project>/images/* paths, or none — Read them if present>
TASK_DIR: .ai/<project>/<letter>/ TASK_ID: <project>-<letter>
TASK_BASE_SHA: <HEAD before this runner was spawned>
HOST_KIND: <native-windows | wsl-linux | macos | other>
Config: BUILD=<value>; EXE=<absolute executable>; COMPUTER_USE_APP_TARGET=<absolute outer .app | absolute Windows EXE | none>; MAX_ATTEMPTS/MAX_TEST_RUNS=<values>; COMPUTER_USE_POLICY=<value>; COMPUTER_USE_SKILL=<active path | none>.
Read first: AGENTS.md; REVIEW.md; `.agents/skills/task-think/PROMPTS.md` (Phase 1-6 templates +
execution rules); `.agents/shared/test-loop.md` (testing). Read any IMAGES listed above. For a
follow-up letter, also read `.ai/<project>/about.md` and the nearest earlier task `context.md` that
exists; prerequisite-blocked tasks may have none. Within
task-think instructions, "main/current session" means this runner, not the orchestrator.
Treat `IMAGES: none` as normal; missing mockups alone never justify pausing, blocking, or asking.
Create `<TASK_DIR>/` and `<TASK_DIR>/logs/`. Maintain
`<TASK_DIR>/logs/task-runner.progress.md` at phase boundaries so the orchestrator can distinguish a
long phase from a stalled runner.
This wrapper overrides shared commit ownership: leaf workers never commit; the runner stages exact
owned paths and commits without `git add -A`. Safety rules below replace conflicting generic reset,
account, and file-lock mechanics.
Pipeline for THIS task only, writing prompt/progress/result logs per task-think:
1. CONTEXT — use Phase 1F whenever earlier project context exists, including the first
`implementing.md` batch in an older task-think project; otherwise use Phase 1. Preserve the
current `about.md` if present, then let the
context phase write its future-looking blueprint, then move that new file to
`<TASK_DIR>/about.proposed.md` and restore the prior project blueprint (or leave it absent for a
new project). Current downstream phases use context.md, not the proposed blueprint. Promote
about.proposed.md to the project `about.md` only after this task is approved; a blocked task must
not make future follow-ups believe missing behavior exists.
1b. DESIGN-SPEC — only for `Visual: layout`. Inventory `Design-Basis:`: read supplied images, if any,
then inspect current/legacy implementations and closest desktop widgets/style tokens. Write
`<TASK_DIR>/visual.md` with cited evidence, assumptions, and test-loop.md's ordered derivation. Ground
every dimension in a font metric, style token, sibling geometry, or explicit request
relationship, with a tolerance. With no mockup, use repository anchors and proceed. Skip for
appearance-only and non-visual tasks.
2. PLAN — Phase 2 -> plan.md. For layout work, derive all style metrics from visual.md.
3. ASSESS — Phase 3.
4. IMPLEMENT— Phase 4, sequentially, one leaf worker per plan phase in NESTED mode. Give layout
workers visual.md and require exact contract compliance. Implementation and later impl-fix
workers edit and report; they do NOT commit. You own every commit boundary.
5. BUILD — Phase 5, using the resolved BUILD. Proactively stop only a straggler whose executable
path exactly equals EXE before building. If the build itself reports C1041, LNK1104, a locked
output, access denied, or file in use, AGENTS.md wins: do not retry or use a workaround. Return a
global hard-stop asking the user to close this checkout's app/debugger.
6. REVIEW — Phase 6 but a SINGLE pass: one 6a, then one 6b if NEEDS_CHANGES, followed by a build.
Give the reviewer visual.md for layout work so contract violations are review findings.
6b. NORMALIZE — on native Windows only, run task-think Phase 7 on the exact task-owned source/config
paths after the last review edit and before the implementation commit. Then run one final BUILD
so the bytes about to be committed are the bytes verified. For every later impl-fix attempt,
normalize its exact touched paths before its final build and commit. On WSL/Linux/macOS keep
project and `.ai` text LF/no-BOM and never run CRLF normalization.
7. COMMIT — verify every dirty path belongs to this task and matches the owned write sets. Stage
only explicit task-owned paths; `git add -A` is forbidden. Commit an intended submodule only when
its own preflight was clean and its changes belong to this task, then stage that pointer. Use a
concise plain-language subject (about 50-60 characters, matching recent history), a short body
only when necessary, and no `Autotask:`, attempt, `Co-Authored-By:`, or assistant attribution.
Record the commit as IMPL_SHA and attempt 1.
8. TEST — run `.agents/shared/test-loop.md` to APPROVED / BLOCKED / attempt cap and read its
Codex-only `references/computer-use-testing.md` adapter. Spawn a leaf test-author and feed it BOTH
sides per test-loop.md "Design the tests from THIS task":
(1) the TASK SPEC — this task's full description block including `Design-Basis:` PLUS referenced
IMAGES when present (read them), and (2) the implementation — `git show
<IMPL_SHA>` + touched files. It designs a falsifiable oracle per change and writes the plan into
`<TASK_DIR>/test.md` BEFORE running. Give it `COMPUTER_USE_POLICY` and the adapter path; it selects
`Driver: overlay` or `Driver: hybrid` per check and predeclares its action, fallback, target, ready
marker, and safety envelope. Only the task-runner operates Computer Use. Visual checks compare
old/new art when it exists; otherwise use exact task criteria, visual.md, current/legacy analogues,
style-token identity, and TASK_BASE_SHA behavior. Never synthesize target art. For layout, require
arithmetic geometry checks, a same-scale best-reference/baseline comparison, and an adversarial
contract pass. Cover every `Observable:` and named surface; never reuse a generic test.
Treat TASK_BASE_SHA, not `IMPL_SHA^`, as the pre-task OLD baseline across every fix attempt. Drive
RUN/ASSESS adversarially: missing evidence = TEST_FLAW; no difference from TASK_BASE_SHA =
IMPL_BUG. If attempt equals MAX_ATTEMPTS, block before creating another impl-fix commit. Otherwise
a leaf impl-fix edits without committing; you normalize if native Windows, build, stage exact
owned paths, commit the next attempt, and update IMPL_SHA.
Codex safety overrides for the shared mechanics:
- Overlay code may modify tracked task-owned files only; it may not create untracked source files.
Inventory its paths in `<TASK_DIR>/test-overlay.paths`.
- Save it with `git diff --binary HEAD > <TASK_DIR>/test-overlay.patch`, which captures staged
changes after `git apply --3way`. Verify the patch is nonempty and reappliable. Restore only the
inventoried overlay paths to IMPL_SHA (including inside an intended submodule) rather than
resetting the whole checkout. If any unexpected path is dirty, hard-stop without resetting it.
- Use `TelegramForcePortable/.codex-implement-test-copy` as the ownership marker. SETUP may delete
only marked live; otherwise move unmarked live to real when real is absent, or stop if both
exist. Copy golden to live and mark it. At terminal cleanup delete marked live, then, only if
real exists, MOVE it back to live so later manual changes are recaptured.
- Set `RUN_DIR=<TASK_DIR>/runs/attempt-<n>/run-<m>/` and `EVIDENCE_DIR=RUN_DIR`; overlay and
assessor use it for logs, screenshots, `app_stdout.txt`, and `app_stderr.txt`. Remove stale live-copy
`tdata/working`, record a dump baseline, and stop with BLOCKED(test) at MAX_TEST_RUNS even when
TEST_FLAW repairs did not consume an implementation attempt.
- Repository file-lock instructions remain authoritative: clean up the exact EXE proactively,
but never retry after an actual lock build failure.
Skip TEST only for documentation or metadata with no runnable behavior; record
`VERDICT: NOT_APPLICABLE` and the file-level validation. "Config" alone is not a reason to skip.
If you must return `STATUS: BLOCKED`, FIRST leave the checkout clean and buildable for the next
task by restoring only proven task-owned paths to the last green IMPL_SHA, or TASK_BASE_SHA if no
green implementation exists. Never reset an unexpected path. State the blocker type:
`BLOCKED(test)` = a building implementation is committed and only exact named verification remains;
`BLOCKED(impl)` = no green implementation, with HEAD left at TASK_BASE_SHA. A known implementation
bug at the attempt cap is BLOCKED(impl); do not keep a behavior-known-bad commit as successful work.
Reserve unrecoverable for a checkout you cannot safely return to a clean, buildable commit.
On APPROVED or justified NOT_APPLICABLE, promote `<TASK_DIR>/about.proposed.md` to the project
blueprint before replying. On BLOCKED, keep the prior blueprint and retain the proposal only as a
task artifact.
Before replying, write `<TASK_DIR>/result.md` with these exact fields:
```
# Task result: <TASK_ID>
STATUS: DONE | BLOCKED
Verdict: APPROVED | NOT_APPLICABLE | <specific blocker>
Blocker-Type: none | test | impl | unrecoverable
Task-Base-SHA: <sha>
Implementation-SHA: <sha or none>
Attempts: <n>
Test-Runs: <n>
UI-Driver: overlay | hybrid | mixed | hybrid-unavailable | not-applicable
Touched: <repo paths or none>
Test-Report: <path or not-applicable>
Evidence: <specific log/screenshot paths and what they prove>
Unverified: none | <exact behavior and manual follow-up>
Checkout: clean-buildable | unsafe
Discovered: none | present
## Discovered tasks
<ordered complete `### discovered-N: ...` blocks; dependencies may name existing ids or earlier placeholders; omit when none>
```
`STATUS: DONE` requires APPROVED or a justified NOT_APPLICABLE verdict, a clean checkout, and all
task-owned changes committed after any native-Windows normalization. The result file is mandatory.
Reply with only the compact summary block from test-loop.md
(TASK/STATUS/VERDICT/ATTEMPTS/TOUCHED/DISCOVERED/NOTES); include result.md and test.md paths plus the
key evidence or exact unverified behavior in NOTES.
````
## Completion
When the loop ends (every task is `approved` or `blocked`):
1. **FIRST — LOUDLY AND IN BOLD — list everything that did NOT fully succeed.** Every `blocked`
task and every task whose tests could not fully verify it gets its own bold line stating EXACTLY
what failed or what is still UNVERIFIED and the manual follow-up needed, e.g.
**"⚠️ <letter> — impl committed (<sha>) & review-approved, but <behavior> is UNVERIFIED
(<why, e.g. test-harness limit>); verify manually — <test.md/result.md path>"**. Make this block
impossible to miss. If everything passed and was verified, say that explicitly instead.
2. Summarize each validated result.md: approved vs blocked, implementation SHA, attempts, files
touched, and the exact log/screenshot evidence or unverified behavior.
3. List any discovered tasks that were added.
4. Note the project name for `implement <project> <follow-up>`.
5. Show total elapsed time (`Xh Ym Zs`, omit zero components).
6. Remind that test overlays are saved as `.ai/<project>/<letter>/test-overlay.patch`; the working
tree is clean at the final retained implementation HEAD, and overlays are not present in it.
7. In Goal mode, mark complete only if every task is approved. With any blocked task, report the
terminal pipeline state without claiming the objective was achieved.
## Error handling
- Follow task-think's retry ladder only for disposable leaf phases. Never automatically duplicate a
stateful task-runner. A runner returning BLOCKED does not stop the loop by default; record it and
continue while the checkout stays clean and buildable. Stop only when continuing is impossible.
- Retry a malformed plan with its disposable planner; repair runner artifacts in the same runner's follow-up turn, never a duplicate.
- On a file-lock build error, follow AGENTS.md: stop immediately, do not retry or attempt a
workaround, and ask the user to close this checkout's app and debugger. Proactive pre-build
cleanup remains full-path-scoped to EXE; image-name-wide termination is always forbidden.
- The launch gate (Phase A) guarantees the test account exists before any work begins.
- Never stash, stage, commit, restore, or reset unrelated user changes. Unexpected dirty paths are a
hard stop, not permission to clean the checkout.
- Keep `.ai/` artifacts and project text LF/no-BOM on WSL; normalize CRLF/no-BOM only on native Windows.
## User invocation
`Use local implement skill: <request or path>`; resume/extend with `<project> [additional change]`. A prepared `.ai/<project>/tasks/about.md` is the automatic project-only source.
@@ -1,4 +0,0 @@
interface:
display_name: "Implement"
short_description: "Implement and verify Telegram changes"
default_prompt: "Use $implement to implement and fully verify this Telegram Desktop change."
+111
View File
@@ -0,0 +1,111 @@
---
name: perform-task
description: Resolve, claim, implement, commit, and verify exactly one existing ai-tdesktop task by short slug or full dated id. Use when the user invokes $perform-task or /perform-task with a known task name, or when the continue scheduler delegates one selected task. Runs the complete mature context, planning, assessment, Debug build, review, test-loop, Computer Use, resume, and publication pipeline without selecting any additional work.
---
# Perform One AI Task
Own exactly one task through a Telegram commit and terminal AI commit. Do not
process the inbox, split the task, drain the queue, or select a follow-up after
this task reaches a terminal state.
## Read the complete engine
Read these files completely before phase work:
- `references/pipeline.md` for the authoritative end-to-end runner contract;
- `references/phase-prompts.md` for exact leaf prompts and retry rules;
- `.agents/shared/test-loop.md` for the implementation/test state machine;
- `references/computer-use-testing.md` when UI-driver selection or operation is
relevant.
The pipeline reference adapts conflicting generic test-loop mechanics for the
external AI worktree and exact-path safety. Its named adapter wins at those
points; retain every other test-loop rule.
## Resolve the workspace and task
Run from a Telegram Desktop checkout. Use the host's Python 3 command:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py resolve \
--name <short-slug-or-full-task-id>
```
Use `python` or `py -3` when appropriate. The helper reads the ignored machine
tag, derives the checkout tag, synchronizes clean AI state, and resolves:
1. an exact full id such as `2026/07/19/fix-community-forward`;
2. an exact final path slug such as `fix-community-forward`;
3. an exact normalized friendly task title.
Prefer a unique unfinished match when approved history has the same slug.
Never guess among several unfinished matches; report their full ids so the
human can choose one.
An interactive `/perform-task` or `$perform-task` invocation requires a
nonempty name. If none was supplied, ask for the friendly short name or full
id and do not select from the queue. A `continue` delegation always supplies
the full id.
When invoked by `continue`, accept its explicit `source_root`, `slot_worktree`,
`checkout_tag`, and full `task_id`, but still run `resolve` and verify they
match local discovery.
If `commits.slot_only` is nonzero and the slot is clean, run the helper's
`publish` command and resolve again before changing ownership. If the slot is
dirty, permit it only for an already `in-progress` task owned by this checkout
and only within that task's allowed paths; the pipeline preflight will validate
resumption ownership. Any other dirty or divergent state is a hard stop. Never
discard an unpublished checkpoint.
## Acquire exactly this task
Inspect the resolved task, its `ready` value, `other_active_task`, state, and
owner before source work.
- If another task is already `in-progress` for this checkout, stop. Never
abandon or supersede it implicitly.
- If this task is `approved` or `blocked`, report its terminal result and stop.
- If it is claimed by another checkout, stop without touching it.
- If it is unclaimed but its dependencies are unfinished, report those
dependencies and stop without claiming it.
- If it is ready and unclaimed, claim only this full id:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py claim \
--task <full-task-id>
```
- If it is `todo` and owned by this checkout, start it:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py start \
--task <full-task-id>
```
- If it is already `in-progress` and owned by this checkout, resume it without
another claim or start commit.
Refresh with `resolve` after every state mutation. The source pipeline starts
only after canonical AI state shows this task `in-progress` for this checkout.
## Run and publish
Execute `references/pipeline.md` exactly. The task must normally produce:
1. one or more tested Telegram implementation-attempt commits, each with an
exact one-line subject, blank line, and `Task: <full-task-id>`;
2. tracked resumable AI checkpoints during phase work;
3. a terminal AI slot commit containing final result/state, rebased and
published to canonical AI master without force.
Do not report success from a source commit alone. The final AI commit must also
be canonical. On a retryable concurrent-master race, keep fetching, rebasing,
and publishing until it succeeds. On a semantic conflict, unsafe checkout, or
unreachable remote, preserve resumable state and report a hard stop.
Return a compact result with the full task id, terminal status or hard stop,
attempts, touched files, canonical-publication confirmation, and exact evidence
or unverified behavior. Never persist or report commit hashes; the full task id
is the only cross-repository link.
@@ -0,0 +1,4 @@
interface:
display_name: "Perform AI Task"
short_description: "Implement one Telegram AI task by name"
default_prompt: "Use $perform-task to resolve, implement, verify, and publish one named ai-tdesktop task."
@@ -1,6 +1,6 @@
# Computer Use testing adapter
Read this during `$implement` TEST when selecting or using the UI driver. This is a Codex-only
Read this during `$perform-task` TEST when selecting or using the UI driver. This is a Codex-only
adapter over `.agents/shared/test-loop.md`; the shared task-derived scenarios, oracles, overlay,
`-testagent` launch, portable account, watchdog, crash handling, and artifact verdicts remain
authoritative.
@@ -1,17 +1,32 @@
# Phase Prompts
# Telegram Task Phase Prompts
Use these templates as Codex subagent messages. Use them as same-session checklists only for Phase 0, intentional current-session build work, Phase 7, or when delegation is unavailable from the start at the current agent depth. Replace every applicable placeholder: `<TASK>`, `<PROJECT>`, `<LETTER>`, `<PREV_LETTER>`, `<BUILD>`, `<N>`, `<OWNED_WRITE_SET>`, `<R>`, `<R-1>`, and `<phase-name>`.
## Contents
- [Orchestration rules](#orchestration-rules)
- [Completion checks](#artifact-based-completion-checks)
- [Context](#phase-1-context)
- [Plan and assessment](#phase-2-plan)
- [Implementation and build](#phase-4-implementation)
- [Review](#phase-6-code-review-loop)
- [Windows normalization](#phase-7-native-windows-text-normalization)
- [Prompt delivery](#prompt-delivery-and-logs)
Use these templates as Codex subagent messages. Use them as same-session
checklists only for intentional current-session build work, Phase 7, or when
delegation is unavailable from the start at the current agent depth. Replace
every applicable placeholder: `<TASK>`, `<TASK_ID>`, `<WORK_DIR>`,
`<PROJECT_FILE>`, `<PREVIOUS_CONTEXT>`, `<BUILD>`, `<N>`,
`<OWNED_WRITE_SET>`, `<R>`, `<R-1>`, and `<phase-name>`.
## Orchestration Rules
- Phase 0 runs in the main session.
- When delegation is available, use a fresh subagent for Phase 1, Phase 2, Phase 3, each Phase 4 implementation unit, and each Phase 6 pass. Do not switch those phases to same-session midstream because of a timeout or missing artifact.
- Treat delegation as selected only after the first real phase spawn succeeds; tool presence is insufficient. An immediate depth/capacity/policy rejection before phase work selects same-session checklists and is not a delegated retry.
- Phase 7 runs in the current session on native, non-WSL Windows because it depends on the final local diff and touched-file set. Skip it on WSL and keep files LF/no-BOM there.
- Write each phase prompt to `.ai/<PROJECT>/<LETTER>/logs/phase-<phase-name>.prompt.md` before execution.
- Write each phase prompt to `<WORK_DIR>/logs/phase-<phase-name>.prompt.md` before execution.
- If you delegate a phase, send the prompt file contents as the initial `spawn_agent` message.
- When writing the phase prompt file, append the standard progress file contract and the standard compact reply block below so the subagent knows how to surface progress before the final artifact.
- After each phase completes, write `.ai/<PROJECT>/<LETTER>/logs/phase-<phase-name>.result.md` with exact
- After each phase completes, write `<WORK_DIR>/logs/phase-<phase-name>.result.md` with exact
`STATUS:`, `ARTIFACTS:`, `TOUCHED:`, `BLOCKER:`, and `NOTES:` fields.
- Use `fork_turns: "none"` by default. If the phase depends on thread-only context or UI attachments, pass it explicitly or use the smallest positive turn fork needed.
- Use only fields the current `spawn_agent` schema exposes; do not invent role, model, or reasoning arguments. Inherit the parent model/reasoning selection, or match it if the host explicitly supports overrides.
@@ -32,7 +47,7 @@ Append this verbatim to every delegated phase prompt:
```text
You are a leaf phase worker. Do not spawn or delegate to other agents.
Before deep work, create or update the matching progress file in `.ai/<PROJECT>/<LETTER>/logs/`.
Before deep work, create or update the matching progress file in `<WORK_DIR>/logs/`.
Use `phase-<phase-name>.progress.md` as a concise heartbeat with:
- `Heartbeat: <N>` on the first line, incremented on each meaningful update
@@ -64,76 +79,48 @@ Do not restate the full context, plan, diff, or long reasoning in the chat reply
## Artifact-Based Completion Checks
- Phase 1 is complete only when `about.md` and `context.md` both exist and are non-empty.
- Phase 1 is complete only when `context.md` exists and is non-empty. For a
project task, `project.proposed.md` must also exist and be non-empty.
- Phase 2 is complete only when `plan.md` exists, contains a `## Status` section, and no unintended source edits were made.
- Phase 3 is complete only when `plan.md` contains both `Phases:` in the Status section and `Assessed: yes`.
- Phase 4 is complete only when the target phase checkbox changed to checked and the touched-file list matches the owned write set, or the blocker explains any mismatch.
- Phase 5 is complete only when the build outcome is known and the build checkbox is updated on success.
- Phase 6a is complete only when `review<R>.md` exists and contains a verdict line.
- Phase 6b is complete only when the requested fixes were applied and the post-fix build outcome is known.
- An implement-specific visual design phase is complete only when `visual.md` cites its available
- A perform-task visual design phase is complete only when `visual.md` cites its available
design sources (images when supplied; otherwise request facts and repository/baseline anchors),
records assumptions, and contains desktop anchors, an ordered derivation, tolerances, and
falsifiable geometry checks. Missing mockups alone never make the phase incomplete.
## Phase 0: Setup
Record the current time now and store it as `$START_TIME`. You will use this at the end to display total elapsed time.
Before running any phase prompts, determine whether this is a new project or a follow-up task.
Follow-up detection:
1. Extract the first word or token from the task description. Call it `FIRST_TOKEN`.
2. Check `.ai/` to see existing project names.
3. Check whether `.ai/<FIRST_TOKEN>/about.md` exists.
4. If the file exists, this is a follow-up task. The project name is `FIRST_TOKEN`. The task description is everything after `FIRST_TOKEN`.
5. If the file does not exist, this is a new project. The full input is the task description.
Do not proceed until you have determined follow-up vs new.
For new projects:
- Using the list of existing projects, pick a unique short name (1-2 lowercase words, hyphen-separated) that does not collide.
- Create `.ai/<PROJECT>/`, `.ai/<PROJECT>/a/`, and `.ai/<PROJECT>/a/logs/`.
- Set `<LETTER>` = `a`.
For follow-up tasks:
- Scan `.ai/<PROJECT>/` for spreadsheet-style task folders (`a/`...`z/`, `aa/`...). Find the latest id.
- The previous task id = that highest id.
- The new task id = next spreadsheet-style id; never reuse an existing artifact directory.
- Create `.ai/<PROJECT>/<LETTER>/` and `.ai/<PROJECT>/<LETTER>/logs/`.
Then proceed to Phase 1. Follow-up tasks do not skip context gathering. They use a modified Phase 1F prompt.
## Phase 1: Context (New Project, letter = `a`)
## Phase 1: Context
```text
You are a context-gathering agent for a large C++ codebase (Telegram Desktop).
TASK: <TASK>
YOUR JOB: Read AGENTS.md, inspect the codebase, find all files and code relevant to this task, and write two documents.
YOUR JOB: Read AGENTS.md, inspect the codebase, find all files and code relevant to this task, and write self-contained implementation context.
Steps:
1. Read AGENTS.md for project conventions and build instructions.
2. Search the codebase for files, classes, functions, and patterns related to the task.
3. Read all potentially relevant files. Be thorough and prefer reading more rather than less.
4. For each relevant file, note:
2. When `<PROJECT_FILE>` is not `none`, read it as the current durable project
blueprint and preserve everything still accurate in the proposal.
3. Search the codebase for files, classes, functions, and patterns related to the task.
4. Read all potentially relevant files. Be thorough and prefer reading more rather than less.
5. For each relevant file, note:
- file path
- relevant line ranges
- what the code does and how it relates to the task
- key data structures, function signatures, and patterns used
5. Look for similar existing features that could serve as a reference implementation.
6. Check api.tl if the task involves Telegram API.
7. Check .style files if the task involves UI.
8. Check lang.strings if the task involves user-visible text.
6. Look for similar existing features that could serve as a reference implementation.
7. Check api.tl if the task involves Telegram API.
8. Check .style files if the task involves UI.
9. Check lang.strings if the task involves user-visible text.
Write two files.
File 1: .ai/<PROJECT>/about.md
This file is not used by any agent in the current task. It exists solely as a starting point for a future follow-up task's context gatherer. No planning, implementation, or review phase should rely on it during the current task.
Write it as if the project is already fully implemented and working. It should contain:
Write `<WORK_DIR>/project.proposed.md` only when `<PROJECT_FILE>` is not
`none`. It is not used by the current task. Describe the project as if this
task is approved and fully working, so the performer can promote it only after
approval. Include:
- Project: What this project does (feature description, goals, scope)
- Architecture: High-level architectural decisions, which modules are involved, how they interact
- Key Design Decisions: Important choices made about the approach
@@ -141,7 +128,7 @@ Write it as if the project is already fully implemented and working. It should c
Do not include temporal state like "Current State", "Pending Changes", "Not yet implemented", or "TODO". Describe the project as a complete, coherent whole.
File 2: .ai/<PROJECT>/<LETTER>/context.md
Always write `<WORK_DIR>/context.md`.
This is the primary task-specific implementation context. All downstream phases should be able to work from this file plus the referenced source files. It must be self-contained. Include:
- Task Description: The full task restated clearly
@@ -159,7 +146,7 @@ Be extremely thorough. Another agent with no prior context will rely on this fil
Do not implement code in this phase.
```
## Phase 1F: Context (Follow-up Task, letter = `b`, `c`, ...)
## Phase 1F: Context for an existing project
```text
You are a context-gathering agent for a follow-up task on an existing project in a large C++ codebase (Telegram Desktop).
@@ -170,20 +157,22 @@ YOUR JOB: Read the existing project state, gather any additional context needed,
Steps:
1. Read AGENTS.md for project conventions and build instructions.
2. Read .ai/<PROJECT>/about.md. This is the project-level blueprint describing everything done so far.
3. Read .ai/<PROJECT>/<PREV_LETTER>/context.md. This is the previous task's gathered context.
4. Understand what has already been implemented by reading the actual source files referenced in about.md and the previous context.
2. Read <PROJECT_FILE>. This is the project-level blueprint describing everything done so far.
3. Read <PREVIOUS_CONTEXT>. This is the previous task's gathered context.
4. Understand what has already been implemented by reading the actual source files referenced in the project file and previous context.
5. Based on the new task description, search the codebase for any additional files, classes, functions, and patterns that are relevant to the new task but not already covered.
6. Read all newly relevant files thoroughly.
Write two files.
File 1: .ai/<PROJECT>/about.md (rewrite)
File 1: `<WORK_DIR>/project.proposed.md`
Rewrite this file instead of appending to it. The new about.md must be a single coherent document that describes the project as if everything, including this new task's changes, is already fully implemented and working.
Write a single coherent proposed project document that describes everything,
including this task's changes, as fully implemented and working. Do not modify
`<PROJECT_FILE>` during this phase.
It should incorporate:
- everything from the old about.md that is still accurate and relevant
- everything from the existing project document that is still accurate and relevant
- the new task's functionality described as part of the project, not as a pending change
- any changed design decisions or architectural updates from the new task requirements
@@ -194,10 +183,10 @@ It should not contain:
- task-by-task changelog or timeline
- information that contradicts the new task requirements
File 2: .ai/<PROJECT>/<LETTER>/context.md
File 2: `<WORK_DIR>/context.md`
This is the primary document for the new task. It must be self-contained and should include:
- Task Description: The new task restated clearly, with enough project background that an implementation agent can understand it without reading any other .ai files
- Task Description: The new task restated clearly, with enough project background that an implementation agent can understand it without reading other AI task files
- Relevant Files: Every file path with line ranges relevant to this task
- Key Code Patterns: How similar things are done in the codebase
- Data Structures: Relevant types, structs, classes
@@ -218,10 +207,10 @@ Do not implement code in this phase.
You are a planning agent. You must create a detailed implementation plan.
Read these files:
- .ai/<PROJECT>/<LETTER>/context.md
- <WORK_DIR>/context.md
- Then read the specific source files referenced in context.md to understand the code deeply.
Create a detailed plan in: .ai/<PROJECT>/<LETTER>/plan.md
Create a detailed plan in: <WORK_DIR>/plan.md
The plan.md should contain:
@@ -273,8 +262,8 @@ Do not implement code in this phase.
You are a plan assessment agent. Review and refine an implementation plan.
Read these files:
- .ai/<PROJECT>/<LETTER>/context.md
- .ai/<PROJECT>/<LETTER>/plan.md
- <WORK_DIR>/context.md
- <WORK_DIR>/plan.md
- Then read the actual source files referenced to verify the plan makes sense.
Assess the plan:
@@ -308,8 +297,8 @@ For each phase in the plan that is not yet marked as done, use this prompt:
You are an implementation agent working on phase <N> of an implementation plan.
Read these files first:
- .ai/<PROJECT>/<LETTER>/context.md
- .ai/<PROJECT>/<LETTER>/plan.md
- <WORK_DIR>/context.md
- <WORK_DIR>/plan.md
Then read the source files you will be modifying.
@@ -323,7 +312,7 @@ Rules:
- Follow the plan precisely.
- Follow AGENTS.md coding conventions.
- You are not alone in the codebase. Respect existing changes and do not revert unrelated work.
- Do not modify .ai/ files except the Status section in plan.md and the matching
- Do not modify AI task files except the Status section in plan.md and the matching
`logs/phase-<phase-name>.progress.md` heartbeat required by this prompt.
- When done, update plan.md Status section: change `- [ ] Phase <N>: ...` to `- [x] Phase <N>: ...`
- Do not work on other phases.
@@ -347,8 +336,8 @@ Prefer running the build in the main session because it is critical-path work. I
You are a build verification agent.
Read these files:
- .ai/<PROJECT>/<LETTER>/context.md
- .ai/<PROJECT>/<LETTER>/plan.md
- <WORK_DIR>/context.md
- <WORK_DIR>/plan.md
The implementation is complete. Your job is to build the project and fix any build errors that block the planned work.
@@ -400,10 +389,10 @@ FINISH:
You are a code review agent for Telegram Desktop (C++ / Qt).
Read these files:
- .ai/<PROJECT>/<LETTER>/context.md
- .ai/<PROJECT>/<LETTER>/plan.md
- <WORK_DIR>/context.md
- <WORK_DIR>/plan.md
- REVIEW.md
- If R > 1, also read .ai/<PROJECT>/<LETTER>/review<R-1>.md
- If R > 1, also read <WORK_DIR>/review<R-1>.md
Then run `git diff` to see the current uncommitted changes for this task.
@@ -425,7 +414,7 @@ Important guidelines:
- Be pragmatic. Each suggestion should have a clear, concrete benefit.
- Do not suggest comments, docstrings, or over-engineering.
Write your review to: .ai/<PROJECT>/<LETTER>/review<R>.md
Write your review to: <WORK_DIR>/review<R>.md
The review document should contain:
@@ -457,9 +446,9 @@ When finished, report your verdict clearly as: APPROVED or NEEDS_CHANGES.
You are a review fix agent. You implement improvements identified during code review.
Read these files:
- .ai/<PROJECT>/<LETTER>/context.md
- .ai/<PROJECT>/<LETTER>/plan.md
- .ai/<PROJECT>/<LETTER>/review<R>.md
- <WORK_DIR>/context.md
- <WORK_DIR>/plan.md
- <WORK_DIR>/review<R>.md
Then read the source files mentioned in the review.
@@ -469,7 +458,7 @@ Rules:
- Implement exactly the review changes, nothing more.
- Follow AGENTS.md coding conventions.
- You are not alone in the codebase. Respect existing changes and do not revert unrelated work.
- Do not modify .ai/ files except where the review process explicitly requires it.
- Do not modify AI task files except where the review process explicitly requires it.
After all changes are made:
1. Run the resolved Debug build command from context.md (`<BUILD>`) at the repository root.
@@ -487,18 +476,18 @@ finished. Keep WSL/Linux text LF/no-BOM.
Use the current task's result logs as the source of truth for what Codex touched. Do not sweep the whole repo and do not rewrite unrelated files from a dirty worktree.
```text
You are performing the final native-Windows-only text normalization phase for task-think.
You are performing the final native-Windows-only text normalization phase for perform-task.
Read these files:
- .ai/<PROJECT>/<LETTER>/plan.md
- .ai/<PROJECT>/<LETTER>/logs/phase-4*.result.md
- .ai/<PROJECT>/<LETTER>/logs/phase-5*.result.md
- .ai/<PROJECT>/<LETTER>/logs/phase-6*.result.md
- <WORK_DIR>/plan.md
- <WORK_DIR>/logs/phase-4*.result.md
- <WORK_DIR>/logs/phase-5*.result.md
- <WORK_DIR>/logs/phase-6*.result.md
Your job:
- Collect the union of repo file paths listed in the exact `TOUCHED:` fields in those result logs.
- Keep only files inside the repository that currently exist and are textual project files: source, headers, build/config files, localization files, style files, and similar text assets.
- Exclude `.ai/`, `out/`, binary files, and unrelated user files that were not touched by Codex in this task.
- Exclude `out/`, binary files, and unrelated user files that were not touched by Codex in this task.
- Rewrite each kept file so all line endings are CRLF.
- If a kept file is UTF-8 or ASCII text, write it back as UTF-8 without BOM. Never add a UTF-8 BOM to source/config/project text files.
- Preserve file content otherwise. Preserve whether the file ended with a trailing newline.
@@ -511,7 +500,7 @@ Rules:
- If a file cannot be normalized safely, record it as a failure instead of silently skipping it.
When finished:
1. Write `.ai/<PROJECT>/<LETTER>/logs/phase-7-line-endings.result.md`
1. Write `<WORK_DIR>/logs/phase-7-line-endings.result.md`
2. Include:
- whether the phase completed
- which files were normalized
@@ -523,13 +512,14 @@ When finished:
## Completion
When all phases, including build verification, code review, and Windows line ending normalization when applicable, are done:
1. Read the final `plan.md` and report the summary to the user.
1. Read the final `plan.md` and prepare the compact performer result.
2. Show which files were modified or created.
3. Note any issues encountered during implementation.
4. Summarize the code review iterations: how many rounds, what was found and fixed, or whether it was approved on the first pass.
5. On native, non-WSL Windows, mention the text-normalization result briefly: which project files were normalized, whether any BOMs were removed, or whether nothing needed changes.
6. Calculate and display the total elapsed time since `$START_TIME` (format as `Xh Ym Zs`, omitting zero components).
7. Remind the user of the project name so they can request follow-up tasks within the same project.
7. Include the full task id and project slug, when any, so later follow-ups can
be routed without relying on session memory.
## Error Handling
@@ -541,10 +531,10 @@ When all phases, including build verification, code review, and Windows line end
## Prompt Delivery And Logs
For each phase:
1. Write the full prompt to `.ai/<PROJECT>/<LETTER>/logs/phase-<phase-name>.prompt.md`
1. Write the full prompt to `<WORK_DIR>/logs/phase-<phase-name>.prompt.md`
2. Delegate by sending that prompt text to a fresh subagent, or use it as a same-session checklist only for the designated main-session phases or when delegation was unavailable from the start
3. For delegated phases, expect a matching `.ai/<PROJECT>/<LETTER>/logs/phase-<phase-name>.progress.md` heartbeat while work is in flight
4. Save `.ai/<PROJECT>/<LETTER>/logs/phase-<phase-name>.result.md` with `STATUS:`, `ARTIFACTS:`,
3. For delegated phases, expect a matching `<WORK_DIR>/logs/phase-<phase-name>.progress.md` heartbeat while work is in flight
4. Save `<WORK_DIR>/logs/phase-<phase-name>.result.md` with `STATUS:`, `ARTIFACTS:`,
`TOUCHED:`, `BLOCKER:`, and `NOTES:` fields.
For review iterations, include the iteration in the file name, for example:
@@ -0,0 +1,371 @@
# Complete Telegram Task Pipeline
## Contents
- [Contract and inputs](#contract-and-inputs)
- [Preflight](#preflight)
- [Artifacts and resumption](#artifacts-and-resumption)
- [Delegation](#delegation)
- [Implementation phases](#implementation-phases)
- [Telegram commits](#telegram-commits)
- [Test loop adapter](#test-loop-adapter)
- [Terminal state](#terminal-state)
- [Failure handling](#failure-handling)
## Contract and inputs
Run exactly one already selected `ai-tdesktop` task in its Telegram checkout.
Do not split it, claim other work, process the inbox, or create a second
stateful runner. Treat the external `task.md`, its referenced inputs, project
context, and repository as sufficient unless the request expressly requires
unavailable exact bytes or content.
Use visual evidence in this order: explicit task facts; supplied inputs;
adjacent current UI/code/styles and the pre-task baseline; repository history
and legacy implementations; then the closest established desktop convention
and the smallest common-sense change. Record assumptions and never invent a
reference. Missing optional art is not a blocker and never weakens a visual
task.
Resolve these values before phase work:
```text
SOURCE_ROOT
AI_SLOT
TASK_ID
TASK_DIR = AI_SLOT/tasks/TASK_ID
WORK_DIR = TASK_DIR/work
LOCAL_DIR = TASK_DIR/.local
TASK_SPEC = TASK_DIR/task.md plus referenced TASK_DIR/input files
PROJECT_FILE = AI_SLOT/projects/<project>/project.md, or none
PREVIOUS_CONTEXT = latest approved project task's work/context.md, or none
BASE_REF = refs/ai-tasks/TASK_ID/base
GREEN_REF = refs/ai-tasks/TASK_ID/green
```
Capture a wall-clock start time for the final elapsed-time report.
Resolve host kind, build tree, command, executable, and desktop target as one
consistent platform configuration:
```text
native Windows: cmake --build ./out --config Debug --target Telegram
WSL/Linux: Telegram/build/docker/centos_env/build_debug.sh
macOS/other: AGENTS.md and the configured Debug tree
EXE candidates:
out/Debug/Telegram.exe
out/Debug/Telegram
out/Debug/Telegram.app/Contents/MacOS/Telegram
TEST_ACCOUNT = out/Debug/test_TelegramForcePortable
MAX_ATTEMPTS = 4
MAX_TEST_RUNS = 12
COMPUTER_USE_POLICY = auto | overlay-only | required
```
On macOS, pass the outer `.app` containing the resolved executable to a UI
driver. Never mix native Windows commands with a WSL tree. Build Debug only.
Proactive process cleanup may target only the exact resolved executable path;
never terminate Telegram by image name.
## Preflight
Before planning or editing:
1. Read `SOURCE_ROOT/AGENTS.md`, `REVIEW.md`, `AI_SLOT/AGENTS.md`, `TASK_SPEC`,
every referenced input, and relevant project context.
2. Verify `state.yaml` is `in-progress` and owned by this checkout tag.
3. Require the prepared portable test account. Its absence is a global hard
stop before implementation.
4. Verify a usable Debug executable/build tree, safe path-scoped process
control, safe portable-folder operations, and an app-run display. Computer
Use remains optional unless policy is `required`.
5. For a new run require a clean tracked Telegram worktree, clean submodules,
and no unrelated untracked files, then initialize local recovery state:
```bash
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
source-begin --source-root SOURCE_ROOT --task TASK_ID
```
On resume, run the same command. It verifies the local refs and reconciles
them from contiguous tip commits with this task's exact `Task:` line after a
source rebase. Never resolve or record a ref's object name in an artifact.
6. For an interrupted run, allow dirty Telegram paths only when every one is
listed in `work/owned-paths.txt` and completed phase artifacts prove this
task owns them. Otherwise hard-stop without cleaning them.
Do not stash. Do not reset, restore, stage, commit, or delete an unexpected
path. Invocation authorizes recovery only for paths proven to belong to this
task and only back to `GREEN_REF` or `BASE_REF`, as appropriate.
## Artifacts and resumption
Use tracked, resumable task artifacts:
```text
work/context.md
work/project.proposed.md # project tasks only
work/visual.md # layout tasks only
work/plan.md
work/review1.md
work/test.md
work/result.md
work/owned-paths.txt
work/progress.md
work/logs/phase-*.prompt.md
work/logs/phase-*.progress.md
work/logs/phase-*.result.md
work/test-overlay.patch
evidence/ # selected durable proof
```
Use ignored local storage for bulky or machine-specific data:
```text
.local/runs/attempt-<n>/run-<m>/
.local/build-logs/
.local/dumps/
```
Keep complete portable accounts, browser/Computer Use profiles, downloaded
components, raw run directories, full build output, and temporary files under
`.local/` or the checkout's existing ignored build tree. Never commit them.
At startup read `phase` plus the existing progress, plan, review, test, and
result artifacts. Resume at the first incomplete validated boundary. Do not
repeat an approved phase merely because the prior agent session disappeared.
Treat a compact subagent reply as a notification; the artifact and repository
state are proof.
At each stable boundary update `work/progress.md` and publish a checkpoint:
```bash
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
checkpoint --source-root SOURCE_ROOT --task TASK_ID --phase PHASE
```
Checkpoint after context, assessed plan, each completed implementation phase
when useful for recovery, the retained implementation commit, review, and each
material test attempt. Never checkpoint a half-written artifact. A checkpoint
commit must be rebased and published to AI master before later phase work.
## Delegation
Use `references/phase-prompts.md` for the exact context, plan, assessment,
implementation, build, review, and native-Windows normalization prompts.
- The performer is the only stateful task owner.
- Probe nested mode with the first real leaf phase. If depth, capacity, or
policy rejects that spawn before work begins, execute the same prompt
checklists in the performer. This is a supported mode, not degraded failure.
- In nested mode, use a fresh leaf for context, planning, assessment, each
implementation unit, review, review-fix, and test authoring. Every leaf must
be told not to delegate and never to commit.
- Use `fork_turns: "none"` with explicit paths. Fork the smallest turn window
only for genuinely unavailable chat-only visual context.
- Inherit the parent's model and reasoning level. Do not invent tool fields.
- Keep implementation units sequential unless the assessed plan proves
disjoint write sets and capacity makes parallel edits safe.
- Never duplicate the performer or an implementation unit with uncertain
writes.
Write the delegated prompt first. Require an early small heartbeat and a final
reply containing only status, artifact paths, touched paths, and blocker.
Poll no longer than 60 seconds. A timeout is not failure. Use artifact mtimes
and heartbeat counters; after five minutes without movement, message the same
target, and after a second unchanged five-minute window interrupt and retry
that disposable phase once. Never replace a live stateful performer.
## Implementation phases
Run sequentially:
1. **Context.** Write a self-contained `work/context.md`. For project work,
read the current project file and nearest approved task context, then write
`work/project.proposed.md` as a coherent finished-state blueprint. Use the
Phase 1F prompt when prior task context exists; otherwise use Phase 1 with
the project file. Do not promote the proposal yet; blocked work must not
become project truth.
2. **Visual design.** For `Visual: layout`, write `work/visual.md`. Derive every
dimension from request relationships, supplied images, font metrics, style
tokens, sibling geometry, or a cited desktop analogue. Use ordered
calculations, tolerances, relationship checks, same-scale comparison, and
an adversarial rejection pass. For `Visual: appearance`, keep the lighter
exact color/text/glyph oracle. Skip for non-visual work.
3. **Plan.** Write `work/plan.md` with exact files, functions, ordered steps,
bounded phases, owned write sets, Debug build verification, and status
checkboxes.
4. **Assess.** Independently verify paths and APIs, completeness, design,
duplication, edge cases, repository conventions, and phase sizing. Require
`Phases: <N>` and `Assessed: yes`.
5. **Implement.** Run one leaf per assessed plan phase. Before each edit,
update `work/owned-paths.txt`. A leaf edits only its owned paths and its
phase status; it does not commit.
6. **Build.** Run the resolved Debug build in the performer. Fix only build
errors belonging to the task. If the task changed only a resource consumed
by codegen, force its documented regeneration so the Debug binary contains
the new resource. A file-lock/access-denied build error is an immediate
global hard stop with no retry or workaround.
7. **Review.** Run the independent focused review/fix loop from the phase
prompts for up to three review iterations. Review the task diff using
`REVIEW.md`: correctness/safety, dead code, redundant changes, duplication,
placement, decomposition, exceptional module structure, and style. Rebuild
after every fix pass. Give layout reviewers the visual contract.
8. **Normalize.** On native non-WSL Windows, normalize only task-owned source,
header, style, localization, and build/config text to CRLF without BOM,
preserving content and trailing-newline state, then rebuild. On macOS,
Linux, and WSL preserve LF/no-BOM.
9. **Commit and test.** Create the Telegram implementation commit, then run the
test loop below. An implementation bug creates the next committed attempt;
keep the same `Task:` locator on every attempt. After each clean buildable
attempt, move the local retained-implementation ref with:
```bash
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
source-mark-green --source-root SOURCE_ROOT --task TASK_ID
```
## Telegram commits
The performer owns commit boundaries. Inspect every dirty path, verify it is in
the union of owned write sets, and stage only explicit paths. Never use
`git add -A`. Commit an intended submodule first only when its preflight was
clean and all of its changes belong to this task, then stage the superproject
pointer.
Every implementation or implementation-fix commit message is exactly:
```text
<one concise plain-language subject, about 50-60 characters>
Task: <full TASK_ID>
```
Do not add a body, `Autotask:`, attempt marker, `Co-Authored-By:`, assistant
attribution, or any other trailer. Track rationale in the AI task. If a short
durable explanation will help source-history readers, write
`SOURCE_ROOT/tasks/TASK_ID.md` and include it in the same commit.
Record only the attempt number. Use `BASE_REF` as the old behavioral baseline
across all attempts and `GREEN_REF` as the current retained implementation.
These refs are local recovery mechanics: never copy their resolved object names
into AI artifacts, source notes, reports, chat, or commit messages.
## Test loop adapter
Read `.agents/shared/test-loop.md` completely and apply it after the first green
implementation commit. Read `references/computer-use-testing.md` when choosing
or operating a UI driver. Retain all task-derived oracle, layout measurement,
overlay, watchdog, crash/assertion, hang, account, attempt, report, and evidence
rules, with these external-task safety adaptations:
- The performer, not leaves, stages and commits every attempt.
- Overlay code may modify only tracked task-owned source paths. Inventory them
in `work/test-overlay.paths`; never introduce an untracked source file.
- Save the overlay with `git diff --binary HEAD > work/test-overlay.patch`,
verify it is nonempty and reapplicable, then restore only inventoried overlay
paths to `GREEN_REF`. Do not run a repository-wide hard reset.
- Reapply with `git apply --3way`; re-author a conflicting hunk from `test.md`
rather than leaving conflict markers.
- Missing `test_TelegramForcePortable` is the only portable-account setup
blocker. If live exists without real, move live to real. If live and real
both exist, recursively delete live completely. Then deep-copy golden to
live and continue without ownership-marker checks. After successful SETUP,
terminal cleanup deletes live and moves real back to live when real exists.
If SETUP did not complete, cleanup leaves all three folders untouched. Never
alter golden or real in place.
- Set `RUN_DIR` and `EVIDENCE_DIR` to
`TASK_DIR/.local/runs/attempt-<n>/run-<m>/`. Promote only decisive compact
logs/screenshots into tracked `evidence/`.
- Launch every test binary with `-testagent`. Detect crashes from process death
without `TEST_COMPLETE` plus a new `tdata/working`, not exit code. Read
captured stderr first, then `tdata/working`, then note the minidump.
- Before each app run and build, stop only a process whose resolved executable
path equals `EXE`. Never use image-name-wide termination.
- Enforce both the in-app watchdog and an external wall-clock deadline. Count
test runs independently from implementation attempts and stop at
`MAX_TEST_RUNS`.
- Delete the overlay-bearing Debug executable on every terminal test exit so
the user cannot launch it accidentally.
The test author must read both the full task specification and the complete
`BASE_REF..GREEN_REF` diff. It writes checks before running, covers every
acceptance surface, declares a falsifiable oracle for each, and never reuses a
generic navigate-and-screenshot scenario. Missing or ambiguous evidence is
`TEST_FLAW`; no expected delta from `BASE_REF` is `IMPL_BUG`. Two identical
consecutive failure signatures block early. A known implementation bug at the
attempt cap is implementation-blocked, not a successful retained commit.
Skip runtime testing only for a task with no runnable behavior. Record
`NOT_APPLICABLE` and exact file-level validation. Configuration alone is not a
reason to skip.
## Terminal state
Before terminal publication, require a clean Telegram checkout at `GREEN_REF`
when an implementation is retained, no overlay in source, no owned live test
copy, and no overlay-bearing executable. For implementation-blocked work with
no retained commit, restore only proven owned paths to `BASE_REF`. For
test-blocked work retain the latest implementation commit and state the exact
unverified behavior.
Write `work/result.md` with exactly one value for every field:
```text
# Task result: <TASK_ID>
STATUS: DONE | BLOCKED
Verdict: APPROVED | NOT_APPLICABLE | <specific blocker>
Blocker-Type: none | test | impl | unrecoverable
Attempts: <n>
Test-Runs: <n>
UI-Driver: overlay | hybrid | mixed | hybrid-unavailable | not-applicable
Touched: <source paths or none>
Test-Report: work/test.md | not-applicable
Evidence: <tracked evidence paths and what they prove>
Unverified: none | <exact behavior and manual follow-up>
Checkout: clean-buildable | unsafe
Discovered: none | present
## Discovered tasks
<complete independently testable follow-ups, or omit>
```
For approved project work, promote `work/project.proposed.md` to the project's
`project.md` immediately before final AI publication. For blocked work, retain
the proposal only as a task artifact.
Publish terminal AI state only after the Telegram commit and result are final:
```bash
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
finish --source-root SOURCE_ROOT --task TASK_ID \
--status approved|blocked
```
The helper verifies a clean source checkout, local task refs, current `HEAD`,
and the exact three-line commit message. It commits the task result and state in
the AI slot, fetches newer canonical state when configured, rebases the slot,
publishes without force, fast-forwards local AI master, and then deletes the
local task refs. Do not report a terminal task until that final AI commit
reaches canonical master. Preserve an unpublished slot commit on a semantic
conflict or remote outage and hard-stop instead of pretending completion.
When `Discovered: present`, preserve complete task blocks in `result.md`. The
`continue` scheduler must route them through the same independent-testability
planner into new unclaimed dated tasks before selecting more shared work.
## Failure handling
- A disposable phase may be retried once through the wait ladder. Never fresh
retry the performer.
- A clean terminal `blocked` task lets `continue` proceed with independent
work. A dirty/non-buildable checkout or global environment problem stops it.
- A file-lock build error always stops immediately and asks the human to close
this checkout's Telegram/debugger.
- Missing optional screenshots or mockups never block.
- Never silently pass unverified behavior. Surface every blocked or partially
verified task with exact `work/test.md`, `work/result.md`, and evidence paths.
- In Goal mode, report terminal blocked state without claiming achievement;
complete the goal only when every selected task is approved.
+213
View File
@@ -0,0 +1,213 @@
---
name: process-inbox
description: Process the local ignored ai-tdesktop inbox into durable, independently testable Telegram Desktop task records. Use when the user invokes $process-inbox or /process-inbox, asks to triage or process ai-tdesktop/inbox/inbox.md, or wants inbox notes and pasted images routed into new or existing AI projects and dated tasks without implementing them.
---
# Process Inbox
Turn the human-written ignored inbox into tracked planning artifacts. Route and
plan only: do not edit Telegram source, build, test, claim, or implement tasks.
## Workspace
Run from a Telegram Desktop checkout. Use the bundled helper with an available
Python 3 interpreter:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py ensure
python3 .agents/skills/process-inbox/scripts/workspace.py prepare
```
Use `python` or `py -3` when that is the host's Python 3 command. The helper:
- reads `Telegram/build/ai-machine-tag`;
- combines it with the checkout folder, for example `macbook-twork`;
- locates the sibling `ai-tdesktop` and `ai-tdesktop-worktrees` directories,
with `AI_TDESKTOP_ROOT` and `AI_TDESKTOP_WORKTREES_ROOT` as overrides;
- ensures the local `slot/<checkout-tag>` linked worktree exists;
- snapshots the ignored inbox before planning and prints JSON paths.
`prepare` resumes the one active `.processing-*` snapshot when present. Save its
`transaction`, `digest`, `ai_main`, `slot_worktree`, `slot_branch`, and
`checkout_tag` values. Read raw input only from the transaction snapshot, not
from the live inbox.
If the inbox is empty, stop normally. If tracked AI worktrees are dirty, a slot
has unpublished commits, or the machine tag is invalid, stop without changing
or clearing the inbox.
If `ai_main` has an `origin`, fetch it before a new transaction and
fast-forward local `master` to `origin/master`. Never force-push shared AI
history.
## Route and plan
Read these before planning:
- source checkout `AGENTS.md`;
- `ai_main/AGENTS.md`;
- existing `projects/*/project.md` and task states relevant to the request;
- the transaction's `inbox.md` and every file it references.
Use one disposable leaf planner when the harness supports delegation; instruct
it not to delegate. Otherwise perform the same work locally. The planner may
write a proposed routing file inside the ignored transaction, but only the
orchestrator writes tracked AI state.
Treat natural-language hints as evidence, not required syntax. Segment the
inbox into requests, then decide for each request whether to:
- create a standalone task with no project;
- add one or more tasks to an existing project;
- create a new project when durable shared context is useful.
Do not create generic holding projects such as `fixes`. A release batch of
unrelated regressions normally becomes standalone tasks or tasks in existing
domain projects. Group requests into one task only when they form one cohesive,
independently testable behavior. Split work until every task is implementable
in one pass and has an exact observable acceptance result.
Briefly inspect Telegram source when needed to understand scope and testable
seams. Do not plan implementation internals and do not modify the source tree.
## Assign task paths
Use the processing date and a concise imperative kebab-case slug:
```text
tasks/YYYY/MM/DD/<task-slug>/
```
The task identifier is the path below `tasks/`, for example:
```text
2026/07/18/fix-community-forward
```
Never ask the human to choose or remember it. Consult existing directories and
append `-2`, `-3`, and so on to resolve a same-day collision. Dependencies may
name only task identifiers created earlier in the same routing result or
existing tasks.
## Write tracked artifacts
Write only inside the checkout-specific `slot_worktree`.
For every task, create `task.md`:
```markdown
# <imperative title>
<self-contained request and relevant constraints>
## Acceptance
- <specific observable result proving the behavior>
## Inputs
- [<descriptive label>](input/<file>)
```
Omit `Inputs` when none are used. For visual work, include the design basis and
the exact visual/layout evidence expected. Copy every pertinent supplied file
into `input/`; never reference the ignored inbox or its backup from a task.
Create `state.yaml` in this exact field order:
```yaml
status: todo
created: YYYY-MM-DD
project: null
depends_on: []
claimed_by: null
claimed_at: null
claim_order: null
lease_until: null
phase: null
inbox_receipt: receipts/YYYY/MM/DD/<receipt>.md
```
Use a project slug instead of `null` when routed to a project. Use a YAML list
of task identifiers for dependencies. Inbox processing never reserves work:
new tasks always remain `status: todo` with `claimed_by`, `claimed_at`, and
`claim_order` set to `null`. The checkout tag belongs in the receipt only.
For a new project, create `projects/<slug>/project.md` with a concise durable
scope and `projects/<slug>/tasks.md` with task links. For an existing project,
append only new links. Project indexes do not store live status.
Create one tracked Markdown receipt under `receipts/YYYY/MM/DD/`. Include:
- local processing time, checkout tag, and inbox digest;
- every inbox request mapped to friendly task titles and identifiers;
- every supplied file mapped to its copied task input, or explicitly unused;
- created projects and updated projects;
- deduplication decisions.
Before writing, search receipts for the same digest. If it was already fully
processed and all referenced tasks still exist, create nothing and reuse that
receipt for finalization.
## Validate and publish
Before committing, verify:
- every request and supplied file is accounted for;
- every new task has `task.md`, valid `state.yaml`, and a falsifiable
acceptance result;
- every task link, dependency, and copied input exists;
- no raw inbox path, `.local/`, browser profile, portable account, credential,
complete run directory, or complete build log is tracked;
- no Telegram or AI commit hash is copied into a task, project, or receipt;
- only expected `tasks/`, `projects/`, and `receipts/` paths changed;
- tracked text uses the checkout's native convention (LF on Unix/WSL, CRLF on
native Windows) without a BOM or mixed line endings.
Stage only explicit generated paths; never use `git add -A`. Commit on the slot
branch with the one-line subject:
```text
Process inbox for <checkout-tag>
```
Immediately before publishing, fetch `origin` when configured and
fast-forward `ai_main/master` when possible. Rebase the clean slot branch onto
local `master`, then fast-forward `master` to the slot branch. Push `master`
when an origin exists. Retry ordinary non-fast-forward races by fetching,
rebasing, and publishing again until success. If a semantic rebase conflict,
unsafe worktree, or remote outage occurs, do not clear the inbox; leave the
active transaction and slot commit recoverable and report the exact state.
Never force-push.
After master contains the generated commit and any configured push succeeded,
finalize using the receipt path relative to `ai_main`:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py finalize \
--transaction <transaction-path> \
--receipt <receipts/YYYY/MM/DD/name.md>
```
The helper verifies the live inbox digest, preserves the raw snapshot under
ignored `inbox/backup/`, and empties `inbox.md` only when the input remained
unchanged. If the human edited the inbox during planning, it preserves those
edits and reports `cleared: false`.
If planning fails before any tracked changes or commits exist, preserve the
live inbox and close the snapshot with:
```bash
python3 .agents/skills/process-inbox/scripts/workspace.py abort \
--transaction <transaction-path>
```
Do not abort after a generated commit exists; retain the transaction so the
publication can be resumed.
## Report
Return a compact summary with friendly task and project titles, the AI master
publication status, the local backup path, whether the inbox was cleared, and
any unused input. Do not report a commit hash or start implementation
automatically.
@@ -0,0 +1,4 @@
interface:
display_name: "Process AI Inbox"
short_description: "Route inbox notes into durable AI tasks"
default_prompt: "Use $process-inbox to route and plan the local AI inbox."
File diff suppressed because it is too large Load Diff
-149
View File
@@ -1,149 +0,0 @@
---
name: task-think
description: Orchestrate a multi-phase Telegram Desktop implementation workflow with persistent per-project task artifacts under .ai. Use when Codex should drive context gathering, planning, plan assessment, implementation, Debug build verification, review, and native-Windows text normalization through bounded phase handoffs while keeping the parent task lean. Uses current spawn_agent, wait_agent, send_message, followup_task, and interrupt_agent semantics.
---
# Task Pipeline
Run a full implementation workflow with repository artifacts and clear phase boundaries.
## Inputs
Collect:
- task description
- optional project name (if missing, derive a short kebab-case name)
- optional constraints (files, architecture, risk tolerance)
- optional screenshot paths
If screenshots are attached in UI but not present as files, write a brief textual summary into the task artifacts before spawning fresh subagents so later phases can read the requirements without inheriting the whole parent thread.
## Overview
The workflow is organized around projects. Each project lives in `.ai/<project-name>/` and can contain sequential spreadsheet-style task ids (`a`...`z`, `aa`...).
Project structure:
```text
.ai/<project-name>/
about.md # Single source of truth for the entire project
a/ # First task
context.md # Gathered codebase context for this task
plan.md # Implementation plan
review1.md # Code review documents (up to 3 iterations)
review2.md
review3.md
logs/
phase-*.prompt.md
phase-*.progress.md
phase-*.result.md
b/ # Follow-up task
context.md
plan.md
review1.md
logs/
...
c/ # Another follow-up task
...
```
- `about.md` is the project-level blueprint: a single comprehensive document describing what this project does and how it works, written as if everything is already fully implemented. It contains no temporal state ("current state", "pending changes", "not yet implemented"). It is rewritten, not appended to, each time a new task starts, incorporating the new task's changes as if they were always part of the design.
- Each task folder (`a/`, `b/`, ...) contains self-contained files for that task. The task's `context.md` carries all task-specific information: what specifically needs to change, the delta from the current codebase, gathered file references, and code patterns. Planning, implementation, and review phases should rely on the current task folder.
## Artifacts
Create and maintain:
- `.ai/<project-name>/about.md`
- `.ai/<project-name>/<letter>/context.md`
- `.ai/<project-name>/<letter>/plan.md`
- `.ai/<project-name>/<letter>/review<R>.md` (up to 3 review iterations)
- `.ai/<project-name>/<letter>/logs/phase-<phase-name>.prompt.md`
- `.ai/<project-name>/<letter>/logs/phase-<phase-name>.progress.md` for delegated phases
- `.ai/<project-name>/<letter>/logs/phase-<phase-name>.result.md`
Each `phase-<phase-name>.result.md` uses exact `STATUS:`, `ARTIFACTS:`, `TOUCHED:`, `BLOCKER:`, and
`NOTES:` fields. Each delegated `phase-<phase-name>.progress.md` is a heartbeat: a tiny monotonic counter
plus current step, files being read or edited, concrete findings, and next checkpoint. It lets the
parent distinguish active research from a stuck subagent without rereading large context.
## Phases
Run these phases sequentially:
1. Phase 0: Setup - Record start time, detect follow-up vs new project, create directories.
2. Phase 1: Context Gathering - Read codebase, write `about.md` and `context.md`. Use Phase 1F for follow-up tasks.
3. Phase 2: Planning - Read context, write detailed `plan.md` with numbered steps grouped into phases.
4. Phase 3: Plan Assessment - Review and refine the plan for correctness, completeness, code quality, and phase sizing.
5. Phase 4: Implementation - Execute one implementation unit per plan phase.
6. Phase 5: Build Verification - Build the project, fix any build errors. Skip if no source code was modified.
7. Phase 6: Code Review Loop - Run review and fix iterations until approved or the iteration limit is reached.
8. Phase 7: Windows Text Normalization - On native, non-WSL Windows only, after review passes and before the final summary, normalize LF to CRLF for the text source/config files Codex edited in this task and ensure rewritten UTF-8 project files are saved without BOM. Keep WSL/Linux files LF/no-BOM.
Use the phase prompt templates in `PROMPTS.md`.
## Execution Mode
Use Codex subagents as the primary orchestration mechanism when they are available at the current
agent depth.
- When delegation is available, Phase 1, Phase 2, Phase 3, each Phase 4 implementation unit, and each Phase 6 review or review-fix pass must run in fresh subagents. Do not rerun those phases in the main session midstream just because a wait timed out or an artifact is missing.
- Run Phase 7 in the main session on native, non-WSL Windows because it depends on the final local file state and exact touched-file set. Skip it on WSL and preserve LF/no-BOM there.
- When any same-session helper rewrites native-Windows project text files, preserve CRLF and write UTF-8 without BOM. Avoid writer APIs or defaults that silently inject a UTF-8 BOM.
- The main session may read `context.md` once after Phase 1 and `plan.md` once after Phase 3. After that, prefer narrow shell checks, file existence checks, and status-line reads instead of rereading full documents or diffs.
- Use only fields exposed by the current `spawn_agent` schema. Some hosts do not expose worker/explorer roles or per-spawn model settings; do not invent them.
- Use `fork_turns: "none"` by default. Pass the phase prompt and explicit file paths instead of the whole thread. Use the smallest positive turn count only for genuinely thread-only context or attachments.
- Inherit the parent task's model and reasoning selection. If a host exposes overrides, match the parent rather than downshifting. Custom agent files use `model_reasoning_effort`.
- Give every spawned phase a unique lowercase/digit/underscore `task_name`, save its returned canonical target, and explicitly make the phase worker a leaf that must not delegate further.
- Tool presence alone does not prove delegation is allowed. Choose delegated mode only after the first real phase spawn succeeds; an immediate depth/capacity/policy rejection before phase work selects same-session checklists. Do not block or launch `codex exec` merely because the default nesting depth is one.
- Write the exact phase prompt to the matching `logs/phase-<phase-name>.prompt.md` file before you delegate. Use the same prompt file as a checklist if you later need to fall back to same-session execution.
- For delegated phases, require an early `logs/phase-<phase-name>.progress.md` heartbeat before deep work. The subagent should create or update it early, keep it tiny, and refresh it sparingly: preferably at natural milestones, and otherwise only after a longer quiet stretch such as roughly 5-10 minutes.
- In every delegated prompt, require a compact final reply with only status, artifact paths, touched files, and blocker or `none`. Detailed reasoning belongs in `.ai/` artifacts, not in the chat reply.
- After a subagent finishes, verify that the expected artifacts or code changes exist, then write `logs/phase-<phase-name>.result.md` with the canonical fields.
- Poll delegated work with `wait_agent` for at most 60 seconds per call. Use elapsed wall-clock windows, not the number of poll timeouts, for stall decisions. When a phase looks close to completion, use 30-60 second polls.
- A timeout is not a failure; it only means no final status arrived yet. Do not treat short waits as stall detection for research-heavy phases.
- `wait_agent` is mailbox-wide and may wake for another agent or steered user input. After every wake, handle new user input if any, inspect the saved target with `list_agents`, then validate the expected artifact and progress-file mtime. Prefer mtime checks first; only reread the progress file when you need detail.
- If the progress file mtime moved or its heartbeat counter increased since the previous check, treat that as active progress and wait again.
- If no usable final artifact exists yet but the progress file is appearing or advancing, keep the same subagent alive. Progress-file movement does not count toward the retry limit.
- If no usable final artifact exists and neither it nor the progress file has moved for a full five-minute blocked-check window, use `send_message` when the target is still running, or `followup_task` when it is idle, asking it to refresh progress, finish the artifact, and return the compact block.
- If there is still no meaningful movement for a second five-minute window after that follow-up, use `interrupt_agent` if it is running, confirm the turn stopped, and retry the disposable phase once with a new unique task name. There is no `close_agent` operation.
- Use `wait_agent` only when the next step is blocked on the result. While the delegated phase runs, do small non-overlapping local tasks such as validating directory structure or preparing the next prompt file.
- Build verification is critical-path work. Prefer running the build in the main session, and only delegate a bounded build-fix phase when there is a concrete reason.
- If subagents are unavailable in the current environment, current depth, or policy from the start, run the phase in the current session using the same prompt files. Otherwise, do not switch a pre-build phase to same-session midstream. Never fall back to shell-spawned `codex exec` child processes from this skill.
## Verification Rules
- If build or test commands fail due to file locks or access-denied outputs (C1041, LNK1104), stop and ask the user to close locking processes before retrying.
- Treat a delegated phase as complete only when the required artifact or status update exists on disk and matches the phase goals; do not rely on the chat reply alone.
- Never claim completion without:
- implemented code changes present
- build attempt results recorded
- review pass documented with any follow-up fixes
- on native, non-WSL Windows, if the task edited project source/config text files, a CRLF / no-BOM normalization pass recorded after review
## Completion Criteria
Mark complete only when:
- All plan phases are done
- Build verification is recorded
- Review issues are addressed or explicitly deferred with rationale
- On native, non-WSL Windows, Codex-edited project source/config text files have been normalized to CRLF, any UTF-8 rewrites were saved without BOM, and the result is logged
- Display total elapsed time since start (format: `Xh Ym Zs`, omitting zero components)
- Remind the user of the project name so they can request follow-up tasks within the same project
## Error Handling
- If any phase fails, times out, or gets stuck, follow the retry ladder from Execution Mode. Do not close an agent solely because the final artifact is missing while its progress file is still moving. After two delegated attempts remain blocked with no meaningful progress, report the issue to the user. Do not absorb the phase into the main session before build unless delegation was unavailable from the start.
- If `context.md` or `plan.md` is not written properly by a phase, rerun that phase in a fresh subagent with more specific instructions. Do not repair it locally before build unless delegation was unavailable from the start.
- If build errors persist after the build phase's attempts, report the remaining errors to the user.
- If a review-fix phase introduces new build errors that it cannot resolve, report to the user.
- If Phase 7 cannot safely normalize a touched file on native, non-WSL Windows or remove an introduced UTF-8 BOM from a touched project text file, record the failure in the result log and report it in the final summary instead of silently skipping it.
## User Invocation
Use plain language with the skill name in the request, for example:
`Use local task-think skill with subagents: make sure FileLoadTask::process does not create or read QPixmap on background threads; use QImage with ARGB32_Premultiplied instead.`
For follow-up tasks on an existing project:
`Use local task-think skill with subagents: my-project also handle the case where the file is already cached`
If screenshots are relevant, include file paths in the same prompt when possible.
+23
View File
@@ -0,0 +1,23 @@
---
description: Continue work from the shared ai-tdesktop queue
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Agent, AskUserQuestion, TodoWrite
---
# Continue AI Work
Read `.claude/ai-workflow-adapter.md` and
`.agents/skills/continue/SKILL.md` completely. Follow the shared skill with the
Claude adapter's delegation and text-handling substitutions. Keep processing
the inbox and eligible work until the scheduler's normal stop condition or a
global hard stop.
Every inbox worker, performer, and discovered-task routing Agent must be told
in its initial prompt to read `.claude/ai-workflow-adapter.md` completely before
the applicable shared skill or reference. Use the Agent tool for those workers;
do not start Claude subprocesses through Bash.
Arguments, when present, are natural-language scheduling or claim-scope hints:
```text
$ARGUMENTS
```
-379
View File
@@ -1,379 +0,0 @@
---
description: Autonomously implement a task (split into a task list if needed), then implement + test each task to approval via isolated per-task subagents
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion, TodoWrite
---
# Implement - Autonomous Implement-and-Test Orchestrator
You are the **top orchestrator**. You take a request — an inline description OR a task-list file —
normalize it into a project with a testability-split task list, and drive each task to
test-approval through an isolated per-task `task-runner` subagent. Your context must stay lean: you
hold only the task list and one compact summary per task. All heavy work (planning, coding,
building, testing) happens inside subagents whose context is discarded.
This is the tested superset of `/task`: it reuses `/task`'s phase prompts for implementation and
adds the impl⇄test loop defined in `.agents/shared/test-loop.md`.
Mockups, screenshots, and graphic references are optional evidence, not launch gates. Their absence
alone must never stop or block the run. For visual work, use explicit task facts first, supplied
references when present, then current/legacy repository UI and style tokens, and finally the closest
established desktop convention plus the smallest common-sense change. Only an expressly required
exact artifact that is unavailable and unrecoverable is missing required input.
**Arguments:** `$ARGUMENTS` = ONE of:
- an inline task description (e.g. `add a dark-mode toggle to settings`)
- a path to a task-list file (e.g. `.ai/communities/tasks.txt` — a rough list of tasks to refine)
- an existing project name to resume (e.g. `communities`), optionally followed by extra work
- **just a project name with a prepared `.ai/<project>/tasks/about.md`** — the default task source
(see Artifacts). With no other input, `/implement <project>` plans and implements straight from
that file, so `/implement communities` alone fires the full pipeline off `.ai/communities/tasks/about.md`.
May also reference attached images.
## Config
Runs in the **current checkout** — wherever `/implement` is invoked. No worktrees are created; all
paths below are relative to that repository root.
```
BUILD = cmake --build ./out --config Debug --target Telegram
EXE = ./out/Debug/Telegram.exe
TEST_ACCOUNT = ./out/Debug/test_TelegramForcePortable # user-prepared golden; launch gate aborts if absent
MAX_ATTEMPTS = 4
```
The test binary is **always launched with `-testagent`** (see test-loop.md "Crashes & assertions"):
it suppresses the Debug Abort/Retry/Ignore dialogs that would hang the run, turns any CRT/STL
assertion (and a frozen main thread) into an immediate crash with a written `tdata/working` report,
and writes the assertion text to a captured stderr file so a crash is diagnosable instead of a silent
hang. Key crash detection on the report file, not the exit code.
Tasks run **sequentially** in this one checkout (the build cache stays warm; app runs must
serialize against the account anyway). To parallelize, launch `/implement` in a different
checkout/slot (e.g. `C:\Telegram\tdesktop`, `D:\Telegram\tdesktop`, `D:\Telegram\twin`) — each run
is independent and single-tree. Don't run the **test phase** in two slots against the same account
at once (concurrent clients on one auth key can trigger a session reset); give parallel slots
separate test accounts.
## Artifacts (per project)
- `.ai/<project>/tasks/about.md` — the **default task source**: a human-prepared description (or
rough list) of the batch to implement, with any available mockups optionally dropped beside it.
This is the file you prepare; the planner reads it as SOURCE when `/implement <project>` is invoked
with no other input. It is **distinct** from the project blueprint `.ai/<project>/about.md` (the
`tasks/` subdir is what disambiguates them).
- `.ai/<project>/implementing.md` — the canonical, final, testability-split task list (descriptions
+ status). Your single source of truth; you are its only writer.
- `.ai/<project>/images/` — illustrations referenced by tasks (`images/01.png`, ...).
- `.ai/<project>/<letter>/` — per-task artifacts (context, plan, review, test, result, overlay).
- `.ai/<project>/about.md` — project blueprint (the `/task` convention).
## Done (for `/goal` loop mode)
The run is **done** when every task in `implementing.md` has `Status: approved` or
`Status: blocked: <reason>`. Under a `/goal` loop this is the stop condition. The run is
**resumable**: re-invoking with the project name reads `implementing.md` and continues from the
first unfinished task.
## Phase A: Setup & input resolution
1. Record start time (`Get-Date`).
2. **Test-account gate (hard precondition — before any work).** If
`out/Debug/test_TelegramForcePortable` does NOT exist, STOP the entire command immediately and
tell the user: the test account is not prepared — create `out/Debug/test_TelegramForcePortable`
(a portable-data folder authed to a throwaway test account) before `/implement` can run, because
autonomous testing is impossible without it. Do no implementation work.
3. **Resolve `$ARGUMENTS` into (project, SOURCE, mode) — without reading task files or images.**
The main thread never loads task prose or assets; resolving needs only paths and existence
checks. SOURCE ends up as EITHER inline text OR a confirmed file path (the planner reads it).
- **File input** — if the first token is a path: confirm it exists (`Test-Path`, do NOT read it)
and set SOURCE = that path. If the path is under `.ai/<name>/`, project = `<name>`; else derive
a short kebab name from the filename. Mode = **extend** if that project already has
`implementing.md`, else new.
- **Existing project** — else if `.ai/<FIRST_TOKEN>/` exists: project = `FIRST_TOKEN`.
- If there is a **remainder** → mode = **extend**: if the remainder is itself a path to an
existing file, SOURCE = that path (confirm with `Test-Path`, do NOT read it); otherwise
SOURCE = the remainder text.
- If the remainder is **empty**, resolve SOURCE in this priority order (existence checks only,
`Test-Path`, do NOT read):
1. If `.ai/<project>/tasks/about.md` exists → SOURCE = that file (the **default task
source**); mode = **extend** if `implementing.md` already exists, else **new**. This is
the `/implement <project>` with a prepared task source path — it fires the full pipeline.
2. Else if `implementing.md` exists → mode = **resume** (no SOURCE; Phase C finishes the
still-unfinished tasks).
3. Else there is nothing to implement — tell the user to prepare `.ai/<project>/tasks/about.md`
(or pass a description / task-file path) and stop.
- **New inline** — else SOURCE = the `$ARGUMENTS` text; pick a unique short kebab-case project
name (consult `ls .ai/`).
After this step you always have a project name and either a SOURCE (inline text or a confirmed
path) or mode = **resume** — and you have read neither the file nor any image.
4. Create `.ai/<project>/` and `.ai/<project>/images/` if new.
5. **Persist supplied images when present.** The planner reads images as files, and subagents cannot
see chat attachments. The main thread **cannot** save a pasted/inline chat image to disk
(`Write` is text-only; there is no save-attachment tool, and on Windows clipboard-paste isn't even
supported). For a chat-only image, pass a detailed textual description; ask for an on-disk copy
only when exact unavailable bytes are themselves required. With no image, continue normally. Do
not claim to have saved one. SOURCE-referenced images are the planner's job.
6. If mode = **resume**, skip Phase B and go to Phase C.
## Phase B: Planning & testability split
Spawn one planner subagent (Task, `general-purpose`):
```
You are a planning/splitting agent for a large C++ codebase (Telegram Desktop).
SOURCE — EITHER an inline request OR a path to a task-list file. If it is a PATH, READ it yourself
(and any task files it points to); the main thread has NOT read it. If it is inline text, use it as
the request:
<the inline description, or the file path>
PROJECT: <project> MODE: <new | extend>
IMAGES (optional) — the SOURCE and/or its task file may reference images by path (resolve them relative to the
SOURCE file's directory, or use absolute paths; when SOURCE is `.ai/<project>/tasks/about.md`, its
sibling files in `.ai/<project>/tasks/` — e.g. the mockup PNGs there — are those images). READ every
referenced image yourself, then COPY
each into `.ai/<project>/images/` with a descriptive kebab-case name, and reference it from the
specific task(s) it pertains to (see "Images per task" below). The main thread did NOT read or move
these — that is your job. If an image exists only as a textual description (because the user pasted
it into chat and it could not be saved to a file), it is provided here — treat that description as
visual evidence: <description(s) or none>. If none exists, continue from the request and repository;
do not ask for mockups or weaken, omit, or block a visual task solely for lacking optional
references. The express exact-artifact exception above still applies.
Read AGENTS.md. Briefly scan the codebase to gauge scope. Produce the FINAL ordered task list that
satisfies BOTH constraints for every task:
- **Implementable in one pass**: a single agent with a ~200k-token budget must be able to implement
the task fully on its own WITHOUT triggering context compaction — i.e. a bounded change it can
read and edit across a handful of files, not a sweep across dozens. If a unit is too big, split
it.
- **Independently testable**: each task must yield an observable behavior the test agent can drive
from an in-app debug overlay and verify via log/screenshot. Split on testable seams, so each task
ends at a point where something concrete can be exercised and checked.
Use the minimal number of tasks subject to both constraints; preserve dependency order (a task
comes before any task that depends on it). If the SOURCE is already a list, respect its intended
breakdown and refine only as needed: split entries that are too big or not independently testable;
you may merge trivially tiny adjacent entries if the result is still one testable unit.
Write `.ai/<project>/implementing.md` in EXACTLY this format:
# Implementing: <project>
## Goal
<one-line overall goal>
## Tasks
### a: <imperative title>
Status: todo
<2-4 line self-contained description: what to implement and the observable, testable result. Enough
that a fresh agent can act on it.>
Visual: layout | appearance (user-visible visual/asset changes only; omit otherwise)
Design-Basis: <ordered request/image/current/legacy/repository evidence and assumptions; visual tasks only>
Images: images/<file> — <caption> (this line only if the task uses an image)
### b: <imperative title>
Status: todo
<...>
**Images per task (required when supplied).** Attach every pertinent supplied image via `Images:`,
with a precise caption. Explicitly account for irrelevant/context-only images without attaching or
treating them as targets. With none on a visual task, omit `Images:`, cite non-image evidence in
`Design-Basis:`, and never create a placeholder. Non-visual tasks omit both.
**Visual classification (required for visual/asset changes).** For every task that changes
how user-visible UI, rendered output, or an asset looks, add `Visual:`; it routes the task-runner:
- `Visual: layout` — changes element sizes, proportions, spacing/margins, alignment, or component
geometry. It triggers a numeric design contract and geometry-MEASURING oracle whether or not a
mockup exists.
- `Visual: appearance` — must match COLORS / wording / which-style / glyph identity, but NOT
proportions or geometry (e.g. "make Decline red", "use the box-button palette"). Lighter check; no
contract.
- omit the line — the task changes no appearance.
Classify from the requested change, never from image availability. When torn between the two, choose
`layout` for anything built from multiple sized/positioned pieces. Every visual task must include
`Design-Basis:`; images are only one possible basis.
Use spreadsheet-style task ids (`a`...`z`, `aa`...). Do not plan internals or implement. When done, reply with ONLY a
compact confirmation — `ready — <N> tasks` (extend: `ready — appended <letters>`); do NOT echo the
task list or image contents back, the main thread reads `implementing.md` itself.
```
For **extend** mode, instead instruct the planner to FIRST read the existing `implementing.md`, then
rewrite it as: (1) a TRIMMED completed-history — keep only the **three most recent** `Status: approved`
task blocks (the three nearest the bottom of the file) and drop all earlier approved ones; (2) every
still-unfinished task left untouched, in place and with its status — that is all `todo`, `in-progress`,
and `blocked` blocks (never drop these); then (3) APPEND new tasks starting after the highest id in
the pre-trim union of headings and `.ai/<project>/<id>/` artifact directories. Never reuse an id
merely because trimming removed its heading. The trim only removes
already-approved entries from the list — it never touches the per-task `.ai/<project>/<letter>/`
artifacts on disk, so a follow-up letter can still read an earlier letter's `context.md` even after its
block was trimmed out of `implementing.md`. It must append ONLY tasks from SOURCE not already
represented in `implementing.md` — so re-running `/implement <project>` against an unchanged default
`tasks/about.md` appends nothing (the planner replies `ready — appended (none)`, still applying the
completed-history trim) and Phase C just finishes whatever is still unfinished. (Any
`todo`/`in-progress` leftovers from an interrupted run are picked up by Phase C regardless, so
defaulting to extend never loses an in-flight batch — it is a superset of resume.)
After the planner replies `ready`, read `implementing.md` back ONCE (your first and only load of the
task prose; you never read the images). Initialize a TodoWrite list mirroring the tasks so progress
is visible.
## Phase C: Per-task loop
For each task in `implementing.md` whose `Status` is not `approved`/`blocked`, in order:
1. Record `TASK_BASE_SHA = HEAD`, then set `Status: in-progress` (and mark TodoWrite in progress).
2. Spawn ONE `task-runner` subagent (Task, `general-purpose`) with the prompt below. Wait for it.
3. Read ONLY its compact summary block (the `task-runner` writes all detail to `.ai/`).
4. Update the task's `Status:` line — `approved` if `STATUS: DONE`, else `blocked: <reason>`.
5. If `DISCOVERED` lists follow-ups, send them through a planner to produce complete ID-free task
blocks. Rescan the union of headings and artifact dirs, assign unused spreadsheet ids, validate
dependencies, append after current tasks, and add them to TodoWrite. Only the main thread assigns
ids and writes `implementing.md`.
6. If `STATUS: BLOCKED`, **do NOT stop the loop — prioritize continuing development.** This often
runs unattended for hours, so NEVER pause to ask the user whether to go on; record the blocker
and move to the next task as long as further progress is possible. Distinguish:
- **Test-blocked** — the runner committed a building impl and only its in-app verification could
not complete (a test-harness limitation, or the attempt cap hit on a test flaw rather than a
real bug). The committed code is on disk, so CONTINUE. Capture EXACTLY what was left unverified
for the loud final report.
- **Impl-blocked but checkout clean** — no green impl for THIS task, but the runner left HEAD at
a prior committed, buildable commit. CONTINUE — later tasks may be independent of this one;
record that this task's behavior is missing.
- **Hard stop ONLY when continuing is truly impossible** — the checkout is left broken /
uncommitted / non-buildable (a later task-runner could not even start from a clean base), or a
global environment failure blocks all work (file-lock build error needing the user to close
`Telegram.exe`; the test-account gate). Only then stop and report.
Before spawning the next task, confirm the working tree is clean and at a buildable commit
(`git status` + the runner's summary). If a blocked runner left it dirty or broken, reset to the
last known-good commit first; if you cannot recover a clean buildable base, that is the hard-stop
case above. Every blocked/unverified task MUST be surfaced LOUDLY in the Completion report —
continuing is never the same as silently passing.
### task-runner prompt
```
You are a task-runner for ONE task in an autonomous implement-and-test workflow on Telegram
Desktop (C++ / Qt). You own this task end to end and isolate its context from the orchestrator.
You MAY and SHOULD spawn your own subagents (the Task tool is available to you).
PROJECT: <project> TASK: <letter> — <title>
TASK DESCRIPTION:
<the task's full description block from implementing.md>
IMAGES: <referenced .ai/<project>/images/* paths, or none — Read them if present>
TASK_DIR: .ai/<project>/<letter>/
TASK_ID: <project>-<letter>
TASK_BASE_SHA: <HEAD before this runner was spawned>
Config (paths relative to this checkout): BUILD=<...> EXE=<...> MAX_ATTEMPTS=<...>. The test account
is the out/Debug/ portable-data folders (see test-loop.md "Test account"). For each test execution,
set `EVIDENCE_DIR=<TASK_DIR>/runs/attempt-<n>/run-<m>/` and create it before launch.
Read first: AGENTS.md; REVIEW.md; `.claude/commands/task.md` (for the exact Phase 1-6 prompt
templates); `.agents/shared/test-loop.md` (for the testing phase). For a follow-up letter, also read
`.ai/<project>/about.md` and the previous letter's `context.md`.
Treat `IMAGES: none` as normal. Missing mockups alone never justify pausing, blocking, or asking the
user. For visual work use `Design-Basis:`; otherwise use the task description and repository.
Run this pipeline for THIS task only, spawning a fresh subagent per phase (so each phase's output
stays in YOUR context, not the orchestrator's):
1. CONTEXT — run task.md's Phase 1 (new) or Phase 1F (follow-up) prompt for this task; produces
`<TASK_DIR>/context.md` (and `about.md` for the project).
1b. DESIGN-SPEC — only if the task is `Visual: layout`. Inventory `Design-Basis:`: read supplied
images when present, then inspect current/legacy implementations and the closest desktop
widgets/style tokens. Write `<TASK_DIR>/visual.md` with cited evidence, assumptions, and the
ordered derivation from `.agents/shared/test-loop.md`; every quantity must use a font metric,
style token, sibling geometry, or explicit task relationship and have a tolerance. With no
mockup, use repository anchors and proceed. Before PLAN, verify `visual.md` cites available design
sources, records assumptions, and contains desktop anchors, an ordered derivation, tolerances,
and falsifiable geometry checks. Skip for non-visual and appearance-only tasks.
2. PLAN — task.md Phase 2 -> `<TASK_DIR>/plan.md`. For a `Visual: layout` task the plan's `.style`
metrics come straight from `<TASK_DIR>/visual.md`.
3. ASSESS — task.md Phase 3 (refine plan, size phases).
4. IMPLEMENT— task.md Phase 4, one subagent per plan phase. For a `Visual: layout` task, give each
impl subagent `<TASK_DIR>/visual.md` and require its `.style` metrics to satisfy that contract
exactly (no eyeballed sizes). Implementation agents do NOT commit yet; you commit after build
passes.
5. BUILD — task.md Phase 5 (build with BUILD, fix errors). Proactive cleanup may stop only THIS
checkout's full-path binary before building. If the build reports a file-lock error, stop
immediately without retry/workaround and ask the user to close the app/debugger.
6. REVIEW — task.md Phase 6 but a SINGLE pass (not 3): one review agent, then one fix agent if
NEEDS_CHANGES, then rebuild. (Tests catch behavior; review catches dead code / duplication /
placement / style.) For a `Visual: layout` task, also hand the review agent `<TASK_DIR>/visual.md`
so it flags any `.style` metric that violates the contract.
7. COMMIT — `git add -A && git commit` with a concise plain-language subject (≤ ~50-60 chars,
matching recent `git log` style; usually the whole message — add a short plain body only if the
subject can't carry it). NO `Autotask:`/attempt trailer and NO `Co-Authored-By:`/attribution line
(this overrides the default; see test-loop.md "Commit message"). Commit submodules first if dirty,
then bump the pointer. Record the commit SHA as IMPL_SHA (you track the attempt number yourself).
8. TEST — run the loop in `.agents/shared/test-loop.md` to APPROVED, BLOCKED, or attempt cap.
Spawn a test-author subagent and feed it BOTH sides per test-loop.md "Design the tests from THIS
task": (1) the TASK SPEC — this task's full description including `Design-Basis:` PLUS referenced
IMAGES when present, and (2) the implementation —
`git show <IMPL_SHA>` + touched files. It designs a falsifiable oracle per change and writes the
plan into `<TASK_DIR>/test.md` BEFORE running (visual checks compare old/new art when it exists;
otherwise they use exact task criteria, the numeric contract, current/legacy analogues, style
token/resource identity, and pre-task behavior; never synthesize target art. For a
`Visual: layout` task, measured sizes/spacings/alignment must satisfy each derivation line within
tolerance, using a same-scale best-reference/baseline comparison plus an adversarial contract pass;
"all elements present" is NOT a pass — see test-loop.md "Visual contract"), covers every surface
the task names, and never reuses another task's
navigate+screenshot. You drive RUN/ASSESS yourself, ADVERSARIALLY (no pass-by-inference; missing
evidence = TEST_FLAW; no-difference-from-before = IMPL_BUG), treating TASK_BASE_SHA rather than
`IMPL_SHA^` as the baseline across every fix attempt, and keep the human-readable
`<TASK_DIR>/test.md` report. Spawn an impl-fix subagent on IMPL_BUG (it commits the next attempt →
new IMPL_SHA). After each run, save the overlay patch into TASK_DIR and `git reset --hard
<IMPL_SHA>` so the checkout returns to impl-only. Run the test-account SETUP steps before each
launch, set the run-specific `EVIDENCE_DIR`, and honor every test-account hard rule (serialize
app runs; avoid account-fatal calls — logout/session-termination/account-deletion/whole-account
wipe. Other cloud-side changes are fine: it is a test-server account, so create content in any
chats freely and delete/clear content that test runs created, even in earlier runs — e.g. clear
a junk-accumulated cloud draft before a run instead of designing the oracle around it).
Skip TEST only if the task changed no runnable behavior (docs/config only) — say so explicitly.
If you must return `STATUS: BLOCKED`, FIRST leave the checkout clean and buildable for the next
task: `git reset --hard` to your last green IMPL_SHA if you have one, else to TASK_BASE_SHA
(never leave uncommitted or non-building changes behind). In the summary state the blocker TYPE so
the orchestrator can continue: `BLOCKED(test)` = impl committed & building, only verification
incomplete (give the exact unverified behavior + the commit SHA); `BLOCKED(impl)` = no green impl
for this task (say whether HEAD is left clean/buildable at a prior commit). Reserve a true
unrecoverable stop for a broken checkout you cannot reset to a buildable commit.
When done, write nothing new to chat except the compact summary block from test-loop.md
("TASK/STATUS/VERDICT/ATTEMPTS/TOUCHED/DISCOVERED/NOTES"). This wrapper has no `result.md`, so put
concise semicolon-separated follow-ups inline in `DISCOVERED`, or `none`. All reasoning lives in `.ai/`.
```
## Completion
When the loop ends (every task is `approved` or `blocked`):
1. **FIRST — LOUDLY AND IN BOLD — list everything that did NOT fully succeed.** Every `blocked`
task and every task whose tests could not fully verify it gets its own bold line stating EXACTLY
what failed or what is still UNVERIFIED and the manual follow-up needed, e.g.
**"⚠️ <letter> — impl committed (<sha>) & review-approved, but <behavior> is UNVERIFIED
(<why, e.g. test-harness limit>); verify manually"**. Make this block impossible to miss. If
everything passed AND verified, say that explicitly instead.
2. Summarize per task: approved vs blocked, attempts, files touched, key test evidence.
3. List any discovered tasks that were added.
4. Note the project name for `/implement <project> <follow-up>`.
5. Show total elapsed time (`Xh Ym Zs`, omit zero components).
6. Remind that test overlays are saved as `.ai/<project>/<letter>/test-overlay.patch` and the
checkout is left at each task's implementation commit (overlays reset away).
## Error handling
- A `task-runner` returning BLOCKED does NOT stop the loop by default — record the blocker and
continue to the next task as long as the checkout stays clean and buildable (see Phase C step 6).
Stop the loop ONLY when continuing is impossible: a broken/non-buildable checkout, or a global
environment failure (file lock requiring user action, missing test account). Whatever the outcome, report
every blocker's reason and `test.md` path LOUDLY in the Completion summary.
- If `implementing.md` or any artifact is malformed, re-spawn that step with tighter instructions.
- Never proceed past a file-lock build error — ask the user to close `Telegram.exe`.
- The launch gate (Phase A) guarantees the test account exists before any work begins; if it is
absent the command never starts.
- Missing optional screenshots, mockups, or graphics are never an error or blocker.
+22
View File
@@ -0,0 +1,22 @@
---
description: Implement one existing AI task by short name or full id
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Agent, AskUserQuestion, TodoWrite
---
# Perform One AI Task
Read `.claude/ai-workflow-adapter.md` and
`.agents/skills/perform-task/SKILL.md` completely. Follow the shared skill with
the Claude adapter's delegation and text-handling substitutions. Resolve,
claim when needed, implement, verify, and publish only the named task. Do not
continue with other queue work afterward.
Tell every phase Agent to read `.claude/ai-workflow-adapter.md` before its
shared phase prompt. Use the Agent tool for delegation; do not start Claude
subprocesses through Bash.
Task short name or full id:
```text
$ARGUMENTS
```
+22
View File
@@ -0,0 +1,22 @@
---
description: Route the local AI inbox into durable planned tasks
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Agent, AskUserQuestion, TodoWrite
---
# Process Inbox
Read `.claude/ai-workflow-adapter.md` and
`.agents/skills/process-inbox/SKILL.md` completely. Follow the shared skill
with the Claude adapter's delegation and text-handling substitutions. Process
the ignored inbox associated with the current Telegram Desktop checkout. Route
and plan tasks only; do not implement, build, or test them.
If a planner Agent is used, tell it to read
`.claude/ai-workflow-adapter.md` before the shared skill instructions. Use the
Agent tool for delegation; do not start Claude subprocesses through Bash.
Arguments, when present, are additional routing hints:
```text
$ARGUMENTS
```
+8 -6
View File
@@ -1,6 +1,6 @@
---
description: Learn from corrections — examine staged vs unstaged diffs and optionally distill insights into AGENTS.md or REVIEW.md
allowed-tools: Read, Edit, Bash(git diff:*), Bash(git status:*), Bash(git log:*), Bash(ls:*), AskUserQuestion
allowed-tools: Read, Edit, Bash(git diff:*), Bash(git status:*), Bash(git log:*), Bash(ls:*), Bash(python3 .agents/skills/process-inbox/scripts/workspace.py:*), Bash(python .agents/skills/process-inbox/scripts/workspace.py:*), Bash(py -3 .agents/skills/process-inbox/scripts/workspace.py:*), AskUserQuestion
---
# Reflect — Learn from Corrections
@@ -13,7 +13,9 @@ You are a reflection agent. Your job is to examine the difference between what a
`$ARGUMENTS` = "$ARGUMENTS"
If `$ARGUMENTS` is provided, it is a task name (project name from the `/task` workflow). This means the agent was working within `.ai/<task-name>/` and you should read the task context for deeper understanding of what the agent was trying to do.
If `$ARGUMENTS` is provided, it is a short or full task name from the external
`ai-tdesktop` workflow. Resolve it with the workspace helper and read that
task's durable context before judging the correction.
If `$ARGUMENTS` is empty, skip the task context step — just work from the diffs alone.
@@ -38,11 +40,11 @@ If either diff is empty, tell the user and stop. Both diffs must be non-empty fo
### Task context (only if `$ARGUMENTS` is non-empty)
The task name is `$ARGUMENTS`. Read the task's project context:
Resolve the task and read its context:
1. Read `.ai/$ARGUMENTS/about.md` — the project-level description of what this feature does.
2. Find the latest task iteration folder: list `.ai/$ARGUMENTS/` and pick the folder with the highest letter (`a`, `b`, `c`, ...).
3. Read `.ai/$ARGUMENTS/<latest-letter>/context.md` — the detailed implementation context the agent was working from.
1. Run `python3 .agents/skills/process-inbox/scripts/workspace.py resolve --name "$ARGUMENTS"` (use the host's Python 3 command).
2. Read the resolved task's `task.md` and `work/context.md` from the returned AI slot worktree.
3. When `project` is non-null, also read `projects/<project>/project.md`.
This helps you distinguish between:
- **Task-specific mistakes** — the agent misunderstood this particular feature's requirements or made a wrong choice within the specific problem. These are NOT documentation-worthy.
-506
View File
@@ -1,506 +0,0 @@
---
description: Implement a feature or fix using multi-agent workflow with fresh context at each phase
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion, TodoWrite
---
# Task - Multi-Agent Implementation Workflow
You orchestrate a multi-phase implementation workflow that uses fresh agent spawns to work within context window limits on a large codebase.
**Arguments:** `$ARGUMENTS` = "$ARGUMENTS"
If `$ARGUMENTS` is provided, it's the task description. If empty, ask the user what they want implemented.
## Overview
The workflow is organized around **projects**. Each project lives in `.ai/<project-name>/` and can contain multiple sequential **tasks** (labeled `a`, `b`, `c`, ... `z`).
Project structure:
```
.ai/<project-name>/
about.md # Single source of truth for the entire project
a/ # First task
context.md # Gathered codebase context for this task
plan.md # Implementation plan
review1.md # Code review documents (up to 3)
review2.md
review3.md
b/ # Follow-up task
context.md
plan.md
review1.md
c/ # Another follow-up task
...
```
- `about.md` is the project-level blueprint — a single comprehensive document describing what this project does and how it works, written as if everything is already fully implemented. It contains no temporal state ("current state", "pending changes", "not yet implemented"). It is **rewritten** (not appended to) each time a new task starts, incorporating the new task's changes as if they were always part of the design.
- Each task folder (`a/`, `b/`, ...) contains self-contained files for that task. The task's `context.md` carries all task-specific information: what specifically needs to change, the delta from the current codebase, gathered file references and code patterns. Planning, implementation, and review agents only read the current task's folder.
## Phase 0: Setup
**Record the current time now** (using `Get-Date` in PowerShell or equivalent) and store it as `$START_TIME`. You will use this at the end to display total elapsed time.
⚠️ **CRITICAL: Follow-up detection MUST happen FIRST, before anything else.**
### Step 0a: Follow-up detection (MANDATORY — do this BEFORE understanding the task)
Extract the first word/token from `$ARGUMENTS` (everything before the first space or newline). Call it `FIRST_TOKEN`.
Then run these TWO commands using the Bash tool, IN PARALLEL, right now:
1. `ls .ai/` — to see all existing project names
2. `ls .ai/<FIRST_TOKEN>/about.md` — to check if this specific project exists
**Evaluate the results:**
- If command 2 **succeeds** (the file exists): this is a **follow-up task**. The project name is `FIRST_TOKEN`. The task description is everything in `$ARGUMENTS` AFTER `FIRST_TOKEN` (strip leading whitespace).
- If command 2 **fails** (file not found): this is a **new project**. The full `$ARGUMENTS` is the task description.
**Do NOT proceed to step 0b until you have run these commands and determined follow-up vs new.**
### Step 0b: Project setup
**For new projects:**
- Using the list from command 1, pick a unique short name (1-2 lowercase words, hyphen-separated) that doesn't collide with existing projects.
- Create `.ai/<project-name>/` and `.ai/<project-name>/a/`.
- Set current task letter = `a`.
**For follow-up tasks:**
- Scan `.ai/<project-name>/` for existing task folders (`a/`, `b/`, ...). Find the latest one (highest letter).
- The previous task letter = that highest letter.
- The new task letter = next letter in sequence.
- Create `.ai/<project-name>/<new-letter>/`.
Then proceed to Phase 1 (Context Gathering) in both cases. Follow-up tasks do NOT skip context gathering — they go through a modified version of it.
## Phase 1: Context Gathering
### For New Projects (task letter = `a`)
Spawn an agent (Task tool, subagent_type=`general-purpose`) with this prompt structure:
```
You are a context-gathering agent for a large C++ codebase (Telegram Desktop).
TASK: <paste the user's task description here>
YOUR JOB: Read AGENTS.md, inspect the codebase, find ALL files and code relevant to this task, and write two documents.
Steps:
1. Read AGENTS.md for project conventions and build instructions.
2. Search the codebase for files, classes, functions, and patterns related to the task.
3. Read all potentially relevant files. Be thorough - read more rather than less.
4. For each relevant file, note:
- File path
- Relevant line ranges
- What the code does and how it relates to the task
- Key data structures, function signatures, patterns used
5. Look for similar existing features that could serve as a reference implementation.
6. Check api.tl if the task involves Telegram API.
7. Check .style files if the task involves UI.
8. Check lang.strings if the task involves user-visible text.
Write TWO files:
### File 1: .ai/<project-name>/about.md
NOTE: This file is NOT used by any agent in the current task. It exists solely as a starting point for a FUTURE follow-up task's context gatherer. No planning, implementation, or review agent will ever read it. Only the context-gathering agent of the next follow-up task reads about.md (together with the latest context.md) to produce a fresh context.md for that next task.
Write it as if the project is already fully implemented and working. It should contain:
- **Project**: What this project does (feature description, goals, scope)
- **Architecture**: High-level architectural decisions, which modules are involved, how they interact
- **Key Design Decisions**: Important choices made about the approach
- **Relevant Codebase Areas**: Which parts of the codebase this project touches, key types and APIs involved
Do NOT include temporal state like "Current State", "Pending Changes", "Not yet implemented", "TODO", or any other framing that distinguishes between "done" and "not done". Describe the project as a complete, coherent whole — as if everything is already working. This is a project overview, not a status tracker. Task-specific work belongs exclusively in context.md.
### File 2: .ai/<project-name>/a/context.md
This is the task-specific implementation context. This is the PRIMARY document — all downstream agents (planning, implementation, review) will read ONLY this file. It must be completely self-contained. It should contain:
- **Task Description**: The full task restated clearly
- **Relevant Files**: Every file path with line ranges and descriptions of what's there
- **Key Code Patterns**: How similar things are done in the codebase (with code snippets)
- **Data Structures**: Relevant types, structs, classes
- **API Methods**: Any TL schema methods involved (copied from api.tl)
- **UI Styles**: Any relevant style definitions
- **Localization**: Any relevant string keys
- **Build Info**: Build command and any special notes
- **Reference Implementations**: Similar features that can serve as templates
Be extremely thorough. Another agent with NO prior context will read this file and must be able to understand everything needed to implement the task.
```
After this agent completes, read both `about.md` and `a/context.md` to verify they were written properly.
### For Follow-up Tasks (task letter = `b`, `c`, ...)
Spawn an agent (Task tool, subagent_type=`general-purpose`) with this prompt structure:
```
You are a context-gathering agent for a follow-up task on an existing project in a large C++ codebase (Telegram Desktop).
NEW TASK: <paste the follow-up task description here>
YOUR JOB: Read the existing project state, gather any additional context needed, and produce fresh documents for the new task.
Steps:
1. Read AGENTS.md for project conventions and build instructions.
2. Read .ai/<project-name>/about.md — this is the project-level blueprint describing everything done so far.
3. Read .ai/<project-name>/<previous-letter>/context.md — this is the previous task's gathered context.
4. Understand what has already been implemented by reading the actual source files referenced in about.md and the previous context.
5. Based on the NEW TASK description, search the codebase for any ADDITIONAL files, classes, functions, and patterns that are relevant to the new task but not already covered.
6. Read all newly relevant files thoroughly.
Write TWO files:
### File 1: .ai/<project-name>/about.md (REWRITE)
NOTE: This file is NOT used by any agent in the current task. It exists solely as a starting point for a FUTURE follow-up task's context gatherer. No planning, implementation, or review agent will ever read it. You are rewriting it now so that the next follow-up has an accurate project overview to start from.
REWRITE this file (not append). The new about.md must be a single coherent document that describes the project as if everything — including this new task's changes — is already fully implemented and working.
It should incorporate:
- Everything from the old about.md that is still accurate and relevant
- The new task's functionality described as part of the project (not as "changes to make")
- Any changed design decisions or architectural updates from the new task requirements
It should NOT contain:
- Any temporal state: "Current State", "Pending Changes", "TODO", "Not yet implemented"
- History of how requirements changed between tasks
- References to "the old approach" vs "the new approach"
- Task-by-task changelog or timeline
- Any distinction between "what was done before" and "what this task adds"
- Information that contradicts the new task requirements (if the new task changes direction, the about.md should reflect the NEW direction as if it was always the plan)
Think of about.md as "the complete description of what this project does and how it works." Someone reading it should understand the full project as a finished product, without knowing it went through multiple tasks.
### File 2: .ai/<project-name>/<new-letter>/context.md
This is the PRIMARY document — all downstream agents (planning, implementation, review) will read ONLY this file. It must be completely self-contained. about.md will NOT be available to them.
It should contain:
- **Task Description**: The new task restated clearly, with enough project background (from about.md and previous context.md) that an implementation agent can understand it without reading any other .ai/ files
- **Relevant Files**: Every file path with line ranges relevant to THIS task (including files modified by previous tasks and any newly relevant files)
- **Key Code Patterns**: How similar things are done in the codebase
- **Data Structures**: Relevant types, structs, classes
- **API Methods**: Any TL schema methods involved
- **UI Styles**: Any relevant style definitions
- **Localization**: Any relevant string keys
- **Build Info**: Build command and any special notes
- **Reference Implementations**: Similar features that can serve as templates
Be extremely thorough. Another agent with NO prior context will read ONLY this file and must be able to understand everything needed to implement the new task. Do NOT assume the reader has seen about.md or any previous task files. The context.md is the single source of truth for all downstream agents — it must include all relevant project background, not just the delta.
```
After this agent completes, read both `about.md` and `<new-letter>/context.md` to verify they were written properly.
## Phase 2: Planning
Spawn an agent (Task tool, subagent_type=`general-purpose`) with this prompt structure:
```
You are a planning agent. You must create a detailed implementation plan.
Read these files:
- .ai/<project-name>/<letter>/context.md - Contains all gathered context for this task
- Then read the specific source files referenced in context.md to understand the code deeply.
Think carefully about the implementation approach.
Create a detailed plan in: .ai/<project-name>/<letter>/plan.md
The plan.md should contain:
## Task
<one-line summary>
## Approach
<high-level description of the implementation approach>
## Files to Modify
<list of files that will be created or modified>
## Files to Create
<list of new files, if any>
## Implementation Steps
Each step must be specific enough that an agent can execute it without ambiguity:
- Exact file paths
- Exact function names
- What code to add/modify/remove
- Where exactly in the file (after which function, in which class, etc.)
Number every step. Group steps into phases if there are more than ~8 steps.
### Phase 1: <name>
1. <specific step>
2. <specific step>
...
### Phase 2: <name> (if needed)
...
## Build Verification
- Build command to run
- Expected outcome
## Status
- [ ] Phase 1: <name>
- [ ] Phase 2: <name> (if applicable)
- [ ] Build verification
- [ ] Code review
```
After this agent completes, read `plan.md` to verify it was written properly.
## Phase 3: Plan Assessment
Spawn an agent (Task tool, subagent_type=`general-purpose`) with this prompt structure:
```
You are a plan assessment agent. Review and refine an implementation plan.
Read these files:
- .ai/<project-name>/<letter>/context.md
- .ai/<project-name>/<letter>/plan.md
- Then read the actual source files referenced to verify the plan makes sense.
Carefully assess the plan:
1. **Correctness**: Are the file paths and line references accurate? Does the plan reference real functions and types?
2. **Completeness**: Are there missing steps? Edge cases not handled?
3. **Code quality**: Will the plan minimize code duplication? Does it follow existing codebase patterns from AGENTS.md?
4. **Design**: Could the approach be improved? Are there better patterns already used in the codebase?
5. **Phase sizing**: Each phase should be implementable by a single agent in one session. If a phase has more than ~8-10 substantive code changes, split it further.
Update plan.md with your refinements. Keep the same structure but:
- Fix any inaccuracies
- Add missing steps
- Improve the approach if you found better patterns
- Ensure phases are properly sized for single-agent execution
- Add a line at the top of the Status section: `Phases: <N>` indicating how many implementation phases there are
- Add `Assessed: yes` at the bottom of the file
If the plan is small enough for a single agent (roughly <=8 steps), mark it as a single phase.
```
After this agent completes, read `plan.md` to verify it was assessed.
## Phase 4: Implementation
Now read `plan.md` yourself to understand the phases.
For each phase in the plan that is not yet marked as done, spawn an implementation agent (Task tool, subagent_type=`general-purpose`):
```
You are an implementation agent working on phase <N> of an implementation plan.
Read these files first:
- .ai/<project-name>/<letter>/context.md - Full codebase context
- .ai/<project-name>/<letter>/plan.md - Implementation plan
Then read the source files you'll be modifying.
YOUR TASK: Implement ONLY Phase <N> from the plan:
<paste the specific phase steps here>
Rules:
- Follow the plan precisely
- Follow AGENTS.md coding conventions (no comments except complex algorithms, use auto, empty line before closing brace, etc.)
- Do NOT modify .ai/ files except to update the Status section in plan.md
- When done, update plan.md Status section: change `- [ ] Phase <N>: ...` to `- [x] Phase <N>: ...`
- Do NOT work on other phases
When finished, report what you did and any issues encountered.
```
After each implementation agent returns:
1. Read `plan.md` to check the status was updated.
2. If more phases remain, spawn the next implementation agent.
3. If all phases are done, proceed to build verification.
## Phase 5: Build Verification
Only run this phase if the task involved modifying project source code (not just docs or config).
Spawn a build verification agent (Task tool, subagent_type=`general-purpose`):
```
You are a build verification agent.
Read these files:
- .ai/<project-name>/<letter>/context.md
- .ai/<project-name>/<letter>/plan.md
The implementation is complete. Your job is to build the project and fix any build errors.
Steps:
1. Run (from repository root): cmake --build ./out --config Debug --target Telegram
2. If the build succeeds, update plan.md: change `- [ ] Build verification` to `- [x] Build verification`
3. If the build fails:
a. Read the error messages carefully
b. Read the relevant source files
c. Fix the errors in accordance with the plan and AGENTS.md conventions
d. Rebuild and repeat until the build passes
e. Update plan.md status when done
Rules:
- Only fix build errors, do not refactor or improve code
- Follow AGENTS.md conventions
- If build fails with file-locked errors (C1041, LNK1104), STOP and report - do not retry
When finished, report the build result.
```
After the build agent returns, read `plan.md` to confirm the final status. Then proceed to Phase 6.
## Phase 6: Code Review Loop
After build verification passes, run up to 3 review-fix iterations to improve code quality. Set iteration counter `R = 1`.
### Review Loop
```
LOOP:
1. Spawn review agent (Step 6a) with iteration R
2. Read review<R>.md verdict:
- "APPROVED" → go to FINISH
- Has improvement suggestions → spawn fix agent (Step 6b)
3. After fix agent completes and build passes:
R = R + 1
If R > 3 → go to FINISH (stop iterating, accept current state)
Otherwise → go to step 1
FINISH:
- Update plan.md: change `- [ ] Code review` to `- [x] Code review`
- Proceed to Completion
```
### Step 6a: Code Review Agent
Spawn an agent (Task tool, subagent_type=`general-purpose`):
```
You are a code review agent for Telegram Desktop (C++ / Qt).
Read these files:
- .ai/<project-name>/<letter>/context.md - Codebase context
- .ai/<project-name>/<letter>/plan.md - Implementation plan
- REVIEW.md - Style and formatting rules to enforce
<if R > 1, also read:>
- .ai/<project-name>/<letter>/review<R-1>.md - Previous review (to see what was already addressed)
Then run `git diff` to see all uncommitted changes made by the implementation. Implementation agents do not commit, so `git diff` shows exactly the current feature's changes.
Then read the modified source files in full to understand changes in context.
Perform a thorough code review.
REVIEW CRITERIA (in order of importance):
1. **Correctness and safety**: Obvious logic errors, missing null checks at API boundaries, potential crashes, use-after-free, dangling references, race conditions. This is the highest priority — bugs and safety issues must be caught first. Do NOT nitpick internal code that relies on framework guarantees.
2. **Dead code**: Any code added or left behind that is never called or used, within the scope of the changes. Unused variables, unreachable branches, leftover scaffolding.
3. **Redundant changes**: Changes in the diff that have no functional effect — moving declarations or code blocks to a different location without reason, reformatting untouched code, reordering includes or fields with no purpose. Every line in the diff should serve the feature. If a file appears in `git diff` but contains only no-op rearrangements, flag it for revert.
4. **Code duplication**: Unnecessary repetition of logic that should be shared. Look for near-identical blocks that differ only in minor details and could be unified.
5. **Wrong placement**: Code added to a module where it doesn't logically belong. If another existing module is a clearly better fit for the new code, flag it. Consider the existing module boundaries and responsibilities visible in context.md.
6. **Function decomposition**: For longer functions (roughly 50+ lines), consider whether a logical sub-task could be cleanly extracted into a separate function. This is NOT a hard rule — a 100-line function that flows naturally and isn't easily divisible is perfectly fine. But sometimes even a 20-line function contains a clear isolated subtask that reads better as two 10-line functions. The key is to think about it each time: does extracting improve readability and reduce cognitive load, or does it just scatter logic across call sites for no real benefit? Only suggest extraction when there's a genuinely self-contained piece of logic with a clear name and purpose.
7. **Module structure**: Only in exceptional cases — if a large amount of newly added code (hundreds of lines) is logically distinct from the rest of its host module, suggest extracting it into a new module. But do NOT suggest new modules lightly: every module adds significant build overhead due to PCH and heavy template usage. Only suggest this when the new code is both large enough AND logically separated enough to justify it. At the same time, don't let modules grow into multi-thousand-line monoliths either.
8. **Style compliance**: Verify adherence to REVIEW.md rules (empty line before closing brace, operators at start of continuation lines, minimize type checks with direct cast instead of is+as, no if-with-initializer when simpler alternatives exist) and AGENTS.md conventions (no unnecessary comments, `auto` usage, no hardcoded sizes — must use .style definitions), etc.
IMPORTANT GUIDELINES:
- Review ONLY the changes made, not pre-existing code in the repository.
- Be pragmatic. Don't suggest changes for the sake of it. Each suggestion should have a clear, concrete benefit.
- Don't suggest adding comments, docstrings, or type annotations — the codebase style avoids these.
- Don't suggest error handling for impossible scenarios or over-engineering.
Write your review to: .ai/<project-name>/<letter>/review<R>.md
The review document should contain:
## Code Review - Iteration <R>
## Summary
<1-2 sentence overall assessment>
## Verdict: <APPROVED or NEEDS_CHANGES>
<If APPROVED, stop here. Everything looks good.>
<If NEEDS_CHANGES, continue with:>
## Changes Required
### <Issue 1 title>
- **Category**: <dead code | duplication | wrong placement | function decomposition | module structure | style | correctness>
- **File(s)**: <file paths>
- **Problem**: <clear description of what's wrong>
- **Fix**: <specific description of what to change>
### <Issue 2 title>
...
Keep the list focused. Only include issues that genuinely improve the code. If you find yourself listing more than ~5-6 issues, prioritize the most impactful ones.
When finished, report your verdict clearly as: APPROVED or NEEDS_CHANGES.
```
After the review agent returns, read `review<R>.md`. If the verdict is APPROVED, proceed to Completion. If NEEDS_CHANGES, spawn the fix agent.
### Step 6b: Review Fix Agent
Spawn an agent (Task tool, subagent_type=`general-purpose`):
```
You are a review fix agent. You implement improvements identified during code review.
Read these files:
- .ai/<project-name>/<letter>/context.md - Codebase context
- .ai/<project-name>/<letter>/plan.md - Original implementation plan
- .ai/<project-name>/<letter>/review<R>.md - Code review with required changes
Then read the source files mentioned in the review.
YOUR TASK: Implement ALL changes listed in review<R>.md.
For each issue in the review:
1. Read the relevant source file(s).
2. Make the specified change.
3. Verify the change makes sense in context.
After all changes are made:
1. Build (from repository root): cmake --build ./out --config Debug --target Telegram
2. If the build fails, fix build errors and rebuild until it passes.
3. If build fails with file-locked errors (C1041, LNK1104), STOP and report - do not retry.
Rules:
- Implement exactly the changes from the review, nothing more.
- Follow AGENTS.md coding conventions.
- Do NOT modify .ai/ files.
When finished, report what changes were made.
```
After the fix agent returns, increment R and loop back to Step 6a (unless R > 3, in which case proceed to Completion).
## Completion
When all phases including build verification and code review are done:
1. Read the final `plan.md` and report the summary to the user.
2. Show which files were modified/created.
3. Note any issues encountered during implementation.
4. Summarize code review iterations: how many rounds, what was found and fixed, or if it was approved on first pass.
5. Calculate and display the total elapsed time since `$START_TIME` (format as `Xh Ym Zs`, omitting zero components — e.g. `12m 34s` or `1h 5m 12s`).
6. Remind the user of the project name so they can use `/task <project-name> <follow-up description>` for follow-up changes.
## Error Handling
- If any agent fails or gets stuck, report the issue to the user and ask how to proceed.
- If context.md or plan.md is not written properly by an agent, re-spawn that agent with more specific instructions.
- If build errors persist after the build agent's attempts, report the remaining errors to the user.
- If a review fix agent introduces new build errors that it cannot resolve, report to the user.
+1
View File
@@ -3,6 +3,7 @@ Debug/
Release/
/ThirdParty/
/Telegram/build/target
/Telegram/build/ai-machine-tag
/Telegram/tests/
/Telegram/gyp/tests/*.test
/Telegram/out/
+8 -3
View File
@@ -21,7 +21,7 @@ wsl.exe -d {distro} --cd /home/{user}/Telegram/tdesktop -- <command>
- For WSL/Linux builds, use the Docker build entry point from the repository root: `Telegram/build/docker/centos_env/build_debug.sh`. The Docker daemon must be reachable from WSL; checking `docker info` is fine, but do not start a build unless the user asked for one.
- Existing build outputs may be Linux binaries, for example `out/Debug/Telegram` as an ELF executable, not `Telegram.exe`. Verify the build tree before assuming which platform produced it.
- Be careful with text file line endings. In a WSL/Linux checkout, files should remain LF-only unless the file already uses another convention. CRLF finishing applies only to native, non-WSL Windows runs/checkouts. Do not let PowerShell or Windows tools silently rewrite WSL files to CRLF. If a file becomes mixed, normalize it back to the convention appropriate for the current checkout, without adding a UTF-8 BOM.
- When using the local `task-think` skill from this WSL checkout, keep `.ai/...` artifacts and edited project text files LF-only. Treat the skill's Windows text-normalization phase as not applicable to WSL, except to record that line endings were checked and kept LF/no-BOM. Run CRLF normalization for `task-think` only in a native, non-WSL Windows checkout.
- When using the local `perform-task` skill from this WSL checkout, keep external AI task artifacts and edited project text files LF-only. Treat its Windows text-normalization phase as not applicable to WSL, except to record that line endings were checked and kept LF/no-BOM. Run CRLF normalization only in a native, non-WSL Windows checkout.
## Build System Structure
@@ -132,9 +132,14 @@ Retrying builds wastes time and context. The ONLY fix is for the user to close t
## Commits
- Subject: one concise, plain-language line summarizing the change, ~50-60 characters, matching the style of recent `git log` subjects. This is usually the entire message.
- Add a short plain-language body only when the subject can't carry it (what was done, not the technical how) — a line or two at most.
- For ordinary work not associated with an AI task, add a short plain-language body only when the subject can't carry it (what was done, not the technical how) — a line or two at most.
- Never add a `Co-Authored-By:` line or any tool/assistant attribution trailer.
- Never add `Autotask:`/attempt or other workflow markers commits read like normal history.
- Never add `Autotask:`/attempt or other internal run markers. A commit owned by
an `ai-tdesktop` task has exactly three lines: the concise subject, a blank
line, and `Task: <task-id>`. Do not add a body. Keep rationale and
implementation notes out of the commit message; put a short durable note
under `tasks/<task-id>.md` only when useful. Do not copy commit hashes into
that note or any AI task artifact; the task id is the cross-repository link.
## Local Storage Serialization