@linxin666/dsh-client-ui-task-board 0.4.5 → 0.4.6
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.i18n.yaml +2 -2
- package/README.md +20 -12
- package/README.zh.md +20 -12
- package/lib/client.js +1327 -229
- package/lib/client.js.map +1 -1
- package/lib/index.js +1909 -348
- package/lib/types/client/TaskBoardSettingsCard.d.ts +12 -0
- package/lib/types/client/index.d.ts +4 -5
- package/lib/types/client/locales.d.ts +65 -0
- package/lib/types/client/plugin-card-seat.d.ts +5 -0
- package/lib/types/client/schedule-zone.d.ts +50 -0
- package/lib/types/core/controller.d.ts +10 -11
- package/lib/types/core/poll-cadence.d.ts +31 -0
- package/lib/types/core/tasks.d.ts +144 -14
- package/lib/types/core/use-cases/task-schedule.d.ts +68 -10
- package/lib/types/core/verification-budget.d.ts +52 -0
- package/lib/types/core/verification.d.ts +376 -9
- package/lib/types/host/verification-gate.d.ts +24 -0
- package/lib/types/host/verification-runner.d.ts +38 -7
- package/lib/types/host-ledger.d.ts +82 -7
- package/lib/types/host-runner.d.ts +32 -9
- package/lib/types/host-service.d.ts +117 -9
- package/lib/types/index.d.ts +54 -0
- package/lib/types/protocol.d.ts +50 -12
- package/package.json +2 -6
- package/src/client/TaskBoardSettingsCard.tsx +74 -1
- package/src/client/board/NewTaskModal.tsx +151 -20
- package/src/client/board/TaskCard.tsx +3 -3
- package/src/client/board/TaskDetail.tsx +219 -18
- package/src/client/board/VerificationReport.tsx +132 -13
- package/src/client/board/status-key.ts +3 -0
- package/src/client/index.ts +43 -50
- package/src/client/locales.ts +137 -4
- package/src/client/plugin-card-seat.ts +7 -0
- package/src/client/schedule-zone.ts +100 -2
- package/src/core/controller.ts +12 -8
- package/src/core/poll-cadence.ts +41 -0
- package/src/core/store.ts +64 -15
- package/src/core/tasks.ts +193 -39
- package/src/core/use-cases/task-create.ts +30 -9
- package/src/core/use-cases/task-schedule.ts +190 -25
- package/src/core/use-cases/task-update.ts +3 -3
- package/src/core/verification-budget.ts +115 -0
- package/src/core/verification.ts +785 -17
- package/src/host/agent-tools.ts +106 -21
- package/src/host/verification-gate.ts +172 -16
- package/src/host/verification-runner.ts +207 -40
- package/src/host-ledger.ts +328 -42
- package/src/host-runner.ts +52 -19
- package/src/host-service.ts +299 -36
- package/src/index.ts +101 -5
- package/src/protocol.ts +132 -28
- package/lib/invariant.js +0 -6
- package/lib/types/client/board-card-seat.d.ts +0 -34
- package/lib/types/invariant.d.ts +0 -3
- package/src/client/board-card-seat.ts +0 -102
- package/src/invariant.ts +0 -4
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# node scripts/verify-docs.mjs --write <dir>
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 56e7e147e72719ca5607a508bb189c44ddd4937f
|
|
6
|
+
README.zh.md: 2fe78563e70a9374f91eb509601aceefd5938a37
|
package/README.md
CHANGED
|
@@ -39,16 +39,18 @@ Cards keep multi-line title and description previews with visible metadata. Prev
|
|
|
39
39
|
- **Host-authoritative ledger**: tasks, schedules, and execution records live in `$DSH_HOME/task-board/ledger-v2.json`; browser actions become confirmed Host transactions.
|
|
40
40
|
- **Bounded execution history**: each task keeps the most recent 20 execution records; the oldest runs are trimmed when a new run starts, so ledger size and write cost stay bounded regardless of how often a task has run.
|
|
41
41
|
- **Real execution**: manual and scheduled runs use the same Host runner, which by default creates a fresh session, renames it, applies the agent preset and `/permission <id>`, then queues the task prompt.
|
|
42
|
-
- **Goal-driven runs (on by default)
|
|
43
|
-
- **Goal acceptance (on by default)**: a task executed in goal form must pass ONE acceptance before `update_goal(action: complete)` may take effect, because the board gates that call on the official tool pre-execute lifecycle instead of trusting the agent's own report. Acceptance runs the default final acceptance of the installed `dsh-llm-verifier` (MIT): the three coding criteria (Specification Adherence, Output Match, Error Signal Detection), a 0.65 threshold applied to the total AND to every criterion, two judge rounds per criterion with the A/B slots swapped and averaged, the task's real trajectory (tool calls, their output, assistant prose) judged against the empty-work baseline, the work must beat that baseline, and — when the deployment records workspace changes — the HOST's own record of what the run changed on disk (file list with added/deleted counts and bounded per-file comparisons) is attached as the prompt's reference context so a described-but-unapplied patch cannot pass. One execution may accept twice: the first failure returns the total, the per-criterion scores and the located findings to the fixing agent, the second failure ends that execution as failed. The budget lives on the execution record, so a repeated completion call, a new goal round, a plugin reload and a Host restart all reuse the same cycle, while a rerun or a scheduled occurrence is a new execution with its own budget. An anomaly (timeout, authentication failure, unparseable judge answer, unresolvable judge route) is recorded separately from a quality verdict
|
|
44
|
-
- **Optional session reuse**: a task can opt into continuing in its previous execution's session (issue #1419). Reuse happens only when that session is idle and still present in the runtime roster — the Host then re-applies the pinned permission and model on it and queues the prompt, keeping the conversation title and history; otherwise the run mints a fresh session as before, so an unknown roster or a busy session never blocks a scheduled run.
|
|
42
|
+
- **Goal-driven runs (opt-in per card, on top of the global switch)**: the GLOBAL native `/goal` switch (below, off by default) is the master control; with it on, and only when a card opts in through its detail-view checkbox (the new-task dialog starts unchecked), the runner queues the task prompt and then arms dsh's built-in `/goal` with that same composed prompt as the objective. dsh's goal-round driver keeps starting continuation rounds in the session until the agent marks the goal complete, and the board keeps the execution in `running` until the goal leaves its active phase: a completed goal settles the run as succeeded, a blocked one fails it with the goal's own reason. The option is per task (`goalRun`, absent means off, so a card that never touched it runs one plain turn) and is available to `task_board_create`/`task_board_update` too. The checkbox is always operable: the master switch decides whether the preference takes effect, never whether it can be stated, and it never rewrites the stored value.
|
|
43
|
+
- **Goal acceptance (on by default)**: a task executed in goal form must pass ONE acceptance before `update_goal(action: complete)` may take effect, because the board gates that call on the official tool pre-execute lifecycle instead of trusting the agent's own report. Acceptance runs the default final acceptance of the installed `dsh-llm-verifier` (MIT): the three coding criteria (Specification Adherence, Output Match, Error Signal Detection), a 0.65 threshold applied to the total AND to every criterion, two judge rounds per criterion with the A/B slots swapped and averaged, the task's real trajectory (tool calls, their output, assistant prose) judged against the empty-work baseline, the work must beat that baseline, and — when the deployment records workspace changes — the HOST's own record of what the run changed on disk (file list with added/deleted counts and bounded per-file comparisons) is attached as the prompt's reference context so a described-but-unapplied patch cannot pass. A veto is booked as a quality verdict only when it can be LOCATED: every criterion that makes the run fail must arrive with a structured finding naming the requirement it imposes, the observation that falls short, the difference, and a verbatim citation of the task, the work's own trajectory or the host's workspace record. A rejecting answer with no finding, a generic or empty finding, a citation that does not occur in the reviewed evidence, a citation of the empty-work baseline, and a criterion failed without its own evidence are recorded as an INVALID acceptance instead: they spend no quality budget, do not fail the card, and are bounded separately (two), after which the board stops calling the judge and holds the card for a human. A run whose only records are invalid ends for lack of a matching pass, but with its own terminal reason that states the acceptance was unusable and explicitly denies being an evidence-backed quality veto. A judge that could not see the output because the trace was truncated is treated the same way, because insufficient evidence is not a failure of the work. One execution may accept twice: the first failure returns the total, the per-criterion scores and the located findings to the fixing agent, the second failure ends that execution as failed. Once an execution PASSES and settles, the acceptance-only detail (its findings and structured citations) is removed automatically and only a lightweight audit credential remains — verdict, scores, time, judge route, evidence hash and a one-line problem summary. Nothing outside that execution's own acceptance record is touched, a failed or invalid execution keeps everything a repair or a review needs, the removal is idempotent, and a cleanup that fails is recorded and retried on the next Host start without ever revoking the pass. The budget lives on the execution record, so a repeated completion call, a new goal round, a plugin reload and a Host restart all reuse the same cycle, while a rerun or a scheduled occurrence is a new execution with its own budget. An anomaly (timeout, authentication failure, unparseable judge answer, unresolvable judge route) is recorded separately from a quality verdict and never consumes the quality budget. Exhausting the anomaly budget does NOT fail the card: a judge route that cannot answer is the environment failing, not the work, so the cycle is held open with no further judge call until a user clears the recorded anomalies through `task_board_manage(action: reset-verification)`. An attempt that the acceptance time budget ends before any verdict is recorded as its own stage, spends no budget at all and also fails nothing. Both ceilings are settings (`goalVerificationCallTimeoutSeconds`, `goalVerificationBudgetSeconds`), read live, and a judge call is never opened when the time left cannot hold it. The running column shows executing / verifying / fixing, and each execution's row carries its verdict, judge model and level, count, scores with thresholds, findings, evidence scope and token usage. Forced acceptance also keeps the old fallback paths honest: a paused goal, an unreadable projection, a completed turn and a manual settle can no longer settle a goal execution as succeeded without a matching pass record. A failure carrying acceptance records means the judge answered and the work did not pass, while a failure with no acceptance record at all is reported as its own reason: the gate never opened because the session never called `update_goal(action: complete)` — often a session that narrated completion in prose — so nothing was ever judged and the delivery was never rejected. **A single card can opt out of the gate**: the new-task form and the task detail both carry a Skip acceptance checkbox (off by default, a card-level option like Continue in the same conversation and Start with /goal), and a checked card no longer intercepts its completion claim in goal form. The execution records `applicability: skipped` and the report says the CARD skipped acceptance, which is a different fact from the board-wide switch being off and is reported as such. It applies only to executions started afterwards, so flipping it mid-run never rewrites the rule judging a run already in flight.
|
|
44
|
+
- **Optional session reuse**: a task can opt into continuing in its previous execution's session (issue #1419). Reuse happens only when that session is idle and still present in the runtime roster — the Host then re-applies the pinned permission and model on it and queues the prompt, keeping the conversation title and history; otherwise the run mints a fresh session as before, so an unknown roster or a busy session never blocks a scheduled run. The roster read is taken for the launch itself, so a board that has been idle reuses a session that has been idle all along instead of refusing it.
|
|
45
|
+
- **Idle-aware session polling (issue #1821)**: the Host reads the DSH session roster only while the board has something that roster can decide — an execution to inspect, or a card parked in the running column whose verdict may arrive from a settle this process never saw. An empty board with no running card, no open execution and no enabled schedule polls nothing at all, so an idle Host no longer rebuilds every persisted session row (string conversion, object allocation, one stat per record) on a fixed heartbeat. The cadence that governs a busy board is the `sessionPollSeconds` setting, and a roster read that fails or stays unknown backs off on a doubling delay up to one minute, so a session tree that is down is not hammered at the poll interval.
|
|
45
46
|
- **Fail-closed pins**: a missing workspace, missing or broken preset, or rejected permission command fails before the task prompt is sent.
|
|
46
|
-
- **Host scheduler**: 5-field cron supports `*`, `*/n`, ranges, comma lists, and Sunday `0/7`. Each rule carries its own IANA time zone (the Host's zone by default), and day-of-month/day-of-week follow Vixie semantics: both fields restricted means OR, any other combination means AND. Wall-clock gaps at a daylight-saving transition are skipped, and an ambiguous repeated time fires once, at the earlier instant.
|
|
47
|
+
- **Host scheduler**: 5-field cron supports `*`, `*/n`, ranges, comma lists, and Sunday `0/7`. Each rule carries its own IANA time zone (the Host's zone by default), and day-of-month/day-of-week follow Vixie semantics: both fields restricted means OR, any other combination means AND. Wall-clock gaps at a daylight-saving transition are skipped, and an ambiguous repeated time fires once, at the earlier instant. A rule is either a recurring cron rule — optionally capped by a run limit (unlimited, 1, 2, or any positive whole number) — or a one-shot pinned to a single future instant; the Host counts the executions it actually opens, and a rule that reaches its cap or fires its one-shot stops itself in the ledger rather than waiting for the executed work to disarm it.
|
|
47
48
|
- **Deterministic recovery**: a running execution with a recorded session is observed after restart; an interrupted start without a session id is cancelled and is not resent.
|
|
48
49
|
- **Live synchronization**: mutations return a full revisioned snapshot; SSE announces revision, scheduler, and power changes, while reconnect and page visibility recovery fetch a full snapshot.
|
|
49
50
|
- **Optional idle-sleep protection**: off by default; when enabled it covers every running DSH session, enabled non-archived task-board schedules, and unknown session state.
|
|
50
51
|
- **System-prompt injection**: the Host registers a `plugin:task-board` section (order 200) through `SystemPrompt.section`, and the task-board settings can disable the announcement without disabling the board. The guidance also reminds agents to close any visible `todo_write` plan before the final answer.
|
|
51
52
|
- **Agent tools**: every session gets eight model-facing tools (`task_board_list`, `task_board_get`, `task_board_create`, `task_board_update`, `task_board_set_parent`, `task_board_run`, `task_board_manage`, `task_board_schedule`) that drive the same Host ledger the browser drives, so an agent can list the board, create subtasks, link or detach them, run a cascade, move a card to any column (declaring it done, failed, or in progress without a run), archive/restore/delete it, settle a card the board can no longer observe, and arm its cron schedule from the conversation.
|
|
53
|
+
- **External outcomes (issue #1826)**: work that is not executed by this Host — an agent outside DSH such as Codex or Claude Code, running its own model — can be recorded as a real run rather than a bare column edit. `task_board_manage(action: 'record-external-outcome', result: 'succeeded'|'failed', initiatedBy: <who>)` appends an execution record carrying the verdict, the caller and an optional summary, and the terminal column is derived from that same record by the same rule a Host settlement uses (`core/tasks.ts` `settledStatus`). The record is marked `external`, never carries a session, and is refused while the card still has an open execution (while this Host is running the card it stays the only authority) and on an archived card. `running` and `cancelled` cannot be recorded this way: those stay Host-only. A manual `move-done`/`move-failed` remains available and still writes only the column — the difference is that this one leaves a record behind, so the column and the run history can never disagree.
|
|
52
54
|
|
|
53
55
|
- **External provider extensions**: the GitHub Issues extension (`@linxin666/dsh-client-ui-task-board-github`, enabled by default) synchronizes GitHub Issues into board cards. It is a provider of THIS board, so its configuration renders inside this plugin's own settings card — the section only appears while the extension is installed, and its repository/credential form only while the extension is on; see [its README](../dsh-task-board-github/README.md).
|
|
54
56
|
|
|
@@ -57,8 +59,8 @@ Cards keep multi-line title and description previews with visible metadata. Prev
|
|
|
57
59
|
The board view renders on first open and keeps its local view state when closed and reopened. Host synchronization, scheduling and execution remain active independently of the view.
|
|
58
60
|
|
|
59
61
|
- `src/index.ts` mounts the Host service through the official `@deepseek-ai/dsh-api-gateway`, `@deepseek-ai/dsh-workspace`, and `@deepseek-ai/dsh-host-webserver` SDKs.
|
|
60
|
-
- `src/host-ledger.ts` serializes actions and persists `{ schemaVersion:
|
|
61
|
-
- `src/host-service.ts` owns
|
|
62
|
+
- `src/host-ledger.ts` serializes actions and persists `{ schemaVersion: 6, revision, tasks, scheduler, recentRequests }` through a temporary file plus atomic rename.
|
|
63
|
+
- `src/host-service.ts` owns schedule firing (a single timer armed at the ledger's nearest target through the host's `timer` service, falling back to process timers when the host serves none), missed-trigger skipping, runner launch, restart reconciliation, and power reasons; the ledger itself owns the run budget, so a one-shot or an exhausted capped rule can never be opened a second time.
|
|
62
64
|
- `src/client/native-panel.tsx` registers the board's sidebar row and center-column page (the official `sidebar.panellist` list seat and the keyed `main` seat) and maintains the center-column exclusivity protocol with the ssh panel.
|
|
63
65
|
- `src/client/host-api.ts` imports legacy browser data once, submits idempotent actions, and treats Host snapshots as the only confirmed UI state.
|
|
64
66
|
- Same-origin endpoints are `GET /api/task-board/state`, `GET /api/task-board/events`, and `POST /api/task-board/action`.
|
|
@@ -75,7 +77,7 @@ The board is operable from a conversation, not only from the GUI. Each tool driv
|
|
|
75
77
|
- `task_board_set_parent` links an existing card under a parent, or detaches it with an empty parent id.
|
|
76
78
|
- `task_board_run` runs a card now (optionally re-running a settled one), cascading over its whole subtask tree; it consumes real API quota and refuses an unconfirmed above-default permission with `confirmation-required`.
|
|
77
79
|
- `task_board_manage` moves a card to any column — the move writes the column and never an execution record, so backlog/todo plan, done/failed declare work that finished outside a tracked run and running parks work that is under way without a session, while a card with an open execution refuses the move until it settles — archives or restores it, deletes it, or settles a running card the board can no longer observe (recording a cancelled verdict with the caller as the reason and returning the card to todo), with the Host's running-task and subtask guards.
|
|
78
|
-
- `task_board_schedule` arms, changes, or disarms a card's cron
|
|
80
|
+
- `task_board_schedule` arms, changes, or disarms a card's schedule — a recurring cron rule (optionally capped by `maxRuns`; `0` clears the cap back to unlimited) or a one-shot at an epoch-millisecond `at` — including its IANA time zone (an empty `timeZone` clears it back to the Host zone).
|
|
79
81
|
|
|
80
82
|
There is deliberately no tool that confirms a permission binding: that gate exists so a human lifts an above-default permission, and an agent able to stamp it would make the gate decorative. An agent that hits `confirmation-required` asks the user to confirm the card in the board UI. Tool calls are attributed: a run records the calling session as its initiator, and a create/update stamps it into a continuation card's snapshot.
|
|
81
83
|
|
|
@@ -110,9 +112,13 @@ This plugin's settings card groups its options into collapsible sections — the
|
|
|
110
112
|
| `proxyTokenEnv` | `DSH_TASK_BOARD_PROXY_TOKEN` | Environment variable containing the reverse-proxy token; the token itself is never stored in plugin config. |
|
|
111
113
|
| `sessionDefaultPermission` | follow the Host | Explicit baseline for the permission confirmation gate. Unset, the board follows the Host's own default permission preset (what new DSH sessions start at) and falls back to `read-only` when the deployment serves no permission catalog. A card whose effective permission (handover bundle or pin) is above the baseline requires a human confirmation before it may run; cron refuses unconfirmed cards. |
|
|
112
114
|
| `maxSubtaskDepth` | `1` | Subtask depth limit, 1 to 3. At 1 a task may carry one level of subtasks and a subtask cannot be given subtasks of its own; every extra level multiplies the sessions one run of the root opens. |
|
|
113
|
-
| `
|
|
115
|
+
| `sessionPollSeconds` | `5` | How often, in seconds, the Host re-reads the DSH session roster while the board has something to reconcile: a running card or an open execution. An idle board with neither does not poll at all. Range 1 to 300; a shorter interval settles runs sooner and costs the Host more. |
|
|
116
|
+
| `goalRunEnabled` | `false` | GLOBAL native `/goal` switch. While off, every card runs one plain turn and the board never arms dsh's built-in `/goal`; a run uses native `/goal` only when this is on AND the card's own Start with /goal option is checked (that option is off by default). The value is frozen when an execution starts, so a live edit only affects executions that begin afterwards, and a card's stored `goalRun` preference is never rewritten. Such a run is recorded as `goal-disabled`: it is neither reported as accepted nor failed for lacking a completion call. Independent of `goalVerification`. |
|
|
117
|
+
| `goalVerification` | `true` | Goal acceptance for executions this board starts. When on, `update_goal(action: complete)` inside a task execution is refused until an acceptance pass is recorded for that execution. Only goal-form executions are affected: plain chat and a card that did not opt into `goalRun` are untouched. A single card can opt out of the gate on its own with the Skip acceptance checkbox (below). |
|
|
114
118
|
| `goalVerificationModel` | `''` (inherit) | Judge model route as `provider/model`. Blank inherits the HOST model catalog default — never the card's pinned execution model. |
|
|
115
119
|
| `goalVerificationReasoningEffort` | `''` (inherit) | Judge reasoning level. Blank inherits the host default level; a level the resolved model does not declare is never sent, and the fallback to that model's own default is recorded and shown. |
|
|
120
|
+
| `goalVerificationCallTimeoutSeconds` | `150` | Ceiling of ONE judge request of an acceptance, in seconds (range 30 to 600). One acceptance issues six judge requests, so a ceiling too small for the judge model turns a slow but healthy route into a wall of timeouts. |
|
|
121
|
+
| `goalVerificationBudgetSeconds` | `1200` | Total ceiling of ONE acceptance attempt, in seconds (range 120 to 1800), covering evidence rendering and every judge call including retries. Keep it at or above the per-call ceiling times six or the acceptance can never finish; an attempt that runs out is recorded as a budget stop that judges nothing and spends no budget. |
|
|
116
122
|
| `teamProvider` | `spawn` | Continuable-subagent provider the Agent Teams service composes a teammate from. Only team-mode runs use it; it matches the Agent Teams tool plugin's `freshProvider` default. |
|
|
117
123
|
|
|
118
124
|
Direct browser access remains limited to the DSH loopback origin. For a same-host authenticated reverse proxy, bind DSH Web to loopback, set `trustedProxyHosts`, place a high-entropy token in the environment variable selected by `proxyTokenEnv`, and configure the proxy to replace (not forward from the client) `X-Dsh-Task-Board-Proxy-Token` after it authenticates the request. The proxy Host must be allowlisted, and the browser `Origin` must have that same authority. Restart the Host after changing these composition-level proxy settings.
|
|
@@ -126,8 +132,9 @@ On macOS the backend starts `/usr/bin/caffeinate -i -w <host-pid>` and never req
|
|
|
126
132
|
- A v2 to v3 migration failure (structurally invalid task rows) fails closed with an explicit error and keeps the original file untouched; it never restarts from an empty ledger silently. A corrupt or unsupported-schema file is moved to a collision-resistant `ledger-v2.json.corrupt-*` name and the Host starts with an empty ledger plus a visible scheduler error. The corrupt bytes are not overwritten.
|
|
127
133
|
- On the first upgraded page load for an origin, `dsh.taskBoard.v1` is imported by stable source and request ids. Tasks merge by id, strictly newer browser top-level fields win, equal timestamps keep Host fields, and execution records merge by execution id.
|
|
128
134
|
- The most recent 256 request ids and SHA-256 action fingerprints are stored with the ledger, so a retried mutation remains idempotent after a Host restart without duplicating full action payloads.
|
|
135
|
+
- An external-outcome execution record adds one optional boolean (`external`). A ledger written before it existed carries none, and the loader neither invents one nor treats an absent field as external, so old documents read back unchanged; a non-boolean value is dropped rather than trusted as provenance. The ledger stays at v5: the field is absent from every existing row, which is exactly the additive change the v5 migration already describes.
|
|
129
136
|
- Task labels are an optional `tags` field on the task row (`{ name, promptPrefix? }[]`) and needed no schema bump: a v3 document without it loads unchanged, and a malformed list is repaired entry by entry (blanks, repeats, and over-long names dropped, count capped) rather than dropping the task row.
|
|
130
|
-
- The goal opt-in is an optional `goalRun` field on the task row and needed no schema bump either: absent means
|
|
137
|
+
- The goal opt-in is an optional `goalRun` field on the task row and needed no schema bump either: absent means off, an explicit `true` is the opt-in, and a stray `false` is repaired back to absent on load.
|
|
131
138
|
- The import marker `dsh.taskBoard.v2.hostImported` stores the confirmed Host ledger generation only after import succeeds. A new or recovered ledger generation is offered the retained v1 data again. The v1 localStorage value remains untouched as a read-only rollback copy.
|
|
132
139
|
- One Host process owns a task-board ledger directory at a time through `$DSH_HOME/task-board/ledger-v2.lock`; a second Host using the same DSH home fails closed instead of concurrently writing the ledger.
|
|
133
140
|
|
|
@@ -161,7 +168,7 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
161
168
|
2. Create and edit a task; refresh or open a second same-origin tab and confirm both show the same Host revision.
|
|
162
169
|
3. Run a task with pinned workspace, preset, and permission; confirm a new session appears and the task settles from its `turn/end` history.
|
|
163
170
|
4. Run a task with the /goal option checked: confirm the session starts a goal and the card stays in `running` across continuation rounds until the goal completes, then settles as succeeded. Uncheck the option and confirm the next run is a single turn that settles from one `turn/end`.
|
|
164
|
-
5. Enable a near-future cron, close all browser pages, and confirm the Host still creates and settles exactly one execution.
|
|
171
|
+
5. Enable a near-future cron, close all browser pages, and confirm the Host still creates and settles exactly one execution. Then arm a one-shot at a near-future instant and confirm exactly one execution is created and the rule reads as ended; set a recurring rule's run limit to 2 and confirm the third occurrence creates nothing.
|
|
165
172
|
6. Stop the Host past a cron occurrence, restart it, and confirm the missed occurrence is skipped and `nextRunAt` rolls forward from current Host time.
|
|
166
173
|
7. Enable `preventIdleSleep`, run a long session, and let the display turn off; after restoring the display, confirm the session continued and the execution settled.
|
|
167
174
|
8. Disable the setting and all schedules, stop DSH, and confirm the helper exits; on macOS, `pmset -g assertions` should show no display-sleep assertion from this plugin.
|
|
@@ -170,7 +177,8 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
170
177
|
## Known limitations
|
|
171
178
|
|
|
172
179
|
- Missed occurrences during Host downtime, system sleep, or a long pause are skipped and never queued for catch-up.
|
|
173
|
-
- A task that is already running skips its due occurrence and rolls to the next cron match; task runs never overlap or queue.
|
|
180
|
+
- A task that is already running skips its due occurrence and rolls to the next cron match; task runs never overlap or queue. A one-shot has no next match: an instant missed because the card was running or the Host was down stops the rule as skipped, and is never replayed.
|
|
181
|
+
- A capped rule counts the executions the scheduler opened, and a manual run never spends the scheduled budget. A launch that fails before any session exists is refunded, so the rule keeps its next occurrence; a run that did reach a session counts even if it then failed.
|
|
174
182
|
- DST follows the Host local wall clock: a nonexistent spring-forward minute is skipped, and a repeated fall-back minute is not replayed a second time.
|
|
175
183
|
- Power protection prevents only idle system sleep. It deliberately allows display sleep and lock.
|
|
176
184
|
- Lid close, manual sleep, hibernation, shutdown, low-battery forced sleep, and enterprise power policy are outside the guarantee.
|
|
@@ -186,7 +194,7 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
186
194
|
- Acceptance spends model requests: one acceptance is three criteria times two rounds (six judge requests), and one execution may accept twice, so a goal cycle that needs its one repair costs up to twelve extra requests on top of the work itself.
|
|
187
195
|
- No cost estimate is shown for an acceptance: this deployment exposes no reliable per-token price for the resolved judge route, so the report lists tokens only.
|
|
188
196
|
- The host-observed workspace-change block appears only when the deployment records changes and the read succeeds; an unavailable service or a failed comparison degrades the evidence to the trajectory alone rather than failing the acceptance.
|
|
189
|
-
- Acceptance is enforced only where it can be: a run that never became a goal run (`/goal` refused or unavailable) and a teammate execution are not gated, and their record says so explicitly instead of implying they were verified. A deployment that serves no model catalog cannot resolve a judge route, so a completion claim
|
|
197
|
+
- Acceptance is enforced only where it can be: a run that never became a goal run (`/goal` refused or unavailable, or the global switch off) and a teammate execution are not gated, and their record says so explicitly instead of implying they were verified. A global-switch run is marked `goal-disabled` — its own reason, distinct from a refused command — so it is never read as a passed acceptance either. A deployment that serves no model catalog cannot resolve a judge route, so a completion claim is refused and recorded as an acceptance anomaly; once the anomaly budget is spent the card is held open rather than failed, and recovering needs a user to clear the anomalies.
|
|
190
198
|
- The first version always judges with the coding criteria: there is no automatic rubric selection, so a non-coding task is judged by engineering criteria (the settings copy states this).
|
|
191
199
|
- If a third-party verifier (for example the installed `dsh-llm-verifier`) also enables its own automatic acceptance, both judges score the same session independently: this board's acceptance gates completion while the other only steers, and no public SDK interface lets them share one verdict. Turning that plugin's automatic mode off is the only reliable way to avoid paying for two judgments.
|
|
192
200
|
|
package/README.zh.md
CHANGED
|
@@ -39,16 +39,18 @@
|
|
|
39
39
|
- **Host 权威账本**:任务、计划和执行记录存于 `$DSH_HOME/task-board/ledger-v2.json`;浏览器动作只有经 Host 确认后才成为 UI 状态。
|
|
40
40
|
- **有界执行历史**:每个任务只保留最近 20 条执行记录;新运行开始时截掉最旧的记录,使账本大小与每次写入成本不随任务历史无限增长。
|
|
41
41
|
- **真实执行**:手动运行和定时运行共用 Host runner,默认新建独立会话、重命名、应用 agent 预设和 `/permission <id>`,再以 queue 模式发送任务 Prompt。
|
|
42
|
-
-
|
|
43
|
-
- **任务验收(默认开启)**:以 goal 形式执行的任务必须先通过一次验收,`update_goal(action: complete)` 才会生效——看板在官方「工具执行前」生命周期上拦截这次调用,而不是相信 agent 的自述。验收沿用已安装 dsh-llm-verifier(MIT)的默认最终验收:三项 coding 判据(Specification Adherence、Output Match、Error Signal Detection)、总分与每项判据都必须达到 0.65 阈值、每项两轮并交换 A/B 位置后取平均、以任务真实轨迹(工具调用及其输出、assistant
|
|
44
|
-
- **可选会话复用**:任务可选择在上一执行会话中继续(issue #1419)。仅当该会话空闲且仍在运行时会话名册中才复用——Host 会重新应用钉住的权限与模型再以 queue 模式发送 Prompt
|
|
42
|
+
- **目标驱动执行(卡片逐张选择加入,且需总开关开启)**:全局原生 `/goal` 开关(见下,默认关闭)是总开关;开启后,只有卡片在详情页勾选加入(新建任务对话框默认不勾选)时,runner 才会先入队任务 Prompt,再以同一份组合 Prompt 作为目标武装 dsh 内置的 `/goal`。dsh 的目标轮次驱动器会在同一会话中不断开启续跑轮次,直到 agent 标记目标完成;看板则让该执行一直保持 `running`,直到目标离开 active 阶段:目标正常完成判为成功,被阻塞则以目标自身的原因判为失败。该选项按任务设置(`goalRun`,缺席即关闭,因此从未动过该选项的卡片只执行一轮普通对话),`task_board_create`/`task_board_update` 同样可用。勾选框始终可操作:总开关只决定该偏好是否生效,从不决定它能否被表达,也绝不改写已保存的值。
|
|
43
|
+
- **任务验收(默认开启)**:以 goal 形式执行的任务必须先通过一次验收,`update_goal(action: complete)` 才会生效——看板在官方「工具执行前」生命周期上拦截这次调用,而不是相信 agent 的自述。验收沿用已安装 dsh-llm-verifier(MIT)的默认最终验收:三项 coding 判据(Specification Adherence、Output Match、Error Signal Detection)、总分与每项判据都必须达到 0.65 阈值、每项两轮并交换 A/B 位置后取平均、以任务真实轨迹(工具调用及其输出、assistant 文本)对比空工作基线,实际工作必须胜过该基线;部署记录工作区变更时,还会附上宿主自身对「本次运行改了磁盘上什么」的记录(文件清单与增删行数、有界的逐文件对比)作为提示词的参考上下文,使「只在自述里写过的补丁」无法通过。否决只有在**可定位**时才记为质量判定:任何导致不通过的判据都必须带有结构化问题反馈,写明它施加的任务要求、未达标的实际观测、差异,以及对任务、本次执行自己的轨迹或宿主工作区记录的逐字引用。没有反馈的否决、空泛或空的反馈、引用并不出现在所审证据中、引用空工作基线、以及「判据不通过却没有它自己的证据」,都记为**无效验收**:不消耗质量额度、不判卡片失败,并单独有界(两次);额度用尽后看板停止调用裁判、把卡片留给人工处理。若某次执行的记录只有无效验收,它同样因没有匹配的通过记录而结束,但使用独立终态原因,说明验收本身不可用,并明确否认这是有证据的质量判负。轨迹被截断导致裁判看不到输出时同样按无效验收处理,因为证据不足不等于工作没做。同一 execution 最多验收两次:第一次不通过把总分、逐项分数与可定位问题交回修复的 agent,第二次仍不通过即判该 execution 失败。执行**通过**并结算后,验收专用详细材料(问题反馈与结构化引用)会自动移除,只保留轻量审计凭据——判定、分数、时间、裁判路由、证据哈希与一行问题摘要。该 execution 记录之外的任何东西都不动;失败或无效的执行保留修复与复核所需的全部材料;移除是幂等的;清理失败会被记录并在宿主下次启动时重试,且绝不撤销通过记录。额度记录在 execution 记录上,因此重复完成调用、跨入下一 goal 轮次、插件重载与宿主重启都复用同一周期;重跑或一次定时触发则是新的 execution、重新计数。验收异常(超时、鉴权失败、裁判回答无法解析、裁判路由不可解析)与质量判定分开记录,不消耗质量额度。异常额度用尽并不把卡片判死:裁判路由答不上来是环境故障而不是工作不合格,此时执行周期保持打开、不再发起裁判调用,直到用户通过 `task_board_manage(action: reset-verification)` 清除已记录的异常。若一次验收在产生任何判定前就耗尽时间预算,会单独记为一类结果,不消耗任何额度,同样不判死卡片。两个上限都是配置项(`goalVerificationCallTimeoutSeconds`、`goalVerificationBudgetSeconds`),按需实时读取;剩余时间装不下一次调用时不会发起这次注定被中断的调用。运行列显示「执行中 / 验收中 / 验收未通过修复中」,每条 execution 记录展示判定、裁判模型与强度、次数、各项分数与阈值、问题反馈、证据范围与 token 用量。强制验收还堵住了旧回退路径:暂停的 goal、读取失败的 projection、已完成的回合与人工强制结算,都不能在没有匹配通过记录的情况下把 goal 执行结算为成功。带着验收记录失败意味着裁判给出了判定而工作没通过;一条验收记录都没有的失败则单独说明:验收门从未打开,因为执行会话没有调用 `update_goal(action= complete)`(常见于只在回复里宣告完成),交付从未被判定,更谈不上被判负。**单张卡片可以退出这道门**:新建任务与任务详情都有「跳过本任务的验收」勾选(默认不勾,语义与「同一对话继续」「以 /goal 开始执行任务」同级的卡片级选项),勾选后该卡以 goal 形式执行时不再拦截完成声明,执行记录标注 `applicability: skipped` 并在验收面板写明「该任务卡勾选了跳过验收」——它与总开关关闭是两回事,看板会分别说明。只对之后新开的执行生效,运行中改勾选不会改写已在飞的执行的判定规则。
|
|
44
|
+
- **可选会话复用**:任务可选择在上一执行会话中继续(issue #1419)。仅当该会话空闲且仍在运行时会话名册中才复用——Host 会重新应用钉住的权限与模型再以 queue 模式发送 Prompt,会话标题与历史保持不变;否则照旧新建会话,因此名册未知或会话正忙都不会阻塞定时运行。名册读取就发生在这次启动本身,所以长期空闲的看板会复用一个一直空闲的会话,而不是因为缓存过期而拒绝它。
|
|
45
|
+
- **空闲时停止会话轮询(issue #1821)**:只有当看板确实有需要名册裁决的事情时,Host 才读取 DSH 会话名册——存在待核对的执行,或运行列里有一张卡片(它的结果可能来自本进程没观测到的结算)。空看板、没有运行中卡片、没有未结算执行、也没有已启用计划时不轮询任何东西,因此空闲的 Host 不再按固定心跳重建每一条持久化会话行(字符串转换、对象分配、每条记录一次 stat)。有工作时按配置项 `sessionPollSeconds` 的节奏轮询;读取失败或名册仍未知时按翻倍延迟退避,上限一分钟,因此会话树故障时不会被按轮询间隔反复冲击。
|
|
45
46
|
- **钉子失败即关闭**:工作区缺失、预设缺失或损坏、权限命令被拒绝时,任务 Prompt 不会发送。
|
|
46
|
-
- **Host 调度器**:5 段 cron 支持 `*`、`*/n`、范围、逗号列表和周日 `0/7`。每条规则携带自己的 IANA 时区(默认跟随 Host 时区),日期/星期遵循 Vixie 语义:两个字段都受限时为 OR,其余组合为 AND
|
|
47
|
+
- **Host 调度器**:5 段 cron 支持 `*`、`*/n`、范围、逗号列表和周日 `0/7`。每条规则携带自己的 IANA 时区(默认跟随 Host 时区),日期/星期遵循 Vixie 语义:两个字段都受限时为 OR,其余组合为 AND。夏令时切换处的墙上时间空洞会被跳过,重复出现的歧义时刻只触发一次并取更早者。规则有两种计划:循环 cron(可设次数上限,支持不限、1、2 或任意正整数)或在未来某一时刻只执行一次的单次计划;Host 只统计它真正开启的执行,达到上限或单次已执行的规则会在账本里自行停止,而不是等被执行的工作去关掉它。
|
|
47
48
|
- **确定性恢复**:已有 session id 的 running execution 在重启后继续观察;没有 session id 的启动中断会取消且不会重发。
|
|
48
49
|
- **实时同步**:变更返回完整 revision snapshot;SSE 只提示 revision、scheduler 与 power 变化,重连和页面恢复可见时重新拉完整 snapshot。
|
|
49
50
|
- **可选空闲睡眠保护**:默认关闭;开启后覆盖全部运行中的 DSH 会话、已启用且未归档的任务计划和未知会话状态。
|
|
50
51
|
- **系统提示词注入**:Host 通过 `SystemPrompt.section` 注册 order 200 的 `plugin:task-board` 段;任务看板设置可单独关闭声明而不关闭看板。该提示也会提醒 agent 在最终回复前收尾可见的 `todo_write` 计划列表。
|
|
51
52
|
- **Agent 工具**:每个会话都可使用八个面向模型的工具(`task_board_list`、`task_board_get`、`task_board_create`、`task_board_update`、`task_board_set_parent`、`task_board_run`、`task_board_manage`、`task_board_schedule`),它们驱动与浏览器完全相同的 Host 账本,因此 agent 可以在对话里列出看板、创建子任务、关联或解除关联、执行级联、把卡片移到任意列(含不经执行直接声明完成、失败或进行中)、归档/恢复/删除卡片、对看板已无法观察的卡片强制结算,以及为卡片配置 cron 计划。
|
|
53
|
+
- **Host 之外完成的执行结果(issue #1826)**:不由本 Host 执行的工作——例如在 DSH 之外用各自模型工作的 Codex、Claude Code——可以登记成一次真实执行,而不是只改一列。`task_board_manage(action: 'record-external-outcome', result: 'succeeded'|'failed', initiatedBy: <完成者>)` 会追加一条 execution 记录,带上判定、完成者与可选摘要;终态列由这条记录推导,与 Host 结算走同一条规则(`core/tasks.ts` 的 `settledStatus`)。该记录带 `external` 标记、永远不带 session,并在卡片仍有未结算 execution 时被拒绝(本 Host 正在执行时它才是唯一权威),归档卡片同样拒绝。`running` 与 `cancelled` 不能这样登记:它们只属于 Host。手工 `move-done`/`move-failed` 仍然可用,也仍然只写列——区别在于这一条会留下记录,因此列与执行历史永远不会脱节。
|
|
52
54
|
|
|
53
55
|
- **外部提供方扩展**:GitHub Issues 扩展(`@linxin666/dsh-client-ui-task-board-github`,默认开启)把 GitHub Issues 同步成看板卡片。它是本看板的提供方,因此其配置渲染在本插件自己的设置卡里——仅当扩展已安装时该区块才出现,且只有扩展开启时才显示仓库与凭据表单;见[扩展包 README](../dsh-task-board-github/README.zh.md)。
|
|
54
56
|
|
|
@@ -57,8 +59,8 @@
|
|
|
57
59
|
看板视图在首次打开时渲染,关闭后重新打开会保留本地视图状态。Host 同步、调度和执行独立于视图持续运行。
|
|
58
60
|
|
|
59
61
|
- `src/index.ts` 通过官方 `@deepseek-ai/dsh-api-gateway`、`@deepseek-ai/dsh-workspace` 与 `@deepseek-ai/dsh-host-webserver` SDK 挂载 Host 服务。
|
|
60
|
-
- `src/host-ledger.ts` 串行动作,并用临时文件加原子 rename 持久化 `{ schemaVersion:
|
|
61
|
-
- `src/host-service.ts`
|
|
62
|
+
- `src/host-ledger.ts` 串行动作,并用临时文件加原子 rename 持久化 `{ schemaVersion: 6, revision, tasks, scheduler, recentRequests }`。
|
|
63
|
+
- `src/host-service.ts` 负责调度触发武装(按账本最近的到期时刻武装单个定时器,宿主未提供 `timer` 服务时回退到进程定时器)、错过触发跳过、runner 启动、重启对账和电源保护理由;次数预算由账本自己执行,因此单次计划或已用尽上限的循环规则绝不会被第二次开启。
|
|
62
64
|
- `src/client/native-panel.tsx` 注册看板的侧栏行与中栏页面(官方 `sidebar.panellist` 列表座位与 keyed `main` 座位),并维护与 ssh 面板的中栏互斥协议。
|
|
63
65
|
- `src/client/host-api.ts` 单次导入旧浏览器数据、提交幂等动作,并把 Host snapshot 当作唯一已确认 UI 状态。
|
|
64
66
|
- 同源接口为 `GET /api/task-board/state`、`GET /api/task-board/events` 和 `POST /api/task-board/action`。
|
|
@@ -75,7 +77,7 @@
|
|
|
75
77
|
- `task_board_set_parent`:把现有卡片挂到某个父任务下,或用空 parentId 解除关联。
|
|
76
78
|
- `task_board_run`:立即执行一张卡片(可选择重跑已结算的卡片),并级联执行它整棵子任务树;会消耗真实 API 额度,且未确认的高于默认权限的绑定会以 `confirmation-required` 被拒绝。
|
|
77
79
|
- `task_board_manage`:把卡片移到任意列——只写列、绝不伪造执行记录,因此待规划/待办用于规划、已完成/已失败用于声明工作在受追踪的执行之外结束、进行中用于表示工作正在进行但没有会话;真正有未结算执行的卡片会拒绝移动直到结算——归档或恢复、删除,或对看板已无法观察的运行中卡片强制结算(记为 cancelled 并记录调用者原因,卡片回到待办),同样受 Host 的运行中子任务与父子关系护栏约束。
|
|
78
|
-
- `task_board_schedule
|
|
80
|
+
- `task_board_schedule`:启用、修改或关闭卡片的计划——循环 cron(可选 `maxRuns` 上限,传 `0` 清空回不限次)或在 `at`(epoch 毫秒)指定时刻只执行一次的单次计划——包括其 IANA 时区(`timeZone` 传空字符串即清除,回退到 Host 时区)。
|
|
79
81
|
|
|
80
82
|
这里刻意没有「确认权限」工具:该门禁存在的意义就是由人工放行高于默认值的权限,若 agent 能自行盖章,这道门就形同虚设。遇到 `confirmation-required` 的 agent 应当请用户在界面确认该卡片。工具调用带归属:执行会把发起会话记为 initiator,创建/更新则会把发起会话写进续接卡片快照。
|
|
81
83
|
|
|
@@ -110,9 +112,13 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-task-board
|
|
|
110
112
|
| `proxyTokenEnv` | `DSH_TASK_BOARD_PROXY_TOKEN` | 保存反向代理 token 的环境变量名;token 本身不会写入插件配置。 |
|
|
111
113
|
| `sessionDefaultPermission` | 跟随宿主 | 权限确认门的显式基线。未设置时跟随宿主自己的默认权限预设(DSH 新会话的起始权限),部署不提供权限目录时回退 `read-only`。卡片有效权限(交接包或钉住字段)高于该基线时,运行前必须经人工确认;cron 拒绝调度待确认卡片。 |
|
|
112
114
|
| `maxSubtaskDepth` | `1` | 子任务深度上限,1 到 3。取 1 时一个任务只能有一层子任务,子任务不能再创建或关联子任务;每多一层,执行根任务一次开启的会话数就会成倍增加。 |
|
|
113
|
-
| `
|
|
115
|
+
| `sessionPollSeconds` | `5` | 看板有需要核对的事情(运行中的卡片或未结算执行)时,Host 重新读取 DSH 会话名册的间隔秒数。两者都没有的空闲看板完全不轮询。取值 1 到 300;间隔越短结算越快、Host 负载越高。 |
|
|
116
|
+
| `goalRunEnabled` | `false` | 全局原生 `/goal` 执行开关。关闭时所有卡片都按普通单回合执行,看板不再武装 dsh 内置的 `/goal`;只有它开启、且卡片自身的「以 /goal 开始执行任务」被勾选时(该选项默认关闭),运行才使用原生 /goal。该值在执行启动时冻结,因此实时修改只影响之后新开的执行,卡片存储的 `goalRun` 偏好绝不被改写。这类运行记录为 `goal-disabled`:既不会被报告为已验收通过,也不会因缺少完成调用被判失败。与 `goalVerification` 相互独立。 |
|
|
117
|
+
| `goalVerification` | `true` | 本插件所开执行的 goal 验收。开启后,任务执行内的 `update_goal(action: complete)` 在该执行取得验收通过记录前一律被拒绝。只影响以 goal 形式执行的运行:普通聊天与未勾选 `goalRun` 的卡片不受影响。单张任务卡可以用「跳过本任务的验收」勾选退出本开关的约束(见下)。 |
|
|
114
118
|
| `goalVerificationModel` | `''`(继承) | 裁判模型路由,形如 `provider/model`。留空继承宿主模型目录的默认路由,绝不是任务卡钉住的执行模型。 |
|
|
115
119
|
| `goalVerificationReasoningEffort` | `''`(继承) | 裁判推理强度。留空继承宿主默认档位;目标模型未声明的档位绝不传参,回退到该模型自身默认档位并记录、展示。 |
|
|
120
|
+
| `goalVerificationCallTimeoutSeconds` | `150` | 单次裁判调用的上限(秒,范围 30–600)。一次验收要发六次裁判调用,上限过小会把「慢但健康」的路由变成一整排超时。 |
|
|
121
|
+
| `goalVerificationBudgetSeconds` | `1200` | 单次验收的总时间上限(秒,范围 120–1800),覆盖证据渲染与全部裁判调用(含重试)。应不小于单次调用上限的六倍,否则一次验收永远跑不完;耗尽时记为一类「预算耗尽」结果,不产生任何判定,也不消耗任何额度。 |
|
|
116
122
|
| `teamProvider` | `spawn` | Agent Teams 服务用来组成 teammate 的 continuable-subagent provider。仅团队执行模式使用,与 Agent Teams 工具插件的 `freshProvider` 默认值一致。 |
|
|
117
123
|
|
|
118
124
|
浏览器直接访问仍限制为 DSH loopback origin。若使用同机认证反向代理,应让 DSH Web 绑定 loopback,配置 `trustedProxyHosts`,在 `proxyTokenEnv` 指定的环境变量中放置高熵 token,并让代理在完成认证后替换(不能透传客户端提供的)`X-Dsh-Task-Board-Proxy-Token`。代理 Host 必须在白名单内,浏览器 `Origin` 必须与其 authority 相同。修改这些 composition 级代理设置后需重启 Host。
|
|
@@ -126,8 +132,9 @@ macOS 后端启动 `/usr/bin/caffeinate -i -w <host-pid>`,绝不请求 `-d`。
|
|
|
126
132
|
- v2 到 v3 迁移失败(任务行结构非法)时失败关闭并报出明确错误,原文件保持不动;绝不静默以空账本重启。损坏或未知 schema 的文件会移动到防碰撞的 `ledger-v2.json.corrupt-*` 名称,Host 以空账本和可见 scheduler 错误启动,不覆盖损坏字节。
|
|
127
133
|
- 每个 origin 首次加载新版页面时,按稳定 source id 和 request id 导入 `dsh.taskBoard.v1`。任务按 id 合并,浏览器端严格较新的顶层字段优先,时间戳相同时保留 Host 字段,执行记录按 execution id 合并。
|
|
128
134
|
- 最近 256 个 request id 与动作的 SHA-256 指纹会随账本持久化,因此 Host 重启后的变更重试仍保持幂等,且不会复制完整动作载荷。
|
|
135
|
+
- 外部结果 execution 记录只新增一个可选布尔字段(`external`)。该字段出现之前写入的账本没有它,读取时既不会凭空补写、也不会把「没有该字段」当成外部执行,因此旧文档原样读回;非布尔值会被丢弃,不会被当成可信来源标记。账本仍保持 v5:该字段在既有行里一律缺席,正是 v5 迁移已描述的那种增量变更。
|
|
129
136
|
- 任务标签是任务行上的可选 `tags` 字段(`{ name, promptPrefix? }[]`),无需 bump schema:不含该字段的 v3 文档原样加载,非法的标签列表逐条修复(丢弃空名、重复项与超长名,并封顶数量),而不是丢掉整行任务。
|
|
130
|
-
- /goal 选项是任务行上的可选 `goalRun` 字段,同样无需 bump schema
|
|
137
|
+
- /goal 选项是任务行上的可选 `goalRun` 字段,同样无需 bump schema:缺席即关闭,显式 `true` 是加入选择,多写的 `false` 在加载时被修复回缺席。
|
|
131
138
|
- 只有导入成功并经 Host 确认后,`dsh.taskBoard.v2.hostImported` 才保存当前 Host 账本 generation;新建或损坏恢复出的新 generation 会再次接收保留的 v1 数据。v1 localStorage 原值保持不变,作为只读回退备份。
|
|
132
139
|
- 同一时间只有一个 Host 进程能通过 `$DSH_HOME/task-board/ledger-v2.lock` 持有任务看板账本目录;第二个使用同一 DSH home 的 Host 会失败关闭,不并发写账本。
|
|
133
140
|
|
|
@@ -161,7 +168,7 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
161
168
|
2. 新建并编辑任务;刷新或打开第二个同源标签页,确认两者显示同一 Host revision。
|
|
162
169
|
3. 执行一个钉住工作区、预设和权限的任务;确认出现新会话,并由该会话的 `turn/end` 历史结算任务。
|
|
163
170
|
4. 在勾选 /goal 选项的情况下执行一个任务:确认会话启动了目标,卡片在多轮续跑期间保持 `running`,直到目标完成后结算为成功。取消勾选后再执行一次,确认变回单回合、由一条 `turn/end` 结算。
|
|
164
|
-
5. 启用一个即将到期的 cron,关闭全部浏览器页面,确认 Host 仍只创建并结算一次 execution
|
|
171
|
+
5. 启用一个即将到期的 cron,关闭全部浏览器页面,确认 Host 仍只创建并结算一次 execution。再把单次计划设在即将到来的时刻,确认恰好创建一次 execution 且规则显示为已结束;把循环规则的次数上限设为 2,确认第三次触发不再创建任何执行。
|
|
165
172
|
6. 让 Host 停止并错过一个 cron 触发点,重启后确认该次被跳过,`nextRunAt` 从当前 Host 时间向后滚动。
|
|
166
173
|
7. 开启 `preventIdleSleep` 并运行长任务,让显示器自动熄灭;恢复显示后确认会话继续且 execution 已结算。
|
|
167
174
|
8. 关闭设置并禁用所有计划,再停止 DSH,确认 helper 退出;macOS 可用 `pmset -g assertions` 辅助确认插件没有 display-sleep assertion。
|
|
@@ -170,7 +177,8 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
170
177
|
## 已知限制
|
|
171
178
|
|
|
172
179
|
- Host 停止、系统睡眠或长暂停期间错过的触发点会跳过,绝不排队补跑。
|
|
173
|
-
- 同一任务已在运行时会跳过到期出现并滚动到下一 cron
|
|
180
|
+
- 同一任务已在运行时会跳过到期出现并滚动到下一 cron 匹配点;任务运行不并发、不排队。单次计划没有下一匹配点:因卡片正在运行或 Host 停机而错过的时刻会以「已跳过」结束该规则,绝不补跑。
|
|
181
|
+
- 有限次规则按调度器真正开启的执行计数,手动执行绝不消耗定时预算。任何会话存在之前就启动失败的那次会退回次数,规则因此保留下一次出现;而确实已到达会话的运行即使随后失败也计数。
|
|
174
182
|
- DST 采用 Host 本地墙上时钟语义:春季跳时中不存在的分钟会跳过,秋季回拨中重复的分钟不会执行第二次。
|
|
175
183
|
- 电源保护只阻止空闲系统睡眠,明确允许显示器睡眠与锁屏。
|
|
176
184
|
- 合盖、手动睡眠、休眠、关机、低电量强制睡眠和企业电源策略不在保证范围内。
|
|
@@ -186,7 +194,7 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
186
194
|
- 每次验收都会消耗模型请求:一次验收是 3 项判据 × 2 轮(6 次裁判请求),而同一 execution 最多验收两次,因此一个需要修复一次的 goal 周期最多在任务本身之外多花 12 次请求。
|
|
187
195
|
- 验收不估费用:本部署无法为目标裁判路由提供可靠的分 token 价格来源,报告只列出 token 用量。
|
|
188
196
|
- 宿主观察的工作区变更块只在部署确实记录变更且读取成功时出现;服务不可用或对比读取失败时,证据降级为只判轨迹,而不是让验收失败。
|
|
189
|
-
- 验收只在能生效的地方强制执行:没有成为 goal 执行的运行(`/goal`
|
|
197
|
+
- 验收只在能生效的地方强制执行:没有成为 goal 执行的运行(`/goal` 被拒绝或不可用,或全局总开关关闭)与团队执行的 teammate 成员不受门禁,记录会明确说明,而不是暗示它们已被验收。总开关关闭的运行记为 `goal-disabled`(独立原因,与「命令被拒」区分),因此也不会被读成已验收通过。宿主不提供模型目录时无法解析裁判路由,完成声明按 fail closed 拒绝并记为验收异常;异常额度用尽后卡片保持打开而不是判死,恢复需要用户清除这些异常。
|
|
190
198
|
- 第一版一律使用 coding 判据:没有自动 rubric 选择,非工程任务也按工程判据评判(设置界面已说明)。
|
|
191
199
|
- 若第三方验收插件(例如已安装的 `dsh-llm-verifier`)也开启了自己的自动验收,两个裁判会各自对同一会话评分:本看板的验收决定能否完成,另一个只做提示,公开 SDK 接口无法让二者共享同一判定。要避免为两次判定付费,只能关闭对方的自动模式。
|
|
192
200
|
|