@zerwiz/ymir 0.1.16 → 0.1.18
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/.agents/config/app-repos.yaml +38 -0
- package/.claude/settings.json +31 -0
- package/.codex/hooks.json +43 -0
- package/.cursor/hooks.json +33 -0
- package/.pi/extensions/README.md +39 -0
- package/.pi/extensions/gna-pi-watch.ts +15 -0
- package/.pi/extensions/lib/ro-assistant-layout.ts +96 -0
- package/.pi/extensions/lib/ro-operational-user-layout.ts +145 -0
- package/.pi/extensions/lib/ro-visibility.ts +99 -0
- package/.pi/extensions/lib/ro-working-ship.ts +243 -0
- package/.pi/extensions/lib/rodd-operational-input.ts +62 -0
- package/.pi/extensions/lib/skuld-branch-dispatch.ts +252 -0
- package/.pi/extensions/lib/skuld-branch-model-picker.ts +77 -0
- package/.pi/extensions/lib/vordr-sessionstart-supervisor.mjs +48 -0
- package/.pi/extensions/ro.ts +11 -0
- package/.pi/extensions/skuld-branch-supervision.ts +11 -0
- package/.pi/extensions/syn-turnend-guard.ts +11 -0
- package/.pi/mcp.json +16 -0
- package/.pi/mcp.json.example +11 -0
- package/.pi/npm/.gitignore +2 -0
- package/.pi/settings.json +8 -0
- package/.pi/shared/extensions/gna-pi-watch.ts +750 -0
- package/.pi/shared/extensions/herdr-agent-state.ts +257 -0
- package/.pi/shared/extensions/open-editor.ts +509 -0
- package/.pi/shared/extensions/ro.ts +504 -0
- package/.pi/shared/extensions/skuld-branch-supervision.ts +1535 -0
- package/.pi/shared/extensions/syn-turnend-guard.ts +683 -0
- package/.pi/shared/extensions/todo.ts +133 -0
- package/.pi/shared/extensions/ymir-subagents.ts +287 -0
- package/.pi/shared/extensions/ymir-well.ts +130 -0
- package/CHANGELOG.md +23 -0
- package/assets/Ymir.md +4654 -0
- package/assets/healer.html +717 -0
- package/assets/icon-family/family-sheet.png +0 -0
- package/assets/icon-family/hlidskjalf.svg +1 -0
- package/assets/icon-family/sessrumnir.svg +1 -0
- package/assets/icon-family/smidja.svg +1 -0
- package/assets/icon-family/ymir.svg +1 -0
- package/assets/mimirswell.html +880 -0
- package/assets/mock/README.md +16 -0
- package/assets/mock/feeds.ts +175 -0
- package/assets/mock/mock.ts +408 -0
- package/assets/reference/docs/agent-control.md +122 -0
- package/assets/reference/docs/apodex/Appdex_as_Orchestrator_Planner_Reviewer_Assessment.md +176 -0
- package/assets/reference/docs/apodex/Final Report(1).md +198 -0
- package/assets/reference/docs/apodex/Final Report(2).md +54 -0
- package/assets/reference/docs/apodex/Final Report(3).md +40 -0
- package/assets/reference/docs/apodex/Final Report(4).md +234 -0
- package/assets/reference/docs/apodex/Final Report(5).md +13 -0
- package/assets/reference/docs/apodex/Final Report.md +82 -0
- package/assets/reference/docs/architecture.md +392 -0
- package/assets/reference/docs/arm-pretool-check.md +247 -0
- package/assets/reference/docs/calm-mode-feasibility.md +541 -0
- package/assets/reference/docs/calm.md +59 -0
- package/assets/reference/docs/captain-hold-lifecycle.md +96 -0
- package/assets/reference/docs/cd-guard.md +165 -0
- package/assets/reference/docs/cmux-backend.md +133 -0
- package/assets/reference/docs/codex-app-backend.md +57 -0
- package/assets/reference/docs/configuration.md +924 -0
- package/assets/reference/docs/documentation-audiences.json +468 -0
- package/assets/reference/docs/documentation-audiences.md +28 -0
- package/assets/reference/docs/examples/crew-dispatch.json +26 -0
- package/assets/reference/docs/examples/process-event-extension/file-signal.mjs +96 -0
- package/assets/reference/docs/examples/process-event-extension/firstmate-extension.json +15 -0
- package/assets/reference/docs/examples/watched-tools.json +24 -0
- package/assets/reference/docs/examples/wedge-alarm +22 -0
- package/assets/reference/docs/extension-bindings.md +237 -0
- package/assets/reference/docs/fm-test-isolation-proof.json +37 -0
- package/assets/reference/docs/fm-test-isolation-proof.md +149 -0
- package/assets/reference/docs/fm-test-portable-shards.md +118 -0
- package/assets/reference/docs/gitlab-merge-watch.md +275 -0
- package/assets/reference/docs/herdr-backend.md +346 -0
- package/assets/reference/docs/orca-backend.md +84 -0
- package/assets/reference/docs/pi-supervision-branch-poster.svg +125 -0
- package/assets/reference/docs/pi-supervision-branch.md +96 -0
- package/assets/reference/docs/plans/agentic-engineering-workflow.md +395 -0
- package/assets/reference/docs/plans/agentic-factory-implementation-plan.md +615 -0
- package/assets/reference/docs/plans/command-factory-enhancement-plan.md +420 -0
- package/assets/reference/docs/plans/phase-1-layer3-program-design.md +134 -0
- package/assets/reference/docs/plans/phase-2-vertical-slices.md +100 -0
- package/assets/reference/docs/plans/phase-3-measurable-goals.md +106 -0
- package/assets/reference/docs/plans/phase-4-context-budget.md +106 -0
- package/assets/reference/docs/plans/phase-5-pre-mortem-confidence.md +100 -0
- package/assets/reference/docs/plans/phase-6-incident-to-agent.md +109 -0
- package/assets/reference/docs/remote-secondmates.md +268 -0
- package/assets/reference/docs/scripts.md +146 -0
- package/assets/reference/docs/sessionstart-nudge.md +115 -0
- package/assets/reference/docs/subagent-guard.md +383 -0
- package/assets/reference/docs/supervision-protocols/claude.md +27 -0
- package/assets/reference/docs/supervision-protocols/codex.md +16 -0
- package/assets/reference/docs/supervision-protocols/cursor.md +31 -0
- package/assets/reference/docs/supervision-protocols/grok.md +39 -0
- package/assets/reference/docs/supervision-protocols/opencode.md +17 -0
- package/assets/reference/docs/supervision-protocols/pi.md +33 -0
- package/assets/reference/docs/supervision-protocols/unknown.md +13 -0
- package/assets/reference/docs/tmux-backend.md +115 -0
- package/assets/reference/docs/trace-context.md +117 -0
- package/assets/reference/docs/turnend-guard.md +170 -0
- package/assets/reference/docs/verification/dispatch-auth.md +204 -0
- package/assets/reference/docs/verification/muse.md +221 -0
- package/assets/reference/docs/verification/process-event-sources.md +208 -0
- package/assets/reference/docs/verification/public-followup.md +119 -0
- package/assets/reference/docs/verification/runtime-backends.md +1022 -0
- package/assets/reference/docs/verification/stow-memory.md +53 -0
- package/assets/reference/docs/verification/supervision.md +534 -0
- package/assets/reference/docs/verification/trace-context.md +31 -0
- package/assets/reference/docs/voice-relay.md +295 -0
- package/assets/reference/docs/watcher-continuity.md +119 -0
- package/assets/reference/docs/wedge-alarm.md +39 -0
- package/assets/reference/docs/zellij-backend.md +114 -0
- package/assets/reference/index.html +1172 -0
- package/assets/reference/skills/afk/SKILL.md +241 -0
- package/assets/reference/skills/ahoy/SKILL.md +56 -0
- package/assets/reference/skills/ask-user-authority/SKILL.md +56 -0
- package/assets/reference/skills/bearings/SKILL.md +161 -0
- package/assets/reference/skills/bearings/assets/board-template.html +731 -0
- package/assets/reference/skills/bootstrap-diagnostics/SKILL.md +68 -0
- package/assets/reference/skills/captain-hold-lifecycle/SKILL.md +54 -0
- package/assets/reference/skills/decision-hold-lifecycle/SKILL.md +15 -0
- package/assets/reference/skills/diagnostic-reasoning/SKILL.md +53 -0
- package/assets/reference/skills/firstmate-codexapp/SKILL.md +110 -0
- package/assets/reference/skills/firstmate-codexapp/agents/openai.yaml +4 -0
- package/assets/reference/skills/firstmate-coding-guidelines/SKILL.md +127 -0
- package/assets/reference/skills/firstmate-orca/SKILL.md +92 -0
- package/assets/reference/skills/fmx-respond/SKILL.md +283 -0
- package/assets/reference/skills/harness-adapters/SKILL.md +95 -0
- package/assets/reference/skills/harness-adapters/references/common/control-and-recovery.md +37 -0
- package/assets/reference/skills/harness-adapters/references/common/dispatch.md +32 -0
- package/assets/reference/skills/harness-adapters/references/common/model-and-effort.md +42 -0
- package/assets/reference/skills/harness-adapters/references/common/primary-hooks.md +40 -0
- package/assets/reference/skills/harness-adapters/references/harness/claude.md +55 -0
- package/assets/reference/skills/harness-adapters/references/harness/codex.md +43 -0
- package/assets/reference/skills/harness-adapters/references/harness/cursor.md +75 -0
- package/assets/reference/skills/harness-adapters/references/harness/grok.md +69 -0
- package/assets/reference/skills/harness-adapters/references/harness/kimi.md +51 -0
- package/assets/reference/skills/harness-adapters/references/harness/muse.md +70 -0
- package/assets/reference/skills/harness-adapters/references/harness/opencode.md +42 -0
- package/assets/reference/skills/harness-adapters/references/harness/pi.md +56 -0
- package/assets/reference/skills/process-event-sources/SKILL.md +137 -0
- package/assets/reference/skills/project-management/SKILL.md +92 -0
- package/assets/reference/skills/quota-array-dispatch/SKILL.md +131 -0
- package/assets/reference/skills/secondmate-provisioning/SKILL.md +254 -0
- package/assets/reference/skills/stow/SKILL.md +309 -0
- package/assets/reference/skills/stuck-crewmate-recovery/SKILL.md +54 -0
- package/assets/reference/skills/updatefirstmate/SKILL.md +64 -0
- package/assets/skills/README.md +5 -0
- package/assets/yggdrasil.html +649 -0
- package/assets/ymir-banner-01.png +0 -0
- package/assets/ymir-banner-02.png +0 -0
- package/assets/ymir-banner-03.png +0 -0
- package/assets/ymir-banner-04.png +0 -0
- package/assets/ymir-banner-05.png +0 -0
- package/assets/ymir-banner-06.png +0 -0
- package/assets/ymir-emblem-darksteel.svg +63 -0
- package/assets/ymir-emblem-forged.svg +55 -0
- package/assets/ymir-emblem-slate.svg +55 -0
- package/assets/ymir-mark-algiz-anvil.svg +9 -0
- package/assets/ymir-stave.svg +53 -0
- package/assets/ymir.html +563 -0
- package/bin/ymir-install.sh +6 -1
- package/data/learnings.md +33 -0
- package/data/local-models.md +34 -0
- package/data/operator.md +15 -0
- package/data/projects.md +28 -0
- package/data/realm.md +1 -0
- package/deploy/Containerfile +27 -0
- package/deploy/README.md +104 -0
- package/deploy/compose/compose.yaml +45 -0
- package/deploy/env.example +30 -0
- package/deploy/quadlet/ymir.container +57 -0
- package/package.json +10 -8
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Orca runtime backend
|
|
2
|
+
|
|
3
|
+
Orca is an experimental macOS backend in which the Orca app owns both the task worktree and terminal endpoint.
|
|
4
|
+
The crewmate harness remains the agent process launched inside that endpoint.
|
|
5
|
+
Firstmate agents load [`firstmate-orca`](../.agents/skills/firstmate-orca/SKILL.md) before operating or recovering this backend.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
Pick Orca when you already use the Orca macOS app and want Orca-managed worktrees and terminals instead of Treehouse plus a session multiplexer.
|
|
10
|
+
Orca is macOS-only, explicit-only, and does not support secondmate spawns.
|
|
11
|
+
|
|
12
|
+
Prerequisites:
|
|
13
|
+
|
|
14
|
+
- `/Applications/Orca.app` installed, running, and ready.
|
|
15
|
+
- The `orca` CLI, installed with `brew install orca`.
|
|
16
|
+
- The universal harness and toolchain requirements in [`configuration.md`](configuration.md#toolchain).
|
|
17
|
+
|
|
18
|
+
Select Orca with local `config/backend` containing `orca`, `FM_BACKEND=orca` for one launch, or an explicit request to Firstmate.
|
|
19
|
+
It is never auto-detected.
|
|
20
|
+
|
|
21
|
+
Before any spawn mutates repository state, Firstmate requires `orca status --json` to report `reachable=true` and `state="ready"`.
|
|
22
|
+
The first task for a project registers that repository with `orca repo add --path` when needed.
|
|
23
|
+
No manual repository registration is required.
|
|
24
|
+
|
|
25
|
+
Open the Orca app to watch a task's terminal.
|
|
26
|
+
Routine supervision uses the recorded endpoint through `bin/fm-peek.sh <id>` and `FM_HOME=<home> bin/fm-send.sh <id> '<text>'`.
|
|
27
|
+
Enter and Ctrl-C are supported; Escape is not.
|
|
28
|
+
|
|
29
|
+
## Task shape and metadata
|
|
30
|
+
|
|
31
|
+
Each task has one Orca-managed git worktree and one Orca terminal.
|
|
32
|
+
`fm-spawn.sh` does not call Treehouse for Orca tasks.
|
|
33
|
+
The normal isolation and unlanded-work refusal rules still apply.
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
backend=orca
|
|
37
|
+
window=fm-<id>
|
|
38
|
+
terminal=<orca terminal handle>
|
|
39
|
+
orca_worktree_id=<orca worktree id>
|
|
40
|
+
worktree=<absolute Orca worktree path>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`window=` remains the caller-facing Firstmate alias.
|
|
44
|
+
`terminal=` and `orca_worktree_id=` are the backend authority used by operation and cleanup paths.
|
|
45
|
+
|
|
46
|
+
## Current lifecycle and safety
|
|
47
|
+
|
|
48
|
+
Spawn registers the repository, creates an independent worktree, reuses only the verified `result.terminal.handle` returned by Orca or creates a terminal explicitly, installs harness hooks, records metadata, and launches the selected harness.
|
|
49
|
+
Exact command flags and response parsing are owned by `bin/backends/orca.sh` and script help.
|
|
50
|
+
|
|
51
|
+
`fm-peek.sh` reads with `orca terminal read`.
|
|
52
|
+
An ordinary metadata-routed `fm-send.sh` text steer becomes a durable steering-inbox record, and only its best-effort constant doorbell passes through Orca's submit machinery.
|
|
53
|
+
On the typed plane, `fm-send.sh` verifies composer clearance through the fleet-wide classifier in `bin/fm-composer-lib.sh`, retrying Enter without retyping when a slash popup first fills an argument placeholder.
|
|
54
|
+
The composer read is one bounded tail of the live terminal and never pages backward into scrollback, so a stale startup banner cannot compete with the bottom-anchored composer.
|
|
55
|
+
A bare shell row is `unknown`, not an empty agent composer, and plain-text captures degrade a glyph row carrying trailing text to `unknown` rather than a false `pending`.
|
|
56
|
+
The watcher has no native Orca busy signal, so each harness adapter's semantic lifecycle supplies worker state.
|
|
57
|
+
Grok alone retains its isolated rendered-tail fallback.
|
|
58
|
+
|
|
59
|
+
Cleanup keeps all shared Firstmate safety checks.
|
|
60
|
+
A scout still requires its report and completed decision inventory.
|
|
61
|
+
A ship still refuses dirty or unlanded work.
|
|
62
|
+
Before release, cleanup resolves the recorded Orca worktree id and verifies its path matches the recorded worktree path.
|
|
63
|
+
A missing, unreadable, or mismatched identity preserves metadata and stops rather than deleting anything.
|
|
64
|
+
After those checks, Firstmate closes the exact terminal and releases the exact worktree with Orca's worktree command.
|
|
65
|
+
It never raw-deletes an Orca worktree.
|
|
66
|
+
|
|
67
|
+
## Active limits
|
|
68
|
+
|
|
69
|
+
- Orca is macOS-only and explicit-only.
|
|
70
|
+
- The app must be running and report ready.
|
|
71
|
+
- Secondmate spawns are unsupported.
|
|
72
|
+
- Escape is unsupported.
|
|
73
|
+
- Orca exposes no stable CLI version or protocol marker, so readiness is the compatibility gate rather than a version floor.
|
|
74
|
+
- Only the verified terminal-handle and worktree result fields are accepted; speculative response shapes are rejected.
|
|
75
|
+
|
|
76
|
+
## Regression entry points
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
tests/fm-backend-orca.test.sh
|
|
80
|
+
tests/fm-backend.test.sh
|
|
81
|
+
tests/fm-bootstrap.test.sh
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
[`verification/runtime-backends.md`](verification/runtime-backends.md#orca) records the real readiness and response-shape smoke.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 860" width="1200" height="860" role="img" aria-labelledby="poster-title poster-desc">
|
|
3
|
+
<title id="poster-title">Multi-brain agent architecture</title>
|
|
4
|
+
<desc id="poster-desc">One agent. Two branches of attention. Events are commits. A git-graph poster of one fix: silent notes merge with zero turns; only the merge that matters wakes the main brain.</desc>
|
|
5
|
+
<defs>
|
|
6
|
+
<pattern id="poster-grid" width="36" height="36" patternUnits="userSpaceOnUse">
|
|
7
|
+
<path d="M 36 0 L 0 0 0 36" fill="none" stroke="#8CAAE6" stroke-opacity="0.06" stroke-width="1"/>
|
|
8
|
+
</pattern>
|
|
9
|
+
</defs>
|
|
10
|
+
<rect width="1200" height="860" fill="#0D1321"/>
|
|
11
|
+
<rect width="1200" height="860" fill="url(#poster-grid)"/>
|
|
12
|
+
<rect x="0.5" y="0.5" width="1199" height="859" fill="none" stroke="#94B4FF" stroke-opacity="0.20" stroke-width="1"/>
|
|
13
|
+
<g font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">
|
|
14
|
+
<text x="48" y="56" fill="#E6EDF3" font-size="36" font-weight="700">Multi-brain agent architecture</text>
|
|
15
|
+
<text x="48" y="86" fill="#8CA3C7" font-size="18">One agent. Two branches of attention. Events are commits.</text>
|
|
16
|
+
<text x="1152" y="56" text-anchor="end" fill="#8CA3C7" fill-opacity="0.7" font-size="14">fig. 1 - firstmate</text>
|
|
17
|
+
</g>
|
|
18
|
+
<g transform="translate(0 100)" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">
|
|
19
|
+
<title id="mb-title">Multi-brain agent architecture drawn as a git graph: one fix's lifecycle. The worker finishes and CI runs (silent note), the captain's merge-when-green instruction is cherry-picked down, a flaky test is rerun (silent note), and when CI goes green the supervision brain merges and one note wakes the main brain.</title>
|
|
20
|
+
<defs>
|
|
21
|
+
<marker id="ah-cyan" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7.5" markerHeight="7.5" orient="auto-start-reverse">
|
|
22
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#56C8FF"></path>
|
|
23
|
+
</marker>
|
|
24
|
+
<marker id="ah-amber" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7.5" markerHeight="7.5" orient="auto-start-reverse">
|
|
25
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#FFB454"></path>
|
|
26
|
+
</marker>
|
|
27
|
+
<marker id="ah-time" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
28
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#8CA3C7"></path>
|
|
29
|
+
</marker>
|
|
30
|
+
<linearGradient id="merge-up" x1="0" y1="1" x2="1" y2="0">
|
|
31
|
+
<stop offset="0" stop-color="#56C8FF"></stop>
|
|
32
|
+
<stop offset="1" stop-color="#FFB454"></stop>
|
|
33
|
+
</linearGradient>
|
|
34
|
+
</defs>
|
|
35
|
+
|
|
36
|
+
<!-- ================= LANE LINES ================= -->
|
|
37
|
+
<line x1="280" y1="210" x2="1140" y2="210" stroke="#FFB454" stroke-width="3" stroke-linecap="round"></line>
|
|
38
|
+
<path d="M 310 221 C 310 380, 330 490, 420 490" fill="none" stroke="#56C8FF" stroke-width="3" stroke-linecap="round"></path>
|
|
39
|
+
<line x1="420" y1="490" x2="1140" y2="490" stroke="#56C8FF" stroke-width="3" stroke-linecap="round"></line>
|
|
40
|
+
|
|
41
|
+
<!-- ================= LANE LABELS ================= -->
|
|
42
|
+
<text x="64" y="200" fill="#FFB454" font-size="24" font-weight="700">MAIN SESSION</text>
|
|
43
|
+
<text x="64" y="230" fill="#E6EDF3" opacity="0.6" font-size="16">talks with the captain</text>
|
|
44
|
+
<text x="64" y="480" fill="#56C8FF" font-size="24" font-weight="700">SUPERVISION SESSION</text>
|
|
45
|
+
<text x="64" y="510" fill="#E6EDF3" opacity="0.6" font-size="16">handles the routine,</text>
|
|
46
|
+
<text x="64" y="534" fill="#E6EDF3" opacity="0.6" font-size="16">decides to wake main brain or not</text>
|
|
47
|
+
|
|
48
|
+
<!-- ================= CROSS-LANE ARCS (all arrowed, drawn under chips) ================= -->
|
|
49
|
+
<path id="arc-quiet-1" d="M 460 479 C 490 400, 520 300, 545 221" fill="none" stroke="#56C8FF" stroke-width="2.5" stroke-dasharray="1 7" stroke-linecap="round" opacity="0.6" marker-end="url(#ah-cyan)"></path>
|
|
50
|
+
<path id="arc-cherry" d="M 620 221 C 645 300, 675 400, 700 479" fill="none" stroke="#FFB454" stroke-width="2.5" stroke-dasharray="2 8" stroke-linecap="round" opacity="0.8" marker-end="url(#ah-amber)"></path>
|
|
51
|
+
<path id="arc-quiet-2" d="M 760 479 C 785 400, 810 300, 830 221" fill="none" stroke="#56C8FF" stroke-width="2.5" stroke-dasharray="1 7" stroke-linecap="round" opacity="0.6" marker-end="url(#ah-cyan)"></path>
|
|
52
|
+
<path id="arc-wake" d="M 940 479 C 975 410, 1015 300, 1038 226" fill="none" stroke="url(#merge-up)" stroke-width="4" stroke-linecap="round" marker-end="url(#ah-amber)"></path>
|
|
53
|
+
|
|
54
|
+
<!-- ================= EXAMPLE CHIPS ON THE ARCS ================= -->
|
|
55
|
+
<g id="chip-quiet-1">
|
|
56
|
+
<title>A silent note: nothing needs the captain yet</title>
|
|
57
|
+
<rect x="385" y="312" width="230" height="36" rx="6" fill="#0D1321" stroke="#56C8FF" stroke-width="1.5" opacity="0.95"></rect>
|
|
58
|
+
<text x="500" y="336" text-anchor="middle" fill="#B9E5FF" font-size="16">“PR opened, CI running”</text>
|
|
59
|
+
</g>
|
|
60
|
+
<g id="chip-cherry">
|
|
61
|
+
<title>The captain's own instruction, cherry-picked down as context</title>
|
|
62
|
+
<rect x="530" y="377" width="260" height="36" rx="6" fill="#0D1321" stroke="#FFB454" stroke-width="1.5" opacity="0.95"></rect>
|
|
63
|
+
<text x="660" y="401" text-anchor="middle" fill="#FFD9A0" font-size="16">you: “merge when CI green”</text>
|
|
64
|
+
</g>
|
|
65
|
+
<g id="chip-quiet-2">
|
|
66
|
+
<title>A silent note: the supervision brain already fixed it</title>
|
|
67
|
+
<rect x="665" y="272" width="270" height="36" rx="6" fill="#0D1321" stroke="#56C8FF" stroke-width="1.5" opacity="0.95"></rect>
|
|
68
|
+
<text x="800" y="296" text-anchor="middle" fill="#B9E5FF" font-size="16">“flaky test: reran, passed”</text>
|
|
69
|
+
</g>
|
|
70
|
+
<g id="chip-wake">
|
|
71
|
+
<title>The outcome the captain asked for: this note wakes the main brain</title>
|
|
72
|
+
<rect x="865" y="342" width="250" height="38" rx="6" fill="#0D1321" stroke="#FFB454" stroke-width="2"></rect>
|
|
73
|
+
<text x="990" y="367" text-anchor="middle" fill="#FFB454" font-size="17" font-weight="600">“merged: your fix is in”</text>
|
|
74
|
+
</g>
|
|
75
|
+
|
|
76
|
+
<!-- ================= MAIN COMMITS ================= -->
|
|
77
|
+
<g id="main-commits">
|
|
78
|
+
<title>The captain's conversation, commit by commit</title>
|
|
79
|
+
<circle cx="310" cy="210" r="11" fill="#0D1321" stroke="#FFB454" stroke-width="3.5"></circle>
|
|
80
|
+
<circle cx="620" cy="210" r="11" fill="#0D1321" stroke="#FFB454" stroke-width="3.5"></circle>
|
|
81
|
+
<circle cx="1120" cy="210" r="11" fill="#0D1321" stroke="#FFB454" stroke-width="3.5"></circle>
|
|
82
|
+
</g>
|
|
83
|
+
<!-- silent-note landings -->
|
|
84
|
+
<g id="silent-landings">
|
|
85
|
+
<title>Notes merged silently into the conversation: no one is woken</title>
|
|
86
|
+
<circle cx="545" cy="210" r="7" fill="#0D1321" stroke="#56C8FF" stroke-width="3" opacity="0.85"></circle>
|
|
87
|
+
<circle cx="830" cy="210" r="7" fill="#0D1321" stroke="#56C8FF" stroke-width="3" opacity="0.85"></circle>
|
|
88
|
+
</g>
|
|
89
|
+
<text x="545" y="174" text-anchor="middle" fill="#56C8FF" opacity="0.8" font-size="13.5">silent merge. zero turns</text>
|
|
90
|
+
<text x="830" y="174" text-anchor="middle" fill="#56C8FF" opacity="0.8" font-size="13.5">silent merge. zero turns</text>
|
|
91
|
+
<!-- the merge commit that wakes the main brain -->
|
|
92
|
+
<g id="merge-commit">
|
|
93
|
+
<title>Merged and surfaced: the main brain is woken exactly once</title>
|
|
94
|
+
<circle cx="1040" cy="210" r="13" fill="#FFB454"></circle>
|
|
95
|
+
<circle cx="1040" cy="210" r="21" fill="none" stroke="#FFB454" stroke-width="1.5" opacity="0.5"></circle>
|
|
96
|
+
<path d="M 1019 189 A 30 30 0 0 1 1061 189" fill="none" stroke="#FFB454" stroke-width="2.5" stroke-linecap="round" opacity="0.8"></path>
|
|
97
|
+
<path d="M 1011 181 A 41 41 0 0 1 1069 181" fill="none" stroke="#FFB454" stroke-width="2.5" stroke-linecap="round" opacity="0.5"></path>
|
|
98
|
+
</g>
|
|
99
|
+
<text x="1040" y="148" text-anchor="middle" fill="#FFB454" font-size="18" font-weight="700">wakes the main brain</text>
|
|
100
|
+
|
|
101
|
+
<!-- ================= BRANCH COMMITS + EVENT EXAMPLES ================= -->
|
|
102
|
+
<g id="branch-commits">
|
|
103
|
+
<title>One fix's routine events, handled on the supervision brain</title>
|
|
104
|
+
<circle cx="460" cy="490" r="10" fill="#0D1321" stroke="#56C8FF" stroke-width="3.5"></circle>
|
|
105
|
+
<circle cx="760" cy="490" r="10" fill="#0D1321" stroke="#56C8FF" stroke-width="3.5"></circle>
|
|
106
|
+
<circle cx="940" cy="490" r="10" fill="#0D1321" stroke="#56C8FF" stroke-width="3.5"></circle>
|
|
107
|
+
</g>
|
|
108
|
+
<!-- cherry-pick landing -->
|
|
109
|
+
<circle cx="700" cy="490" r="8" fill="#0D1321" stroke="#FFB454" stroke-width="3"></circle>
|
|
110
|
+
|
|
111
|
+
<line x1="460" y1="503" x2="460" y2="530" stroke="#56C8FF" stroke-width="1.5" opacity="0.35"></line>
|
|
112
|
+
<text x="460" y="554" text-anchor="middle" fill="#E6EDF3" opacity="0.75" font-size="16">worker finishes the fix</text>
|
|
113
|
+
<line x1="760" y1="503" x2="760" y2="530" stroke="#56C8FF" stroke-width="1.5" opacity="0.35"></line>
|
|
114
|
+
<text x="760" y="554" text-anchor="middle" fill="#E6EDF3" opacity="0.75" font-size="16">a flaky test fails</text>
|
|
115
|
+
<line x1="940" y1="503" x2="940" y2="530" stroke="#56C8FF" stroke-width="1.5" opacity="0.35"></line>
|
|
116
|
+
<text x="940" y="554" text-anchor="middle" fill="#E6EDF3" opacity="0.75" font-size="16">CI goes green</text>
|
|
117
|
+
|
|
118
|
+
<!-- ================= TIME AXIS ================= -->
|
|
119
|
+
<line x1="1010" y1="660" x2="1110" y2="660" stroke="#8CA3C7" stroke-width="2" stroke-linecap="round" marker-end="url(#ah-time)"></line>
|
|
120
|
+
<text x="1128" y="665" fill="#8CA3C7" font-size="15">time</text>
|
|
121
|
+
|
|
122
|
+
<!-- ================= MORAL ================= -->
|
|
123
|
+
<text x="560" y="700" text-anchor="middle" fill="#E6EDF3" opacity="0.6" font-size="18">Routine merges back silently. Only what needs you wakes the main brain.</text>
|
|
124
|
+
</g>
|
|
125
|
+
</svg>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Pi supervision branch
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
The poster is the visual of the idea.
|
|
6
|
+
This document stays the owner and the contract.
|
|
7
|
+
|
|
8
|
+
Fleet supervision on the Pi primary harness runs on a second, persistent conversation - the supervision branch - inside the same `pi` process as the captain's chat.
|
|
9
|
+
Supervision is default-on: once a Pi primary session owns this home's fleet lock, the branch handles eligible task-local rows from ordinary actionable wakes plus heartbeat scans that the cheap bash-level scan flags as possibly captain-relevant, then merges each outcome back by appending a short note to the captain conversation's tail.
|
|
10
|
+
Ordinary main-only rows remain on main even when eligible task-local rows share their queue.
|
|
11
|
+
An unresolvable row makes the scan unsafe and returns the whole wake to main, and every watcher-failure alarm also stays on main.
|
|
12
|
+
Only captain-relevant branch outcomes open a turn on main; the generated [Pi supervision protocol](supervision-protocols/pi.md) requires MAIN to produce the captain-visible response in that turn, while Pi never separately prints or renders a captain-facing merge note.
|
|
13
|
+
The design source is the captain-approved forked-supervision architecture board, a captain-private fleet record (a self-contained HTML explainer with the measured cache and judgment evidence); this document records the shape it landed as, and the delivering PR cites the board artifact itself.
|
|
14
|
+
|
|
15
|
+
This feature is Pi-only by construction and changes nothing anywhere else:
|
|
16
|
+
|
|
17
|
+
- The branch lives in `.pi/extensions/fm-branch-supervision.ts`, which only a Pi primary ever loads; no other harness gains or loses behavior.
|
|
18
|
+
- The bash-side additions (leases, the outcome store, session-start recovery) are inert in a home that never runs the branch: no lease files exist, no actor variable is set, every guard passes silently, and no new state appears (`tests/fm-branch-supervision.test.sh` holds this).
|
|
19
|
+
- It does not change which harness is primary and never moves a home to Pi.
|
|
20
|
+
|
|
21
|
+
## Components and their owners
|
|
22
|
+
|
|
23
|
+
- Wake dispatch: `.pi/extensions/fm-primary-pi-watch.ts` stays the dispatcher; `.pi/extensions/lib/fm-branch-dispatch.ts` owns the offer handshake and row eligibility, while [`watcher-continuity.md`](watcher-continuity.md#per-actor-acknowledgement) owns the per-actor consume contract.
|
|
24
|
+
A successful row grant transfers ownership of exactly the currently branch-eligible rows to the branch; a check-kind triggering close (merge-confirmation polls, Relay mentions, credential/auth failures, and every other legitimately main-only class) is never offered even when other rows are eligible, no acceptor (extension absent, away mode, branch broken) keeps today's wake-to-main path for that close, and watcher-failure alarms always go to main because only main can repair the watcher cycle.
|
|
25
|
+
A fleet-wide heartbeat keeps its own all-or-nothing rule (see "Heartbeat routing" below): it takes every branch-ownable unread row or none of them.
|
|
26
|
+
A co-present main-owned check row no longer defers that review to main, because it is not fleet context the branch is missing and main is woken for it on its own triggering close.
|
|
27
|
+
- The branch itself: `.pi/extensions/fm-branch-supervision.ts` creates and reopens the persistent branch session, serializes wakes, mirrors dialog, and merges outcomes.
|
|
28
|
+
It checks the current extension generation and `state/.lock` ownership before each guarded branch side effect so replacement or lock loss cannot let an old continuation mutate the new session.
|
|
29
|
+
Every path that cannot reach a working branch falls back to delivering the wake to main - a broken branch degrades to today's behavior, never to a lost wake.
|
|
30
|
+
- Branch model and effort selection: the same extension registers `/supervision-model`, which picks the branch's model and then its reasoning effort, and applies both at the branch-session creation boundary; [configuration.md](configuration.md#pi-supervision-branch-model-and-effort-configsupervision-branch-model-configsupervision-branch-effort) owns the operator-facing schema and behavior.
|
|
31
|
+
- Branch system prompt: `bin/fm-branch-prompt.sh`; its header owns the byte-stable-prefix contract (no timestamps, no fleet snapshot, no per-wake content).
|
|
32
|
+
- Outcome store: `bin/fm-branch-outcome.sh`; its header owns the append-only format and the read cursor.
|
|
33
|
+
Outcomes are written to the store before any note is handed to Pi, and rows that never reach that handoff replay once through the next locked session-start digest.
|
|
34
|
+
- Consistency: `bin/fm-lease-lib.sh` owns the per-task lease contract, the main-only role partition, and the deliberate CONFUSED-AGENT-GRADE threat model these guards target (captain-decided; adversarial-grade separation is out of scope and tracked as follow-up design work); `bin/fm-lease.sh` is the command surface.
|
|
35
|
+
The guards are wired into `fm-send.sh`, `fm-control.sh`, and `fm-teardown.sh` (overlap, lease-checked, with claim serialization retained through the mutation) and `fm-pr-merge.sh`, `fm-merge-local.sh`, and `fm-spawn.sh` (main-owned, branch refused; a relaunch through `fm-control` stays branch-legal recovery).
|
|
36
|
+
- Autonomy: supervision is default-on for every task once a Pi primary session owns the fleet lock (docs/configuration.md "Pi supervision branch"); no captain grant file is required.
|
|
37
|
+
A fleet-wide heartbeat is separately eligible only when every non-check row in the unread queue is a heartbeat row or a resolvable task-local row (see "Heartbeat routing" below); every other fleet-wide or unresolvable wake, and every watcher-failure alarm, stays on main.
|
|
38
|
+
The branch recomputes eligibility immediately before prompting the branch to drain and publishes the exact eligible row set to `state/.branch-eligible-rows` through `writeEligibleRowsSnapshot`.
|
|
39
|
+
A newly-arrived main-owned row observed at that recheck no longer defers the whole queue to main: it is excluded from the eligible set, so whatever else is currently eligible still reaches the branch, and the main-owned row stays queued for main's own later drain.
|
|
40
|
+
[`watcher-continuity.md`](watcher-continuity.md#per-actor-acknowledgement) owns the consume-side guarantee that neither actor can present or acknowledge the other's claim.
|
|
41
|
+
Heartbeat keeps its own all-or-nothing recheck over the rows it can claim: it takes every branch-ownable unread row or none of them, and an unresolvable task-local row still defers the whole review to main.
|
|
42
|
+
A producer can still append a row in the instant between that final check and drain startup; this accepted residual follows the confused-agent-grade boundary above rather than claiming adversarial queue isolation.
|
|
43
|
+
Away mode and a broken branch keep today's wake-to-main behavior.
|
|
44
|
+
|
|
45
|
+
## How the branch knows what the captain said
|
|
46
|
+
|
|
47
|
+
Main's captain and assistant text - never tool calls, tool results, operational injections, or the branch's own merged notes - is mirrored into the branch as read-only `fm-main-mirror` messages.
|
|
48
|
+
The idle path mirrors at main's turn end.
|
|
49
|
+
At `before_agent_start`, Pi's authoritative prompt is staged verbatim before SessionManager persists that user entry, so the complete current captain message precedes any branch wake accepted after that boundary; the later persisted copy is suppressed and older dialog entries remain bounded.
|
|
50
|
+
The mirror cursor is durable (`state/.branch-mirror-cursor`), so a restart replays only the not-yet-mirrored dialog from main's session file, and a replacement main session re-anchors from its start.
|
|
51
|
+
The branch prompt frames mirrored text as context for judgment, never as instructions addressed to the branch; an authorization addressed to main (for example "you may merge when green") does not relax the branch's role limits.
|
|
52
|
+
|
|
53
|
+
## Two-stage noise filter
|
|
54
|
+
|
|
55
|
+
Stage one is unchanged: the bash watcher absorbs everything provably fine at zero token cost.
|
|
56
|
+
Stage two is the branch's verdict on each handled event, reported through its `fm_branch_report` tool: `routine` merges without a follow-up turn, while `captain` merges with exactly one follow-up turn.
|
|
57
|
+
The generated [Pi supervision protocol](supervision-protocols/pi.md) requires MAIN to produce the captain-visible response in the one follow-up turn a `captain` verdict opens, so its merge note is delivered silently and never printed or rendered in Pi.
|
|
58
|
+
Because Pi gives the model only a custom message's `content`, that silent note normally carries both a relay instruction and the `branch-outcome` operational kind owned by `bin/fm-operational-input.sh` inside its own text.
|
|
59
|
+
This self-description lets main distinguish a new supervision outcome from its own earlier captain-facing answer; without it, main can mistake the outcome for that answer and lose the outcome while deciding how to handle it.
|
|
60
|
+
The generated [Pi supervision protocol](supervision-protocols/pi.md) owns main's event-ownership and conversational-treatment instructions for merged outcomes.
|
|
61
|
+
If envelope encoding fails, the captain-facing note degrades to the same runtime instruction as plain text rather than losing the outcome or opening another turn.
|
|
62
|
+
A no-change heartbeat outcome explicitly reported with `task=fleet` and `silent=true` is also delivered silently with no rendered note, while every other `routine` outcome stays rendered with its sailboat prefix.
|
|
63
|
+
The branch prompt owns the verdict criteria, including its unconditional explicit-request rule; unsolicited routine outcomes remain routine sailboat notes, unchanged fleet reviews remain silent, and doubt escalates.
|
|
64
|
+
Main can read the durable outcome store on demand through its `fm_branch_outcomes` tool.
|
|
65
|
+
|
|
66
|
+
## Heartbeat routing
|
|
67
|
+
|
|
68
|
+
The cheap bash-level heartbeat scan absorbs a genuinely no-op pass before it reaches Pi, unchanged from before.
|
|
69
|
+
Only a scan already flagged as possibly captain-relevant emits the bare `heartbeat` wake; `.pi/extensions/fm-primary-pi-watch.ts` flags that offer `heartbeat: true`, and the branch accepts it without a project only when every non-check row observed in the unread-queue eligibility check is either heartbeat-kind or a resolvable task-local signal or stale event.
|
|
70
|
+
|
|
71
|
+
A heartbeat is never vetoed or ridden into main by a co-present check row.
|
|
72
|
+
A check row is permanently main-owned in every mode: it is excluded from what the branch may claim and left queued for main, which is woken for it on that check's own watcher cycle, so nothing starves by being left behind.
|
|
73
|
+
Deferring the fleet review to main merely because some unrelated merge poll or Relay mention happened to be sitting unread put a routine review in the captain's chat for a reason that had nothing to do with the fleet, and that coupling is gone.
|
|
74
|
+
What all-or-nothing still guarantees is unchanged: the branch takes every branch-ownable unread row or none of them, and an unresolvable task-local row, an unknown row kind, or an unreadable queue still defers the whole review to main.
|
|
75
|
+
The branch runs its normal operating procedure for the wake (`bin/fm-branch-prompt.sh` "Handling a wake") and performs the deeper fleet review that main previously performed.
|
|
76
|
+
A review that found literally nothing worth reporting uses verdict `routine`, `task=fleet`, and `silent=true` so it has no rendered note, while a fleet-wide routine action omits `silent` and keeps its rendered sailboat note.
|
|
77
|
+
Only a captain-worthy finding reports verdict `captain` and opens a main turn.
|
|
78
|
+
Every other fleet-wide or unresolvable wake - including watcher-failure alarms, which are never offered to the branch - keeps today's wake-to-main path.
|
|
79
|
+
|
|
80
|
+
## Cost model and the byte-stable prefix
|
|
81
|
+
|
|
82
|
+
The captain accepted the normal provider prompt-caching strategy: a byte-identical branch prefix generated once per firstmate version, the same tool set in the same order on every request, and one shared `prompt_cache_key` per home for all branch sessions (set in a `before_provider_request` hook, and only for providers whose requests already carry that field); main keeps its own per-session key.
|
|
83
|
+
Budget roughly 60% cache hits on a fresh branch session's first call and 95% on later calls of the persistent session; reuse is best-effort, never guaranteed.
|
|
84
|
+
The branch can also run on a cheaper model and a shallower reasoning effort than main, both pinned with the Pi `/supervision-model` command; [configuration.md](configuration.md#pi-supervision-branch-model-and-effort-configsupervision-branch-model-configsupervision-branch-effort) owns those pins' operator-facing schema and unpinned behavior.
|
|
85
|
+
No caching machinery beyond this exists, deliberately: any later dynamic content in the branch prefix silently removes most of the cache benefit, which is why `bin/fm-branch-prompt.sh`'s header is the contract's single owner and `tests/fm-branch-supervision.test.sh` pins the output to byte identity.
|
|
86
|
+
|
|
87
|
+
## Away mode
|
|
88
|
+
|
|
89
|
+
Away mode carries over unchanged: while `state/.afk` exists the away daemon owns supervision, and the branch declines every wake offer for the duration.
|
|
90
|
+
What is new is only the attended path: outside away mode, the branch absorbs the routine majority that previously interrupted the captain's conversation, applying the same escalation etiquette the daemon applies while away.
|
|
91
|
+
|
|
92
|
+
## Verification
|
|
93
|
+
|
|
94
|
+
Portable regressions: `tests/fm-pi-branch-extension.test.sh` (dispatch, default-on eligibility, main-only classification, requested-versus-unsolicited outcome delivery, pre-turn-end complete-current-request mirroring, fleet-event ownership, main outcome access, eligible-row claim lifecycle, partial pre-drain recheck, fallback, filter, model-visible captain-outcome typing and plain-instruction fallback, cache key, persistence, model pin and searchable picker, effort pin), `tests/fm-branch-supervision.test.sh` (prompt stability, store append-only, leases, guards, non-branch-home invariance), the branch-offer, heartbeat-offer, heartbeat-not-ridden-by-a-check, and main-only-check-class tests in `tests/fm-pi-watch-extension.test.sh`, the recovery test in `tests/fm-session-start.test.sh`, and the per-actor consume regression in `tests/fm-wake-queue.test.sh`.
|
|
95
|
+
Live guard: `FM_PI_BRANCH_LIVE_E2E=1 tests/fm-pi-branch-live-e2e.test.sh` exercises the real installed Pi SDK's custom-message conversion and branch-session surfaces with no user credentials and no provider call; run it after every Pi upgrade and record the dated result in [docs/verification/runtime-backends.md](verification/runtime-backends.md).
|
|
96
|
+
The strict typecheck in `tests/fm-pi-primary-types.test.sh` pins the extension against the installed Pi package.
|