baxian 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/README.zh-CN.md +5 -7
- package/dist/agent/bootstrap.d.ts.map +1 -1
- package/dist/agent/bootstrap.js +2 -4
- package/dist/agent/bootstrap.js.map +1 -1
- package/dist/agent/branch.d.ts +0 -12
- package/dist/agent/branch.d.ts.map +1 -1
- package/dist/agent/branch.js +1 -71
- package/dist/agent/branch.js.map +1 -1
- package/dist/agent/dispatch-reconciler.d.ts.map +1 -1
- package/dist/agent/dispatch-reconciler.js +9 -9
- package/dist/agent/dispatch-reconciler.js.map +1 -1
- package/dist/agent/manager.d.ts +65 -138
- package/dist/agent/manager.d.ts.map +1 -1
- package/dist/agent/manager.js +928 -2442
- package/dist/agent/manager.js.map +1 -1
- package/dist/agent/pane-streamer.d.ts +4 -1
- package/dist/agent/pane-streamer.d.ts.map +1 -1
- package/dist/agent/pane-streamer.js +25 -5
- package/dist/agent/pane-streamer.js.map +1 -1
- package/dist/agent/phase-signal-watcher.d.ts +2 -11
- package/dist/agent/phase-signal-watcher.d.ts.map +1 -1
- package/dist/agent/phase-signal-watcher.js +38 -87
- package/dist/agent/phase-signal-watcher.js.map +1 -1
- package/dist/agent/phase-signal.d.ts +14 -40
- package/dist/agent/phase-signal.d.ts.map +1 -1
- package/dist/agent/phase-signal.js +47 -90
- package/dist/agent/phase-signal.js.map +1 -1
- package/dist/agent/preflight.d.ts +0 -1
- package/dist/agent/preflight.d.ts.map +1 -1
- package/dist/agent/preflight.js +8 -15
- package/dist/agent/preflight.js.map +1 -1
- package/dist/agent/prompt.d.ts +1 -30
- package/dist/agent/prompt.d.ts.map +1 -1
- package/dist/agent/prompt.js +21 -148
- package/dist/agent/prompt.js.map +1 -1
- package/dist/agent/repo-store.d.ts.map +1 -1
- package/dist/agent/repo-store.js +0 -4
- package/dist/agent/repo-store.js.map +1 -1
- package/dist/agent/root-agent-runtime.d.ts.map +1 -1
- package/dist/agent/root-agent-runtime.js +4 -2
- package/dist/agent/root-agent-runtime.js.map +1 -1
- package/dist/agent/root-recovery-coordinator.d.ts +0 -1
- package/dist/agent/root-recovery-coordinator.d.ts.map +1 -1
- package/dist/agent/root-recovery-coordinator.js +39 -61
- package/dist/agent/root-recovery-coordinator.js.map +1 -1
- package/dist/agent/vt-visible-text.d.ts +42 -0
- package/dist/agent/vt-visible-text.d.ts.map +1 -0
- package/dist/agent/vt-visible-text.js +482 -0
- package/dist/agent/vt-visible-text.js.map +1 -0
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +6 -2
- package/dist/api/config.js.map +1 -1
- package/dist/api/platform-guard.js +2 -2
- package/dist/api/platform-guard.js.map +1 -1
- package/dist/api/projects.d.ts.map +1 -1
- package/dist/api/projects.js +598 -318
- package/dist/api/projects.js.map +1 -1
- package/dist/api/tasks.d.ts.map +1 -1
- package/dist/api/tasks.js +15 -39
- package/dist/api/tasks.js.map +1 -1
- package/dist/config/loader.d.ts +5 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +36 -24
- package/dist/config/loader.js.map +1 -1
- package/dist/config/validator.d.ts +7 -4
- package/dist/config/validator.d.ts.map +1 -1
- package/dist/config/validator.js +57 -73
- package/dist/config/validator.js.map +1 -1
- package/dist/event/handlers.d.ts.map +1 -1
- package/dist/event/handlers.js +359 -226
- package/dist/event/handlers.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +1 -1
- package/dist/platform/command-renderer.d.ts +6 -0
- package/dist/platform/command-renderer.d.ts.map +1 -1
- package/dist/platform/command-renderer.js +20 -0
- package/dist/platform/command-renderer.js.map +1 -1
- package/dist/platform/driver-host.d.ts.map +1 -1
- package/dist/platform/driver-host.js +3 -1
- package/dist/platform/driver-host.js.map +1 -1
- package/dist/platform/driver-spec.d.ts.map +1 -1
- package/dist/platform/driver-spec.js +32 -4
- package/dist/platform/driver-spec.js.map +1 -1
- package/dist/platform/git-driver.d.ts +2 -0
- package/dist/platform/git-driver.d.ts.map +1 -1
- package/dist/platform/git-driver.js +9 -3
- package/dist/platform/git-driver.js.map +1 -1
- package/dist/platform/platform-poller.d.ts +0 -1
- package/dist/platform/platform-poller.d.ts.map +1 -1
- package/dist/platform/platform-poller.js +0 -6
- package/dist/platform/platform-poller.js.map +1 -1
- package/dist/platform/plugins/github/driver.json +5 -0
- package/dist/platform/plugins/github/skills/baxian-cli-gh/SKILL.md +20 -14
- package/dist/platform/startup.d.ts.map +1 -1
- package/dist/platform/startup.js +5 -5
- package/dist/platform/startup.js.map +1 -1
- package/dist/platform/types.d.ts +1 -0
- package/dist/platform/types.d.ts.map +1 -1
- package/dist/platform/types.js +3 -3
- package/dist/platform/types.js.map +1 -1
- package/dist/shared/constants.d.ts +1 -6
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +2 -29
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/types.d.ts +28 -124
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +7 -6
- package/dist/shared/types.js.map +1 -1
- package/dist/skills/baxian-pr-feedback/SKILL.md +5 -3
- package/dist/skills/baxian-pr-recheck/SKILL.md +4 -0
- package/dist/skills/baxian-pr-review/SKILL.md +4 -0
- package/dist/skills/baxian-signals/SKILL.md +15 -32
- package/dist/skills/baxian-task-check/SKILL.md +13 -14
- package/dist/state/snapshot.d.ts.map +1 -1
- package/dist/state/snapshot.js +5 -2
- package/dist/state/snapshot.js.map +1 -1
- package/dist/state/task-store.d.ts.map +1 -1
- package/dist/state/task-store.js +56 -140
- package/dist/state/task-store.js.map +1 -1
- package/dist/web/assets/index-BKiM0MSM.js +15 -0
- package/dist/web/assets/index-BS2adAfI.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/agent/review-transport.d.ts +0 -92
- package/dist/agent/review-transport.d.ts.map +0 -1
- package/dist/agent/review-transport.js +0 -512
- package/dist/agent/review-transport.js.map +0 -1
- package/dist/event/server-handlers.d.ts +0 -4
- package/dist/event/server-handlers.d.ts.map +0 -1
- package/dist/event/server-handlers.js +0 -1294
- package/dist/event/server-handlers.js.map +0 -1
- package/dist/skills/baxian-research/SKILL.md +0 -28
- package/dist/skills/baxian-server-feedback/SKILL.md +0 -40
- package/dist/skills/baxian-server-feedback/agents/openai.yaml +0 -2
- package/dist/skills/baxian-server-review/SKILL.md +0 -58
- package/dist/skills/baxian-server-review/agents/openai.yaml +0 -2
- package/dist/state/review-store.d.ts +0 -33
- package/dist/state/review-store.d.ts.map +0 -1
- package/dist/state/review-store.js +0 -272
- package/dist/state/review-store.js.map +0 -1
- package/dist/web/assets/index-BPv6vv3U.css +0 -1
- package/dist/web/assets/index-BXfgaFNm.js +0 -18
|
@@ -14,28 +14,32 @@ baxian scans the pane fuzzily (strips ANSI escapes and whitespace), so a TUI sof
|
|
|
14
14
|
## Format
|
|
15
15
|
|
|
16
16
|
- Two-segment: `[bx:KIND:TOKEN]` — for kinds with no payload.
|
|
17
|
-
-
|
|
18
|
-
- Actor form: `[bx:pr-created:<pr_number>:<base64url-actor-id>:TOKEN]` — whenever `cli:` is present, `pr-created` MUST use this form with the platform account id computed by your `baxian-cli-<tool>` skill §Create; omitting the actor prevents feedback acknowledgements from being authorized.
|
|
17
|
+
- Actor form: `[bx:KIND:<pr_number>:<base64url-actor-id>:TOKEN]` — KIND is `pr-created` or `spec-done`. Both kinds MUST carry the selected PR and platform account id computed by your `baxian-cli-<tool>` skill §Create; omitting the actor prevents feedback acknowledgements from being authorized.
|
|
19
18
|
|
|
20
19
|
If your runtime's TUI renders assistant markdown and would turn a bare `[bx:...]` into a link — dropping the square brackets from what baxian captures — wrap the signal in inline-code backticks so the brackets survive to the pane: `` `[bx:KIND:TOKEN]` ``. Backticks are always safe to add, so when in doubt wrap every signal.
|
|
21
20
|
|
|
22
21
|
## How to emit
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
For task completion, select KIND by the dispatch's `phase:` and the exit section completed in its phase skill:
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
| Phase | Exit | KIND |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `develop` | `§Deliver` | `pr-created` |
|
|
28
|
+
| `develop` | `§SDD` | `spec-done` |
|
|
29
|
+
| `code` | `§Deliver` | `pr-created` |
|
|
30
|
+
| `fix` | `§Fix` | `pr-fixed` |
|
|
31
|
+
| `post-approve` | `§Post-Approve` | `pr-merge-ready` |
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
The descriptor supplies the rotating `token:` only. A phase skill may expose multiple exits; emit the kind for the route you actually completed, never both.
|
|
34
|
+
|
|
35
|
+
1. Build the wire form `[bx:KIND:TOKEN]` with the selected KIND and the descriptor's TOKEN. A kind that carries a PR number (see Format) takes the number of the PR created or published by the current phase's instructions; the descriptor has no PR-number field.
|
|
32
36
|
2. Emit the filled signal **alone on its own line**.
|
|
33
37
|
3. **Never emit an angle-bracket placeholder** like `[bx:pr-fixed:<token>]` verbatim — the scanner's strict regex cannot match placeholders, so it fires nothing and the task hangs forever waiting on a signal.
|
|
34
38
|
4. Emit **exactly once**, only when the route's precondition holds. The token rotates every dispatch, so a stale or guessed token never fires.
|
|
35
39
|
|
|
36
40
|
## Signal catalog
|
|
37
41
|
|
|
38
|
-
Phase signals — the per-dispatch transition signals baxian consumes to advance a task. The
|
|
42
|
+
Phase signals — the per-dispatch transition signals baxian consumes to advance a task. The route table and phase skill together define which one to emit and when.
|
|
39
43
|
|
|
40
44
|
Bootstrap handshake (before any task):
|
|
41
45
|
|
|
@@ -47,7 +51,7 @@ PR flow:
|
|
|
47
51
|
|
|
48
52
|
| Signal | Meaning |
|
|
49
53
|
|---|---|
|
|
50
|
-
| `pr-created` (+PR#) |
|
|
54
|
+
| `pr-created` (+PR# and actor with `cli:`) | code is ready on the selected PR; hand off to QA code review |
|
|
51
55
|
| `pr-fixed` | dev addressed all review feedback |
|
|
52
56
|
| `pr-merge-ready` | post-approve feedback handled clean; safe to merge |
|
|
53
57
|
|
|
@@ -57,18 +61,7 @@ SDD spec flow:
|
|
|
57
61
|
|
|
58
62
|
| Signal | Meaning |
|
|
59
63
|
|---|---|
|
|
60
|
-
| `spec-done`
|
|
61
|
-
|
|
62
|
-
Server review flow (no PR; exchange via `.baxian/review/*.json`):
|
|
63
|
-
|
|
64
|
-
| Signal | Meaning |
|
|
65
|
-
|---|---|
|
|
66
|
-
| `spec-reviewed` | QA wrote spec findings |
|
|
67
|
-
| `spec-fixed` | dev handled every spec finding |
|
|
68
|
-
| `code-done` | dev implemented (committed locally, not pushed) |
|
|
69
|
-
| `code-reviewed` | QA wrote code findings |
|
|
70
|
-
| `code-fixed` | dev handled every code finding |
|
|
71
|
-
| `code-ready` (opt. PR#) | publish phase pushed the branch / opened the PR |
|
|
64
|
+
| `spec-done` (+PR# and actor) | spec is ready on the selected PR |
|
|
72
65
|
|
|
73
66
|
Root recovery runtime:
|
|
74
67
|
|
|
@@ -76,16 +69,6 @@ Root recovery runtime:
|
|
|
76
69
|
|---|---|
|
|
77
70
|
| `root-done` | root agent atomically wrote the requested recovery response; the request prompt supplies the attempt token |
|
|
78
71
|
|
|
79
|
-
## Context-request side-channel
|
|
80
|
-
|
|
81
|
-
During server review, request file context only when the prompt says `review-checkout: base`, or during server spec review / legacy batch continuation when the prompt context is insufficient:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
[bx:read-file:<path>:<start>-<end>]
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Own line, repo-relative path, ≤200 lines, then wait — baxian injects the content. This does NOT consume the phase-signal watch, so you may request several before emitting your phase signal.
|
|
88
|
-
|
|
89
72
|
## Need-input side-channel
|
|
90
73
|
|
|
91
74
|
A paired ask/answer protocol. Neither signal consumes the phase-signal watch or advances the task.
|
|
@@ -18,36 +18,35 @@ Installed skills and personal workflows apply as usual — baxian orchestrates t
|
|
|
18
18
|
|
|
19
19
|
## Conventions
|
|
20
20
|
|
|
21
|
-
Stay in scope — out-of-scope work goes to a new issue via your platform skill
|
|
21
|
+
Stay in scope — out-of-scope work goes to a new issue via your platform skill. Deliver only through this dispatch's signal route, never a skill's own finishing flow, and never merge — baxian owns merging.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- `git-pr`: communicate via the platform PR (description, commits, reviews, comments). Load the `baxian-cli-<tool>` skill named by your `cli:` field (`cli: gh` means `baxian-cli-gh`) and take every platform command from it. Commit on the branch already checked out in `workdir:` — the PR must come from exactly the `branch:` value, or baxian can't match it to your task.
|
|
26
|
-
- `server-files`: baxian reads your Workdir directly; do NOT push or open a PR (the publish phase does that).
|
|
23
|
+
Communicate through the platform PR (description, commits, reviews, comments). Load the `baxian-cli-<tool>` skill named by your `cli:` field (`cli: gh` means `baxian-cli-gh`) and take every platform command from it. Commit on the branch already checked out in `workdir:` — the PR must come from exactly the `branch:` value, or baxian can't match it to your task.
|
|
27
24
|
|
|
28
25
|
## Develop
|
|
29
26
|
|
|
30
27
|
How you develop is yours — your installed skills and workflows decide how you analyze, design, and implement. baxian defines only the exits, and you emit exactly one exit signal per dispatch:
|
|
31
28
|
|
|
32
|
-
- Deliver the implementation: follow §Deliver
|
|
33
|
-
- Get a design reviewed before you code: follow §SDD
|
|
29
|
+
- Deliver the implementation: follow §Deliver.
|
|
30
|
+
- Get a design reviewed before you code: follow §SDD.
|
|
34
31
|
|
|
35
32
|
## SDD
|
|
36
33
|
|
|
37
34
|
The companion for spec-first development: baxian routes your spec through review before you code.
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
The spec is a permanent repository document on the task branch.
|
|
37
|
+
|
|
38
|
+
1. Verify `git symbolic-ref --quiet --short HEAD` is byte-for-byte equal to the descriptor's original, case-sensitive `branch:` value. Derive the flat path with this single command: `branch="$(git symbolic-ref --quiet --short HEAD)" && slug="$(printf %s "$branch" | LC_ALL=C tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//' | cut -c1-48)" && hash16="$(printf %s "$branch" | openssl dgst -sha256 -r | cut -c1-16)" && spec_path="docs/specs/${slug}-${hash16}.md"`. Do not invent a fallback slug or a nested directory.
|
|
39
|
+
2. Start the file with YAML front matter whose `branch:` value is the JSON-quoted exact original branch, then write the design. Before any write, use one shell invocation rooted at the absolute logical `workdir:` to enforce all three guards: every existing component from Workdir through the target is a non-symlink and its canonical path stays under the canonical Workdir; the first target creation uses `set -o noclobber` so it is atomic and no-clobber; if the target already exists, compare its front-matter `branch:` value with the current branch byte-for-byte and continue only when they match. Re-check newly created directories and the target as non-symlinks before writing content. A collision, malformed front matter, canonical-prefix failure, or any ambiguous probe stops the task without overwriting the file.
|
|
40
|
+
3. Commit the spec and follow your `baxian-cli-<tool>` skill §Create. It pushes and adopts or creates the PR. After every common check passes, complete the `develop` / `§SDD` route from baxian-signals in its actor form, carrying the selected PR number.
|
|
41
|
+
|
|
42
|
+
Complete only the `§SDD` route: `§Deliver` selects direct code delivery instead.
|
|
41
43
|
|
|
42
44
|
After the spec is approved, baxian dispatches the code phase back to you.
|
|
43
45
|
|
|
44
46
|
## Code
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
Derive the approved repository spec path from `branch:` with §SDD's exact mapping and read it from the current branch; the descriptor also carries the already-bound `pr:` that §Create must adopt or reopen, never replace. Implement it, then follow §Deliver.
|
|
47
49
|
|
|
48
50
|
## Deliver
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `git-pr`: commit, then create the PR per your `baxian-cli-<tool>` skill §Create — it owns push, non-interactive create with the source branch, repository, and target identity passed explicitly in that platform's own flags, Draft recovery, and the actor self-report segment. Emit `pr-created` in the actor-segment form that section specifies, only after its checks pass.
|
|
53
|
-
- `server-files`: local commit only (do NOT push, no PR). Emit `code-done`.
|
|
52
|
+
Commit, then create the PR per your `baxian-cli-<tool>` skill §Create — it owns push, non-interactive create with the source branch, repository, and target identity passed explicitly in that platform's own flags, Draft recovery, and the actor self-report segment. Complete the current phase's `§Deliver` route from baxian-signals in the actor-segment form that section specifies, only after its checks pass.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3D,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAC/E,CAAC;IACF,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IACjH,SAAS,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IAC9D,sBAAsB,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,sBAAsB,CAAA;KAAE,CAAC;IACxE,gBAAgB,CAAC,EAAE;QACjB,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAC/E,sBAAsB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QAChE,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,iBAAiB,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACvD,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;KAC5D,CAAC;CACH;AAOD,wBAAgB,aAAa,CAC3B,UAAU,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,oBAAoB,CAAC,EAAE,iBAAiB,EACxC,KAAK,CAAC,EAAE,MAAM,GACb,aAAa,CAkBf;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,kBAAkB,CAiBpB;AAkFD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAmB5F;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiB/B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3D,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAC/E,CAAC;IACF,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IACjH,SAAS,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IAC9D,sBAAsB,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,sBAAsB,CAAA;KAAE,CAAC;IACxE,gBAAgB,CAAC,EAAE;QACjB,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAC/E,sBAAsB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QAChE,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,iBAAiB,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACvD,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;KAC5D,CAAC;CACH;AAOD,wBAAgB,aAAa,CAC3B,UAAU,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,oBAAoB,CAAC,EAAE,iBAAiB,EACxC,KAAK,CAAC,EAAE,MAAM,GACb,aAAa,CAkBf;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,kBAAkB,CAiBpB;AAkFD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAmB5F;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiB/B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAU7D"}
|
package/dist/state/snapshot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { REVIEW_VERDICT_TIMEOUT_MS } from '../shared/index.js';
|
|
2
2
|
const WORKING_TASK_STATUSES = new Set(['in_progress', 'fixing']);
|
|
3
|
-
const WAITING_TASK_STATUSES = new Set(['review', 'spec-ready', 'approved', 'merge-ready', '
|
|
3
|
+
const WAITING_TASK_STATUSES = new Set(['review', 'spec-ready', 'approved', 'merge-ready', 'max_rounds']);
|
|
4
4
|
const ERROR_TASK_STATUSES = new Set(['failed']);
|
|
5
5
|
const UNREACHABLE_ACTIVE_TASK_GRACE_MS = 30_000;
|
|
6
6
|
export function agentSnapshot(configured, binding, tmuxObservation, task, latestBootstrapError, petId) {
|
|
@@ -153,9 +153,12 @@ export async function buildAgentSnapshotById(ctx, id) {
|
|
|
153
153
|
return agentSnapshot(configured, binding ?? undefined, ctx.tmuxSessionStatusStore.get(id), task ?? undefined, latestBootstrapError, petId);
|
|
154
154
|
}
|
|
155
155
|
export function enrichTaskSnapshot(task) {
|
|
156
|
-
if (task.status !== 'review' || !task.reviewDispatchedAt || !task.
|
|
156
|
+
if (task.status !== 'review' || !task.reviewDispatchedAt || !task.signalToken) {
|
|
157
157
|
return task;
|
|
158
158
|
}
|
|
159
|
+
if (!task.qaAgentId) {
|
|
160
|
+
throw new Error(`enrichTaskSnapshot: review task ${task.id} has no QA participant`);
|
|
161
|
+
}
|
|
159
162
|
const elapsed = Date.now() - Date.parse(task.reviewDispatchedAt);
|
|
160
163
|
if (!Number.isFinite(elapsed) || elapsed < REVIEW_VERDICT_TIMEOUT_MS)
|
|
161
164
|
return task;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAuB/D,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAsB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtF,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAsB,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/state/task-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/state/task-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAY3E,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AA6BD,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAIrD;AA4UD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,CAAC;AACnD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpF,qBAAa,SAAS;IAGR,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,SAAS,CAAgC;gBAE7B,GAAG,EAAE,MAAM;IAE/B,QAAQ,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAKrC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAa1C,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAI/C,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YAI7C,YAAY;IAiCpB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAczB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvC,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,IAAI;CAGb"}
|
package/dist/state/task-store.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile, readdir, unlink, rename } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { isRecord, mapWithConcurrency, FS_READ_CONCURRENCY, TASK_PHASE_SET } from '../shared/index.js';
|
|
3
|
+
import { effectiveTaskReviewRound, isRecord, mapWithConcurrency, FS_READ_CONCURRENCY, TASK_PHASE_SET, } from '../shared/index.js';
|
|
4
4
|
// a store id becomes a filename; constrain it so a path-like id can't escape the store dir
|
|
5
5
|
const SAFE_ID = /^[A-Za-z0-9_-]+$/;
|
|
6
6
|
function withTaskFileContext(file, error) {
|
|
@@ -10,11 +10,10 @@ function withTaskFileContext(file, error) {
|
|
|
10
10
|
}
|
|
11
11
|
const TASK_FIELDS = [
|
|
12
12
|
'id', 'projectId', 'title', 'description', 'preferredAgentId',
|
|
13
|
-
'agentId', 'devAgentId', 'qaAgentId', '
|
|
14
|
-
'reviewDispatchedAt', 'prFeedbackReceivedAt', 'reviewConversationUpdatedAt', 'fixDispatchedAt', 'reviewRound', 'reviewRoundPending', 'specReviewRound', 'phase', 'signalToken',
|
|
15
|
-
'serverSignalRecovery',
|
|
13
|
+
'agentId', 'devAgentId', 'qaAgentId', 'prNumber', 'prUrl', 'branch', 'branchCreatedByBaxian', 'branchCleanupPending', 'branchCleanupSkipped', 'remoteCleanup', 'branchLocalCleaned', 'latestHeadSha', 'reviewHeadAnchorSha',
|
|
14
|
+
'reviewDispatchedAt', 'prFeedbackReceivedAt', 'reviewConversationUpdatedAt', 'fixDispatchedAt', 'reviewRound', 'reviewRoundPending', 'specReviewRound', 'phase', 'deliveryConfirmation', 'signalToken',
|
|
16
15
|
'status', 'createdAt', 'updatedAt', 'images',
|
|
17
|
-
'
|
|
16
|
+
'maxRoundsContinues',
|
|
18
17
|
'postApproveRevoked', 'postApproveHeadSha', 'verdictOverdue',
|
|
19
18
|
'passToken', 'failToken', 'pendingPrSignalToken', 'postApproveToken', 'postApproveGeneration', 'postApprovePhase', 'reviewDispatch', 'platformBinding', 'baseBranch', 'replyActorId', 'replyActorStatus',
|
|
20
19
|
'closedUnmergedAnchor', 'passProvenance', 'consumedFeedback', 'outbox', 'pendingRedispatch', 'redispatchCount',
|
|
@@ -22,22 +21,8 @@ const TASK_FIELDS = [
|
|
|
22
21
|
const REVIEW_TOKEN_RE = /^[0-9a-f]{12}$/;
|
|
23
22
|
const TASK_STATUSES = new Set([
|
|
24
23
|
'pending', 'in_progress', 'review', 'fixing', 'spec-ready', 'approved', 'merge-ready',
|
|
25
|
-
'
|
|
24
|
+
'merged', 'done', 'max_rounds', 'failed', 'cancelled',
|
|
26
25
|
]);
|
|
27
|
-
const SERVER_SIGNAL_KINDS = new Set([
|
|
28
|
-
'code-done', 'code-reviewed', 'code-fixed', 'code-ready', 'spec-done', 'spec-reviewed', 'spec-fixed',
|
|
29
|
-
]);
|
|
30
|
-
const SERVER_RECOVERY_MODES = new Set(['classify-response', 'correct-response', 'hold']);
|
|
31
|
-
const SERVER_RECOVERY_REASONS = new Set([
|
|
32
|
-
'response-missing', 'response-invalid', 'round-mismatch', 'token-mismatch',
|
|
33
|
-
'findings-digest-mismatch', 'coverage-gap', 'fix-no-dev-agent', 'fix-findings-missing',
|
|
34
|
-
'response-read-failed', 'verdict-store-failed', 'handler-failed',
|
|
35
|
-
]);
|
|
36
|
-
const SERVER_RESPONSE_REASONS = new Set([
|
|
37
|
-
'response-missing', 'response-invalid', 'round-mismatch', 'token-mismatch',
|
|
38
|
-
'findings-digest-mismatch', 'coverage-gap',
|
|
39
|
-
]);
|
|
40
|
-
const SHA256_RE = /^[0-9a-f]{64}$/;
|
|
41
26
|
const HEAD_SHA_RE = /^[0-9a-f]{7,64}$/i;
|
|
42
27
|
const REMOTE_FAILURE_KINDS = new Set([
|
|
43
28
|
'config', 'binding', 'close', 'persist', 'delete', 'probe', 'tip-changed',
|
|
@@ -90,8 +75,6 @@ function validateRemoteCleanup(raw) {
|
|
|
90
75
|
const value = raw.remoteCleanup;
|
|
91
76
|
if (value === undefined)
|
|
92
77
|
return;
|
|
93
|
-
if (raw.reviewMode !== 'git')
|
|
94
|
-
throw taskSchemaError('remoteCleanup', 'present only for git review tasks');
|
|
95
78
|
if (!isRecord(value))
|
|
96
79
|
throw taskSchemaError('remoteCleanup', 'an object when present');
|
|
97
80
|
if (typeof value.generation !== 'string' || !REVIEW_TOKEN_RE.test(value.generation)) {
|
|
@@ -126,76 +109,6 @@ function validateRemoteCleanup(raw) {
|
|
|
126
109
|
throw taskSchemaError('remoteCleanup.failure', 'present during manual cleanup');
|
|
127
110
|
}
|
|
128
111
|
}
|
|
129
|
-
function validateSortedStringArray(value, field) {
|
|
130
|
-
if (value === undefined)
|
|
131
|
-
return;
|
|
132
|
-
if (!Array.isArray(value) || value.some(item => typeof item !== 'string' || item.trim() === '')) {
|
|
133
|
-
throw taskSchemaError(field, 'an array of non-empty strings when present');
|
|
134
|
-
}
|
|
135
|
-
const sorted = [...value].sort();
|
|
136
|
-
if (new Set(value).size !== value.length || value.some((item, index) => item !== sorted[index])) {
|
|
137
|
-
throw taskSchemaError(field, 'a sorted array of unique strings when present');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function validateServerSignalRecovery(raw) {
|
|
141
|
-
const value = raw.serverSignalRecovery;
|
|
142
|
-
if (value === undefined)
|
|
143
|
-
return;
|
|
144
|
-
if (!isRecord(value))
|
|
145
|
-
throw taskSchemaError('serverSignalRecovery', 'an object when present');
|
|
146
|
-
if (typeof value.mode !== 'string' || !SERVER_RECOVERY_MODES.has(value.mode)) {
|
|
147
|
-
throw taskSchemaError('serverSignalRecovery.mode', 'classify-response, correct-response, or hold');
|
|
148
|
-
}
|
|
149
|
-
if (typeof value.signalKind !== 'string' || !SERVER_SIGNAL_KINDS.has(value.signalKind)) {
|
|
150
|
-
throw taskSchemaError('serverSignalRecovery.signalKind', 'a server review signal kind');
|
|
151
|
-
}
|
|
152
|
-
if (value.phase !== 'spec' && value.phase !== 'code') {
|
|
153
|
-
throw taskSchemaError('serverSignalRecovery.phase', 'spec or code');
|
|
154
|
-
}
|
|
155
|
-
if (!Number.isInteger(value.round) || value.round < 0) {
|
|
156
|
-
throw taskSchemaError('serverSignalRecovery.round', 'an integer >= 0');
|
|
157
|
-
}
|
|
158
|
-
for (const field of ['sourceToken', 'createdAt'])
|
|
159
|
-
requireString(value, field);
|
|
160
|
-
if (typeof value.reason !== 'string' || !SERVER_RECOVERY_REASONS.has(value.reason)) {
|
|
161
|
-
throw taskSchemaError('serverSignalRecovery.reason', 'a known recovery reason');
|
|
162
|
-
}
|
|
163
|
-
for (const field of ['findingsDigest', 'failureSignature', 'responseDigest']) {
|
|
164
|
-
const digest = value[field];
|
|
165
|
-
if (digest !== undefined && (typeof digest !== 'string' || !SHA256_RE.test(digest))) {
|
|
166
|
-
throw taskSchemaError(`serverSignalRecovery.${field}`, 'a lowercase SHA-256 digest when present');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
optionalString(value, 'failurePhase');
|
|
170
|
-
for (const field of ['missingFindingIds', 'unknownFindingIds', 'schemaViolationCodes']) {
|
|
171
|
-
validateSortedStringArray(value[field], `serverSignalRecovery.${field}`);
|
|
172
|
-
}
|
|
173
|
-
const responseMode = value.mode === 'classify-response' || value.mode === 'correct-response';
|
|
174
|
-
if (responseMode && (!SERVER_RESPONSE_REASONS.has(value.reason)
|
|
175
|
-
|| (value.signalKind !== 'code-fixed' && value.signalKind !== 'spec-fixed')
|
|
176
|
-
|| typeof value.findingsDigest !== 'string'
|
|
177
|
-
|| typeof value.failureSignature !== 'string'
|
|
178
|
-
|| (value.reason !== 'response-missing' && typeof value.responseDigest !== 'string'))) {
|
|
179
|
-
throw taskSchemaError('serverSignalRecovery', 'response recovery fields for classify/correct mode');
|
|
180
|
-
}
|
|
181
|
-
const expectedPhase = String(value.signalKind).startsWith('spec-') ? 'spec' : 'code';
|
|
182
|
-
if (value.phase !== expectedPhase) {
|
|
183
|
-
throw taskSchemaError('serverSignalRecovery.signalKind', `a ${value.phase} signal kind`);
|
|
184
|
-
}
|
|
185
|
-
const taskPhaseMatches = value.phase === 'spec'
|
|
186
|
-
? raw.phase !== 'code'
|
|
187
|
-
: raw.phase === 'code' || raw.phase === undefined;
|
|
188
|
-
if (!taskPhaseMatches) {
|
|
189
|
-
throw taskSchemaError('serverSignalRecovery.phase', 'the current task phase');
|
|
190
|
-
}
|
|
191
|
-
const currentRound = value.phase === 'spec' ? (raw.specReviewRound ?? 0) : raw.reviewRound;
|
|
192
|
-
if (value.round !== currentRound) {
|
|
193
|
-
throw taskSchemaError('serverSignalRecovery.round', 'the current task review round');
|
|
194
|
-
}
|
|
195
|
-
if (typeof raw.signalToken !== 'string' || raw.signalToken === value.sourceToken) {
|
|
196
|
-
throw taskSchemaError('serverSignalRecovery.sourceToken', 'a token superseded by task.signalToken');
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
112
|
function validateTask(raw) {
|
|
200
113
|
requireString(raw, 'id');
|
|
201
114
|
requireString(raw, 'projectId');
|
|
@@ -207,26 +120,35 @@ function validateTask(raw) {
|
|
|
207
120
|
requireString(raw, 'createdAt');
|
|
208
121
|
requireString(raw, 'updatedAt');
|
|
209
122
|
optionalString(raw, 'qaAgentId');
|
|
210
|
-
optionalString(raw, 'researchAgentId');
|
|
211
123
|
for (const field of [
|
|
212
124
|
'prUrl', 'branch', 'latestHeadSha', 'reviewHeadAnchorSha', 'reviewDispatchedAt',
|
|
213
125
|
'prFeedbackReceivedAt', 'reviewConversationUpdatedAt', 'fixDispatchedAt', 'signalToken',
|
|
214
|
-
'
|
|
126
|
+
'postApproveHeadSha',
|
|
215
127
|
])
|
|
216
128
|
optionalString(raw, field);
|
|
217
129
|
if (!Number.isInteger(raw.reviewRound) || raw.reviewRound < 0) {
|
|
218
130
|
throw taskSchemaError('reviewRound', 'an integer >= 0');
|
|
219
131
|
}
|
|
220
132
|
if (raw.phase !== undefined && (typeof raw.phase !== 'string' || !TASK_PHASE_SET.has(raw.phase))) {
|
|
221
|
-
throw taskSchemaError('phase', '
|
|
133
|
+
throw taskSchemaError('phase', 'spec or code when present');
|
|
134
|
+
}
|
|
135
|
+
if (raw.deliveryConfirmation !== undefined) {
|
|
136
|
+
const confirmation = raw.deliveryConfirmation;
|
|
137
|
+
if (!isRecord(confirmation)
|
|
138
|
+
|| (confirmation.phase !== 'spec' && confirmation.phase !== 'code')
|
|
139
|
+
|| (confirmation.source !== 'signal' && confirmation.source !== 'human')
|
|
140
|
+
|| typeof confirmation.at !== 'string' || !Number.isFinite(Date.parse(confirmation.at))) {
|
|
141
|
+
throw taskSchemaError('deliveryConfirmation', 'a { phase, source, at } record');
|
|
142
|
+
}
|
|
143
|
+
if (confirmation.phase !== raw.phase) {
|
|
144
|
+
throw taskSchemaError('deliveryConfirmation.phase', 'the current task phase');
|
|
145
|
+
}
|
|
222
146
|
}
|
|
223
147
|
if (typeof raw.status !== 'string' || !TASK_STATUSES.has(raw.status)) {
|
|
224
148
|
throw taskSchemaError('status', 'a known task status');
|
|
225
149
|
}
|
|
226
150
|
optionalInteger(raw, 'prNumber', 1);
|
|
227
151
|
optionalInteger(raw, 'specReviewRound', 0);
|
|
228
|
-
optionalInteger(raw, 'batchIndex', 0);
|
|
229
|
-
optionalInteger(raw, 'batchTotal', 1);
|
|
230
152
|
optionalInteger(raw, 'maxRoundsContinues', 0);
|
|
231
153
|
for (const field of ['branchCreatedByBaxian', 'verdictOverdue', 'reviewRoundPending'])
|
|
232
154
|
optionalBoolean(raw, field);
|
|
@@ -234,17 +156,6 @@ function validateTask(raw) {
|
|
|
234
156
|
|| raw.images.some(image => typeof image !== 'string' || image.trim() === ''))) {
|
|
235
157
|
throw taskSchemaError('images', 'an array of non-empty strings when present');
|
|
236
158
|
}
|
|
237
|
-
if (raw.reviewMode !== 'git' && raw.reviewMode !== 'server') {
|
|
238
|
-
throw taskSchemaError('reviewMode', 'git or server');
|
|
239
|
-
}
|
|
240
|
-
if (raw.reviewCheckoutMode !== undefined
|
|
241
|
-
&& raw.reviewCheckoutMode !== 'head' && raw.reviewCheckoutMode !== 'base') {
|
|
242
|
-
throw taskSchemaError('reviewCheckoutMode', 'head or base when present');
|
|
243
|
-
}
|
|
244
|
-
if (raw.afterDone !== undefined && raw.afterDone !== null
|
|
245
|
-
&& raw.afterDone !== 'pr' && raw.afterDone !== 'branch') {
|
|
246
|
-
throw taskSchemaError('afterDone', 'pr, branch, or null when present');
|
|
247
|
-
}
|
|
248
159
|
validateCleanupPending(raw, 'branchCleanupPending');
|
|
249
160
|
validateCleanupPending(raw, 'branchCleanupSkipped');
|
|
250
161
|
validateRemoteCleanup(raw);
|
|
@@ -257,21 +168,17 @@ function validateTask(raw) {
|
|
|
257
168
|
}
|
|
258
169
|
requireString(cleaned, 'updatedAt');
|
|
259
170
|
}
|
|
260
|
-
validateServerSignalRecovery(raw);
|
|
261
171
|
validateGitReviewFields(raw);
|
|
262
|
-
const participantIds = [raw.devAgentId, raw.qaAgentId
|
|
172
|
+
const participantIds = [raw.devAgentId, raw.qaAgentId]
|
|
263
173
|
.filter((value) => typeof value === 'string' && value !== '');
|
|
264
174
|
if (new Set(participantIds).size !== participantIds.length) {
|
|
265
|
-
throw taskSchemaError('participants', 'distinct dev
|
|
266
|
-
}
|
|
267
|
-
if (raw.agentId !== '' && raw.agentId !== raw.devAgentId && raw.agentId !== raw.researchAgentId) {
|
|
268
|
-
throw taskSchemaError('agentId', 'the task dev or research agent id');
|
|
175
|
+
throw taskSchemaError('participants', 'distinct dev and qa agent ids');
|
|
269
176
|
}
|
|
270
|
-
if (raw.
|
|
271
|
-
throw taskSchemaError('
|
|
177
|
+
if ((raw.devAgentId === '') !== (raw.qaAgentId === undefined)) {
|
|
178
|
+
throw taskSchemaError('participants', 'a complete dev and qa pair, or neither when unassigned');
|
|
272
179
|
}
|
|
273
|
-
if (raw.
|
|
274
|
-
throw taskSchemaError('
|
|
180
|
+
if (raw.agentId !== '' && raw.agentId !== raw.devAgentId) {
|
|
181
|
+
throw taskSchemaError('agentId', 'the task dev agent id');
|
|
275
182
|
}
|
|
276
183
|
}
|
|
277
184
|
function validateGitReviewFields(raw) {
|
|
@@ -313,11 +220,6 @@ function validateGitReviewFields(raw) {
|
|
|
313
220
|
throw taskSchemaError('postApproveGeneration', 'a complete post-approve episode');
|
|
314
221
|
}
|
|
315
222
|
const activeEpisode = activeCount === activeFields.length;
|
|
316
|
-
const hasPostApproveState = activeEpisode || revoked !== undefined
|
|
317
|
-
|| raw.pendingRedispatch !== undefined || raw.redispatchCount !== undefined;
|
|
318
|
-
if (hasPostApproveState && raw.reviewMode !== 'git') {
|
|
319
|
-
throw taskSchemaError('postApproveGeneration', 'post-approve state only for git review tasks');
|
|
320
|
-
}
|
|
321
223
|
if (activeEpisode) {
|
|
322
224
|
if (raw.status !== 'approved' || revoked !== undefined) {
|
|
323
225
|
throw taskSchemaError('postApproveGeneration', 'an active episode only while approved and not revoked');
|
|
@@ -369,9 +271,8 @@ function validateGitReviewFields(raw) {
|
|
|
369
271
|
}
|
|
370
272
|
requireString(lease, 'claimedAt');
|
|
371
273
|
}
|
|
372
|
-
const effectiveRound =
|
|
373
|
-
if (raw.
|
|
374
|
-
|| raw.signalToken !== lease.signalToken
|
|
274
|
+
const effectiveRound = effectiveTaskReviewRound(raw);
|
|
275
|
+
if (raw.status !== 'review' || raw.signalToken !== lease.signalToken
|
|
375
276
|
|| raw.reviewHeadAnchorSha !== lease.headSha
|
|
376
277
|
|| raw.passToken !== lease.passToken
|
|
377
278
|
|| raw.failToken !== lease.failToken
|
|
@@ -386,9 +287,6 @@ function validateGitReviewFields(raw) {
|
|
|
386
287
|
throw taskSchemaError('platformBinding', 'a { mode, repoKey, tool } identity record when present');
|
|
387
288
|
}
|
|
388
289
|
}
|
|
389
|
-
if (raw.afterDone === 'pr' && raw.platformBinding === undefined) {
|
|
390
|
-
throw taskSchemaError('platformBinding', "present when afterDone is 'pr'");
|
|
391
|
-
}
|
|
392
290
|
optionalString(raw, 'baseBranch');
|
|
393
291
|
optionalString(raw, 'replyActorId');
|
|
394
292
|
if (raw.replyActorStatus !== undefined
|
|
@@ -420,12 +318,35 @@ function validateGitReviewFields(raw) {
|
|
|
420
318
|
}
|
|
421
319
|
if (raw.outbox !== undefined) {
|
|
422
320
|
const outbox = raw.outbox;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
321
|
+
if (!Array.isArray(outbox))
|
|
322
|
+
throw taskSchemaError('outbox', 'an array of pending operation entries when present');
|
|
323
|
+
const keys = new Set();
|
|
324
|
+
let hasSpecVerdict = false;
|
|
325
|
+
for (const entry of outbox) {
|
|
326
|
+
if (!isRecord(entry) || typeof entry.key !== 'string' || entry.key.trim() === ''
|
|
327
|
+
|| keys.has(entry.key) || !isRecord(entry.data)) {
|
|
328
|
+
throw taskSchemaError('outbox', 'entries with unique non-empty keys and object data');
|
|
329
|
+
}
|
|
330
|
+
keys.add(entry.key);
|
|
331
|
+
if (entry.type === 'human.intervention')
|
|
332
|
+
continue;
|
|
333
|
+
if (entry.type !== 'git.spec-verdict') {
|
|
334
|
+
throw taskSchemaError('outbox.type', 'human.intervention or git.spec-verdict');
|
|
335
|
+
}
|
|
336
|
+
if (hasSpecVerdict)
|
|
337
|
+
throw taskSchemaError('outbox', 'at most one git.spec-verdict entry');
|
|
338
|
+
hasSpecVerdict = true;
|
|
339
|
+
const data = entry.data;
|
|
340
|
+
if (!REVIEW_TOKEN_RE.test(entry.key)
|
|
341
|
+
|| !Number.isInteger(data.prNumber) || data.prNumber < 1
|
|
342
|
+
|| typeof data.comments !== 'string' || data.comments.trim() === ''
|
|
343
|
+
|| (data.writeAttemptedAt !== undefined
|
|
344
|
+
&& (typeof data.writeAttemptedAt !== 'string' || data.writeAttemptedAt.trim() === ''))
|
|
345
|
+
|| raw.phase !== 'spec' || raw.prNumber !== data.prNumber
|
|
346
|
+
|| (raw.status !== 'spec-ready' && raw.status !== 'max_rounds')
|
|
347
|
+
|| !Number.isInteger(raw.specReviewRound) || raw.specReviewRound < 1) {
|
|
348
|
+
throw taskSchemaError('outbox', 'a valid current spec-phase git verdict operation');
|
|
349
|
+
}
|
|
429
350
|
}
|
|
430
351
|
}
|
|
431
352
|
}
|
|
@@ -443,11 +364,6 @@ function sanitizeTask(state) {
|
|
|
443
364
|
out[k] = value;
|
|
444
365
|
}
|
|
445
366
|
}
|
|
446
|
-
// 读侧迁移不可删:worktree 时代的 base 任务丢掉这行会被恢复分类误判(undefined ≠ head)。
|
|
447
|
-
if (out.reviewCheckoutMode === undefined
|
|
448
|
-
&& (raw.reviewWorktreeMode === 'head' || raw.reviewWorktreeMode === 'base')) {
|
|
449
|
-
out.reviewCheckoutMode = raw.reviewWorktreeMode;
|
|
450
|
-
}
|
|
451
367
|
validateTask(out);
|
|
452
368
|
return out;
|
|
453
369
|
}
|