.agents/skills/perform-task/references/pipeline.md
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:
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
RUN_REF = refs/ai-tasks/TASK_ID/run
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:
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.
Before planning or editing:
Read SOURCE_ROOT/AGENTS.md, REVIEW.md, AI_SLOT/AGENTS.md, TASK_SPEC,
every referenced input, and relevant project context.
Verify state.yaml is in-progress and owned by this checkout tag.
Require the prepared portable test account. Its absence is a global hard stop before implementation.
Verify a usable Debug executable/build tree, safe path-scoped process
control, safe portable-folder operations, and the ability to launch and
render the in-binary test flow. A locked macOS session disables Computer Use
only; it does not fail this preflight or block testing, even when policy was
required.
For a new run require a clean tracked Telegram worktree, clean submodules, and no unrelated untracked files, then initialize local recovery state:
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, rediscovers the
latest exact Task: commit from current first-parent history when needed,
and records current HEAD in RUN_REF. Later task commits may remain above
the retained implementation. Never resolve or record a ref's object name in
an artifact.
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 RUN_REF or BASE_REF, as appropriate.
Use tracked, resumable task artifacts:
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:
.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 record the current phase
locally:
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
checkpoint --source-root SOURCE_ROOT --task TASK_ID --phase PHASE
Record progress after context, assessed plan, each completed implementation
phase when useful for recovery, the retained implementation commit, review,
and each material test attempt. Never mark a half-written artifact complete.
The helper changes only task-scoped files in the slot worktree and publishes no
checkpoint commit. Keep this local dirty state until the final Approve or
exceptional Block commit captures the whole task record.
Use references/phase-prompts.md for the exact context, plan, assessment,
implementation, build, review, and native-Windows normalization prompts.
fork_turns: "none" with explicit paths. Fork the smallest turn window
only for genuinely unavailable chat-only visual context.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.
Run sequentially:
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.
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.
Plan. Write work/plan.md with exact files, functions, ordered steps,
bounded phases, owned write sets, Debug build verification, and status
checkboxes.
Assess. Independently verify paths and APIs, completeness, design,
duplication, edge cases, repository conventions, and phase sizing. Require
Phases: <N> and Assessed: yes.
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.
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.
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.
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.
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:
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
source-mark-green --source-root SOURCE_ROOT --task TASK_ID
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:
<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 original local baseline,
GREEN_REF as the latest retained exact task commit, and RUN_REF as the
current clean source tip on which this resumed run operates. Later tasks may
make GREEN_REF an ancestor of RUN_REF. These refs are local recovery
mechanics: never copy their resolved object names into AI artifacts, source
notes, reports, chat, or commit messages.
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:
work/test-overlay.paths; never introduce an untracked source file.git diff --binary HEAD > work/test-overlay.patch,
verify it is nonempty and reapplicable, then restore only inventoried overlay
paths to RUN_REF. Do not run a repository-wide hard reset. After an
implementation-fix commit, move both GREEN_REF and RUN_REF to the new
clean tip before reapplying the overlay.git apply --3way; re-author a conflicting hunk from test.md
rather than leaving conflict markers.test_TelegramForcePortable is the only portable-account setup
blocker. A testing marker file inside the live folder marks it as the
reusable test copy: marker present means touch no folders and go test. An
unmarked live folder is real data: move it to real when real is absent;
delete it only when real already exists. Only then deep-copy golden to live
and create the testing marker inside the copy. There is NO folder cleanup
after testing — the marked copy stays live for the next run and next task.
Never delete, rename, move, or alter golden or real.RUN_DIR and EVIDENCE_DIR to
TASK_DIR/.local/runs/attempt-<n>/run-<m>/. Promote only decisive compact
logs/screenshots into tracked evidence/.-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.EXE. Never use image-name-wide termination.MAX_TEST_RUNS.MAX_TEST_RUNS is a safety cap,
never a budget to spend.The test author must read the full task specification and every current-branch
commit whose message has this task's exact Task: line. For an uninterrupted
contiguous run this is the BASE_REF..GREEN_REF diff; for a resumed older task,
combine the exact task commits and inspect their current code at RUN_REF
without treating intervening tasks as this task's changes. It writes checks
before running, covers every acceptance surface, declares a falsifiable oracle
for each, compresses all checks into the fewest possible runs — normally
exactly one — and never reuses a generic navigate-and-screenshot scenario. Missing
or ambiguous evidence is TEST_FLAW; no expected task delta 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.
Before publishing an approved result or genuine blocked boundary, require a
clean Telegram checkout at RUN_REF, with GREEN_REF in its history when an
implementation is retained, no overlay in source, and no overlay-bearing
executable. The marked live test copy stays in place per the test-loop folder
rules. 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:
# 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 final AI state only after the Telegram commit and result are final:
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 retained implementation's exact three-line commit message. It commits
all task-scoped local artifacts and final state as Approve <TASK_ID> or the
exceptional Block <TASK_ID>, fetches newer canonical state when configured,
rebases the slot, publishes without force, and fast-forwards local AI master.
It deletes all local task refs after approval; after a block it deletes only
RUN_REF and retains implementation recovery refs for the next invocation.
Do not report final state until that AI commit reaches canonical master.
Preserve an unpublished final 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.
in-progress; a later continue invocation resumes it. A later
invocation reopens a published blocked task locally without a Resume
commit.blocked attempt leaves the task unfinished. It lets continue
proceed with independent work, but the next invocation retries it once before
starting new shared work. A dirty/non-buildable checkout or global
environment problem stops the current invocation.work/test.md, work/result.md, and evidence paths.