@agentskit/harness 0.3.0 → 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.
@@ -0,0 +1,121 @@
1
+ # @agentskit/harness — keep-pushing loop configuration.
2
+ # Copy to <your project>/loop.config.yaml. Everything project-specific lives here; the loop code has no names, paths or ids.
3
+ # Never put secrets in this file: `envKeys` are the NAMES of environment variables the loop checks, not their values.
4
+ schemaVersion: 1
5
+
6
+ project:
7
+ name: my-project
8
+ repo: my-org/my-project # GitHub owner/name used for PR review and merge
9
+ baseBranch: main
10
+ root: . # relative to this file
11
+ stateDir: .codex/loop # ledger, cooldowns, contracts
12
+
13
+ orca:
14
+ bin: orca # on Linux outside Orca terminals use orca-ide (bare `orca` is the GNOME screen reader)
15
+ # repoSelector: id:<orca-repo-id> # default: path:<project.root>
16
+ # workspaceSelector: path:/abs/main/checkout # existing worktree the automations run in
17
+ # host: runtime:<environment-id> # paired remote Orca host
18
+ minVersion: 1.4.200
19
+ timeoutMs: 20000
20
+
21
+ linear:
22
+ workspaceId: <linear-workspace-id> # orca linear team list --workspace all --json
23
+ teamKey: ENG
24
+ person: my-linear-display-name # the ONLY queue this machine drains
25
+ people: # display name -> Linear user id (orca linear team members …)
26
+ my-linear-display-name: <linear-user-id>
27
+ states: [Todo, Ready] # dispatchable states; anything already started is left alone
28
+ excludeLabels: [blocked, needs-info]
29
+ requireLabels: []
30
+ projects: [] # empty = all projects
31
+ order: [priority, updatedAt] # urgent first; priority 0 (none) sorts last
32
+ maxQueue: 50
33
+ inProgressState: In Progress
34
+ reviewState: In Review
35
+ doneState: Done
36
+ blockedLabel: blocked
37
+ needsInfoLabel: needs-info
38
+
39
+ models:
40
+ # Tiers, in order. Inside a tier the first provider with usage available wins.
41
+ # Tier 1 = subscriptions, tier 2 = cheap hosted, tier 3 = last resort.
42
+ orchestrator: [[codex/gpt-5.6-sol, claude/opus], [opencode/opencode-go/glm-5.3], [grok/grok-4-fast]]
43
+ reviewer: [[codex/gpt-5.6-sol, claude/opus], [opencode/opencode-go/glm-5.3], [grok/grok-4-fast]]
44
+ builder: [[codex/gpt-5.6-luna, claude/sonnet, claude/haiku], [opencode/opencode-go/glm-5.3-flash], [grok/grok-4-fast]]
45
+ watcher: [[claude/haiku, codex/gpt-5.6-luna], [opencode/opencode-go/glm-5.3-flash]]
46
+ cooldown:
47
+ initialMin: 30 # provider marked exhausted without a known reset waits 30 min, doubling…
48
+ maxMin: 240 # …up to 4 h
49
+ probeBeforeReenable: true
50
+ exhaustedPercent: 100
51
+ providers:
52
+ claude:
53
+ bin: claude
54
+ auth: subscription
55
+ envKeys: [ANTHROPIC_API_KEY] # optional API-key fallback
56
+ tui: "claude --model {model} --permission-mode auto"
57
+ headless: [claude, -p, "{prompt}", --model, "{model}", --permission-mode, plan, --output-format, text]
58
+ codex:
59
+ bin: codex
60
+ auth: subscription
61
+ envKeys: [OPENAI_API_KEY]
62
+ tui: "codex -m {model} --full-auto"
63
+ headless: [codex, exec, -m, "{model}", -s, read-only, --skip-git-repo-check, "{prompt}"]
64
+ opencode:
65
+ bin: opencode
66
+ auth: none
67
+ orcaUsageKey: opencodeGo # key inside `orca account list` rateLimits
68
+ tui: "opencode -m {model}"
69
+ headless: [opencode, run, -m, "{model}", --agent, plan, "{prompt}"]
70
+ grok:
71
+ bin: grok
72
+ auth: subscription # `grok login` (OAuth) — no API key needed
73
+ tui: "grok -m {model}"
74
+ headless: [grok, -p, "{prompt}", -m, "{model}"]
75
+
76
+ machine:
77
+ floor: 1 # always allow one worker
78
+ # ceiling: 4 # default: cpus / 2
79
+ minFreeRamGb: 4
80
+ warningPercent: 75
81
+ criticalPercent: 90
82
+ agentRssMb: 1400 # RAM budget per agent when live RSS is unknown
83
+ wslCap: 1 # host Defender load is invisible from a WSL distro
84
+
85
+ delivery:
86
+ verifyCommand: "pnpm lint && pnpm test" # what the worker must pass before opening a PR
87
+ review:
88
+ cli: agentskit-review
89
+ mode: trusted-local # reuse this user's CLI logins; the isolated default has no credentials
90
+ profile: fast # one bounded pass over required lenses; `full` needs batching to fit a 600 s stage
91
+ votes: 1
92
+ concurrency: 4
93
+ minSeverity: med # nit < med < high < blocker; findings at/above this block auto-merge
94
+ deadlineMs: 600000
95
+ merge:
96
+ auto: true
97
+ method: squash
98
+ requireChecks: true
99
+ maxFixRounds: 2
100
+ workerIdleTimeoutMin: 45
101
+ selfEditPaths: [loop.config.yaml, ".github/**"] # PRs touching these never auto-merge
102
+ ignoreChecks: [] # advisory check names that never block
103
+ requiredChecks: [] # empty = every reported check must be green
104
+ cleanupWorktree: true # remove the Orca worktree after merge
105
+ returnState: Todo # where a stuck/blocked issue goes back to
106
+
107
+ contract:
108
+ maxIssueChars: 12000 # issue text rendered into the orchestrator prompt (as untrusted data)
109
+ timeoutMs: 300000
110
+ maxContextReferences: 6 # Doc Bridge hits appended when .doc-bridge/index.json exists
111
+ reuseHours: 72 # cached contract reused for this long
112
+
113
+ schedule:
114
+ tick: "*/5 * * * *"
115
+ deliver: "*/10 * * * *"
116
+ precheckTimeoutSec: 120
117
+ harnessCommand: ak-harness # how the Orca automation runs the harness inside the workspace
118
+ namePrefix: loop # automations: loop-tick, loop-deliver
119
+ runner: precheck # the stage runs inside Orca's precheck command; no agent session is ever opened
120
+ stageTimeoutSec: 600 # Orca caps prechecks at 600 s; one tick/deliver run must fit
121
+ # provider: claude # Orca agent that executes the automation prompt (default: watcher role)
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@agentskit/harness",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Portable, evidence-backed development harness for coding agents.",
5
5
  "type": "module",
6
- "bin": { "ak-harness": "dist/cli.js", "ak-verify": "dist/cli.js" },
6
+ "bin": {
7
+ "ak-harness": "dist/cli.js",
8
+ "ak-verify": "dist/cli.js"
9
+ },
7
10
  "main": "./dist/index.js",
8
11
  "types": "./dist/index.d.ts",
9
12
  "exports": {
@@ -12,8 +15,25 @@
12
15
  "import": "./dist/index.js"
13
16
  }
14
17
  },
15
- "files": ["dist", "README.md", "CHANGELOG.md", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "SECURITY.md", "MANIFESTO.md", "LICENSE", "docs"],
16
- "engines": { "node": ">=22" },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "CHANGELOG.md",
22
+ "CONTRIBUTING.md",
23
+ "CODE_OF_CONDUCT.md",
24
+ "SECURITY.md",
25
+ "MANIFESTO.md",
26
+ "LICENSE",
27
+ "docs",
28
+ "capabilities",
29
+ "examples",
30
+ "compatibility",
31
+ "release",
32
+ "loop.config.example.yaml"
33
+ ],
34
+ "engines": {
35
+ "node": ">=22"
36
+ },
17
37
  "scripts": {
18
38
  "build": "tsup && node -e \"console.log(JSON.stringify({status:'passed',criteria:['package']}))\"",
19
39
  "typecheck": "tsc -p tsconfig.json --noEmit",
@@ -43,6 +63,18 @@
43
63
  "test:optimization": "pnpm typecheck && vitest run --config vitest.config.ts test/optimization.test.ts test/issues-010-014.eval.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['optimization-contracts','eval','cache','parallelism']}))\"",
44
64
  "test:source": "pnpm typecheck && vitest run --config vitest.config.ts test/source.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['source-current']}))\"",
45
65
  "test:metrics": "pnpm typecheck && vitest run --config vitest.config.ts test/metrics.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['metrics']}))\"",
66
+ "test:capabilities": "node scripts/generate-capability-manifest.mjs --check capabilities/public-surface.json",
67
+ "test:boundaries": "pnpm typecheck && vitest run --config vitest.config.ts test/boundaries.test.ts && node scripts/verify-dependency-directions.mjs",
68
+ "test:phase-executor": "pnpm typecheck && vitest run --config vitest.config.ts test/phase-executor.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['phase-executor']}))\"",
69
+ "test:artifacts": "pnpm typecheck && vitest run --config vitest.config.ts test/artifacts.test.ts && node scripts/verify-artifact-cli.mjs",
70
+ "test:adapters": "pnpm typecheck && vitest run --config vitest.config.ts test/adapters.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['adapters']}))\"",
71
+ "test:loop": "pnpm typecheck && vitest run --config vitest.config.ts test/loop.test.ts test/loop-adapters.test.ts test/loop-tick.test.ts test/loop-deliver.test.ts test/loop-install.test.ts test/loop-guided-install.test.ts test/loop-retro.test.ts test/loop-debrief.test.ts test/loop-watch.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['loop-config','loop-providers','loop-routing','loop-doctor','loop-adapters','loop-tick','loop-deliver','loop-install','loop-debrief','loop-watch']}))\"",
72
+ "test:review": "pnpm typecheck && vitest run --config vitest.config.ts test/review.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['review-delivery']}))\"",
73
+ "test:quality": "pnpm typecheck && vitest run --config vitest.config.ts test/quality.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['quality-matrix']}))\"",
74
+ "test:eval-battery": "pnpm typecheck && vitest run --config vitest.config.ts test/eval-battery.test.ts test/issues-010-014.eval.test.ts test/optimization.test.ts && pnpm build >/dev/null && node scripts/verify-harness-eval-manifest.mjs && node -e \"console.log(JSON.stringify({status:'passed',criteria:['eval-battery','eval-manifest','eval-coverage']}))\"",
75
+ "test:compatibility": "pnpm typecheck && vitest run --config vitest.config.ts test/compatibility.test.ts && pnpm build >/dev/null && node scripts/verify-harness-compatibility-manifest.mjs && node -e \"console.log(JSON.stringify({status:'passed',criteria:['compatibility-contract','compatibility-manifest','pinned-revisions','real-adapter-boundary']}))\"",
76
+ "test:examples": "pnpm typecheck && pnpm build >/dev/null && node scripts/verify-harness-examples.mjs && node scripts/verify-adoption-docs.mjs",
77
+ "test:release-manifest": "pnpm typecheck && pnpm build >/dev/null && node scripts/verify-release-workflow.mjs && node scripts/verify-release-manifest.mjs",
46
78
  "test:benchmark-record": "pnpm typecheck && node scripts/verify-harness-benchmark-record.mjs",
47
79
  "test:agent-protocol": "pnpm typecheck && vitest run --config vitest.config.ts test/agent.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['agent-protocol']}))\"",
48
80
  "test:policy-gate": "pnpm typecheck && vitest run --config vitest.config.ts test/policy.test.ts test/agent.test.ts && node -e \"console.log(JSON.stringify({status:'passed',criteria:['policy-gate','agent-protocol']}))\"",
@@ -53,10 +85,15 @@
53
85
  "prepublishOnly": "pnpm typecheck && pnpm build && pnpm test"
54
86
  },
55
87
  "dependencies": {
56
- "commander": "^14.0.0"
88
+ "commander": "^14.0.0",
89
+ "ink": "7.1.1",
90
+ "react": "19.3.0",
91
+ "yaml": "^2.9.0",
92
+ "zod": "^4.6.2"
57
93
  },
58
94
  "devDependencies": {
59
95
  "@types/node": "^22.10.0",
96
+ "@types/react": "^19.3.0",
60
97
  "tsup": "^8.5.0",
61
98
  "typescript": "^5.7.2",
62
99
  "vitest": "^4.1.10"
@@ -67,9 +104,14 @@
67
104
  "type": "git",
68
105
  "url": "git+https://github.com/AgentsKit-io/harness.git"
69
106
  },
70
- "bugs": { "url": "https://github.com/AgentsKit-io/harness/issues" },
107
+ "bugs": {
108
+ "url": "https://github.com/AgentsKit-io/harness/issues"
109
+ },
71
110
  "homepage": "https://github.com/AgentsKit-io/harness",
72
111
  "author": "AgentsKit Contributors",
73
112
  "sideEffects": false,
74
- "publishConfig": { "access": "public", "provenance": true }
113
+ "publishConfig": {
114
+ "access": "public",
115
+ "provenance": true
116
+ }
75
117
  }
@@ -0,0 +1,36 @@
1
+ {
2
+ "type": "agentskit-harness-release-manifest",
3
+ "schemaVersion": 1,
4
+ "package": "@agentskit/harness",
5
+ "version": "0.5.0",
6
+ "channel": "latest",
7
+ "sourceRevision": "b8cfe596e5f30f2c373b89f00f271079b296feaf",
8
+ "requiredChecks": [
9
+ "typecheck",
10
+ "test",
11
+ "build",
12
+ "pack",
13
+ "cli",
14
+ "consumer",
15
+ "eval-battery",
16
+ "pilot-benchmark",
17
+ "ecosystem-compatibility",
18
+ "registry-smoke"
19
+ ],
20
+ "publication": {
21
+ "workflow": ".github/workflows/release-harness.yml",
22
+ "branch": "main",
23
+ "trustedPublishing": true,
24
+ "usesNpmToken": false
25
+ },
26
+ "evidenceOutputs": [
27
+ "release/qualification.json",
28
+ "release/notes.md"
29
+ ],
30
+ "blockedCriteria": [
31
+ "ecosystem-compatibility",
32
+ "pilot-benchmark"
33
+ ],
34
+ "nextBaseline": "benchmarks/harness-0.4.0-baseline.json",
35
+ "digest": "712347d25fac5a6b0819cf8ba60f11ba9dc37c8d9380fb7df9e834f711509a86"
36
+ }
@@ -0,0 +1,25 @@
1
+ # 0.5.0 release candidate
2
+
3
+ This release adds the keep-pushing SDLC loop (`ak-harness loop …`): project config with a per-machine overlay,
4
+ provider detection with Orca usage awareness and cooldowns, tiered model routing, machine slot assessment, Orca /
5
+ Linear / GitHub / code-review adapters, the dispatch tick with orchestrator-frozen contracts, the deliver stage
6
+ (CI → review → fix rounds → squash-merge → Linear Done) and the Orca automation installer. See `docs/LOOP.md` and
7
+ ADR-0027. `yaml` and `zod` become runtime dependencies.
8
+
9
+ Publication happens only when this candidate merges to `main` (release workflow, npm Trusted Publishing, no
10
+ `NPM_TOKEN`). `release/qualification.json` still records the 0.4.0 publication and will be refreshed after 0.5.0 is
11
+ on the registry. Compatibility and pilot-benchmark criteria remain fail-closed as in 0.4.0.
12
+
13
+ # 0.4.0 release
14
+
15
+ This release packages the deterministic SDLC kernel, phase quality matrix,
16
+ versioned eval battery, compatibility contract, and consumer examples.
17
+
18
+ Publication is intentionally limited to a merge on `main`. The release
19
+ workflow uses npm Trusted Publishing (`id-token: write`) and no `NPM_TOKEN`.
20
+
21
+ The package was published from `main` through npm Trusted Publishing at
22
+ `2df60bcbda850382d1a1112f338fa53858c5d4cf`. Pinned upstream tests and the
23
+ registry/consumer smoke are recorded as passed. Compatibility remains fail-closed
24
+ until the real Code Review quality baseline and the owner-approved ten-task
25
+ Harness/no-Harness pilot cohort are captured.
@@ -0,0 +1,14 @@
1
+ {
2
+ "type": "agentskit-harness-release-qualification",
3
+ "schemaVersion": 1,
4
+ "package": "@agentskit/harness",
5
+ "version": "0.4.0",
6
+ "sourceRevision": "2df60bcbda850382d1a1112f338fa53858c5d4cf",
7
+ "status": "blocked",
8
+ "harnessVerification": { "runId": "1789065264843-3627-dgz8xb", "decision": "COMPLETE", "checksPassed": 21, "checksTotal": 21 },
9
+ "upstreamCompatibility": { "report": "compatibility/report.json", "status": "blocked" },
10
+ "pilotBenchmark": { "status": "blocked", "reason": "No comparable owner-approved no-Harness cohort; real code-review run has no baseline and did not pass quality matrix." },
11
+ "registrySmoke": { "status": "passed", "registry": "https://registry.npmjs.org", "package": "@agentskit/harness@0.4.0", "consumerImport": "passed (runEvalBattery, startRun)", "cliHelp": "passed (ak-verify)" },
12
+ "publishable": false,
13
+ "blockers": ["ecosystem-compatibility", "pilot-benchmark"]
14
+ }