dsh-harbor-evolution 0.1.0 → 0.2.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
CHANGED
|
@@ -4,31 +4,53 @@ Cordis bundle for evaluating immutable DeepSeek Harness Candidates with Harbor.
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
Install `harbor-dsh-evolution` into the same Python environment as Harbor, then add this bundle to the DSH profile:
|
|
7
|
+
Install `harbor-dsh-evolution` into the same Python environment as Harbor, then add this bundle to the DSH profile you actually run. Use `web` for `dsh web`; use `headless` only for the command-line Agent:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
uv venv .venv
|
|
11
11
|
uv pip install --python .venv/bin/python harbor-dsh-evolution
|
|
12
12
|
source .venv/bin/activate
|
|
13
|
-
pnpm dlx @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile
|
|
13
|
+
pnpm dlx @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile web add -w dsh-harbor-evolution@0.2.0
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
Restart DSH after installation. Launch it from the Agent workspace and expose the two Python executables to the DSH process:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cd /absolute/path/to/your-agent-workspace
|
|
20
|
+
HARBOR_BIN=/absolute/path/to/.venv/bin/harbor \
|
|
21
|
+
HARBOR_DSH_BIN=/absolute/path/to/.venv/bin/harbor-dsh \
|
|
22
|
+
pnpm dlx @deepseek-ai/dsh@0.1.0-rc.6 web
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
In the Web UI, search for the Cordis plugin id `harbor-evolution`. See the [complete local DSH Web quickstart](https://github.com/istarwyh/harbor-self-evolving/blob/main/docs/dsh-web-quickstart.md) for persistent configuration, a first evaluation, Candidate comparison, and troubleshooting.
|
|
26
|
+
|
|
16
27
|
For development from this repository:
|
|
17
28
|
|
|
18
29
|
```bash
|
|
19
|
-
./hse dsh-install
|
|
30
|
+
./hse dsh-install web
|
|
20
31
|
```
|
|
21
32
|
|
|
22
|
-
`-w` is required
|
|
33
|
+
`-w` is required because the DSH profile directory is its pnpm workspace root.
|
|
34
|
+
|
|
35
|
+
The bundle inserts one `harbor-evolution` entry and registers this project's model- and user-invocable Skill through the official DSH Skill Registry:
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
- `evolve-agent-with-harbor`
|
|
38
|
+
|
|
39
|
+
The Skill guides the Agent through workspace inspection, requirements clarification, safe initialization, baseline evaluation, evidence-based diagnosis, one controlled Candidate change, regression comparison, and a Promotion Gate recommendation. Invoke it explicitly from Web or TUI with:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
/evolve-agent-with-harbor
|
|
43
|
+
Inspect this workspace and help me clarify and initialize a stable Harbor self-evolution loop.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The Agent can also select it automatically when the request matches its catalog description. The Skill orchestrates four model-facing tools:
|
|
25
47
|
|
|
26
48
|
- `harbor_candidate_snapshot`
|
|
27
49
|
- `harbor_eval_run`
|
|
28
50
|
- `harbor_eval_result`
|
|
29
51
|
- `harbor_candidate_compare`
|
|
30
52
|
|
|
31
|
-
The shortest evaluation call needs only `candidatePath` and `datasetPath`. Candidate identity defaults to `package.json`, the Job name is generated automatically, and `harbor_eval_run` returns the completed evaluation summary directly.
|
|
53
|
+
The shortest direct evaluation call needs only `candidatePath` and `datasetPath`. Candidate identity defaults to `package.json`, the Job name is generated automatically, and `harbor_eval_run` returns the completed evaluation summary directly. Prefer the Skill for a new project because it will not run or compare Jobs until the material evaluation contract is resolved.
|
|
32
54
|
|
|
33
55
|
The helper launches a fixed DSH version through `pnpm dlx`, so it does not conflict with a long-running `npx` DSH process. When installed from this monorepo, the bundle automatically discovers the sibling Python virtual environment created by `./hse dsh-install`. Otherwise it uses `HARBOR_BIN` / `HARBOR_DSH_BIN`, then falls back to `PATH`. Override the inserted entry in the profile's `cordis.patch.yml` when the binaries or Python source live elsewhere:
|
|
34
56
|
|
|
@@ -39,9 +61,11 @@ The helper launches a fixed DSH version through `pnpm dlx`, so it does not confl
|
|
|
39
61
|
jobsDir: jobs
|
|
40
62
|
harborBin: /workspace/venv/bin/harbor
|
|
41
63
|
harborDshBin: /workspace/venv/bin/harbor-dsh
|
|
42
|
-
pythonPath:
|
|
64
|
+
pythonPath: ""
|
|
43
65
|
```
|
|
44
66
|
|
|
67
|
+
Keep `pythonPath` empty when using the published PyPI package. Set it only when developing the Python package from a source checkout.
|
|
68
|
+
|
|
45
69
|
This replaces the complete config for the entry, following DSH patch semantics.
|
|
46
70
|
|
|
47
71
|
The plugin never mutates the active DSH profile and never deploys a Candidate. Another system updates the Champion only after the external Promotion Gate passes.
|
package/index.js
CHANGED
|
@@ -5,9 +5,10 @@ import path from 'node:path'
|
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
6
|
|
|
7
7
|
import { compareCandidates, readEvaluation, runEvaluation, snapshot } from './lib/evolution.js'
|
|
8
|
+
import { loadBundledSkill } from './lib/official-skill.js'
|
|
8
9
|
|
|
9
10
|
export const name = 'harbor-evolution'
|
|
10
|
-
export const inject = ['tools']
|
|
11
|
+
export const inject = ['tools', 'skills']
|
|
11
12
|
|
|
12
13
|
const packageDir = path.dirname(fileURLToPath(import.meta.url))
|
|
13
14
|
const checkoutPythonPackage = path.resolve(packageDir, '../harbor-plugin')
|
|
@@ -55,6 +56,8 @@ export function apply(ctx, config) {
|
|
|
55
56
|
),
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
ctx.skills.register(loadBundledSkill())
|
|
60
|
+
|
|
58
61
|
ctx.tools.register(jsonTool({
|
|
59
62
|
name: 'harbor_candidate_snapshot',
|
|
60
63
|
description: 'Freeze a DeepSeek Harness Cordis composition as an immutable Candidate manifest. Candidate id and version default to package.json.',
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
|
|
5
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url))
|
|
6
|
+
const skillDir = path.resolve(moduleDir, '../skills/evolve-agent-with-harbor')
|
|
7
|
+
const skillPath = path.join(skillDir, 'SKILL.md')
|
|
8
|
+
|
|
9
|
+
function parseScalar(value) {
|
|
10
|
+
const trimmed = value.trim()
|
|
11
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) return JSON.parse(trimmed)
|
|
12
|
+
if (trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1)
|
|
13
|
+
return trimmed
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseBoolean(value, field) {
|
|
17
|
+
const normalized = String(value).toLowerCase()
|
|
18
|
+
if (['true', 'yes', 'on', '1'].includes(normalized)) return true
|
|
19
|
+
if (['false', 'no', 'off', '0'].includes(normalized)) return false
|
|
20
|
+
throw new TypeError(`bundled Skill frontmatter field "${field}" must be a boolean`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseSkillMarkdown(raw) {
|
|
24
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/)
|
|
25
|
+
if (!match) throw new Error(`bundled Skill is missing YAML frontmatter: ${skillPath}`)
|
|
26
|
+
|
|
27
|
+
const metadata = {}
|
|
28
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
29
|
+
if (!line.trim()) continue
|
|
30
|
+
const separator = line.indexOf(':')
|
|
31
|
+
if (separator <= 0) throw new Error(`invalid bundled Skill frontmatter line: ${line}`)
|
|
32
|
+
metadata[line.slice(0, separator).trim()] = parseScalar(line.slice(separator + 1))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const field of ['name', 'description']) {
|
|
36
|
+
if (typeof metadata[field] !== 'string' || !metadata[field]) {
|
|
37
|
+
throw new Error(`bundled Skill frontmatter requires "${field}"`)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
name: metadata.name,
|
|
43
|
+
description: metadata.description,
|
|
44
|
+
...(metadata.whenToUse ? { whenToUse: metadata.whenToUse } : {}),
|
|
45
|
+
invocation: {
|
|
46
|
+
modelInvocable: metadata['disable-model-invocation'] === undefined
|
|
47
|
+
? true
|
|
48
|
+
: !parseBoolean(metadata['disable-model-invocation'], 'disable-model-invocation'),
|
|
49
|
+
userInvocable: metadata['user-invocable'] === undefined
|
|
50
|
+
? true
|
|
51
|
+
: parseBoolean(metadata['user-invocable'], 'user-invocable'),
|
|
52
|
+
},
|
|
53
|
+
source: 'npm:dsh-harbor-evolution',
|
|
54
|
+
resourceBase: { kind: 'directory', path: skillDir },
|
|
55
|
+
content: match[2].trim(),
|
|
56
|
+
path: skillPath,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function loadBundledSkill() {
|
|
61
|
+
return parseSkillMarkdown(readFileSync(skillPath, 'utf8'))
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-harbor-evolution",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "DeepSeek Harness plugin for
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "DeepSeek Harness plugin and bundled Skill for safely evolving Cordis Candidates with Harbor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"exports": "./index.js",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"index.js",
|
|
13
13
|
"lib/",
|
|
14
14
|
"bin/",
|
|
15
|
+
"skills/",
|
|
15
16
|
"cordis.patch.yml",
|
|
16
17
|
"README.md",
|
|
17
18
|
"LICENSE"
|
|
@@ -26,12 +27,15 @@
|
|
|
26
27
|
}
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
30
|
+
"@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
|
|
29
31
|
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
|
|
30
32
|
},
|
|
31
33
|
"dependencies": {
|
|
32
34
|
"@deepseek-ai/schemastery": "3.18.1"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
37
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
38
|
+
"@deepseek-ai/dsh-skill": "0.1.0-rc.6",
|
|
35
39
|
"@deepseek-ai/dsh-tools": "0.1.0-rc.6",
|
|
36
40
|
"@deepseek-ai/schemastery": "3.18.1"
|
|
37
41
|
},
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: evolve-agent-with-harbor
|
|
3
|
+
description: Initialize, evaluate, compare, and safely improve a DeepSeek Harness Agent with Harbor. Use when the user asks to set up Harbor evaluation or Agent self-evolution, clarify an evaluation contract, create a Candidate, Dataset, or Promotion Policy, investigate a failed Job, or decide whether a Candidate should replace a baseline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Evolve Agent With Harbor
|
|
7
|
+
|
|
8
|
+
Turn a vague improvement request into a reproducible evaluation contract, immutable Candidates, comparable Harbor Jobs, and an auditable promotion recommendation. Treat Harbor as the experiment boundary; deployment remains outside this workflow.
|
|
9
|
+
|
|
10
|
+
## Choose the operating mode
|
|
11
|
+
|
|
12
|
+
Infer the narrowest mode that satisfies the request:
|
|
13
|
+
|
|
14
|
+
- **Clarify**: define what progress means and what may change.
|
|
15
|
+
- **Initialize**: create the missing Candidate, Dataset, and Promotion Policy structure.
|
|
16
|
+
- **Evaluate**: snapshot and run one Candidate.
|
|
17
|
+
- **Compare**: compare an existing baseline Job with a new Candidate Job.
|
|
18
|
+
- **Evolve**: run the complete baseline, diagnosis, controlled change, regression, and gate loop.
|
|
19
|
+
- **Meta-evaluate**: optimize a Verifier or Judge against human ground truth rather than optimizing the business Agent.
|
|
20
|
+
|
|
21
|
+
Do not expand an evaluate-only request into code mutation or deployment.
|
|
22
|
+
|
|
23
|
+
## Clarify the evaluation contract
|
|
24
|
+
|
|
25
|
+
Inspect the workspace and existing configuration before asking questions. Summarize known values, then resolve only material gaps. Prefer no more than three grouped questions in one turn.
|
|
26
|
+
|
|
27
|
+
Establish these fields:
|
|
28
|
+
|
|
29
|
+
1. Business behavior and the failure being improved.
|
|
30
|
+
2. Candidate path and stable Agent product identity.
|
|
31
|
+
3. Harbor Dataset path, test population, and environment constraints.
|
|
32
|
+
4. Primary metric, minimum metrics, non-regression metrics, and tolerances.
|
|
33
|
+
5. Baseline Candidate or baseline Job.
|
|
34
|
+
6. Allowed mutation surface, forbidden files, and side-effect boundaries.
|
|
35
|
+
7. Run budget, repeat policy for stochastic Agents, and stopping condition.
|
|
36
|
+
8. Promotion owner and external CI/CD boundary.
|
|
37
|
+
|
|
38
|
+
Candidate and Dataset paths are hard blockers for a run. Baseline and promotion criteria are hard blockers for a comparison. Do not invent ground truth, metrics, or deployment authority. Offer explicit draft defaults when helpful, but obtain acceptance before using them as the evaluation contract.
|
|
39
|
+
|
|
40
|
+
## Initialize safely
|
|
41
|
+
|
|
42
|
+
When required files are missing, read `references/initialization.md` before creating them. Initialize only inside the configured `projectRoot` and preserve existing files.
|
|
43
|
+
|
|
44
|
+
- Keep the baseline immutable; create a new versioned Candidate directory for every optimization attempt.
|
|
45
|
+
- Keep secrets out of Candidate files. Inject equal credentials and permissions at runtime.
|
|
46
|
+
- Pin direct and transitive dependencies with a lockfile.
|
|
47
|
+
- Make the Verifier emit a primary reward plus diagnostic metrics and failure evidence.
|
|
48
|
+
- Version the Promotion Policy. A policy or Verifier change requires a fresh baseline.
|
|
49
|
+
- Use test accounts, mocks, or sandboxes for business side effects.
|
|
50
|
+
|
|
51
|
+
If file-editing capabilities are unavailable, produce the exact initialization plan and unresolved choices instead of pretending files were created.
|
|
52
|
+
|
|
53
|
+
## Run the stable evolution loop
|
|
54
|
+
|
|
55
|
+
### 1. Establish the baseline
|
|
56
|
+
|
|
57
|
+
Call `harbor_candidate_snapshot` for the baseline Candidate. Then call `harbor_eval_run` with the accepted Candidate and Dataset paths. Record the Candidate id, version, digest, Job path, evaluation-context digest, metrics, exceptions, and failed trials.
|
|
58
|
+
|
|
59
|
+
`harbor_eval_run` already snapshots again before execution. Treat a digest mismatch as a real Candidate change, not as noise.
|
|
60
|
+
|
|
61
|
+
### 2. Diagnose before changing
|
|
62
|
+
|
|
63
|
+
Use the summary returned by `harbor_eval_run`; call `harbor_eval_result` only when reopening an existing Job or when the stable summary is needed again. Read failed samples and trajectories when available.
|
|
64
|
+
|
|
65
|
+
Classify each failure as one of:
|
|
66
|
+
|
|
67
|
+
- Agent capability or policy failure.
|
|
68
|
+
- Tool-call, search, citation, or output-contract failure.
|
|
69
|
+
- Dataset, Verifier, or ground-truth defect.
|
|
70
|
+
- Infrastructure, dependency, permission, timeout, or deployment failure.
|
|
71
|
+
- Stochastic variance requiring repeats.
|
|
72
|
+
|
|
73
|
+
Do not optimize the Agent to compensate for a broken evaluation environment. Do not leak holdout answers or ground truth into the Candidate.
|
|
74
|
+
|
|
75
|
+
### 3. Make one controlled change
|
|
76
|
+
|
|
77
|
+
State one hypothesis that connects evidence to the proposed change. Create a new immutable Candidate version and modify only the accepted mutation surface. Never edit the baseline Candidate in place.
|
|
78
|
+
|
|
79
|
+
Snapshot the new Candidate and verify that its digest differs. If it does not differ, stop because no new Candidate exists.
|
|
80
|
+
|
|
81
|
+
### 4. Re-run under the same context
|
|
82
|
+
|
|
83
|
+
Call `harbor_eval_run` with the same Dataset and evaluation settings. For stochastic Agents, use the accepted repeat policy for both baseline and Candidate; never cherry-pick the best run.
|
|
84
|
+
|
|
85
|
+
Compare only Jobs whose `evaluation-context` digests match. If the context changed, establish a new baseline instead of claiming improvement.
|
|
86
|
+
|
|
87
|
+
### 5. Apply the deterministic gate
|
|
88
|
+
|
|
89
|
+
Call `harbor_candidate_compare` with the baseline Job, Candidate Job, and accepted Promotion Policy. Respect its decision:
|
|
90
|
+
|
|
91
|
+
- `PROMOTE`: recommend promotion and provide the evidence package.
|
|
92
|
+
- `REJECT`: keep the current Champion and explain each failed criterion.
|
|
93
|
+
|
|
94
|
+
The gate is a recommendation boundary. Never deploy, mutate the active DSH profile, merge code, or replace the Champion unless the user separately authorizes the external CI/CD action.
|
|
95
|
+
|
|
96
|
+
## Preserve experimental invariants
|
|
97
|
+
|
|
98
|
+
- One Job binds one Candidate digest; one Candidate may have many Jobs.
|
|
99
|
+
- Baseline and Candidate must share the same evaluation-context digest.
|
|
100
|
+
- Keep Candidate, evaluation context, policy, summaries, trajectories, and gate report as checkpoints.
|
|
101
|
+
- Separate infrastructure failures from capability failures in every report.
|
|
102
|
+
- Change one causal factor per iteration unless the user explicitly accepts a bundled experiment.
|
|
103
|
+
- Use hidden or held-out evaluation data for promotion; do not let the Optimizer train directly on it.
|
|
104
|
+
- Report uncertainty when sample size or stochastic variance prevents a stable conclusion.
|
|
105
|
+
|
|
106
|
+
## Handle evaluator meta-evaluation
|
|
107
|
+
|
|
108
|
+
When the object being improved is the evaluator, rotate the roles:
|
|
109
|
+
|
|
110
|
+
- Candidate is a Verifier or Judge version.
|
|
111
|
+
- Dataset contains cases with independently maintained human ground truth.
|
|
112
|
+
- Metrics measure evaluator alignment, such as RCR, bias, variance, calibration, latency, and cost.
|
|
113
|
+
- Promotion compares evaluator Candidates under a fixed GT set and policy.
|
|
114
|
+
|
|
115
|
+
Never let the Candidate Judge provide its own final ground truth or promotion decision.
|
|
116
|
+
|
|
117
|
+
## Report each cycle
|
|
118
|
+
|
|
119
|
+
Return a compact audit record containing:
|
|
120
|
+
|
|
121
|
+
- Accepted evaluation contract and any remaining assumptions.
|
|
122
|
+
- Baseline and Candidate ids, versions, digests, and Job paths.
|
|
123
|
+
- Evaluation-context and Promotion Policy identities.
|
|
124
|
+
- Primary and diagnostic metric deltas.
|
|
125
|
+
- Representative failure evidence and root-cause classification.
|
|
126
|
+
- Gate decision with exact reasons.
|
|
127
|
+
- External action required for promotion and the next controlled hypothesis if rejected.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Initialization Reference
|
|
2
|
+
|
|
3
|
+
Load this reference only when the user needs a new Harbor self-evolution workspace or is missing one of the required contracts.
|
|
4
|
+
|
|
5
|
+
## Readiness checklist
|
|
6
|
+
|
|
7
|
+
Confirm these prerequisites before the first Job:
|
|
8
|
+
|
|
9
|
+
- Docker is available to Harbor.
|
|
10
|
+
- Node.js 22+, the selected DSH version, `harbor`, and `harbor-dsh` are available to the DSH process.
|
|
11
|
+
- `projectRoot` is the intended workspace security boundary.
|
|
12
|
+
- Candidate, Dataset, Job, and Promotion Policy paths stay within `projectRoot`.
|
|
13
|
+
- Runtime credentials use evaluation accounts and are not stored in Candidate files.
|
|
14
|
+
|
|
15
|
+
## Clarification worksheet
|
|
16
|
+
|
|
17
|
+
Use known repository evidence first. Ask the user only for unresolved choices.
|
|
18
|
+
|
|
19
|
+
| Contract field | Example | Why it matters |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Target behavior | Produce cited research answers | Defines task success |
|
|
22
|
+
| Candidate identity | `deep-research-agent` | Keeps v1/v2 in one product line |
|
|
23
|
+
| Candidate path | `candidates/deep-research/v1` | Defines what is snapshotted |
|
|
24
|
+
| Dataset path | `datasets/deep-research-regression` | Fixes tasks and Verifier |
|
|
25
|
+
| Primary metric | `reward` | Ranks Candidates |
|
|
26
|
+
| Minimums | completion and citation >= 0.95 | Prevents unsafe tradeoffs |
|
|
27
|
+
| Non-regression | tool success, latency | Protects existing capability |
|
|
28
|
+
| Mutation surface | prompt and search plugin only | Controls causal attribution |
|
|
29
|
+
| Repeat policy | 5 fixed-seed runs | Controls stochastic variance |
|
|
30
|
+
| Promotion owner | CI gate plus human approval | Keeps deployment external |
|
|
31
|
+
|
|
32
|
+
## Recommended layout
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
agent-workspace/
|
|
36
|
+
├── candidates/
|
|
37
|
+
│ └── <agent-id>/
|
|
38
|
+
│ ├── v1/
|
|
39
|
+
│ │ ├── cordis.yml
|
|
40
|
+
│ │ ├── package.json
|
|
41
|
+
│ │ ├── package-lock.json
|
|
42
|
+
│ │ └── business plugins...
|
|
43
|
+
│ └── v2/
|
|
44
|
+
├── datasets/
|
|
45
|
+
│ └── <suite>/
|
|
46
|
+
│ ├── task.toml
|
|
47
|
+
│ ├── instruction.md
|
|
48
|
+
│ ├── environment/Dockerfile
|
|
49
|
+
│ └── tests/
|
|
50
|
+
│ ├── test.sh
|
|
51
|
+
│ └── verifier files...
|
|
52
|
+
├── policies/
|
|
53
|
+
│ └── <suite>.json
|
|
54
|
+
└── jobs/
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Generate `candidate-manifest.json` with `harbor_candidate_snapshot`; do not hand-author it. One immutable Candidate may be evaluated by many Jobs.
|
|
58
|
+
|
|
59
|
+
## Candidate rules
|
|
60
|
+
|
|
61
|
+
A Candidate is the complete DSH/Cordis composition required to reproduce behavior:
|
|
62
|
+
|
|
63
|
+
- `package.json` supplies the default Candidate id and version.
|
|
64
|
+
- `cordis.yml` composes the model, tools, skills, loop, storage, and business plugins.
|
|
65
|
+
- A lockfile pins transitive runtime dependencies.
|
|
66
|
+
- Local plugin files and prompts belong in the Candidate and therefore affect its digest.
|
|
67
|
+
- Secrets, mutable session state, Jobs, and production deployment configuration do not belong in the Candidate.
|
|
68
|
+
|
|
69
|
+
Copy an existing known-good Candidate when possible. If none exists, create the smallest valid DSH composition for the actual business Agent; do not invent a model provider or credential scheme.
|
|
70
|
+
|
|
71
|
+
## Dataset and Verifier rules
|
|
72
|
+
|
|
73
|
+
A Harbor Dataset contains one or more fixed Tasks. Each Task should define:
|
|
74
|
+
|
|
75
|
+
- `task.toml`: Task identity, timeouts, environment, and Harbor contract.
|
|
76
|
+
- `instruction.md`: the behavior requested from the Candidate.
|
|
77
|
+
- `environment/Dockerfile`: a reproducible sandbox with required runtime dependencies.
|
|
78
|
+
- `tests/test.sh`: the verifier entrypoint.
|
|
79
|
+
- Verifier code that writes primary and diagnostic metrics to Harbor's reward output.
|
|
80
|
+
|
|
81
|
+
For a research Agent, useful diagnostic metrics include task completion, tool-call success, valid-search rate, citation correctness, latency, and cost. Keep their exact definitions in version control. Do not convert tool errors, empty searches, or invalid citations into prose-only observations; expose them as metrics or structured failure evidence.
|
|
82
|
+
|
|
83
|
+
## Promotion Policy starter
|
|
84
|
+
|
|
85
|
+
Create this only after the user accepts the metric names and thresholds:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"schema_version": 1,
|
|
90
|
+
"primary_metric": "reward",
|
|
91
|
+
"min_improvement": 0.05,
|
|
92
|
+
"minimums": {
|
|
93
|
+
"task_completion": 0.95
|
|
94
|
+
},
|
|
95
|
+
"non_regression": [
|
|
96
|
+
"tool_call_success",
|
|
97
|
+
"citation_correctness"
|
|
98
|
+
],
|
|
99
|
+
"non_regression_tolerance": 0.0
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This is a structural example, not a universal default. Thresholds must reflect business risk and sample size. Version the policy; changing it invalidates comparisons made under the old promotion contract.
|
|
104
|
+
|
|
105
|
+
## First-cycle handoff
|
|
106
|
+
|
|
107
|
+
Before calling an evaluation tool, show the user:
|
|
108
|
+
|
|
109
|
+
1. The resolved Candidate, Dataset, Job, and policy paths.
|
|
110
|
+
2. The metric and promotion contract.
|
|
111
|
+
3. The mutation and side-effect boundaries.
|
|
112
|
+
4. Any assumptions still being used.
|
|
113
|
+
|
|
114
|
+
Then snapshot and run the baseline. Do not initialize v2 until baseline evidence identifies a concrete hypothesis.
|