@spences10/pi-harness 0.0.11 → 0.1.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/README.md +62 -19
- package/dist/assessment.d.ts +59 -0
- package/dist/assessment.js +232 -0
- package/dist/assessment.js.map +1 -0
- package/dist/extension.js +313 -16
- package/dist/extension.js.map +1 -1
- package/dist/index.d.ts +31 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/prompt.d.ts +1 -1
- package/dist/prompt.js +5 -1
- package/dist/prompt.js.map +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/renderers.js +7 -8
- package/dist/runtime/renderers.js.map +1 -1
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -1
- package/package.json +3 -3
- package/skills/create-harness/SKILL.md +43 -65
- package/skills/execute-harness/SKILL.md +7 -4
package/README.md
CHANGED
|
@@ -45,8 +45,12 @@ pi -e ./packages/pi-harness
|
|
|
45
45
|
|
|
46
46
|
`pi-harness` adds:
|
|
47
47
|
|
|
48
|
-
- `/
|
|
49
|
-
- `
|
|
48
|
+
- `/assess` command for evidence-gated capability assessment
|
|
49
|
+
- `/harness` command for assess-before-create, run, review, status,
|
|
50
|
+
use, and clear
|
|
51
|
+
- `harness_assess` and `harness_assessment_submit` tools for read-only
|
|
52
|
+
orientation and structured adoption decisions
|
|
53
|
+
- guarded `harness_create` tool that cannot bypass assessment approval
|
|
50
54
|
- `harness_amend` tool for audited, versioned changes to the inner
|
|
51
55
|
scaffold
|
|
52
56
|
- `harness_update` tool for phase/status/evidence logging
|
|
@@ -80,6 +84,11 @@ pi -e ./packages/pi-harness
|
|
|
80
84
|
## Commands
|
|
81
85
|
|
|
82
86
|
```text
|
|
87
|
+
/assess <task>
|
|
88
|
+
/assess status
|
|
89
|
+
/assess approve [harness|direct]
|
|
90
|
+
/assess reject
|
|
91
|
+
/assess clear
|
|
83
92
|
/harness create <task>
|
|
84
93
|
/harness run <dir>
|
|
85
94
|
/harness review <dir>
|
|
@@ -88,18 +97,38 @@ pi -e ./packages/pi-harness
|
|
|
88
97
|
/harness clear
|
|
89
98
|
```
|
|
90
99
|
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
`/assess` and `/harness create` enter the same read-only assessment.
|
|
101
|
+
The agent records repository evidence, existing primitives, rejected
|
|
102
|
+
options, the smallest useful vertical slice, and one recommendation. A
|
|
103
|
+
harness recommendation must include explicit allowed paths and
|
|
104
|
+
validation commands. Direct user approval then creates and activates
|
|
105
|
+
the harness, restores tools for approved direct work, or rejects the
|
|
106
|
+
candidate without project changes.
|
|
93
107
|
|
|
94
|
-
|
|
108
|
+
An agent can enter assessment with `harness_assess`. If it calls
|
|
109
|
+
`harness_create` without approval, the extension blocks the call and
|
|
110
|
+
starts assessment. This backstop does not detect an agent that
|
|
111
|
+
misclassifies a task and never asks for harness machinery.
|
|
112
|
+
|
|
113
|
+
Use assessment when a task may benefit from an enforceable execution
|
|
95
114
|
contract because it has material risk, unresolved scope, destructive
|
|
96
115
|
effects, or complex coordination. Use the normal direct workflow for
|
|
97
116
|
bounded, low-risk changes that standard validation can verify, such as
|
|
98
117
|
documentation and copy edits, focused single-file fixes, configuration
|
|
99
118
|
or metadata updates, test expectation changes, formatting, and
|
|
100
|
-
reviewed commit or push follow-ups.
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
reviewed commit or push follow-ups. A simple ambiguity may need only a
|
|
120
|
+
clarifying question. Broad uncertain refactors, migrations,
|
|
121
|
+
deployments, risky releases, external side effects, and explicit user
|
|
122
|
+
requests are good assessment candidates.
|
|
123
|
+
|
|
124
|
+
Assessment snapshots the current tool set, keeps an explicit read-only
|
|
125
|
+
research subset active, and filters Bash through a strict
|
|
126
|
+
single-command allowlist. Unknown and mutating custom tools are
|
|
127
|
+
withheld. This is a workflow guard, not an operating-system sandbox.
|
|
128
|
+
In print and JSON modes, an assessment can be submitted but remains
|
|
129
|
+
waiting because direct approval cannot be inferred. RPC clients can
|
|
130
|
+
answer Pi's extension UI request, or send `/assess approve ...` as an
|
|
131
|
+
explicit command.
|
|
103
132
|
|
|
104
133
|
`harness.json` contains two deliberately different layers:
|
|
105
134
|
|
|
@@ -139,17 +168,31 @@ linked git worktree, run `review.sh` from that worktree or set
|
|
|
139
168
|
`HARNESS_CWD` so validation, guard checks, and outcome collection use
|
|
140
169
|
the executor workspace.
|
|
141
170
|
|
|
142
|
-
##
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
## Assessment and harness loops
|
|
172
|
+
|
|
173
|
+
Assessment happens before harness creation:
|
|
174
|
+
|
|
175
|
+
1. Read-only context recovery
|
|
176
|
+
2. Source-of-truth and existing-primitive capture
|
|
177
|
+
3. Assumption challenge and rejected options
|
|
178
|
+
4. Smallest vertical slice
|
|
179
|
+
5. Structured recommendation
|
|
180
|
+
6. Direct user adoption decision
|
|
181
|
+
|
|
182
|
+
An approved harness then runs:
|
|
183
|
+
|
|
184
|
+
1. Contract recovery
|
|
185
|
+
2. Surgical execution
|
|
186
|
+
3. Validation evidence
|
|
187
|
+
4. Drift review
|
|
188
|
+
5. OUTCOME.md/outcome.json review
|
|
189
|
+
6. Delta/risk report
|
|
190
|
+
|
|
191
|
+
Use `harness_amend` for bounded inner-scaffold changes. A new
|
|
192
|
+
capability or architecture decision requires assessment; an approved
|
|
193
|
+
harness recommendation can then amend the active scaffold.
|
|
194
|
+
Outer-policy expansion requires a separate execution contract instead
|
|
195
|
+
of silent scope growth.
|
|
153
196
|
|
|
154
197
|
## Using from a custom harness
|
|
155
198
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Type, type Static } from 'typebox';
|
|
2
|
+
export declare const HARNESS_ASSESSMENT_CUSTOM_TYPE = "pi-harness-assessment-state";
|
|
3
|
+
export declare const harness_assess_params_schema: Type.TObject<{
|
|
4
|
+
task: Type.TString;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const harness_assessment_submit_params_schema: Type.TObject<{
|
|
7
|
+
task: Type.TString;
|
|
8
|
+
evidence: Type.TArray<Type.TString>;
|
|
9
|
+
existing_primitives: Type.TArray<Type.TString>;
|
|
10
|
+
rejected_options: Type.TArray<Type.TString>;
|
|
11
|
+
smallest_vertical_slice: Type.TString;
|
|
12
|
+
recommendation: Type.TUnion<[Type.TLiteral<"harness">, Type.TLiteral<"direct">, Type.TLiteral<"reject">]>;
|
|
13
|
+
proposed_contract: Type.TOptional<Type.TObject<{
|
|
14
|
+
task: Type.TString;
|
|
15
|
+
slug: Type.TOptional<Type.TString>;
|
|
16
|
+
cwd: Type.TOptional<Type.TString>;
|
|
17
|
+
allowed_paths: Type.TOptional<Type.TArray<Type.TString>>;
|
|
18
|
+
forbidden_paths: Type.TOptional<Type.TArray<Type.TString>>;
|
|
19
|
+
validation_commands: Type.TOptional<Type.TArray<Type.TString>>;
|
|
20
|
+
forbidden_commands: Type.TOptional<Type.TArray<Type.TString>>;
|
|
21
|
+
allow_test_changes: Type.TOptional<Type.TBoolean>;
|
|
22
|
+
escalation_rules: Type.TOptional<Type.TArray<Type.TString>>;
|
|
23
|
+
planner_model: Type.TOptional<Type.TString>;
|
|
24
|
+
planner_thinking: Type.TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">]>>;
|
|
25
|
+
executor_model: Type.TOptional<Type.TString>;
|
|
26
|
+
executor_thinking: Type.TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">]>>;
|
|
27
|
+
reviewer_model: Type.TOptional<Type.TString>;
|
|
28
|
+
reviewer_thinking: Type.TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">]>>;
|
|
29
|
+
}>>;
|
|
30
|
+
}>;
|
|
31
|
+
export type HarnessAssessParams = Static<typeof harness_assess_params_schema>;
|
|
32
|
+
export type HarnessAssessmentRecord = Static<typeof harness_assessment_submit_params_schema>;
|
|
33
|
+
export type HarnessAssessmentRecommendation = HarnessAssessmentRecord['recommendation'];
|
|
34
|
+
export type HarnessAssessmentSource = 'agent' | 'user' | 'harness-create';
|
|
35
|
+
export type HarnessAssessmentStatus = 'assessing' | 'awaiting_approval' | 'approved' | 'rejected';
|
|
36
|
+
export interface HarnessAssessmentState {
|
|
37
|
+
id: string;
|
|
38
|
+
version: number;
|
|
39
|
+
status: HarnessAssessmentStatus;
|
|
40
|
+
task: string;
|
|
41
|
+
source: HarnessAssessmentSource;
|
|
42
|
+
started_at: string;
|
|
43
|
+
tools_before_assessment: string[];
|
|
44
|
+
record?: HarnessAssessmentRecord;
|
|
45
|
+
decision?: HarnessAssessmentRecommendation;
|
|
46
|
+
}
|
|
47
|
+
export declare function create_assessment_state(task: string, source: HarnessAssessmentSource, tools_before_assessment: string[], now?: Date): HarnessAssessmentState;
|
|
48
|
+
export declare function submit_assessment_record(state: HarnessAssessmentState, record: HarnessAssessmentRecord): HarnessAssessmentState;
|
|
49
|
+
export declare function assessment_active(state: HarnessAssessmentState | undefined): boolean;
|
|
50
|
+
export declare function assessment_tool_names(active_tool_names: string[]): string[];
|
|
51
|
+
export declare function is_assessment_tool_allowed(tool_name: string): boolean;
|
|
52
|
+
export declare function check_assessment_command(command: string): {
|
|
53
|
+
ok: true;
|
|
54
|
+
} | {
|
|
55
|
+
ok: false;
|
|
56
|
+
reason: string;
|
|
57
|
+
};
|
|
58
|
+
export declare function assessment_context(state: HarnessAssessmentState): string;
|
|
59
|
+
export declare function format_assessment_record(state: HarnessAssessmentState): string;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { Type } from 'typebox';
|
|
2
|
+
import { harness_create_params_schema } from './schema.js';
|
|
3
|
+
export const HARNESS_ASSESSMENT_CUSTOM_TYPE = 'pi-harness-assessment-state';
|
|
4
|
+
export const harness_assess_params_schema = Type.Object({
|
|
5
|
+
task: Type.String({
|
|
6
|
+
description: 'Candidate task to investigate before choosing an execution path',
|
|
7
|
+
}),
|
|
8
|
+
});
|
|
9
|
+
export const harness_assessment_submit_params_schema = Type.Object({
|
|
10
|
+
task: Type.String({
|
|
11
|
+
description: 'Refined outcome being assessed',
|
|
12
|
+
}),
|
|
13
|
+
evidence: Type.Array(Type.String({
|
|
14
|
+
description: 'Concrete repository, documentation, or observed evidence',
|
|
15
|
+
})),
|
|
16
|
+
existing_primitives: Type.Array(Type.String({
|
|
17
|
+
description: 'Existing mechanisms that already satisfy part or all of the need',
|
|
18
|
+
})),
|
|
19
|
+
rejected_options: Type.Array(Type.String({
|
|
20
|
+
description: 'Rejected option and the evidence-based reason for rejection',
|
|
21
|
+
})),
|
|
22
|
+
smallest_vertical_slice: Type.String({
|
|
23
|
+
description: 'Smallest useful outcome or experiment that can test the need',
|
|
24
|
+
}),
|
|
25
|
+
recommendation: Type.Union([
|
|
26
|
+
Type.Literal('harness'),
|
|
27
|
+
Type.Literal('direct'),
|
|
28
|
+
Type.Literal('reject'),
|
|
29
|
+
]),
|
|
30
|
+
proposed_contract: Type.Optional(harness_create_params_schema),
|
|
31
|
+
});
|
|
32
|
+
const ASSESSMENT_TOOL_NAMES = new Set([
|
|
33
|
+
'bash',
|
|
34
|
+
'context_get',
|
|
35
|
+
'context_list',
|
|
36
|
+
'context_search',
|
|
37
|
+
'context_stats',
|
|
38
|
+
'find',
|
|
39
|
+
'grep',
|
|
40
|
+
'harness_assess',
|
|
41
|
+
'harness_assessment_submit',
|
|
42
|
+
'harness_read',
|
|
43
|
+
'ls',
|
|
44
|
+
'lsp_definition',
|
|
45
|
+
'lsp_diagnostics',
|
|
46
|
+
'lsp_diagnostics_many',
|
|
47
|
+
'lsp_document_symbols',
|
|
48
|
+
'lsp_find_symbol',
|
|
49
|
+
'lsp_hover',
|
|
50
|
+
'lsp_references',
|
|
51
|
+
'mcp__mcp-omnisearch__ai_search',
|
|
52
|
+
'mcp__mcp-omnisearch__web_extract',
|
|
53
|
+
'mcp__mcp-omnisearch__web_search',
|
|
54
|
+
'mcp__mcp-sqlite-tools__close_database',
|
|
55
|
+
'mcp__mcp-sqlite-tools__database_info',
|
|
56
|
+
'mcp__mcp-sqlite-tools__describe_table',
|
|
57
|
+
'mcp__mcp-sqlite-tools__execute_read_query',
|
|
58
|
+
'mcp__mcp-sqlite-tools__export_schema',
|
|
59
|
+
'mcp__mcp-sqlite-tools__list_databases',
|
|
60
|
+
'mcp__mcp-sqlite-tools__list_tables',
|
|
61
|
+
'mcp__mcp-sqlite-tools__open_database',
|
|
62
|
+
'read',
|
|
63
|
+
]);
|
|
64
|
+
const SAFE_COMMAND_PATTERNS = [
|
|
65
|
+
/^(?:pwd|whoami|uname|date|uptime)(?:\s+.*)?$/,
|
|
66
|
+
/^(?:cat|head|tail|less|more|grep|rg|ls|wc|sort|uniq|diff|file|stat|du|df|tree|which|whereis|type|bat|eza)(?:\s+.*)?$/,
|
|
67
|
+
/^find(?:\s+.*)?$/,
|
|
68
|
+
/^git\s+(?:status|log|diff|show|rev-parse|ls-files|ls-tree|grep)(?:\s+.*)?$/,
|
|
69
|
+
/^git\s+branch(?:\s+(?:--list|-a|--all|-r|--remotes|--show-current|--contains|--merged|--no-merged)(?:\s+.*)?)?$/,
|
|
70
|
+
/^git\s+remote(?:\s+(?:-v|show|get-url)(?:\s+.*)?)?$/,
|
|
71
|
+
/^git\s+config\s+--get(?:\s+.*)?$/,
|
|
72
|
+
/^gh\s+(?:issue\s+(?:list|view)|pr\s+(?:list|view|diff|checks)|repo\s+view)(?:\s+.*)?$/,
|
|
73
|
+
/^gh\s+api(?:\s+.*)?$/,
|
|
74
|
+
/^(?:npm|pnpm|yarn)\s+(?:list|ls|view|info|why|outdated)(?:\s+.*)?$/,
|
|
75
|
+
/^(?:node|python|python3)\s+--version$/,
|
|
76
|
+
/^jq(?:\s+.*)?$/,
|
|
77
|
+
/^sed\s+-n(?:\s+.*)?$/,
|
|
78
|
+
];
|
|
79
|
+
const UNSAFE_READ_COMMAND_PATTERNS = [
|
|
80
|
+
/\bfind\b.*\s-(?:delete|exec|execdir|ok|okdir|fprint|fprintf|fls)\b/i,
|
|
81
|
+
/\brg\b.*\s--pre(?:-glob)?\b/i,
|
|
82
|
+
/\b(?:git\s+(?:log|diff|show)|sort)\b.*(?:\s--output(?:=|\s+)|\s-o\s+)/i,
|
|
83
|
+
/\bsed\b.*\s-i(?:\s|$|[^a-z])/i,
|
|
84
|
+
/\bgh\s+api\b.*(?:\s-X\s*|\s--method(?:=|\s+))(?!GET\b)/i,
|
|
85
|
+
/\bgh\s+api\b.*(?:\s-f\s|\s-F\s|\s--field(?:=|\s+)|\s--raw-field(?:=|\s+))/i,
|
|
86
|
+
/\bgit\s+branch\b.*\s-[dDmM]\b/i,
|
|
87
|
+
];
|
|
88
|
+
export function create_assessment_state(task, source, tools_before_assessment, now = new Date()) {
|
|
89
|
+
const normalized_task = task.trim();
|
|
90
|
+
if (!normalized_task) {
|
|
91
|
+
throw new Error('Assessment task is required');
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
id: `assessment-${now.getTime().toString(36)}`,
|
|
95
|
+
version: 1,
|
|
96
|
+
status: 'assessing',
|
|
97
|
+
task: normalized_task,
|
|
98
|
+
source,
|
|
99
|
+
started_at: now.toISOString(),
|
|
100
|
+
tools_before_assessment: [...new Set(tools_before_assessment)],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export function submit_assessment_record(state, record) {
|
|
104
|
+
if (record.recommendation === 'harness') {
|
|
105
|
+
if (!record.proposed_contract) {
|
|
106
|
+
throw new Error('A harness recommendation requires a proposed contract');
|
|
107
|
+
}
|
|
108
|
+
if (!record.proposed_contract.allowed_paths?.length) {
|
|
109
|
+
throw new Error('An approved harness contract requires explicit allowed paths');
|
|
110
|
+
}
|
|
111
|
+
if (!record.proposed_contract.validation_commands?.length) {
|
|
112
|
+
throw new Error('An approved harness contract requires validation commands');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
...state,
|
|
117
|
+
version: state.version + 1,
|
|
118
|
+
status: 'awaiting_approval',
|
|
119
|
+
task: record.task.trim(),
|
|
120
|
+
record,
|
|
121
|
+
decision: undefined,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function assessment_active(state) {
|
|
125
|
+
return (state?.status === 'assessing' ||
|
|
126
|
+
state?.status === 'awaiting_approval');
|
|
127
|
+
}
|
|
128
|
+
export function assessment_tool_names(active_tool_names) {
|
|
129
|
+
const read_tools = [...new Set(active_tool_names)].filter((name) => ASSESSMENT_TOOL_NAMES.has(name));
|
|
130
|
+
return [
|
|
131
|
+
...new Set([
|
|
132
|
+
...read_tools,
|
|
133
|
+
'harness_assess',
|
|
134
|
+
'harness_assessment_submit',
|
|
135
|
+
'harness_read',
|
|
136
|
+
]),
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
export function is_assessment_tool_allowed(tool_name) {
|
|
140
|
+
return ASSESSMENT_TOOL_NAMES.has(tool_name);
|
|
141
|
+
}
|
|
142
|
+
function has_unquoted_shell_control(command) {
|
|
143
|
+
let quote;
|
|
144
|
+
for (let index = 0; index < command.length; index++) {
|
|
145
|
+
const character = command[index];
|
|
146
|
+
const next = command[index + 1];
|
|
147
|
+
if (quote === 'single') {
|
|
148
|
+
if (character === "'")
|
|
149
|
+
quote = undefined;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (quote === 'double') {
|
|
153
|
+
if (character === '\\') {
|
|
154
|
+
index++;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (character === '"') {
|
|
158
|
+
quote = undefined;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (character === '`' || (character === '$' && next === '(')) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (character === '\\') {
|
|
167
|
+
index++;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (character === "'") {
|
|
171
|
+
quote = 'single';
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (character === '"') {
|
|
175
|
+
quote = 'double';
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (character === '\n' ||
|
|
179
|
+
character === '\r' ||
|
|
180
|
+
character === ';' ||
|
|
181
|
+
character === '&' ||
|
|
182
|
+
character === '|' ||
|
|
183
|
+
character === '<' ||
|
|
184
|
+
character === '>' ||
|
|
185
|
+
character === '`' ||
|
|
186
|
+
(character === '$' && next === '(')) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return quote !== undefined;
|
|
191
|
+
}
|
|
192
|
+
export function check_assessment_command(command) {
|
|
193
|
+
const normalized = command.trim();
|
|
194
|
+
if (!normalized) {
|
|
195
|
+
return { ok: false, reason: 'Assessment mode: empty command' };
|
|
196
|
+
}
|
|
197
|
+
if (has_unquoted_shell_control(normalized) ||
|
|
198
|
+
UNSAFE_READ_COMMAND_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
199
|
+
return {
|
|
200
|
+
ok: false,
|
|
201
|
+
reason: 'Assessment mode: shell composition or a mutating command option is not allowed',
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (!SAFE_COMMAND_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
205
|
+
return {
|
|
206
|
+
ok: false,
|
|
207
|
+
reason: 'Assessment mode: command is not in the read-only allowlist; use one read command per call',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return { ok: true };
|
|
211
|
+
}
|
|
212
|
+
export function assessment_context(state) {
|
|
213
|
+
const approval = state.status === 'awaiting_approval'
|
|
214
|
+
? 'An assessment record is waiting for direct user approval. Do not start implementation or call harness_create.'
|
|
215
|
+
: 'Investigate with read-only tools, then call harness_assessment_submit with one evidence-based recommendation.';
|
|
216
|
+
return `## Active harness assessment\n\nAssessment: \`${state.id}\` v${state.version}\nTask: ${state.task}\n\nRepository mutation is disabled. Treat proposed capabilities as candidates, not tasks. Establish the current source of truth, find existing primitives, reject unsupported options, and define the smallest useful vertical slice. A harness contract is optional and is valid only when the evidence shows that an enforceable execution contract adds value. Bash accepts one allowlisted read command per call; use the dedicated read, find, grep, LSP, and research tools when available.\n\n${approval}`;
|
|
217
|
+
}
|
|
218
|
+
export function format_assessment_record(state) {
|
|
219
|
+
const record = state.record;
|
|
220
|
+
if (!record) {
|
|
221
|
+
return `Assessment ${state.id} v${state.version}: ${state.status}\n\nTask: ${state.task}`;
|
|
222
|
+
}
|
|
223
|
+
const list = (values, empty) => values.length
|
|
224
|
+
? values.map((value) => `- ${value}`).join('\n')
|
|
225
|
+
: `- ${empty}`;
|
|
226
|
+
const contract = record.proposed_contract;
|
|
227
|
+
const contract_section = contract
|
|
228
|
+
? `\n\n## Proposed harness contract\n\n- Task: ${contract.task}\n- Cwd: ${contract.cwd ?? 'current project'}\n- Allowed paths: ${contract.allowed_paths?.join(', ') ?? 'none'}\n- Validation: ${contract.validation_commands?.join(' && ') ?? 'none'}\n- Test changes: ${contract.allow_test_changes ? 'allowed' : 'not allowed'}\n- Forbidden paths: ${contract.forbidden_paths?.join(', ') ?? 'defaults'}\n- Forbidden commands: ${contract.forbidden_commands?.join(', ') ?? 'defaults'}\n- Escalation rules: ${contract.escalation_rules?.join('; ') ?? 'defaults'}\n- Planner: ${contract.planner_model ?? 'default'} (${contract.planner_thinking ?? 'default'})\n- Executor: ${contract.executor_model ?? 'default'} (${contract.executor_thinking ?? 'default'})\n- Reviewer: ${contract.reviewer_model ?? 'default'} (${contract.reviewer_thinking ?? 'default'})`
|
|
229
|
+
: '';
|
|
230
|
+
return `# Harness assessment: ${state.id} v${state.version}\n\n- Status: ${state.status}\n- Recommendation: ${record.recommendation}\n\n## Outcome\n\n${record.task}\n\n## Evidence\n\n${list(record.evidence, 'No evidence recorded')}\n\n## Existing primitives\n\n${list(record.existing_primitives, 'None found')}\n\n## Rejected options\n\n${list(record.rejected_options, 'None recorded')}\n\n## Smallest vertical slice\n\n${record.smallest_vertical_slice}${contract_section}`;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=assessment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assessment.js","sourceRoot":"","sources":["../src/assessment.ts"],"names":[],"mappings":"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"}
|