mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Reconcile harness docs with stale crash setup
Task: 2026/07/30/reconcile-harness-docs-with-setup-contract
This commit is contained in:
@@ -26,8 +26,8 @@ adapter point; every other rule here still applies.
|
||||
- `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.
|
||||
- `EVIDENCE_DIR` — a required run-specific directory the repository ignores; it holds per-run logs,
|
||||
screenshots, and preserved stale-crash payloads.
|
||||
- **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
|
||||
@@ -70,9 +70,12 @@ signature, perform the one-time clean-rebuild recovery under "Crashes & assertio
|
||||
UNRECOVERABLE conditions: the app reaches a login screen / `AUTH_KEY_DUPLICATED` and re-copying the
|
||||
test account does not recover it, or a crash has no usable diagnostic after one retry and the
|
||||
macOS cached-language recovery below does not apply. Missing `test_TelegramForcePortable` is a
|
||||
global environment hard stop, not a task `Block`. A file-lock build error (`LNK1104`, `C1041`,
|
||||
access denied, file in use) is likewise a repository hard stop: do not retry or work around it;
|
||||
ask the user to close the app and debugger.
|
||||
global environment hard stop, not a task `Block`. An unmovable stale-report refusal is also a
|
||||
global environment hard stop, not a task `Block`: report the exact helper refusal, consume no
|
||||
implementation attempt, do not immediately retry it, and wait for the external lock or permission
|
||||
condition to be resolved. A file-lock build error (`LNK1104`, `C1041`, access denied, file in use)
|
||||
is likewise a repository hard stop: do not retry or work around it; ask the user to close the app
|
||||
and debugger.
|
||||
|
||||
## Handoff tokens
|
||||
|
||||
@@ -108,12 +111,13 @@ The debug build runs in portable mode out of `out/Debug/`. Three sibling folders
|
||||
- `real_TelegramForcePortable` — the user's real data, preserved so manual use survives. Once it
|
||||
exists, NO flow step may ever delete, rename, move, overwrite, or write into it.
|
||||
|
||||
**SETUP — run at the START of every test run, with NO app instance alive. Idempotent, and a pure
|
||||
no-op between runs and between consecutive tasks (the marked test copy is simply reused).**
|
||||
**SETUP — run at the START of every test run, with NO app instance alive. It is idempotent: the
|
||||
first SETUP after a crash moves leftover crash files and can refuse before launch; after successful
|
||||
relocation, the next SETUP finds nothing left to move.**
|
||||
The workspace helper's `test-run` command performs exactly these steps before every launch, and
|
||||
`test-account-reset` performs the broken-account recovery below; the manual steps remain the
|
||||
contract those commands implement.
|
||||
1. Require `test_TelegramForcePortable`. Its absence is the only portable-account setup blocker.
|
||||
1. Require `test_TelegramForcePortable`. Its absence is a portable-account setup blocker.
|
||||
2. If `TelegramForcePortable/testing` exists, the live folder is already the reusable test copy:
|
||||
never copy, move, or delete any of the three folders. Clear only what an earlier run left
|
||||
inside the live copy — move a non-empty `TelegramForcePortable/tdata/working` into
|
||||
@@ -140,10 +144,11 @@ Any live/real folder combination is never a blocker. After SETUP the live folder
|
||||
copy, the golden folder is untouched, and `real_...` may or may not exist.
|
||||
|
||||
**NO CLEANUP — the flow performs no folder operations after testing, ever.** The marked test copy
|
||||
stays live, so the next run or next task starts with SETUP as a no-op and the folders are never
|
||||
copied, moved, or deleted between testing phases. The flow never restores real data to live: when
|
||||
the user wants manual use they copy `real_...` to `TelegramForcePortable` themselves (keeping
|
||||
`real_...` in place), and the next SETUP handles that unmarked live folder by step 3.
|
||||
stays live, and the three folders are never copied, moved, or deleted between testing phases. SETUP
|
||||
may move stale crash files from inside the marked live copy before a launch; this is not a folder
|
||||
operation. The flow never restores real data to live: when the user wants manual use they copy
|
||||
`real_...` to `TelegramForcePortable` themselves (keeping `real_...` in place), and the next SETUP
|
||||
handles that unmarked live folder by step 3.
|
||||
|
||||
Deletion guard — the only folder the flow may ever delete is a live `TelegramForcePortable` that
|
||||
either carries the `testing` marker or coexists with `real_...` (step 3). If the test account
|
||||
@@ -458,16 +463,24 @@ bypass it with hand-built relative paths.
|
||||
shows no difference from before is the symptom of skipping this.
|
||||
- Run: execute the workspace helper's `test-run` command with `EXE` and `EVIDENCE_DIR`. One call
|
||||
performs the SETUP steps (Test account), creates `EVIDENCE_DIR`, path-scope-kills stragglers,
|
||||
launches `EXE` **with `-testagent -noupdate`** (so a shipped update can never replace the
|
||||
binary under test mid-run) capturing stdout to `<EVIDENCE_DIR>/app_stdout.txt` and
|
||||
stderr to `<EVIDENCE_DIR>/app_stderr.txt` (the flag prevents modal crash hangs, and stderr
|
||||
captures assertion text), enforces **a hard wall-clock deadline from launch** and a quiet-log
|
||||
watchdog while polling `<EVIDENCE_DIR>/test_log.txt`, detects `TEST_COMPLETE` (success) versus
|
||||
process death (crash) versus the caps elapsing (hang), kills any straggler, and returns one JSON
|
||||
report with the parsed markers, stderr tail, and fresh crash diagnostics. Then read each
|
||||
`SCREENSHOT:` image and judge it, save the binary overlay patch, and restore only inventoried
|
||||
overlay paths (`overlay-save` — the patch must be saved before that restore). The runner only
|
||||
gathers evidence; ASSESS below stays the agent's own adversarial judgement.
|
||||
then, for a reused marked-live account, moves a non-empty live `tdata/working` to
|
||||
`<EVIDENCE_DIR>/stale-crash/working` and every live `tdata/dumps/*.dmp` to
|
||||
`<EVIDENCE_DIR>/stale-crash/dumps/` before launch. A zero-byte `tdata/working` is neither moved
|
||||
nor reported. It launches `EXE` **with `-testagent -noupdate`** (so a shipped update can never
|
||||
replace the binary under test mid-run) capturing stdout to
|
||||
`<EVIDENCE_DIR>/app_stdout.txt` and stderr to `<EVIDENCE_DIR>/app_stderr.txt` (the flag prevents
|
||||
modal crash hangs, and stderr captures assertion text), enforces **a hard wall-clock deadline
|
||||
from launch** and a quiet-log watchdog while polling `<EVIDENCE_DIR>/test_log.txt`, detects
|
||||
`TEST_COMPLETE` (success) versus process death (crash) versus the caps elapsing (hang), kills any
|
||||
straggler, and returns one JSON report with the parsed markers, stderr tail, fresh crash
|
||||
diagnostics, and `stale_crash_cleared`. That field is an ordered list of `{from, kind, to}`
|
||||
entries whose `kind` is `"report"` or `"dump"`, and is `[]` when nothing was cleared. If the
|
||||
stale report cannot be moved, `test-run` refuses before launch, prints the helper error on stderr,
|
||||
exits non-zero, and emits no JSON. If a dump cannot be moved, `test-run` leaves it in place,
|
||||
records `"to": null` (a null destination), and continues to launch. Then read each `SCREENSHOT:`
|
||||
image and judge it, save the binary overlay patch, and restore only inventoried overlay paths
|
||||
(`overlay-save` — the patch must be saved before that restore). The runner only gathers evidence;
|
||||
ASSESS below stays the agent's own adversarial judgement.
|
||||
|
||||
### Crashes & assertions (always launch the test binary with `-testagent`)
|
||||
|
||||
|
||||
@@ -437,17 +437,30 @@ rules, with these external-task safety adaptations:
|
||||
actions or Qt events, log assertions and geometry, capture widgets/windows
|
||||
in-process, save the artifacts, and quit. Do not require an OS-level desktop
|
||||
screenshot or interactive Computer Use evidence.
|
||||
- Missing `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.
|
||||
- Missing `test_TelegramForcePortable` is a portable-account setup blocker. A
|
||||
`testing` marker file inside the live folder marks it as the reusable test
|
||||
copy: never copy, move, or delete any of the three folders on this branch.
|
||||
For this reused marked-live account only, after the exact-path straggler kill
|
||||
and before launch, `test-run` moves a non-empty live `tdata/working` to
|
||||
`RUN_DIR/stale-crash/working` and every live `tdata/dumps/*.dmp` to
|
||||
`RUN_DIR/stale-crash/dumps/`; a zero-byte `tdata/working` is neither moved
|
||||
nor reported. The report is moved because leaving it makes the app show the
|
||||
previous-launch window instead of starting, so no `test_log.txt` is written
|
||||
and the run reads as a hang. A leftover dump never blocks launch and is
|
||||
moved only to keep the current run's mtime-filtered dump report free of old
|
||||
minidumps. After successful relocation, the next SETUP finds nothing left
|
||||
to move. 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. The four account
|
||||
results remain `fresh-copy`, `reused-marked-live`, `preserved-real`, and
|
||||
`replaced-manual-live`; clearing creates no fifth account state. 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.
|
||||
- Set `RUN_DIR` and `EVIDENCE_DIR` to
|
||||
`TASK_DIR/.local/runs/attempt-<n>/run-<m>/`. Promote only decisive compact
|
||||
logs/screenshots into tracked `evidence/`.
|
||||
`TASK_DIR/.local/runs/attempt-<n>/run-<m>/`, an ignored run-specific path.
|
||||
Promote only decisive compact logs/screenshots and decisive preserved
|
||||
`RUN_DIR/stale-crash/` payloads into tracked `evidence/`; keep promotion
|
||||
selective rather than committing every large dump.
|
||||
- Execute every app run through the scripted runner instead of hand-composed
|
||||
launch/poll/kill shell:
|
||||
|
||||
@@ -458,13 +471,21 @@ rules, with these external-task safety adaptations:
|
||||
```
|
||||
|
||||
One call performs the idempotent portable-account SETUP, the path-scoped
|
||||
straggler kill, the `-testagent -noupdate` launch (never auto-update a
|
||||
test binary) with stdout/stderr capture and
|
||||
`TDESKTOP_TEST_EVIDENCE_DIR` set to `RUN_DIR`, the external wall-clock
|
||||
deadline and quiet-log watchdog, and returns one JSON report: outcome,
|
||||
`TEST_COMPLETE` state, parsed `TEST_STEP`/`TEST_RESULT`/`SCREENSHOT`
|
||||
markers, stderr tail, fresh `tdata/working` crash excerpt, and minidump
|
||||
paths. The performer then judges the evidence itself — the runner gathers,
|
||||
straggler kill, stale-crash relocation for a reused marked-live account
|
||||
after that kill and before launch, and the `-testagent -noupdate` launch
|
||||
(never auto-update a test binary) with stdout/stderr capture and
|
||||
`TDESKTOP_TEST_EVIDENCE_DIR` set to `RUN_DIR`. It enforces the external
|
||||
wall-clock deadline and quiet-log watchdog and returns one JSON report:
|
||||
outcome, `TEST_COMPLETE` state, parsed
|
||||
`TEST_STEP`/`TEST_RESULT`/`SCREENSHOT` markers, stderr tail, fresh
|
||||
`tdata/working` crash excerpt, minidump paths, and
|
||||
`stale_crash_cleared`. That field is an ordered list of
|
||||
`{from, kind, to}` entries whose `kind` is `"report"` or `"dump"`, and is
|
||||
`[]` when nothing was cleared. If a stale report cannot be moved, `test-run`
|
||||
refuses before launch, prints the helper error on stderr, exits non-zero,
|
||||
and emits no JSON. If a dump cannot be moved, the run leaves it in place,
|
||||
records its entry with `"to": null` (a null destination), and continues to
|
||||
launch. The performer then judges the evidence itself — the runner gathers,
|
||||
it never assesses. Crash detection keys on process death without
|
||||
`TEST_COMPLETE` plus a fresh `tdata/working`, not exit code.
|
||||
- If the account breaks mid-loop (login screen, `AUTH_KEY_DUPLICATED`), run
|
||||
|
||||
Reference in New Issue
Block a user