pi-continual-harness 0.21.0 → 0.22.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 CHANGED
@@ -8,7 +8,32 @@ Releases are tag-driven (`vX.Y.Z`) and published by GitHub Actions via npm
8
8
  Trusted Publishing. This file begins at 0.7.0; earlier releases are recorded in
9
9
  the git tags (`git tag -l`) and the [GitHub release history](https://github.com/pungggi/pi-continual-harness/releases).
10
10
 
11
- ## [Unreleased]
11
+ ## [0.22.0] — 2026-11-11
12
+
13
+ ### Added
14
+
15
+ - **Classifier auto-discovery** (pi ≥ 1.5.1 interplay): when `classifier.model`
16
+ is unset, the classifier seam now falls back to a single known-good hosted
17
+ classifier — `github-copilot/microsoft-decision-1`, shipped by pi 1.5.1+
18
+ with GitHub Copilot auth — so classifier-confirmed dedupe and the auto-refine
19
+ gate work with zero setup for Copilot users. Discovery deliberately never
20
+ picks a local llama.cpp entry (the catalog can list one while no server
21
+ runs). An explicit `classifier.model` always wins; `"classifier": { "auto":
22
+ false }` restores explicit-only. `/harness status` and the setup/reminder
23
+ copy now treat the gate as the only required key when discovery is on.
24
+ - **Determinism contract for the injected block** (pinned by a test): for an
25
+ unchanged store + config, `renderHarnessBlock` is byte-identical. This is
26
+ what lets pi 1.5.1+'s Anthropic message threads `continue` a conversation —
27
+ the thread-prefix hash covers the system prompt, so unchanged harness state
28
+ rides the server-side thread and the warmed prompt cache, while any harness
29
+ change mismatches the hash and pi correctly falls back to a full resend.
30
+ Idle prompt-cache warming (pi 1.5.1) similarly keeps the injected system
31
+ prefix warm between runs — no package change needed, both verified against
32
+ the pi-ai 1.5.2 source.
33
+ - Dev dependencies bumped to `@earendil-works/pi-*` `^1.5.2` (runtime peers
34
+ stay `>=1.2.0`; nothing 1.5-only is imported at runtime).
35
+
36
+ ## [0.21.0] — 2026-11-07
12
37
 
13
38
  ### Added
14
39
 
package/README.md CHANGED
@@ -195,7 +195,7 @@ Optional config at `~/.pi/agent/harness.json` (missing → defaults; malformed
195
195
  "remindRefine": { "enabled": true, "everyTurns": 25, "detailEvery": 4 },
196
196
  "autoRefine": { "enabled": false, "everyTurns": 100, "commit": false, "gate": false, "refineNoOpSkip": 3 },
197
197
  "outcomeImportance": { "enabled": false, "bump": 0.03 },
198
- "classifier": { "model": "typesafe/jev-latest" },
198
+ "classifier": { "model": "github-copilot/microsoft-decision-1", "auto": true },
199
199
  "virtualBinding": "virtual"
200
200
  }
201
201
  ```
@@ -218,7 +218,7 @@ schemas (the same pattern pi ≥ 1.2 ships for its own `settings.json` /
218
218
  | `remindRefine` | on, every 25 turns | The notify-only `/refine` activation nudge; every 4th one is a detailed educational guide. |
219
219
  | `autoRefine` | off, every 100 turns | Opt-in autonomous `/refine` on a cadence; `gate` adds the classifier question, `refineNoOpSkip` the free history gate. |
220
220
  | `outcomeImportance` | off, bump 0.03 | Opt-in promotion of items you cite by `[h_xxxx]` tag. Promotion only — never deletes. |
221
- | `classifier` | unset | Classifier model (pi ≥ 0.99) enabling classifier-confirmed dedupe + the auto-refine gate. |
221
+ | `classifier` | `model` unset, `auto: true` | Classifier enabling classifier-confirmed dedupe + the auto-refine gate. With `auto` (default), an unset `model` auto-resolves the hosted `github-copilot/microsoft-decision-1` on pi ≥ 1.5.1 with Copilot auth; set `model` to pin any classifier, or `auto: false` to require it. |
222
222
  | `virtualBinding` | `"virtual"` | Per-model isolation key for router (virtual) models; `"physical"` keys by the routed model. |
223
223
 
224
224
  The package's autonomous paths (`autoImport`, `autoRefine`, `outcomeImportance`)
@@ -542,8 +542,12 @@ migration; developed and tested against pi 1.5). Implemented:
542
542
  config key; the store is never changed by selection. Rendered on **every
543
543
  provider request** (`context_with_system`), so a mid-run `harness_mutate`
544
544
  shows up on the very next request.
545
- - **Classifier features (pi ≥ 0.99, opt-in)**: `"classifier": { "model": … }`
546
- enables (1) classifier-confirmed dedupe — candidate merge pairs confirmed by
545
+ - **Classifier features (pi ≥ 0.99, opt-in)**: a classifier resolves via
546
+ `"classifier": { "model": … }`, or — when `model` is unset — via
547
+ auto-discovery (default on, `"classifier": { "auto": false }` opts out)
548
+ of the hosted `github-copilot/microsoft-decision-1` that pi ≥ 1.5.1 ships
549
+ with GitHub Copilot auth. A resolved classifier enables (1)
550
+ classifier-confirmed dedupe — candidate merge pairs confirmed by
547
551
  one batched yes/no call (errors fall back to the rule-based plan) — and (2)
548
552
  the auto-refine gate `"autoRefine": { "gate": true }`, which skips a cadenced
549
553
  refine when the trajectory holds no durable correction.
@@ -131,7 +131,7 @@ export async function handleAutoRefineTurnEnd(pi, event, ctx) {
131
131
  }
132
132
  // Opt-in classifier gate: cheap yes/no before spending the refine.
133
133
  if (config.autoRefine?.gate) {
134
- const classify = buildClassify(ctx, config.classifier?.model);
134
+ const classify = buildClassify(ctx, config.classifier);
135
135
  if (classify) {
136
136
  const evidence = gatherEvidence(ctx, DEFAULT_LOOKBACK_TURNS);
137
137
  const res = await classify(buildGateRequest(evidence));
@@ -65,14 +65,36 @@ interface ClassifierModelLike {
65
65
  * it then degrades to its no-classifier behavior.
66
66
  */
67
67
  export declare function resolveClassifierModel(registry: RegistryLike | undefined, configured?: string): ClassifierModelLike | undefined;
68
+ /**
69
+ * The auto-discovered default classifier: a hosted bool/score classifier that
70
+ * pi ≥ 1.5.1 ships with GitHub Copilot authentication (billed to the user's
71
+ * Copilot plan; no local server, no extra API key). Keeping this a single
72
+ * known-good id — not "first classifier in the catalog" — makes discovery
73
+ * deterministic and reviewable; widen it only deliberately.
74
+ */
75
+ export declare const DEFAULT_CLASSIFIER = "github-copilot/microsoft-decision-1";
76
+ /**
77
+ * Auto-discovery fallback for buildClassify: the hosted default above when the
78
+ * registry lists it, otherwise undefined (degrade to no-classifier behavior).
79
+ */
80
+ export declare function discoverClassifierModel(registry: RegistryLike | undefined): ClassifierModelLike | undefined;
68
81
  /** Build the ClassifyFn adapter over a resolved classifier model. */
69
82
  export declare function makeClassifyFn(registry: RegistryLike, model: ClassifierModelLike, signal?: AbortSignal): ClassifyFn;
83
+ /** Structural slice of the normalized `classifier` config (config.ts). */
84
+ export interface ClassifierConfigSlice {
85
+ model?: string | undefined;
86
+ /** Default true (opt-out): when `model` is unset, fall back to the hosted
87
+ * default classifier when the registry lists one. */
88
+ auto?: boolean;
89
+ }
70
90
  /**
71
91
  * Resolve the ClassifyFn for a session from config + ctx, or undefined.
72
92
  * The single construction point shared by refine (ProposeInput.classify) and
73
- * the auto-refine gate.
93
+ * the auto-refine gate. An explicit `classifier.model` always wins; with
94
+ * `auto` (default) an unset model falls back to discovery (see
95
+ * discoverClassifierModel).
74
96
  */
75
- export declare function buildClassify(ctx: ExtensionContext, configuredModel?: string): ClassifyFn | undefined;
97
+ export declare function buildClassify(ctx: ExtensionContext, classifier?: ClassifierConfigSlice): ClassifyFn | undefined;
76
98
  /**
77
99
  * The auto-refine gate question: did the recent trajectory contain a durable,
78
100
  * reusable correction worth a /refine pass? Pure builder — unit-testable.
package/dist/classify.js CHANGED
@@ -10,6 +10,15 @@
10
10
  // 2. dedupe confirmation (proposer.ts): a precision filter on candidate merge
11
11
  // pairs — see classifyConfirmPairs().
12
12
  //
13
+ // Model resolution has two tiers (buildClassify): an explicitly configured
14
+ // `classifier.model` always wins; when it is unset, auto-discovery (default on,
15
+ // `classifier.auto: false` opts out) falls back to ONE known hosted classifier —
16
+ // github-copilot/microsoft-decision-1, shipped by pi ≥ 1.5.1 with GitHub
17
+ // Copilot auth — so the gated paths work with zero setup for Copilot users.
18
+ // Discovery deliberately never picks a local llama.cpp entry: the catalog can
19
+ // list one while no server is running, and an unreachable classifier is worse
20
+ // than none (the gates would soft-fail every time).
21
+ //
13
22
  // The pi-ai classifier shapes (ClassifierContext/ClassifierQuestion/…) are kept
14
23
  // OUT of the public proposer interface: ClassifyFn below is a minimal structural
15
24
  // contract so proposers stay testable without pi runtime types.
@@ -35,6 +44,21 @@ export function resolveClassifierModel(registry, configured) {
35
44
  return cm.id === configured || `${cm.provider}/${cm.id}` === configured;
36
45
  }) ?? undefined);
37
46
  }
47
+ /**
48
+ * The auto-discovered default classifier: a hosted bool/score classifier that
49
+ * pi ≥ 1.5.1 ships with GitHub Copilot authentication (billed to the user's
50
+ * Copilot plan; no local server, no extra API key). Keeping this a single
51
+ * known-good id — not "first classifier in the catalog" — makes discovery
52
+ * deterministic and reviewable; widen it only deliberately.
53
+ */
54
+ export const DEFAULT_CLASSIFIER = "github-copilot/microsoft-decision-1";
55
+ /**
56
+ * Auto-discovery fallback for buildClassify: the hosted default above when the
57
+ * registry lists it, otherwise undefined (degrade to no-classifier behavior).
58
+ */
59
+ export function discoverClassifierModel(registry) {
60
+ return resolveClassifierModel(registry, DEFAULT_CLASSIFIER);
61
+ }
38
62
  /** Build the ClassifyFn adapter over a resolved classifier model. */
39
63
  export function makeClassifyFn(registry, model, signal) {
40
64
  const label = `${model.provider}/${model.id}`;
@@ -102,12 +126,17 @@ export function makeClassifyFn(registry, model, signal) {
102
126
  /**
103
127
  * Resolve the ClassifyFn for a session from config + ctx, or undefined.
104
128
  * The single construction point shared by refine (ProposeInput.classify) and
105
- * the auto-refine gate.
129
+ * the auto-refine gate. An explicit `classifier.model` always wins; with
130
+ * `auto` (default) an unset model falls back to discovery (see
131
+ * discoverClassifierModel).
106
132
  */
107
- export function buildClassify(ctx, configuredModel) {
133
+ export function buildClassify(ctx, classifier) {
108
134
  const registry = ctx.modelRegistry;
109
- const model = resolveClassifierModel(registry, configuredModel);
110
- if (!registry || !model)
135
+ if (!registry)
136
+ return undefined;
137
+ const model = resolveClassifierModel(registry, classifier?.model) ??
138
+ (classifier?.auto !== false ? discoverClassifierModel(registry) : undefined);
139
+ if (!model)
111
140
  return undefined;
112
141
  return makeClassifyFn(registry, model, ctx.signal);
113
142
  }
package/dist/config.d.ts CHANGED
@@ -72,12 +72,18 @@ export interface HarnessConfig {
72
72
  * DEFAULT_REFINE_NOOP_SKIP (3); 0 disables the history gate. */
73
73
  refineNoOpSkip?: number;
74
74
  };
75
- /** Classifier model for the cheap gated paths (pi ≥ 0.99): "provider/id" or
75
+ /** Classifier for the cheap gated paths (pi ≥ 0.99): "provider/id" or
76
76
  * a bare id of a classifier catalog entry (e.g. "typesafe/jev-latest" or a
77
- * local llama.cpp classifier). When unset or unresolvable, every classifier
78
- * feature degrades to its no-classifier behavior. */
77
+ * local llama.cpp classifier). When `model` is unset or unresolvable,
78
+ * `auto` (default true) falls back to a hosted zero-setup classifier when
79
+ * the registry lists one — pi ≥ 1.5.1 ships
80
+ * "github-copilot/microsoft-decision-1" with GitHub Copilot auth. When
81
+ * nothing resolves, every classifier feature degrades to its no-classifier
82
+ * behavior. */
79
83
  classifier?: {
80
84
  model?: string | undefined;
85
+ /** Default true (opt-out). Set false to require an explicit `model`. */
86
+ auto?: boolean;
81
87
  };
82
88
  /** Virtual-model binding policy (pi ≥ 0.99). Default "virtual". */
83
89
  virtualBinding?: VirtualBinding;
package/dist/config.js CHANGED
@@ -50,7 +50,7 @@ export const DEFAULT_CONFIG = {
50
50
  omitStaleDrafts: true,
51
51
  refineNoOpSkip: DEFAULT_REFINE_NOOP_SKIP,
52
52
  },
53
- classifier: { model: undefined },
53
+ classifier: { model: undefined, auto: true },
54
54
  virtualBinding: "virtual",
55
55
  proposer: "steering",
56
56
  outcomeImportance: { enabled: false, bump: DEFAULT_REF_BUMP },
@@ -113,6 +113,7 @@ function mergeConfig(over) {
113
113
  model: typeof over.classifier?.model === "string" && over.classifier.model
114
114
  ? over.classifier.model
115
115
  : undefined,
116
+ auto: over.classifier?.auto !== false,
116
117
  },
117
118
  virtualBinding: over.virtualBinding === "physical" ? "physical" : "virtual",
118
119
  proposer: over.proposer ?? "steering",
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { preview, renderListReport, selectListItems, type ListOptions, type List
13
13
  export { DEFAULT_INJECTION, estimateTokens, normalizeInjection, selectForInjection, type InjectionConfig, type NormalizedInjection, type SelectionResult, } from "./select.js";
14
14
  export { branchEntries, isVirtualModel, physicalKeyFromBranch, resolveBindingKey, VIRTUAL_MODEL_API, } from "./vmodel.js";
15
15
  export { buildDetailGuide, buildNudge, reminderState, type ReminderState, } from "./remind.js";
16
- export { buildGateRequest, gateDecision, type ClassifyBoolAnswer, type ClassifyBoolQuestion, type ClassifyBoolResult, type ClassifyFn, } from "./classify.js";
16
+ export { DEFAULT_CLASSIFIER, buildGateRequest, discoverClassifierModel, gateDecision, type ClassifyBoolAnswer, type ClassifyBoolQuestion, type ClassifyBoolResult, type ClassifyFn, type ClassifierConfigSlice, } from "./classify.js";
17
17
  export { AUTO_REFINE_ENTRY, buildOmissionDrafts, buildRefineDraft, turnEndedBadly, type OmissionDraft, type ProjectedLike, } from "./auto-refine.js";
18
18
  export { messageText } from "./refine.js";
19
19
  export { deepMergeConfig, readConfigRaw, saveConfig, type SaveConfigResult, } from "./config.js";
package/dist/index.js CHANGED
@@ -51,8 +51,9 @@ export { branchEntries, isVirtualModel, physicalKeyFromBranch, resolveBindingKey
51
51
  // richer /harness status) share the same copy source.
52
52
  export { buildDetailGuide, buildNudge, reminderState, } from "./remind.js";
53
53
  // Classifier seam (pi ≥ 0.99, 0.12.0): the minimal structural ClassifyFn
54
- // contract proposers see, plus the gate builders (pure, testable).
55
- export { buildGateRequest, gateDecision, } from "./classify.js";
54
+ // contract proposers see, plus the gate builders (pure, testable) and the
55
+ // auto-discovery default (0.22.0: hosted fallback for unset classifier.model).
56
+ export { DEFAULT_CLASSIFIER, buildGateRequest, discoverClassifierModel, gateDecision, } from "./classify.js";
56
57
  // Auto-refine boundary helpers (pi ≥ 0.87, 0.12.0–0.13.0): the steering draft,
57
58
  // the stale-draft context-edit omissions, and the shared aborted/error-turn
58
59
  // predicate (pi BoundaryState.outcome). Re-exported for tests and companion
package/dist/inject.d.ts CHANGED
@@ -30,6 +30,14 @@ export declare function resetInjectionStats(): void;
30
30
  * defining the marker when any such item is surfaced; `priority` is honored
31
31
  * inside the selection (trusted items win budget contention).
32
32
  *
33
+ * DETERMINISM CONTRACT: for an unchanged store + config the returned block is
34
+ * byte-identical (stable item ids, no timestamps, no random ordering — pinned
35
+ * by test/model-binding.test.ts). This is what lets pi ≥ 1.5.1 Anthropic message
36
+ * threads `continue` a conversation: the thread-prefix hash covers the system
37
+ * message, so an unchanged harness rides the server-side thread (and the
38
+ * warmed prompt cache) while any harness change mismatches the hash and pi
39
+ * correctly falls back to a full resend. Never add volatile content here.
40
+ *
33
41
  * Note: every non-empty render folds into the session injection stats
34
42
  * (InjectionStats above; /harness status surfaces them). Tests that render
35
43
  * directly reset with resetInjectionStats().
package/dist/inject.js CHANGED
@@ -51,6 +51,14 @@ export function resetInjectionStats() {
51
51
  * defining the marker when any such item is surfaced; `priority` is honored
52
52
  * inside the selection (trusted items win budget contention).
53
53
  *
54
+ * DETERMINISM CONTRACT: for an unchanged store + config the returned block is
55
+ * byte-identical (stable item ids, no timestamps, no random ordering — pinned
56
+ * by test/model-binding.test.ts). This is what lets pi ≥ 1.5.1 Anthropic message
57
+ * threads `continue` a conversation: the thread-prefix hash covers the system
58
+ * message, so an unchanged harness rides the server-side thread (and the
59
+ * warmed prompt cache) while any harness change mismatches the hash and pi
60
+ * correctly falls back to a full resend. Never add volatile content here.
61
+ *
54
62
  * Note: every non-empty render folds into the session injection stats
55
63
  * (InjectionStats above; /harness status surfaces them). Tests that render
56
64
  * directly reset with resetInjectionStats().
package/dist/refine.js CHANGED
@@ -103,7 +103,7 @@ async function buildProposeInput(ctx, evidence, lookback, options) {
103
103
  complete: buildComplete(ctx),
104
104
  // Inject the classifier adapter when `classifier.model` is configured and
105
105
  // resolvable (pi ≥ 0.99) — the dedupe proposer uses it to confirm merges.
106
- classify: buildClassify(ctx, config.classifier?.model),
106
+ classify: buildClassify(ctx, config.classifier),
107
107
  ownerKey,
108
108
  lessons,
109
109
  evidence,
package/dist/remind.js CHANGED
@@ -151,9 +151,9 @@ export const DETAIL_GUIDES = [
151
151
  ' "remindRefine": { "enabled": true, "everyTurns": 25, "detailEvery": 4 },',
152
152
  ' "autoRefine": { "enabled": true, "everyTurns": 100, "gate": true, "commit": false },',
153
153
  ' "outcomeImportance": { "enabled": true, "bump": 0.03 },',
154
- ' "classifier": { "model": "typesafe/jev-latest" }',
154
+ ' "classifier": { "auto": true }',
155
155
  "}",
156
- `Guidance: gate (needs classifier.model) spends one cheap yes/no question before each auto-refine, so cadence becomes signal. Durable writes are autonomous in this config: with autoImport on, the layers re-export on every store change (that is what makes /refine output survive into new sessions); commit only adds a flush at each auto-run and matters when autoImport is off. Prefer autoImport off + manual /harness export until you trust the refinements, then opt in. This nudge fires every ${state.everyTurns} completed turns and shows a guide every ${state.detailEvery}th reminder (about every ${state.everyTurns * state.detailEvery} completed turns).`,
156
+ `Guidance: gate spends one cheap yes/no question before each auto-refine, so cadence becomes signal. With classifier.auto (default true) and no explicit classifier.model, the hosted github-copilot/microsoft-decision-1 resolves automatically on pi >= 1.5.1 with Copilot auth; otherwise set classifier.model to any classifier catalog entry (e.g. a local llama.cpp classifier). Durable writes are autonomous in this config: with autoImport on, the layers re-export on every store change (that is what makes /refine output survive into new sessions); commit only adds a flush at each auto-run and matters when autoImport is off. Prefer autoImport off + manual /harness export until you trust the refinements, then opt in. This nudge fires every ${state.everyTurns} completed turns and shows a guide every ${state.detailEvery}th reminder (about every ${state.everyTurns * state.detailEvery} completed turns).`,
157
157
  ].join("\n"),
158
158
  ];
159
159
  /** Rotation slot for the ordinal-th detailed reminder (1-based, pure). */
package/dist/setup.js CHANGED
@@ -99,7 +99,7 @@ export const PRESETS = {
99
99
  title: "durable sync + awareness reminders",
100
100
  description: "autoImport on (refinements survive into new sessions) paired with the importRemind awareness reminders.",
101
101
  notes: [
102
- "Gate-ready: to make refinement signal-driven later, set classifier.model + autoRefine.gate (pi >= 0.99). This preset leaves the gate off.",
102
+ "Gate-ready: to make refinement signal-driven later, set autoRefine.gate (pi >= 0.99; a classifier resolves automatically on pi >= 1.5.1 with Copilot, else set classifier.model). This preset leaves the gate off.",
103
103
  ],
104
104
  deltas: recommendedDeltas(),
105
105
  },
package/dist/status.js CHANGED
@@ -125,11 +125,15 @@ function applicableHints(state, config, impact) {
125
125
  // Classifier/gate not fully configured → the cheapest activation lever is
126
126
  // invisible to the user. `classifier.model` ALONE changes nothing gating-wise
127
127
  // (the gate needs `autoRefine.gate: true` too — review #27), so the hint
128
- // stays until both are set and the copy names both keys.
129
- if (!config.classifier?.model || config.autoRefine?.gate !== true) {
128
+ // stays until the gate is on and the copy names the keys. Since auto-
129
+ // discovery (0.22.0) a classifier may resolve with `classifier.model` unset
130
+ // (hosted default on pi ≥ 1.5.1 + Copilot auth), so the copy treats the
131
+ // model as optional.
132
+ if (config.autoRefine?.gate !== true ||
133
+ (!config.classifier?.model && config.classifier?.auto === false)) {
130
134
  hints.push({
131
135
  id: "classifier-gate",
132
- text: 'the auto-refine gate is available: set `classifier.model` and `autoRefine: { "gate": true }` in harness.json so cadenced refines skip when nothing durable happened',
136
+ text: 'the auto-refine gate is available: set `autoRefine: { "gate": true }` in harness.json so cadenced refines skip when nothing durable happened (a classifier resolves automatically on pi ≥ 1.5.1 with GitHub Copilot; otherwise also set `classifier.model`)',
133
137
  });
134
138
  }
135
139
  // Zero citations ever and the loop is off → the outcome half of the fitness
@@ -71,12 +71,17 @@
71
71
  },
72
72
  "classifier": {
73
73
  "type": "object",
74
- "description": "Classifier model for the cheap gated paths.",
74
+ "description": "Classifier for the cheap gated paths.",
75
75
  "additionalProperties": true,
76
76
  "properties": {
77
77
  "model": {
78
78
  "type": "string",
79
79
  "description": "\"provider/id\" or a bare id of a classifier catalog entry (e.g. \"typesafe/jev-latest\" or a local llama.cpp classifier). Unset/unresolvable → every classifier feature degrades to its no-classifier behavior."
80
+ },
81
+ "auto": {
82
+ "type": "boolean",
83
+ "default": true,
84
+ "description": "When model is unset (default), fall back to a hosted zero-setup classifier when the registry lists one — pi ≥ 1.5.1 ships github-copilot/microsoft-decision-1 with GitHub Copilot auth. Set false to require an explicit model."
80
85
  }
81
86
  }
82
87
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-continual-harness",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Online self-improvement layer for pi. A unified, in-trajectory harness-state store (prompt notes, memory, skill descriptions, sub-agent specs) with a manual /refine that proposes evidence-backed structured CRUD deltas. Composes with pi-reflect (offline) and pi-mem (storage); owns only the online optimizer layer. Inspired by Continual Harness (arXiv 2605.09998) and ACE (arXiv 2510.04618).",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -44,9 +44,9 @@
44
44
  },
45
45
  "devDependencies": {
46
46
  "@biomejs/biome": "^2.6.4",
47
- "@earendil-works/pi-ai": "^1.5.0",
48
- "@earendil-works/pi-coding-agent": "^1.5.0",
49
- "@earendil-works/pi-schema": "^1.5.0",
47
+ "@earendil-works/pi-ai": "^1.5.2",
48
+ "@earendil-works/pi-coding-agent": "^1.5.2",
49
+ "@earendil-works/pi-schema": "^1.5.2",
50
50
  "@types/node": "^22.0.0",
51
51
  "@vitest/coverage-v8": "^3.2.7",
52
52
  "typebox": ">=1.0.0",