@yadsh/dsh-qa-surface 0.15.3 → 0.15.5

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.
Files changed (47) hide show
  1. package/README.md +49 -8
  2. package/lib/approvals.js +42 -1
  3. package/lib/approvals.js.map +1 -1
  4. package/lib/client/QaSessionController.js +103 -3
  5. package/lib/client/QaSessionController.js.map +1 -1
  6. package/lib/client/QaSurface.js +6 -1
  7. package/lib/client/QaSurface.js.map +1 -1
  8. package/lib/client/QaTranscriptAdapter.js +33 -3
  9. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  10. package/lib/client/components/QaChangelog.js +38 -1
  11. package/lib/client/components/QaChangelog.js.map +1 -1
  12. package/lib/client/components/QaComposer.js +3 -0
  13. package/lib/client/components/QaComposer.js.map +1 -1
  14. package/lib/client/components/QaHeader.js +29 -3
  15. package/lib/client/components/QaHeader.js.map +1 -1
  16. package/lib/client/components/QaRightRail.js +20 -1
  17. package/lib/client/components/QaRightRail.js.map +1 -1
  18. package/lib/client/components/QaSidebar.js +12 -2
  19. package/lib/client/components/QaSidebar.js.map +1 -1
  20. package/lib/client/components/QaSourcesPanel.js +1 -1
  21. package/lib/client/components/QaSourcesPanel.js.map +1 -1
  22. package/lib/client/components/QaWorkGroup.js +13 -7
  23. package/lib/client/components/QaWorkGroup.js.map +1 -1
  24. package/lib/client/components/QaWorkspaceBrowser.js +5 -1
  25. package/lib/client/components/QaWorkspaceBrowser.js.map +1 -1
  26. package/lib/client/settings/styles.js +16 -10
  27. package/lib/client/settings/styles.js.map +1 -1
  28. package/lib/client/slash/SlashPalette.js +3 -1
  29. package/lib/client/slash/SlashPalette.js.map +1 -1
  30. package/lib/client/styles.js +31 -15
  31. package/lib/client/styles.js.map +1 -1
  32. package/lib/client.js +268 -78
  33. package/lib/client.js.map +1 -1
  34. package/lib/qa-tools/file-delete-gate.js +35 -10
  35. package/lib/qa-tools/file-delete-gate.js.map +1 -1
  36. package/lib/qa-tools/file-delete.js +1 -1
  37. package/lib/qa-tools/file-delete.js.map +1 -1
  38. package/lib/types/approvals.d.ts +18 -1
  39. package/lib/types/client/QaSessionController.d.ts +23 -0
  40. package/lib/types/client/components/QaHeader.d.ts +10 -1
  41. package/lib/types/client/components/QaRightRail.d.ts +7 -1
  42. package/lib/types/client/components/QaSidebar.d.ts +5 -0
  43. package/lib/types/client/components/QaWorkGroup.d.ts +5 -2
  44. package/lib/types/client/settings/styles.d.ts +6 -0
  45. package/lib/types/qa-tools/file-delete-gate.d.ts +24 -7
  46. package/lib/types/types.d.ts +5 -2
  47. package/package.json +3 -3
@@ -1,7 +1,20 @@
1
1
  /** The one QA tool whose every call is parked for the operator. */
2
2
  export const QA_FILE_DELETE_TOOL = "file_delete";
3
- /** Why the gate answers `ask` before the chain can decide alone. */
4
- export const QA_FILE_DELETE_ASK_REASON = "deleting a workspace file requires operator confirmation";
3
+ /**
4
+ * Why the gate answers `ask` before the chain can decide alone. The card the
5
+ * operator reads shows this verbatim, so it is written in the language of the
6
+ * surface rather than in the language of the tool chain.
7
+ */
8
+ export const QA_FILE_DELETE_ASK_REASON = "Удаление файла рабочего каталога требует подтверждения оператора.";
9
+ /**
10
+ * Why the gate answers `deny` — not `ask` — for a delegated caller. A child has
11
+ * no one to confirm to it: its card would sit over the parent's composer and
12
+ * stop the parent turn until a person answers something they were never asked
13
+ * about. Deleting a file is not a step a delegation was ever given, so the call
14
+ * is refused where it is raised, and the reason tells the child to report
15
+ * instead of trying again.
16
+ */
17
+ export const QA_FILE_DELETE_DELEGATED_DENY_REASON = "a delegated call cannot delete a workspace file: no operator can confirm it. Report the file that is in the way instead of removing it";
5
18
  /**
6
19
  * The inner half of `file_delete`'s safety: the decision that composes the
7
20
  * approval flow around one destructive tool.
@@ -18,7 +31,10 @@ export const QA_FILE_DELETE_ASK_REASON = "deleting a workspace file requires ope
18
31
  * behavior and refuses the call — nothing is ever deleted without a person.
19
32
  *
20
33
  * Any other tool, and any caller this deployment did not attest, is handed
21
- * back to the chain untouched.
34
+ * back to the chain untouched. A delegated child of an attested chat is the one
35
+ * attested caller that gets no card: it is refused here, on the name, whatever
36
+ * the deployment's approval mode is — the same refusal the answer reviewer of a
37
+ * stand needed before its parent turn could end.
22
38
  */
23
39
  export class QaFileDeleteGate {
24
40
  ctx;
@@ -41,20 +57,29 @@ export class QaFileDeleteGate {
41
57
  async handle(execution, next) {
42
58
  if (execution.name !== QA_FILE_DELETE_TOOL)
43
59
  return next();
44
- if (!this.attested(execution))
60
+ const root = this.rootOf(execution);
61
+ if (root === undefined)
45
62
  return next();
63
+ if (root.sessionId !== root.ownerSessionId) {
64
+ return { kind: "deny", reason: QA_FILE_DELETE_DELEGATED_DENY_REASON };
65
+ }
46
66
  return { kind: "ask", reason: QA_FILE_DELETE_ASK_REASON };
47
67
  }
48
68
  /**
49
- * Whether this deployment attested the chat the call belongs to, delegated
50
- * children included. The same ownership service the approval gate reads,
51
- * so one chat is parked under exactly one surface.
69
+ * The attested chat a call belongs to and the session that made it, delegated
70
+ * children included — the same ownership service the approval gate reads, so
71
+ * one chat is parked under exactly one surface. The two differ for a child,
72
+ * and a child is the caller that cannot be confirmed by anyone.
52
73
  */
53
- attested(execution) {
74
+ rootOf(execution) {
54
75
  const session = execution.agent?.session;
55
76
  if (session === undefined)
56
- return false;
57
- return this.ownership.rootOf(String(session.id)) !== undefined;
77
+ return undefined;
78
+ const ownerSessionId = String(session.id);
79
+ const sessionId = this.ownership.rootOf(ownerSessionId);
80
+ if (sessionId === undefined)
81
+ return undefined;
82
+ return { sessionId, ownerSessionId };
58
83
  }
59
84
  }
60
85
  //# sourceMappingURL=file-delete-gate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-delete-gate.js","sourceRoot":"","sources":["../../src/qa-tools/file-delete-gate.ts"],"names":[],"mappings":"AAKA,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEjD,oEAAoE;AACpE,MAAM,CAAC,MAAM,yBAAyB,GACpC,0DAA0D,CAAC;AAE7D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,gBAAgB;IAIR,GAAG;IACH,SAAS;IAJX,SAAS,GAAmB,EAAE,CAAC;IAEhD,YACmB,GAAY,EACZ,SAA6B;mBAD7B,GAAG;yBACH,SAAS;IACzB,CAAC;IAEJ,2EAA2E;IAC3E,OAAO;QACL,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CACnD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAC7B,CACF,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,OAAO;QACL,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,MAAM,CAClB,SAA8B,EAC9B,IAAoC;QAEpC,IAAI,SAAS,CAAC,IAAI,KAAK,mBAAmB;YAAE,OAAO,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACK,QAAQ,CAAC,SAA8B;QAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;QACzC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;IACjE,CAAC;CACF"}
1
+ {"version":3,"file":"file-delete-gate.js","sourceRoot":"","sources":["../../src/qa-tools/file-delete-gate.ts"],"names":[],"mappings":"AAKA,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,mEAAmE,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAC/C,wIAAwI,CAAC;AAE3I;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,gBAAgB;IAIR,GAAG;IACH,SAAS;IAJX,SAAS,GAAmB,EAAE,CAAC;IAEhD,YACmB,GAAY,EACZ,SAA6B;mBAD7B,GAAG;yBACH,SAAS;IACzB,CAAC;IAEJ,2EAA2E;IAC3E,OAAO;QACL,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CACnD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAC7B,CACF,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,OAAO;QACL,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,MAAM,CAClB,SAA8B,EAC9B,IAAoC;QAEpC,IAAI,SAAS,CAAC,IAAI,KAAK,mBAAmB;YAAE,OAAO,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;QACxE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACK,MAAM,CACZ,SAA8B;QAE9B,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;QACzC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACxD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC9C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;IACvC,CAAC;CACF"}
@@ -80,7 +80,7 @@ async function canonicalCandidate(input) {
80
80
  export function createFileDeleteTool() {
81
81
  return defineTool({
82
82
  name: "file_delete",
83
- description: "Delete one regular file inside this session's workspace. Use it to remove scratch files a task produced and no longer needs. Directories, missing paths and anything outside the workspace — including paths that escape through a symbolic link — are refused. Every deletion is confirmed by the operator before it runs.",
83
+ description: "Delete one regular file inside this session's workspace. Use it to remove scratch files a task produced and no longer needs. Directories, missing paths and anything outside the workspace — including paths that escape through a symbolic link — are refused. Every deletion is confirmed by the operator before it runs, and a call delegated from another agent is refused: nothing you delete on your own can be confirmed.",
84
84
  parameters: {
85
85
  path: {
86
86
  type: "string",
@@ -1 +1 @@
1
- {"version":3,"file":"file-delete.js","sourceRoot":"","sources":["../../src/qa-tools/file-delete.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-delete.js","sourceRoot":"","sources":["../../src/qa-tools/file-delete.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,15 @@ export interface QaApprovalExecution {
14
14
  readonly agent?: Agent;
15
15
  readonly signal?: AbortSignal;
16
16
  }
17
+ /**
18
+ * How long a parked request may hold a turn before it is failed closed. The
19
+ * request is a question to a person who may have walked away, and while it
20
+ * waits the whole turn — including any parent of a delegated caller — waits
21
+ * with it. A stand measured one at 1 h 06 m with nothing on the operator's
22
+ * screen but a thinking timer; minutes is the right unit for a yes/no about
23
+ * one tool call, and an expired request is refused, never assumed allowed.
24
+ */
25
+ export declare const QA_APPROVAL_PARK_TIMEOUT_MS: number;
17
26
  /**
18
27
  * Interactive resolution of the tool policy `ask` decision.
19
28
  *
@@ -30,6 +39,14 @@ export interface QaApprovalExecution {
30
39
  * approved automatically, and the allow-list, the workspace fence and the
31
40
  * read-only sandbox still run on the resolved call.
32
41
  *
42
+ * Two callers never reach the card. A delegated child is refused on the spot:
43
+ * it has no one to answer it — the harness already refuses a question from an
44
+ * agent owned by another live agent — so a parked approval of a child would
45
+ * hold the parent turn for a reply that cannot arrive, which is what an answer
46
+ * reviewer did on a stand until a person rejected it 12,5 minutes later. And a
47
+ * request the operator does not answer expires: the wait is bounded by
48
+ * `QA_APPROVAL_PARK_TIMEOUT_MS` and fails closed like a refusal.
49
+ *
33
50
  * Only sessions this deployment attested are touched. Any other session's ask
34
51
  * is handed back to the chain untouched, so an operator instance that also
35
52
  * serves ordinary chats keeps its own approval flow.
@@ -56,7 +73,7 @@ export declare class QaApprovalGate {
56
73
  * attested chat answers under the chat the operator is looking at.
57
74
  */
58
75
  private ownerOf;
59
- /** Park one call until the operator answers, the turn is cancelled, or … */
76
+ /** Park one call until the operator answers, the turn ends, or the wait expires. */
60
77
  private request;
61
78
  private resolve;
62
79
  /** Fail the requests one session's agent owns; a child never holds the chat. */
@@ -423,6 +423,29 @@ export declare class QaSessionController {
423
423
  * somebody else retired in between is no more this one's to finish.
424
424
  */
425
425
  private bind;
426
+ /**
427
+ * Whether this browser's Session catalog names one id. The Host answers a
428
+ * retain from exactly this set, so a refusal of a listed session is a refusal
429
+ * of a session it knows — never the race this adoption can wait out.
430
+ */
431
+ private catalogLists;
432
+ /**
433
+ * Wait for this browser's Session catalog to come to know one id, after
434
+ * {@link bind} was refused a reference to it, and answer whether the chat on
435
+ * screen still belongs to the adoption that asked (`false` — it moved on, and
436
+ * nothing is retained). Only an id the catalog does not name reaches here: a
437
+ * refusal of a session it already lists is not this race and goes back as it
438
+ * came, so there is always a row to wait for. A refusal is only final once
439
+ * that row has had its chance: this is the one window where the race is
440
+ * repairable rather than reportable, so the failure the caller reads stays the
441
+ * Host's own refusal, not a timeout nobody asked for.
442
+ *
443
+ * Both timestamps are logged because the race is intermittent and the stand
444
+ * keeps no other trace of it: the server never sees a retain, so its journal
445
+ * cannot say which chat lost the create, and the next round needs the id and
446
+ * the two moments to line this up with its own observations.
447
+ */
448
+ private awaitCatalogRow;
426
449
  /**
427
450
  * Give up on an adoption the chat on screen has outgrown, and answer whether
428
451
  * that is what happened (`true` — the caller has nothing left to publish).
@@ -32,7 +32,9 @@ export interface QaHeaderProps {
32
32
  readonly onToggleAgents: () => void;
33
33
  /** Whether the deployment shows the sources control in the header at all. */
34
34
  readonly sourcesVisible: boolean;
35
+ /** Sources of the chat so far; 0 prints no badge but never closes the panel. */
35
36
  readonly sourcesCount: number;
37
+ /** Whether collection has settled: a running turn's 0 is not yet a none. */
36
38
  readonly sourcesComplete: boolean;
37
39
  readonly sourcesOpen: boolean;
38
40
  readonly onOpenSources: () => void;
@@ -72,6 +74,13 @@ export interface QaHeaderProps {
72
74
  readonly showReset: boolean;
73
75
  readonly resetDisabled: boolean;
74
76
  readonly onReset: () => void;
77
+ /**
78
+ * Offered while a panel is in front of the conversation: the «Чат» marker
79
+ * then becomes the control that puts the conversation back, which is what its
80
+ * selected look already promises. Omitted while the chat is all there is —
81
+ * a control that returns the reader to where they stand is a dead button.
82
+ */
83
+ readonly onBackToChat?: () => void;
75
84
  }
76
- export declare function QaHeader({ logoUrl, title, viewingSubagent, onCloseSubagent, roleSelector, themeSwitcher, administration, agentCount, agentsOpen, onToggleAgents, sourcesVisible, sourcesCount, sourcesComplete, sourcesOpen, onOpenSources, fileCount, filesEnabled, filesOpen, onOpenFiles, settings, history, panelLauncher, showReset, resetDisabled, onReset, }: QaHeaderProps): import("react/jsx-runtime").JSX.Element;
85
+ export declare function QaHeader({ logoUrl, title, viewingSubagent, onCloseSubagent, roleSelector, themeSwitcher, administration, agentCount, agentsOpen, onToggleAgents, sourcesVisible, sourcesCount, sourcesComplete, sourcesOpen, onOpenSources, fileCount, filesEnabled, filesOpen, onOpenFiles, settings, history, panelLauncher, showReset, resetDisabled, onReset, onBackToChat, }: QaHeaderProps): import("react/jsx-runtime").JSX.Element;
77
86
  //# sourceMappingURL=QaHeader.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  import type { QaRailTab } from "../use-session-ui-state.js";
3
3
  /** One rail tab's strip chip: label, live count, and its body is the panel. */
4
4
  export interface QaRailTabModel {
@@ -18,6 +18,12 @@ export interface QaRightRailProps {
18
18
  * The chat's right rail: a fixed column whose top edge is the tab strip,
19
19
  * mirroring the Harness right Sidebar's chrome. Tabs are plain chips with
20
20
  * counts; the strip's last control collapses the whole column.
21
+ *
22
+ * On the phone layout the column is the whole surface, so the strip's control
23
+ * is the only way back and Escape has to answer from anywhere on the page —
24
+ * the focus may well still sit in the composer behind the panel. A dialog above
25
+ * the rail keeps the key: the innermost thing on the page is what the reader
26
+ * means to dismiss.
21
27
  */
22
28
  export declare function QaRightRail({ tabs, activeTab, onTabSelect, onClose, }: QaRightRailProps): import("react/jsx-runtime").JSX.Element | null;
23
29
  //# sourceMappingURL=QaRightRail.d.ts.map
@@ -7,6 +7,11 @@ export interface QaChatRow {
7
7
  readonly running: boolean;
8
8
  readonly active: boolean;
9
9
  readonly meta: string;
10
+ /**
11
+ * The chat's whole name, held back from the row only because the row had to
12
+ * be cut to fit; absent when the title is shown in full.
13
+ */
14
+ readonly fullName?: string;
10
15
  readonly updatedAt: number;
11
16
  /** Chat owner's display name; present in the admin ownership view only. */
12
17
  readonly ownerName?: string;
@@ -1,7 +1,10 @@
1
1
  import type { QaWorkItem } from "../../types.js";
2
2
  export interface QaWorkGroupProps {
3
- /** "error" marks a turn the host ended with a provider failure. */
4
- readonly status: "running" | "complete" | "error";
3
+ /**
4
+ * "error" marks a turn the host ended with a provider failure; "stopped"
5
+ * marks one a person ended, whose answer arrived as a prefix.
6
+ */
7
+ readonly status: "running" | "complete" | "error" | "stopped";
5
8
  readonly startedAt?: number;
6
9
  readonly endedAt?: number;
7
10
  readonly items: readonly QaWorkItem[];
@@ -8,6 +8,12 @@
8
8
  * pair rather than a hard-coded outline: the Host's `focus.css` suppresses an
9
9
  * outline under pointer modality at a specificity our rule cannot win, so a
10
10
  * hard-coded ring is one that goes missing rather than one that degrades.
11
+ *
12
+ * The type scale is the surface's: text the operator reads in order to decide —
13
+ * section titles, field labels, the values in the controls, the toggle copy —
14
+ * is 16px, a control's own label and an outcome line are 14px, and only chrome
15
+ * stays small on purpose: the «Изменено» badge (9px), the status chips (11px),
16
+ * the monospace data rows (11px) and the footer note (10px).
11
17
  */
12
18
  export declare const QA_SETTINGS_STYLES: string;
13
19
  //# sourceMappingURL=styles.d.ts.map
@@ -2,8 +2,21 @@ import type { Context } from "@deepseek-ai/cordis";
2
2
  import type { QaSessionOwnership } from "../session-ownership.js";
3
3
  /** The one QA tool whose every call is parked for the operator. */
4
4
  export declare const QA_FILE_DELETE_TOOL = "file_delete";
5
- /** Why the gate answers `ask` before the chain can decide alone. */
6
- export declare const QA_FILE_DELETE_ASK_REASON = "deleting a workspace file requires operator confirmation";
5
+ /**
6
+ * Why the gate answers `ask` before the chain can decide alone. The card the
7
+ * operator reads shows this verbatim, so it is written in the language of the
8
+ * surface rather than in the language of the tool chain.
9
+ */
10
+ export declare const QA_FILE_DELETE_ASK_REASON = "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0444\u0430\u0439\u043B\u0430 \u0440\u0430\u0431\u043E\u0447\u0435\u0433\u043E \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u043E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0430.";
11
+ /**
12
+ * Why the gate answers `deny` — not `ask` — for a delegated caller. A child has
13
+ * no one to confirm to it: its card would sit over the parent's composer and
14
+ * stop the parent turn until a person answers something they were never asked
15
+ * about. Deleting a file is not a step a delegation was ever given, so the call
16
+ * is refused where it is raised, and the reason tells the child to report
17
+ * instead of trying again.
18
+ */
19
+ export declare const QA_FILE_DELETE_DELEGATED_DENY_REASON = "a delegated call cannot delete a workspace file: no operator can confirm it. Report the file that is in the way instead of removing it";
7
20
  /**
8
21
  * The inner half of `file_delete`'s safety: the decision that composes the
9
22
  * approval flow around one destructive tool.
@@ -20,7 +33,10 @@ export declare const QA_FILE_DELETE_ASK_REASON = "deleting a workspace file requ
20
33
  * behavior and refuses the call — nothing is ever deleted without a person.
21
34
  *
22
35
  * Any other tool, and any caller this deployment did not attest, is handed
23
- * back to the chain untouched.
36
+ * back to the chain untouched. A delegated child of an attested chat is the one
37
+ * attested caller that gets no card: it is refused here, on the name, whatever
38
+ * the deployment's approval mode is — the same refusal the answer reviewer of a
39
+ * stand needed before its parent turn could end.
24
40
  */
25
41
  export declare class QaFileDeleteGate {
26
42
  private readonly ctx;
@@ -33,10 +49,11 @@ export declare class QaFileDeleteGate {
33
49
  dispose(): void;
34
50
  private handle;
35
51
  /**
36
- * Whether this deployment attested the chat the call belongs to, delegated
37
- * children included. The same ownership service the approval gate reads,
38
- * so one chat is parked under exactly one surface.
52
+ * The attested chat a call belongs to and the session that made it, delegated
53
+ * children included — the same ownership service the approval gate reads, so
54
+ * one chat is parked under exactly one surface. The two differ for a child,
55
+ * and a child is the caller that cannot be confirmed by anyone.
39
56
  */
40
- private attested;
57
+ private rootOf;
41
58
  }
42
59
  //# sourceMappingURL=file-delete-gate.d.ts.map
@@ -1522,8 +1522,11 @@ export type QaMessage = QaUserMessage | {
1522
1522
  readonly id: string;
1523
1523
  readonly role: "work";
1524
1524
  readonly turn: number;
1525
- /** "error" marks a turn the host ended with a provider failure. */
1526
- readonly status: "running" | "complete" | "error";
1525
+ /**
1526
+ * "error" marks a turn the host ended with a provider failure; "stopped"
1527
+ * marks one the user ended, whose answer is a prefix rather than a reply.
1528
+ */
1529
+ readonly status: "running" | "complete" | "error" | "stopped";
1527
1530
  readonly startedAt?: number;
1528
1531
  readonly endedAt?: number;
1529
1532
  readonly items: readonly QaWorkItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yadsh/dsh-qa-surface",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -136,10 +136,10 @@
136
136
  "yaml": "^2.9.0",
137
137
  "zod": "^4.4.3",
138
138
  "@yadsh/dsh-audit-ui": "^0.1.2",
139
- "@yadsh/dsh-documents": "^0.6.2",
140
139
  "@yadsh/dsh-plugin-kit": "^0.5.0",
140
+ "@yadsh/dsh-plugin-log": "^0.4.1",
141
141
  "@yadsh/dsh-audit-core": "^0.1.1",
142
- "@yadsh/dsh-plugin-log": "^0.4.1"
142
+ "@yadsh/dsh-documents": "^0.6.2"
143
143
  },
144
144
  "devDependencies": {
145
145
  "@deepseek-ai/cordis": "4.0.4",