dsh-doublecheck 0.5.0
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/CHANGELOG.md +65 -0
- package/LICENSE +201 -0
- package/README.es.md +252 -0
- package/README.hi.md +252 -0
- package/README.md +268 -0
- package/README.pt.md +252 -0
- package/README.zh.md +266 -0
- package/cordis.patch.yml +19 -0
- package/lib/domain/evidence.d.ts +100 -0
- package/lib/domain/evidence.js +180 -0
- package/lib/domain/projection.d.ts +60 -0
- package/lib/domain/projection.js +132 -0
- package/lib/domain/report.d.ts +93 -0
- package/lib/domain/report.js +266 -0
- package/lib/domain/stages.d.ts +98 -0
- package/lib/domain/stages.js +192 -0
- package/lib/domain/vagueness.d.ts +25 -0
- package/lib/domain/vagueness.js +56 -0
- package/lib/domain/vocabulary.d.ts +50 -0
- package/lib/domain/vocabulary.js +16 -0
- package/lib/events.d.ts +155 -0
- package/lib/events.js +15 -0
- package/lib/grill/index.d.ts +49 -0
- package/lib/grill/index.js +495 -0
- package/lib/grill/provider.d.ts +56 -0
- package/lib/grill/provider.js +189 -0
- package/lib/guard/command.d.ts +47 -0
- package/lib/guard/command.js +132 -0
- package/lib/guard/index.d.ts +111 -0
- package/lib/guard/index.js +516 -0
- package/lib/guard/prose.d.ts +34 -0
- package/lib/guard/prose.js +80 -0
- package/lib/guard/review.d.ts +67 -0
- package/lib/guard/review.js +184 -0
- package/lib/index.d.ts +17 -0
- package/lib/index.js +15 -0
- package/lib/invariant.d.ts +56 -0
- package/lib/invariant.js +112 -0
- package/lib/types.d.ts +39 -0
- package/lib/types.js +18 -0
- package/package.json +109 -0
- package/skills/delivery-proof/SKILL.md +52 -0
- package/skills/delivery-review/SKILL.md +49 -0
- package/skills/grill-requirements/SKILL.md +98 -0
- package/skills/red-green-tdd/SKILL.md +57 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared discipline vocabulary: the durable structured facts the review and
|
|
3
|
+
* report modules exchange. Kept type-only and import-cycle-free so events,
|
|
4
|
+
* domain folds, and tool implementations all read the same definitions.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-doublecheck/domain/vocabulary
|
|
7
|
+
*/
|
|
8
|
+
/** The six dimensions of a grilled requirements spec (v0.1 canonical fields). */
|
|
9
|
+
export interface GrilledSpec {
|
|
10
|
+
/** What outcome the work must produce, in one verifiable sentence. */
|
|
11
|
+
goal: string;
|
|
12
|
+
/** What is in scope and what is out of scope for this change. */
|
|
13
|
+
scope: string;
|
|
14
|
+
/** Observable checks that prove the work is done. */
|
|
15
|
+
acceptanceCriteria: string;
|
|
16
|
+
/** What can go wrong and the correct behavior in each case. */
|
|
17
|
+
failureModes: string;
|
|
18
|
+
/** What to trade when goals conflict; what is optional. */
|
|
19
|
+
priorities: string;
|
|
20
|
+
/** What the user explicitly does not want. */
|
|
21
|
+
nonGoals: string;
|
|
22
|
+
}
|
|
23
|
+
/** One structured objection from the adversary review. */
|
|
24
|
+
export interface ReviewFinding {
|
|
25
|
+
/** How much the finding threatens the delivery claim. */
|
|
26
|
+
severity: 'blocker' | 'major' | 'minor' | 'info';
|
|
27
|
+
/** One-line statement of the objection. */
|
|
28
|
+
title: string;
|
|
29
|
+
/** The evidence in the session that supports the objection. */
|
|
30
|
+
detail: string;
|
|
31
|
+
}
|
|
32
|
+
/** What the adversary review concluded. */
|
|
33
|
+
export type ReviewVerdict = 'findings' | 'clean' | 'unavailable';
|
|
34
|
+
/** The derived delivery status of a doublecheck report. */
|
|
35
|
+
export type ReportVerdict = 'grill' | 'draft' | 'red' | 'green' | 'objections' | 'verified' | 'proven' | 'challenged' | 'unverified';
|
|
36
|
+
/** One dimension checked by the verify workflow. */
|
|
37
|
+
export type VerifyDimension = 'goal' | 'scope' | 'acceptanceCriteria' | 'failureModes' | 'priorities' | 'nonGoals';
|
|
38
|
+
/** All verify dimensions, in spec order. */
|
|
39
|
+
export declare const VERIFY_DIMENSIONS: readonly VerifyDimension[];
|
|
40
|
+
/** One settled verification check. */
|
|
41
|
+
export interface VerifyCheck {
|
|
42
|
+
/** The spec dimension this check examined. */
|
|
43
|
+
dimension: VerifyDimension;
|
|
44
|
+
/** Whether the delivery satisfies this dimension on the session evidence. */
|
|
45
|
+
verdict: 'pass' | 'fail';
|
|
46
|
+
/** What in the session supports the verdict. */
|
|
47
|
+
evidence: string;
|
|
48
|
+
/** Optional note about what to fix or re-examine. */
|
|
49
|
+
note: string;
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared discipline vocabulary: the durable structured facts the review and
|
|
3
|
+
* report modules exchange. Kept type-only and import-cycle-free so events,
|
|
4
|
+
* domain folds, and tool implementations all read the same definitions.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-doublecheck/domain/vocabulary
|
|
7
|
+
*/
|
|
8
|
+
/** All verify dimensions, in spec order. */
|
|
9
|
+
export const VERIFY_DIMENSIONS = [
|
|
10
|
+
'goal',
|
|
11
|
+
'scope',
|
|
12
|
+
'acceptanceCriteria',
|
|
13
|
+
'failureModes',
|
|
14
|
+
'priorities',
|
|
15
|
+
'nonGoals',
|
|
16
|
+
];
|
package/lib/events.d.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-internal Cordis event vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* These events are process-local notifications between dsh-doublecheck's own
|
|
5
|
+
* plugin modules. Durable state never depends on them: the session log
|
|
6
|
+
* (`tool/call` / `tool/result` / `user/message` events) remains the single
|
|
7
|
+
* source of truth, and every model-visible payload they announce is recorded
|
|
8
|
+
* there through the standard channels before the event fires. Structured
|
|
9
|
+
* discipline facts that must survive the conversation ride the durable log as
|
|
10
|
+
* injected `user/message` sources via the {@link MessageSourceMap} extension
|
|
11
|
+
* below — never as these process-local events.
|
|
12
|
+
*
|
|
13
|
+
* @module dsh-doublecheck/events
|
|
14
|
+
*/
|
|
15
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
16
|
+
import type { Session, SessionEventMap } from '@deepseek-ai/dsh-session';
|
|
17
|
+
import type { GrilledSpec, ReviewFinding, ReviewVerdict, ReportVerdict, VerifyCheck } from './domain/vocabulary.ts';
|
|
18
|
+
export type { GrilledSpec, ReviewFinding, ReviewVerdict, ReportVerdict, VerifyCheck } from './domain/vocabulary.ts';
|
|
19
|
+
/** Guard enforcement strength. */
|
|
20
|
+
export type GuardIntensity = 'remind' | 'warn' | 'block';
|
|
21
|
+
/** Which discipline gate produced a guard reaction. */
|
|
22
|
+
export type GuardGate = 'grill' | 'tdd' | 'delivery';
|
|
23
|
+
/** Policy outcome of one guard reaction. */
|
|
24
|
+
export type GuardVerdict = 'reminded' | 'held' | 'denied' | 'green-pending' | 'report-expected';
|
|
25
|
+
declare module '@deepseek-ai/dsh-session' {
|
|
26
|
+
interface SessionEventMap {
|
|
27
|
+
/**
|
|
28
|
+
* The per-session master switch written by `/doublecheck on|off`: when
|
|
29
|
+
* false, all discipline gates (grill, tdd, adversary) defer to the human
|
|
30
|
+
* chain for this session, surviving restart and restore. The event rides
|
|
31
|
+
* the envelope's `ignorable: true` marker so hosts that do not know the
|
|
32
|
+
* type still load the log.
|
|
33
|
+
*/
|
|
34
|
+
'doublecheck/state': {
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* `Session.append` narrowed to the `doublecheck/state` event. The options bag
|
|
41
|
+
* carries `ignorable: true`; rc.6 hosts ignore it (same event), post-rc.6
|
|
42
|
+
* hosts stamp the marker.
|
|
43
|
+
*/
|
|
44
|
+
export interface StateAppend {
|
|
45
|
+
(type: 'doublecheck/state', data: SessionEventMap['doublecheck/state'], options: {
|
|
46
|
+
ignorable: true;
|
|
47
|
+
}): void;
|
|
48
|
+
}
|
|
49
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
50
|
+
interface MessageSourceMap {
|
|
51
|
+
/**
|
|
52
|
+
* The adversary review injected into the session: the durable record of
|
|
53
|
+
* one settled critique. The model-facing text is the rendered findings
|
|
54
|
+
* (or clean/unavailable notice); the structured findings and verdict live
|
|
55
|
+
* here so the doublecheck report can fold them without re-parsing prose.
|
|
56
|
+
*/
|
|
57
|
+
'doublecheck-review': {
|
|
58
|
+
kind: 'doublecheck-review';
|
|
59
|
+
verdict: ReviewVerdict;
|
|
60
|
+
findings: ReviewFinding[];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
declare module '@deepseek-ai/cordis' {
|
|
65
|
+
interface Events {
|
|
66
|
+
/**
|
|
67
|
+
* The grill module committed a requirements spec: the canonical spec was
|
|
68
|
+
* returned to the model (and recorded as a `tool/result` session event)
|
|
69
|
+
* and the workspace copy write settled. Future discipline modules consume
|
|
70
|
+
* this notification to advance the shared stage state machine.
|
|
71
|
+
* @param payload.session - the session the spec belongs to.
|
|
72
|
+
* @param payload.spec - the six committed spec fields.
|
|
73
|
+
* @param payload.path - absolute workspace path written, or null when no write happened.
|
|
74
|
+
* @param payload.written - whether the markdown copy reached the workspace.
|
|
75
|
+
* @mode emit
|
|
76
|
+
*/
|
|
77
|
+
'doublecheck/spec'(payload: {
|
|
78
|
+
session: Session;
|
|
79
|
+
spec: GrilledSpec;
|
|
80
|
+
path: string | null;
|
|
81
|
+
written: boolean;
|
|
82
|
+
}): void;
|
|
83
|
+
/**
|
|
84
|
+
* The discipline guard reacted: the grill gate hit a requirements-less
|
|
85
|
+
* mutation attempt, the red gate hit an implementation edit without a
|
|
86
|
+
* failing test on record, or the green gate noticed edits without a
|
|
87
|
+
* passing test run at turn end. Reminders queued here ride the standard
|
|
88
|
+
* context channel into the session log; held/denied outcomes happened at
|
|
89
|
+
* the policy gate. Observability only — listeners must not veto or reroute.
|
|
90
|
+
* @param payload.agent - the calling agent, when the call has one.
|
|
91
|
+
* @param payload.session - the session the call belongs to.
|
|
92
|
+
* @param payload.toolName - the intercepted mutation tool; absent for green-gate reactions.
|
|
93
|
+
* @param payload.intensity - the configured enforcement strength.
|
|
94
|
+
* @param payload.gate - the discipline gate that produced this reaction.
|
|
95
|
+
* @param payload.verdict - the policy outcome produced by this reaction.
|
|
96
|
+
* @param payload.reminder - the reminder prose, when one was queued.
|
|
97
|
+
* @mode emit
|
|
98
|
+
*/
|
|
99
|
+
'doublecheck/reminder'(payload: {
|
|
100
|
+
agent: Agent | undefined;
|
|
101
|
+
session: Session;
|
|
102
|
+
toolName?: string;
|
|
103
|
+
intensity: GuardIntensity;
|
|
104
|
+
gate: GuardGate;
|
|
105
|
+
verdict: GuardVerdict;
|
|
106
|
+
reminder?: string;
|
|
107
|
+
}): void;
|
|
108
|
+
/**
|
|
109
|
+
* The adversary module settled one delivery review: a forked critic
|
|
110
|
+
* subagent compared the committed spec against the session's delivery
|
|
111
|
+
* evidence and produced structured findings (or a clean/unavailable
|
|
112
|
+
* verdict). The review text that reached the model rides the standard
|
|
113
|
+
* injection channel and is recorded as a `user/message` session event
|
|
114
|
+
* whose source carries the structured record. Observability only —
|
|
115
|
+
* listeners must not veto or reroute.
|
|
116
|
+
* @param payload.session - the reviewed session.
|
|
117
|
+
* @param payload.agent - the reviewed agent.
|
|
118
|
+
* @param payload.verdict - findings, clean, or unavailable.
|
|
119
|
+
* @param payload.findings - the structured objections, when the critic produced any.
|
|
120
|
+
* @param payload.text - the model-facing review prose, when one was injected.
|
|
121
|
+
* @mode emit
|
|
122
|
+
*/
|
|
123
|
+
'doublecheck/review'(payload: {
|
|
124
|
+
session: Session;
|
|
125
|
+
agent: Agent;
|
|
126
|
+
verdict: ReviewVerdict;
|
|
127
|
+
findings: ReviewFinding[];
|
|
128
|
+
text?: string;
|
|
129
|
+
}): void;
|
|
130
|
+
/**
|
|
131
|
+
* The doublecheck report tool committed a consolidated delivery report:
|
|
132
|
+
* the folded session facts, the derived verdict, the optional
|
|
133
|
+
* verification checks with their completeness flag, and the workspace
|
|
134
|
+
* copy outcome. The report the model sees is the tool's own
|
|
135
|
+
* `tool/result`; this event is observability only — listeners must not
|
|
136
|
+
* veto or reroute.
|
|
137
|
+
* @param payload.session - the reported session.
|
|
138
|
+
* @param payload.verdict - the derived delivery status.
|
|
139
|
+
* @param payload.verification - the verification checks and completeness, when verification ran.
|
|
140
|
+
* @param payload.path - absolute workspace path written, or null when no write happened.
|
|
141
|
+
* @param payload.written - whether the markdown copy reached the workspace.
|
|
142
|
+
* @mode emit
|
|
143
|
+
*/
|
|
144
|
+
'doublecheck/report'(payload: {
|
|
145
|
+
session: Session;
|
|
146
|
+
verdict: ReportVerdict;
|
|
147
|
+
verification: {
|
|
148
|
+
checks: VerifyCheck[];
|
|
149
|
+
complete: boolean;
|
|
150
|
+
} | null;
|
|
151
|
+
path: string | null;
|
|
152
|
+
written: boolean;
|
|
153
|
+
}): void;
|
|
154
|
+
}
|
|
155
|
+
}
|
package/lib/events.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-internal Cordis event vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* These events are process-local notifications between dsh-doublecheck's own
|
|
5
|
+
* plugin modules. Durable state never depends on them: the session log
|
|
6
|
+
* (`tool/call` / `tool/result` / `user/message` events) remains the single
|
|
7
|
+
* source of truth, and every model-visible payload they announce is recorded
|
|
8
|
+
* there through the standard channels before the event fires. Structured
|
|
9
|
+
* discipline facts that must survive the conversation ride the durable log as
|
|
10
|
+
* injected `user/message` sources via the {@link MessageSourceMap} extension
|
|
11
|
+
* below — never as these process-local events.
|
|
12
|
+
*
|
|
13
|
+
* @module dsh-doublecheck/events
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grill module: dsh-doublecheck's requirements-furnace plugin.
|
|
3
|
+
*
|
|
4
|
+
* Registers the bundled `skills/` directory on the DSH skill registry (the
|
|
5
|
+
* official skill capability seam), exposes the model-facing catalog/loader
|
|
6
|
+
* tool `doublecheck_skills`, and provides the two contract tools:
|
|
7
|
+
* `doublecheck_spec` (commit a grilled requirements spec to the session log
|
|
8
|
+
* and a workspace markdown file) and `doublecheck_report` (v0.4: consolidate
|
|
9
|
+
* the session's discipline evidence into a delivery report, optionally
|
|
10
|
+
* orchestrating a per-dimension verification workflow through the DSH
|
|
11
|
+
* workflow seam).
|
|
12
|
+
*
|
|
13
|
+
* @module dsh-doublecheck/grill
|
|
14
|
+
*/
|
|
15
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
16
|
+
import type Schema from '@deepseek-ai/schemastery';
|
|
17
|
+
import type { GrilledSpec } from '../events.ts';
|
|
18
|
+
export declare const name = "doublecheck-grill";
|
|
19
|
+
export declare const inject: string[];
|
|
20
|
+
/** Grill module configuration. */
|
|
21
|
+
export interface Config {
|
|
22
|
+
/** Workspace file (relative to the session cwd) that receives the spec markdown. */
|
|
23
|
+
specFile: string;
|
|
24
|
+
/** Workspace file (relative to the session cwd) that receives the report markdown. */
|
|
25
|
+
reportFile: string;
|
|
26
|
+
/** Whether the report runs the verify workflow when the caller does not choose. */
|
|
27
|
+
reportVerify: boolean;
|
|
28
|
+
/** Subagent provider the verify workflow's checkers run on. */
|
|
29
|
+
verifyProvider: string;
|
|
30
|
+
/** Checker fan-out: one parallel checker per dimension (`all`) or one combined checker (`single`). */
|
|
31
|
+
verifyMode: 'all' | 'single';
|
|
32
|
+
/** Report-scoped knobs: shell tools whose commands may be test runs. */
|
|
33
|
+
reportTestToolNames: string[];
|
|
34
|
+
/** Report-scoped knobs: commands that count as test runs. */
|
|
35
|
+
reportTestCommandPatterns: string[];
|
|
36
|
+
/** Report-scoped knobs: mutation tools counted as implementation edits. */
|
|
37
|
+
reportMutationTools: string[];
|
|
38
|
+
/** Report-scoped knobs: paths identifying test files (not implementation edits). */
|
|
39
|
+
reportTestFilePatterns: string[];
|
|
40
|
+
}
|
|
41
|
+
export declare const Config: Schema<Config>;
|
|
42
|
+
/** The rendered spec document written to the workspace and shown to the model. */
|
|
43
|
+
export declare function renderSpecMarkdown(spec: GrilledSpec): string;
|
|
44
|
+
/**
|
|
45
|
+
* Install the grill module: bundled skill provider plus its three tools.
|
|
46
|
+
* @param ctx - plugin context; registrations unwind with it.
|
|
47
|
+
* @param config - validated {@link Config}.
|
|
48
|
+
*/
|
|
49
|
+
export declare function apply(ctx: Context, config: Config): void;
|