@fro.bot/systematic 3.4.0 → 3.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.
@@ -156,6 +156,16 @@ export type ReceiptReadbackSeedResult = {
156
156
  };
157
157
  export declare function digestReceiptIdentity(domain: ReceiptDigestDomain, identity: string, sessionSalt: Uint8Array): string;
158
158
  export declare function validateReceiptMarker(input: unknown): ReceiptMarkerValidation;
159
+ /**
160
+ * Filters a raw marker array, retaining only markers that belong to the given
161
+ * registrationDigest. Markers that cannot be parsed (malformed, unknown schema,
162
+ * etc.) are retained as-is so that downstream callers can fail-closed on them.
163
+ *
164
+ * Use this before extractReceiptReadbackSeed / foldReceiptReadback when the
165
+ * shared metadata array may contain markers from multiple concurrent
166
+ * registrations (e.g. dual-registration in a single OpenCode session).
167
+ */
168
+ export declare function filterMarkersByRegistration(markers: readonly unknown[], ownRegistrationDigest: string): unknown[];
159
169
  export declare function extractReceiptReadbackSeed(inputs: readonly unknown[]): ReceiptReadbackSeedResult;
160
170
  export declare function projectReceiptMintMarker(receipt: unknown, sessionSalt: Uint8Array): ReceiptMintMarker | undefined;
161
171
  export declare function projectReceiptConsumptionMarker(receipt: unknown, transitionDigest: string, timestamp?: number): ReceiptConsumeMarker | undefined;
@@ -26,8 +26,11 @@
26
26
  "workflow_guard": {
27
27
  "$ref": "#/definitions/__schema57"
28
28
  },
29
- "skills_as_commands": {
29
+ "pi_subagents": {
30
30
  "$ref": "#/definitions/__schema61"
31
+ },
32
+ "skills_as_commands": {
33
+ "$ref": "#/definitions/__schema72"
31
34
  }
32
35
  },
33
36
  "additionalProperties": false,
@@ -1368,16 +1371,178 @@
1368
1371
  "type": "boolean"
1369
1372
  },
1370
1373
  "__schema61": {
1374
+ "default": {
1375
+ "categories": {},
1376
+ "agents": {}
1377
+ },
1378
+ "description": "Pi-native pi-subagents export field overlays (thinking, max_turns, tools, skills). Category values apply first; per-agent values override. No model field — model stays in the categories/agents overlay.",
1379
+ "examples": [
1380
+ {
1381
+ "categories": {
1382
+ "research": {
1383
+ "thinking": "high"
1384
+ }
1385
+ },
1386
+ "agents": {
1387
+ "repo-research-analyst": {
1388
+ "max_turns": 10
1389
+ }
1390
+ }
1391
+ }
1392
+ ],
1393
+ "allOf": [
1394
+ {
1395
+ "$ref": "#/definitions/__schema62"
1396
+ }
1397
+ ]
1398
+ },
1399
+ "__schema62": {
1400
+ "type": "object",
1401
+ "properties": {
1402
+ "categories": {
1403
+ "default": {},
1404
+ "description": "Per-category pi-subagents export overlays keyed by category name",
1405
+ "examples": [
1406
+ {
1407
+ "research": {
1408
+ "thinking": "high"
1409
+ }
1410
+ },
1411
+ {}
1412
+ ],
1413
+ "allOf": [
1414
+ {
1415
+ "$ref": "#/definitions/__schema63"
1416
+ }
1417
+ ]
1418
+ },
1419
+ "agents": {
1420
+ "default": {},
1421
+ "description": "Per-agent pi-subagents export overlays keyed by bundled agent name",
1422
+ "examples": [
1423
+ {
1424
+ "repo-research-analyst": {
1425
+ "max_turns": 10
1426
+ }
1427
+ },
1428
+ {}
1429
+ ],
1430
+ "allOf": [
1431
+ {
1432
+ "$ref": "#/definitions/__schema71"
1433
+ }
1434
+ ]
1435
+ }
1436
+ },
1437
+ "additionalProperties": false
1438
+ },
1439
+ "__schema63": {
1440
+ "type": "object",
1441
+ "propertyNames": {
1442
+ "type": "string"
1443
+ },
1444
+ "additionalProperties": {
1445
+ "description": "Per-category pi-subagents export overlay (Pi-native fields only; no model)",
1446
+ "examples": [
1447
+ {
1448
+ "thinking": "medium"
1449
+ }
1450
+ ],
1451
+ "allOf": [
1452
+ {
1453
+ "$ref": "#/definitions/__schema70"
1454
+ }
1455
+ ]
1456
+ }
1457
+ },
1458
+ "__schema64": {
1459
+ "type": "string",
1460
+ "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max"],
1461
+ "description": "pi-subagents reasoning effort level for exported persona frontmatter",
1462
+ "examples": ["off", "medium", "high"],
1463
+ "trust": "project-or-higher"
1464
+ },
1465
+ "__schema65": {
1466
+ "type": "integer",
1467
+ "minimum": 0,
1468
+ "maximum": 9007199254740991,
1469
+ "description": "pi-subagents maximum turns for a delegated persona (0 = unlimited)",
1470
+ "examples": [0, 10, 25],
1471
+ "trust": "any"
1472
+ },
1473
+ "__schema66": {
1474
+ "type": "string",
1475
+ "minLength": 1,
1476
+ "description": "pi-subagents comma-selector tool string (built-ins, */all/none, or extension selectors)",
1477
+ "examples": ["*", "read,grep,glob", "none"],
1478
+ "trust": "project-or-higher"
1479
+ },
1480
+ "__schema67": {
1481
+ "anyOf": [
1482
+ {
1483
+ "$ref": "#/definitions/__schema68"
1484
+ },
1485
+ {
1486
+ "$ref": "#/definitions/__schema69"
1487
+ }
1488
+ ],
1489
+ "description": "pi-subagents skills selector: true (all) or a comma-separated list of skill names",
1490
+ "examples": [true, "ce:plan,ce:review"],
1491
+ "trust": "project-or-higher"
1492
+ },
1493
+ "__schema68": {
1494
+ "type": "boolean",
1495
+ "const": true
1496
+ },
1497
+ "__schema69": {
1498
+ "type": "string",
1499
+ "minLength": 1
1500
+ },
1501
+ "__schema70": {
1502
+ "type": "object",
1503
+ "properties": {
1504
+ "thinking": {
1505
+ "$ref": "#/definitions/__schema64"
1506
+ },
1507
+ "max_turns": {
1508
+ "$ref": "#/definitions/__schema65"
1509
+ },
1510
+ "tools": {
1511
+ "$ref": "#/definitions/__schema66"
1512
+ },
1513
+ "skills": {
1514
+ "$ref": "#/definitions/__schema67"
1515
+ }
1516
+ },
1517
+ "additionalProperties": false,
1518
+ "description": "Per-agent pi-subagents export overlay (Pi-native fields only; no model)",
1519
+ "examples": [
1520
+ {
1521
+ "thinking": "high",
1522
+ "max_turns": 10
1523
+ }
1524
+ ]
1525
+ },
1526
+ "__schema71": {
1527
+ "type": "object",
1528
+ "propertyNames": {
1529
+ "type": "string"
1530
+ },
1531
+ "additionalProperties": {
1532
+ "$ref": "#/definitions/__schema70"
1533
+ }
1534
+ },
1535
+ "__schema72": {
1371
1536
  "default": true,
1372
1537
  "description": "Register skills discovered from user/project skill directories (OpenCode config and other agent-harness-standard locations) as slash commands. Default true.",
1373
1538
  "examples": [true, false],
1374
1539
  "allOf": [
1375
1540
  {
1376
- "$ref": "#/definitions/__schema62"
1541
+ "$ref": "#/definitions/__schema73"
1377
1542
  }
1378
1543
  ]
1379
1544
  },
1380
- "__schema62": {
1545
+ "__schema73": {
1381
1546
  "type": "boolean"
1382
1547
  }
1383
1548
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.4.0",
4
- "description": "Structured engineering workflows for OpenCode",
3
+ "version": "3.5.0",
4
+ "description": "Compound-engineering loops for OpenCode, Pi, and Claude Code",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
7
7
  "main": "./dist/index.js",
@@ -92,9 +92,10 @@
92
92
  "devDependencies": {
93
93
  "@biomejs/biome": "2.5.5",
94
94
  "@earendil-works/pi-coding-agent": "0.80.10",
95
- "@opencode-ai/plugin": "1.18.5",
96
- "@opencode-ai/sdk": "1.18.5",
95
+ "@opencode-ai/plugin": "1.18.6",
96
+ "@opencode-ai/sdk": "1.18.6",
97
97
  "@semantic-release/exec": "7.1.0",
98
+ "@tintinweb/pi-subagents": "0.14.3",
98
99
  "@types/bun": "latest",
99
100
  "@types/js-yaml": "4.0.9",
100
101
  "@types/node": "24.13.3",
@@ -4,14 +4,14 @@ Evidence registry: see [`HARNESSES.md`](../../../HARNESSES.md).
4
4
 
5
5
  | Capability | Mechanism | Status | Fallback |
6
6
  |---|---|---|---|
7
- | Subagent delegation | `systematic_delegate({agent, task})` with bundled personas | degraded; execution is sequential only | Dispatch sequentially in dependency order or do the work inline |
7
+ | Subagent delegation | Bounded built-in delegate via `systematic_delegate({agent, task})`; optional mature delegation via [pi-subagents](https://github.com/tintinweb/pi-subagents) through opt-in persona export | built-in: degraded (sequential only); pi-subagents path: outside Systematic's bounded-delegate guarantees | Dispatch sequentially in dependency order or do the work inline |
8
8
  | Blocking user interaction | No native blocking tool | degraded | Present numbered options in chat and wait |
9
9
  | Task tracking | No native task-tracking mechanism | unavailable | Maintain a visible task list in responses |
10
10
  | Skill loading | `systematic_skill` tool or Pi-native skill activation | supported | Read the skill instructions listed by the active harness |
11
11
 
12
12
  ## Invocation examples
13
13
 
14
- ### Subagent delegation
14
+ ### Subagent delegation (built-in)
15
15
 
16
16
  ```typescript
17
17
  systematic_delegate({
@@ -20,6 +20,32 @@ systematic_delegate({
20
20
  })
21
21
  ```
22
22
 
23
+ `systematic_delegate` is sequential, capped at 20 turns, depth-1, and spawns its child with `noExtensions: true`. The `noExtensions` guarantee bounds `systematic_delegate`'s own recursion — it does not bound end-to-end delegation depth across a combined pi-subagents + Systematic path.
24
+
25
+ ### Optional: pi-subagents delegation
26
+
27
+ Export Systematic personas for use with [pi-subagents](https://github.com/tintinweb/pi-subagents) (parallel/multi-model delegation). All writes are opt-in; nothing is exported at extension load.
28
+
29
+ Tested against pi-subagents v0.14.3 (verified contract as of July 29, 2026). Versions outside the tested range are unsupported but nonfatal.
30
+
31
+ Exact CLI form: `systematic pi-subagents <preview|export|refresh|cleanup> --scope project|global`. `--scope` is optional and defaults to `project`.
32
+
33
+ ```bash
34
+ systematic pi-subagents preview [--scope project|global]
35
+ systematic pi-subagents export [--scope project|global]
36
+ systematic pi-subagents refresh [--scope project|global]
37
+ systematic pi-subagents cleanup [--scope project|global]
38
+ ```
39
+
40
+ - `project` (default) targets `<cwd>/.pi/agents/`.
41
+ - `global` targets `$PI_CODING_AGENT_DIR/agents/`, or `~/.pi/agent/agents/` if `$PI_CODING_AGENT_DIR` is unset.
42
+
43
+ The pi-subagents delegation path is **outside Systematic's bounded-delegate guarantees** and governed by pi-subagents' own configuration. `systematic_delegate` remains the bounded default.
44
+
45
+ `export`/`refresh`/`cleanup` hold an exclusive per-root mutation lock and fail closed if any path component between the selected scope's anchor and the agents directory is a symlink or not a directory. A manifest (`.systematic-personas.json`) tracks ownership by filename and content hash; cleanup and stale-file removal only delete a file whose on-disk content still matches its recorded hash, refusing otherwise. Manifest hashes are drift evidence, not a cryptographic authenticity guarantee.
46
+
47
+ Systematic's own config (`systematic.json`/`.jsonc`) is the durable source of truth for exported personas; the generated files and their manifest are a disposable projection that `export`/`refresh`/`cleanup` regenerate or remove, and `refresh` intentionally overwrites manifest-owned generated files that diverge from current config — run `preview` first to see what would change. See the [pi-subagents pairing guide](https://fro.bot/systematic/guides/pi-subagents/) for the config precedence, trust boundaries, and a canonical example.
48
+
23
49
  ### Blocking user interaction
24
50
 
25
51
  ```text