@awebai/oats 0.29.4 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -6
- package/bin/oats.mjs +194 -50
- package/docs/capabilities.md +160 -171
- package/docs/capability-manifest.schema.json +6 -11
- package/docs/configuration.md +213 -64
- package/docs/design/2026-09-16-knowledge-capability-contract.md +36 -50
- package/docs/design/2026-09-23-workspace-module-contracts.md +377 -544
- package/docs/design/2026-09-26-okf-knowledge-operations.md +132 -357
- package/docs/design/2026-09-27-team-model-v2.md +97 -117
- package/docs/design/2026-09-28-automations-trust.md +38 -0
- package/docs/design/2026-09-28-soul-launch-preference.md +63 -0
- package/docs/design/HISTORY.md +65 -0
- package/docs/design/README.md +23 -54
- package/docs/desktop-cli-api.md +1787 -1777
- package/docs/desktop.md +30 -91
- package/docs/execution-targets.md +146 -292
- package/docs/first-team.md +31 -17
- package/docs/implementation.md +77 -288
- package/docs/integrations.md +118 -320
- package/docs/knowledge-capability-authoring.md +25 -52
- package/docs/knowledge-reference/acceptance.md +3 -3
- package/docs/knowledge-reference/adoption.md +1 -1
- package/docs/knowledge-reference/harvester.md +2 -2
- package/docs/knowledge-reference/package-craft.md +3 -3
- package/docs/knowledge-reference/provider-mapping.md +3 -6
- package/docs/knowledge-reference/reader-capture.md +3 -3
- package/docs/knowledge-theory.md +62 -166
- package/docs/knowledge.md +225 -404
- package/docs/layers.md +42 -97
- package/docs/oats-local.schema.json +58 -5
- package/docs/oats-membership.schema.json +1 -8
- package/docs/oats-package.schema.json +5 -5
- package/docs/oats-workspace.schema.json +8 -22
- package/docs/official-catalog.md +25 -28
- package/docs/packages.md +45 -63
- package/docs/plans/0.30-close-out.md +83 -0
- package/docs/release-lane.md +82 -0
- package/docs/release-notes/oats-framework-v1.1.3.md +10 -8
- package/docs/release-notes/v0.19.0.md +48 -147
- package/docs/release-notes/v0.19.1.md +2 -3
- package/docs/release-notes/v0.19.3.md +2 -15
- package/docs/release-notes/v0.20.0.md +0 -15
- package/docs/release-notes/v0.22.0.md +71 -138
- package/docs/release-notes/v0.22.1.md +42 -90
- package/docs/release-notes/v0.22.10.md +1 -1
- package/docs/release-notes/v0.22.11.md +1 -47
- package/docs/release-notes/v0.22.12.md +4 -13
- package/docs/release-notes/v0.22.13.md +1 -42
- package/docs/release-notes/v0.22.14.md +3 -11
- package/docs/release-notes/v0.22.15.md +1 -46
- package/docs/release-notes/v0.22.16.md +6 -8
- package/docs/release-notes/v0.22.18.md +1 -99
- package/docs/release-notes/v0.22.19.md +3 -14
- package/docs/release-notes/v0.22.2.md +6 -15
- package/docs/release-notes/v0.22.3.md +0 -1
- package/docs/release-notes/v0.22.4.md +1 -14
- package/docs/release-notes/v0.22.5.md +2 -12
- package/docs/release-notes/v0.22.6.md +0 -3
- package/docs/release-notes/v0.23.0.md +9 -25
- package/docs/release-notes/v0.23.1.md +9 -25
- package/docs/release-notes/v0.23.2.md +2 -4
- package/docs/release-notes/v0.24.0.md +56 -97
- package/docs/release-notes/v0.24.1.md +7 -11
- package/docs/release-notes/v0.24.10.md +34 -45
- package/docs/release-notes/v0.24.11.md +12 -20
- package/docs/release-notes/v0.24.12.md +35 -48
- package/docs/release-notes/v0.24.13.md +34 -41
- package/docs/release-notes/v0.24.2.md +9 -13
- package/docs/release-notes/v0.24.3.md +7 -11
- package/docs/release-notes/v0.24.4.md +6 -6
- package/docs/release-notes/v0.24.5.md +6 -10
- package/docs/release-notes/v0.24.6.md +2 -5
- package/docs/release-notes/v0.24.7.md +46 -75
- package/docs/release-notes/v0.24.8.md +58 -96
- package/docs/release-notes/v0.24.9.md +38 -54
- package/docs/release-notes/v0.25.0.md +59 -76
- package/docs/release-notes/v0.25.1.md +57 -81
- package/docs/release-notes/v0.25.2.md +51 -70
- package/docs/release-notes/v0.25.3.md +11 -13
- package/docs/release-notes/v0.25.4.md +9 -13
- package/docs/release-notes/v0.25.5.md +3 -5
- package/docs/release-notes/v0.25.6.md +20 -29
- package/docs/release-notes/v0.25.7.md +5 -7
- package/docs/release-notes/v0.25.8.md +26 -39
- package/docs/release-notes/v0.26.0.md +175 -646
- package/docs/release-notes/v0.27.0.md +4 -5
- package/docs/release-notes/v0.27.1.md +4 -6
- package/docs/release-notes/v0.27.2.md +1 -1
- package/docs/release-notes/v0.28.0.md +57 -124
- package/docs/release-notes/v0.29.0.md +89 -208
- package/docs/release-notes/v0.29.1.md +1 -1
- package/docs/release-notes/v0.29.2.md +3 -4
- package/docs/release-notes/v0.30.0.md +205 -0
- package/docs/release-notes/v0.30.1.md +123 -0
- package/docs/schedules.md +280 -363
- package/docs/servers.md +99 -117
- package/docs/soul.schema.json +2 -9
- package/docs/souls-and-instances.md +145 -158
- package/docs/workspaces.md +137 -215
- package/lib/automations.mjs +21 -6
- package/lib/core.mjs +226 -74
- package/lib/instance-events.mjs +1 -1
- package/lib/instance-inspect.mjs +109 -34
- package/lib/instance-lifecycle.mjs +14 -1
- package/lib/instance-resolution.mjs +26 -27
- package/lib/launch-preference.mjs +87 -0
- package/lib/materialize.mjs +3 -3
- package/lib/packages.mjs +1 -1
- package/lib/resolve.mjs +30 -88
- package/lib/schedule.mjs +1 -1
- package/lib/teams-verbs.mjs +195 -0
- package/lib/teams.mjs +190 -0
- package/lib/triggers.mjs +2 -2
- package/lib/workspace.mjs +54 -147
- package/package-catalog.json +10 -16
- package/package.json +1 -3
- package/skills/oats-getting-started/SKILL.md +25 -13
- package/capabilities/oats-authoring/LICENSE +0 -21
- package/capabilities/oats-authoring/oats-package.json +0 -11
- package/capabilities/oats-authoring/oats.json +0 -12
- package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +0 -84
- package/capabilities/oats-authoring/skills/skill-craft/SKILL.md +0 -109
- package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +0 -116
- package/capabilities/oats-aweb/bin/oats-aweb-binding.mjs +0 -11
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +0 -1338
- package/capabilities/oats-aweb/injects/aweb.md +0 -47
- package/capabilities/oats-aweb/lib/binding-wire.mjs +0 -356
- package/capabilities/oats-aweb/lib/captured-execution.mjs +0 -91
- package/capabilities/oats-aweb/lib/captured-native.mjs +0 -91
- package/capabilities/oats-aweb/lib/grant-custody.mjs +0 -38
- package/capabilities/oats-aweb/lib/invocation-shape.mjs +0 -135
- package/capabilities/oats-aweb/lib/portable-binding.mjs +0 -146
- package/capabilities/oats-aweb/lib/session-readiness.mjs +0 -56
- package/capabilities/oats-aweb/lib/wake-receive.mjs +0 -56
- package/capabilities/oats-aweb/oats.json +0 -208
- package/capabilities/oats-aweb/skills/LICENSE +0 -21
- package/capabilities/oats-aweb/skills/VENDORED.md +0 -31
- package/capabilities/oats-aweb/skills/aweb-identity/SKILL.md +0 -201
- package/capabilities/oats-aweb/skills/aweb-messaging/SKILL.md +0 -161
- package/capabilities/oats-aweb/skills/aweb-messaging/references/messaging-scenarios.md +0 -61
- package/capabilities/oats-aweb/skills/aweb-team-membership/SKILL.md +0 -116
- package/capabilities/oats-aweb/skills/aweb-team-membership/references/team-membership-reference.md +0 -74
- package/capabilities/oats-aweb/skills/oats-aweb/SKILL.md +0 -216
- package/capabilities/oats-jira/bin/oats-jira.mjs +0 -40
- package/capabilities/oats-jira/injects/jira.md +0 -10
- package/capabilities/oats-jira/oats.json +0 -22
- package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +0 -179
- package/capabilities/oats-linear/bin/oats-linear-hook.mjs +0 -34
- package/capabilities/oats-linear/bin/oats-linear.mjs +0 -344
- package/capabilities/oats-linear/injects/linear.md +0 -8
- package/capabilities/oats-linear/oats.json +0 -24
- package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +0 -223
- package/capabilities/oats-okf/bin/oats-okf-binding.mjs +0 -14
- package/capabilities/oats-okf/bin/oats-okf.mjs +0 -209
- package/capabilities/oats-okf/injects/okf.md +0 -42
- package/capabilities/oats-okf/lib/binding-wire.mjs +0 -348
- package/capabilities/oats-okf/lib/captured-worker.mjs +0 -109
- package/capabilities/oats-okf/lib/config.mjs +0 -124
- package/capabilities/oats-okf/lib/consult.mjs +0 -518
- package/capabilities/oats-okf/lib/harvest-status.mjs +0 -88
- package/capabilities/oats-okf/lib/harvest-switch.mjs +0 -94
- package/capabilities/oats-okf/lib/inspection.mjs +0 -119
- package/capabilities/oats-okf/lib/invocation-context.mjs +0 -111
- package/capabilities/oats-okf/lib/invocation-shape.mjs +0 -135
- package/capabilities/oats-okf/lib/io.mjs +0 -118
- package/capabilities/oats-okf/lib/migration.mjs +0 -137
- package/capabilities/oats-okf/lib/okf-validate.mjs +0 -123
- package/capabilities/oats-okf/lib/portable-binding.mjs +0 -199
- package/capabilities/oats-okf/lib/source-contract.mjs +0 -46
- package/capabilities/oats-okf/lib/sources.mjs +0 -424
- package/capabilities/oats-okf/lib/stores.mjs +0 -473
- package/capabilities/oats-okf/lib/worker.mjs +0 -497
- package/capabilities/oats-okf/oats.json +0 -148
- package/capabilities/oats-okf/schemas/okf-base.schema.json +0 -46
- package/capabilities/oats-okf/schemas/okf-bindings.schema.json +0 -112
- package/capabilities/oats-okf/schemas/okf-portable-declaration.schema.json +0 -87
- package/capabilities/oats-okf/schemas/okf-portable-payload.schema.json +0 -113
- package/capabilities/oats-okf/schemas/okf-soul.schema.json +0 -37
- package/capabilities/oats-okf/skills/okf-consultation/SKILL.md +0 -144
- package/capabilities/oats-okf/skills/okf-consultation/references/consult.md +0 -86
- package/capabilities/oats-okf/skills/okf-instance-knowledge/SKILL.md +0 -104
- package/capabilities/oats-okf-harvest/bin/okf-harvest.mjs +0 -140
- package/capabilities/oats-okf-harvest/injects/harvester.md +0 -12
- package/capabilities/oats-okf-harvest/oats.json +0 -26
- package/capabilities/oats-okf-harvest/skills/knowledge-harvest/SKILL.md +0 -168
- package/capabilities/oats-okf-harvest/skills/knowledge-theory/SKILL.md +0 -192
- package/capabilities/oats-okf-harvest/skills/okf-authoring/SKILL.md +0 -151
- package/capabilities/oats-okf-harvest/skills/okf-authoring/scripts/okf-validate.mjs +0 -123
- package/capabilities/oats-okf-maintenance/bin/okf-maintenance.mjs +0 -170
- package/capabilities/oats-okf-maintenance/injects/maintainer.md +0 -12
- package/capabilities/oats-okf-maintenance/lib/provenance.mjs +0 -50
- package/capabilities/oats-okf-maintenance/oats.json +0 -21
- package/capabilities/oats-okf-maintenance/skills/knowledge-review/SKILL.md +0 -159
- package/capabilities/oats-okf-maintenance/skills/knowledge-theory/SKILL.md +0 -192
- package/capabilities/oats-okf-maintenance/skills/okf-authoring/SKILL.md +0 -151
- package/capabilities/oats-okf-maintenance/skills/okf-authoring/scripts/okf-validate.mjs +0 -123
- package/capabilities/oats-okf-maintenance/skills/okf-trigger-setup/SKILL.md +0 -146
- package/capabilities/oats-review/injects/review.md +0 -69
- package/capabilities/oats-review/oats.json +0 -10
- package/capabilities/oats-review/skills/code-review/SKILL.md +0 -44
- package/capabilities/oats-review/skills/security-review/SKILL.md +0 -59
- package/docs/conventions.md +0 -90
- package/docs/design/2026-09-07-architecture-reassessment.md +0 -131
- package/docs/design/2026-09-07-desktop-souls-capabilities.md +0 -50
- package/docs/design/2026-09-07-mobile-agent-management-proposal.md +0 -228
- package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +0 -558
- package/docs/design/2026-09-13-knowledge-and-memory-direction.md +0 -744
- package/docs/design/2026-09-13-knowledge-implementation.md +0 -127
- package/docs/design/2026-09-13-knowledge-location-contract.md +0 -340
- package/docs/design/2026-09-14-artifact-retention-contract.md +0 -190
- package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +0 -708
- package/docs/design/2026-09-14-portable-souls-contract-amendments.md +0 -85
- package/docs/design/2026-09-14-portable-souls-explainer.md +0 -750
- package/docs/design/2026-09-15-captured-dispatch.md +0 -127
- package/docs/design/2026-09-15-captured-resolution-records.md +0 -143
- package/docs/design/2026-09-15-package-preparation.md +0 -100
- package/docs/design/2026-09-15-portable-data-contract.md +0 -121
- package/docs/design/2026-09-15-portable-declarations.md +0 -189
- package/docs/design/2026-09-15-portable-souls-handoff.md +0 -150
- package/docs/design/2026-09-15-portable-souls-implementation.md +0 -417
- package/docs/design/2026-09-15-selection-lock-and-approval.md +0 -122
- package/docs/design/2026-09-15-source-observation.md +0 -119
- package/docs/design/2026-09-16-captured-admission.md +0 -77
- package/docs/design/2026-09-16-captured-helper-dispatch.md +0 -105
- package/docs/design/2026-09-16-captured-launch-inputs.md +0 -42
- package/docs/design/2026-09-16-command-profile-preparation.md +0 -86
- package/docs/design/2026-09-16-fresh-install-first-rollout.md +0 -47
- package/docs/design/2026-09-16-fresh-operator-walkthrough.md +0 -282
- package/docs/design/2026-09-16-messaging-capability-contract.md +0 -59
- package/docs/design/2026-09-16-portable-migration-evidence.md +0 -158
- package/docs/design/2026-09-16-portable-onboarding.md +0 -179
- package/docs/design/2026-09-16-prepare-request-transport.md +0 -26
- package/docs/design/2026-09-16-provider-binding-codecs.md +0 -98
- package/docs/design/2026-09-16-provider-binding-wire.md +0 -274
- package/docs/design/2026-09-17-capability-helper-input-contract.md +0 -95
- package/docs/design/2026-09-17-captured-backend-parity.md +0 -53
- package/docs/design/2026-09-17-captured-native-start.md +0 -58
- package/docs/design/2026-09-17-portable-boundary-hookup.md +0 -19
- package/docs/design/2026-09-17-portable-boundary-resources.md +0 -52
- package/docs/design/2026-09-17-public-captured-start.md +0 -108
- package/docs/design/2026-09-17-public-prepare-request.md +0 -90
- package/docs/design/2026-09-18-captured-pi-host.md +0 -205
- package/docs/design/2026-09-18-first-cut-release-checklist.md +0 -131
- package/docs/design/2026-09-18-herdr-protocol-compatibility.md +0 -60
- package/docs/design/2026-09-20-redesign-program-board.md +0 -142
- package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +0 -289
- package/docs/design/2026-09-20-workspace-onboarding-public.md +0 -207
- package/docs/design/2026-09-22-desktop-parity-seams.md +0 -58
- package/docs/design/2026-09-23-simplified-workspace-model.md +0 -711
- package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +0 -65
- package/docs/design/2026-09-24-desktop-phase-f-boundary.md +0 -242
- package/docs/design/2026-09-24-phase-d-plan.md +0 -305
- package/docs/design/2026-09-25-teams-contract.md +0 -258
- package/docs/design/2026-09-26-desktop-design-brief-architecture.md +0 -241
- package/docs/design/desktop-ux-plan.md +0 -362
- package/docs/design/launch-configurations.md +0 -168
- package/docs/design/okf-mirror-provenance.md +0 -105
- package/docs/design/operations-contract.md +0 -141
- package/docs/oats-member.schema.json +0 -38
- package/skills/integration-authoring/SKILL.md +0 -84
- package/skills/oats-support/SKILL.md +0 -79
- package/skills/skill-craft/SKILL.md +0 -109
- package/skills/soul-craft/SKILL.md +0 -116
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
# OATS Desktop — UX plan (phase 1)
|
|
2
|
-
|
|
3
|
-
Author: ux-designer-desktop-ux · Branch: `ux-designer/desktop-app`
|
|
4
|
-
Scope: design language + UX for `packages/desktop/` (Electron shell,
|
|
5
|
-
xterm.js terminal, brain viewer, markdown viewer, diff viewer, panel port).
|
|
6
|
-
This is a **decision document**: each section states the chosen option and why.
|
|
7
|
-
It is written against the binding contract in
|
|
8
|
-
`briefs/desktop-app-CONTRACT.md` (view modules `mount(el, ctx)` / `unmount()`;
|
|
9
|
-
data from the oats-web HTTP API; tmux-attach terminals).
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 1. Design research — what we take from VS Code and opencode
|
|
14
|
-
|
|
15
|
-
### VS Code shell anatomy (what applies)
|
|
16
|
-
|
|
17
|
-
VS Code's shell is: **activity bar → sidebar → editor group (tabs) → panel →
|
|
18
|
-
status bar**, all keyboard-addressable through a **command palette**, all
|
|
19
|
-
colored through **semantic theme tokens** (`editor.background`,
|
|
20
|
-
`sideBar.foreground`, …) rather than raw hex in components.
|
|
21
|
-
|
|
22
|
-
Principles we adopt:
|
|
23
|
-
|
|
24
|
-
1. **One persistent shell, swappable content.** Chrome (sidebar, tabs, status
|
|
25
|
-
bar) never remounts; only the active view does. This maps 1:1 onto the
|
|
26
|
-
`mount(el, ctx)` contract — the shell owns chrome, views own their `el`.
|
|
27
|
-
2. **Semantic color tokens.** Components reference roles (`--surface`,
|
|
28
|
-
`--accent`, `--term-bg`), never palette values. Themes are token maps.
|
|
29
|
-
The existing panel (`capabilities/oats-web/ui/panel.html`) already does
|
|
30
|
-
this correctly — we extend its token set, we don't replace it (§4).
|
|
31
|
-
3. **Command palette as the universal escape hatch.** Every action reachable
|
|
32
|
-
by mouse is reachable by `⌘K` (see §5). This is the cheapest way to be
|
|
33
|
-
keyboard-first without designing a shortcut for everything.
|
|
34
|
-
4. **Tabs are documents; the sidebar is the world.** Tabs hold *open work*
|
|
35
|
-
(a terminal, a diff, a markdown file); the sidebar holds *everything that
|
|
36
|
-
exists* (the roster). Closing a tab never destroys the underlying thing —
|
|
37
|
-
which matches the contract exactly (detach pty, never kill tmux).
|
|
38
|
-
5. **Status bar for ambient truth**: connection to the oats-web server,
|
|
39
|
-
active workspace, running-instance count, theme toggle.
|
|
40
|
-
|
|
41
|
-
What we deliberately **do not** clone:
|
|
42
|
-
|
|
43
|
-
- **No activity bar.** VS Code's activity bar exists because it has many
|
|
44
|
-
coequal top-level domains (explorer, SCM, debug, extensions). OATS desktop
|
|
45
|
-
has *one* primary domain — agents — so a vertical icon rail would be
|
|
46
|
-
ceremony. The sidebar gets a small segmented header instead
|
|
47
|
-
(Agents | Hierarchy) — two modes, not five domains.
|
|
48
|
-
- **No multi-root editor-group splitting (phase 2).** The panel's proven
|
|
49
|
-
≤3-pane terminal split is enough initially; generalized grid splitting is
|
|
50
|
-
a later enhancement, not a launch requirement.
|
|
51
|
-
|
|
52
|
-
### opencode (what applies)
|
|
53
|
-
|
|
54
|
-
opencode is a TUI-first agent client: session list on the left, one live
|
|
55
|
-
session dominating the screen, minimal chrome, everything driven by keys and
|
|
56
|
-
a fuzzy switcher. Principles we adopt:
|
|
57
|
-
|
|
58
|
-
1. **The session is the hero.** When you open an instance, its live terminal
|
|
59
|
-
fills the stage immediately — no dashboard detour, no click-through.
|
|
60
|
-
2. **Fast session switching** (fuzzy, recency-ordered) matters more than
|
|
61
|
-
deep navigation trees. Our palette's default mode is "jump to instance".
|
|
62
|
-
3. **State is legible at a glance**: running/idle/busy is shown as a colored
|
|
63
|
-
dot next to every session name, everywhere the name appears (roster,
|
|
64
|
-
tabs, hierarchy graph, palette). One vocabulary of status dots (§5).
|
|
65
|
-
4. **Terminal fidelity over widgetry.** Don't wrap the agent session in
|
|
66
|
-
chat-bubble reconstructions; show the real terminal. The contract's
|
|
67
|
-
direct tmux-attach already commits us to this — the UX embraces it.
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 2. Information architecture — agents at the heart
|
|
72
|
-
|
|
73
|
-
**Decision: the primary object is the agent *instance*.** Files, diffs,
|
|
74
|
-
terminals and brains are *facets of an instance*, not siblings of it. The IA
|
|
75
|
-
is instance-centric, not file-centric — this is the single biggest departure
|
|
76
|
-
from VS Code, and the reason the app exists.
|
|
77
|
-
|
|
78
|
-
### Shell layout
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
82
|
-
│ titlebar: ● oats [workspace ▾] filter/⌘K ◐ theme │
|
|
83
|
-
├───────────────┬──────────────────────────────────────────────┤
|
|
84
|
-
│ SIDEBAR │ TAB STRIP [dev-1 ⬤][dev-1: diff][README.md] │
|
|
85
|
-
│ ┌───────────┐ ├──────────────────────────────────────────────┤
|
|
86
|
-
│ │Agents|Tree│ │ │
|
|
87
|
-
│ └───────────┘ │ ACTIVE VIEW │
|
|
88
|
-
│ roster: │ (terminal / brain / markdown / diff / │
|
|
89
|
-
│ ws → repo → │ hierarchy / home) │
|
|
90
|
-
│ instances │ │
|
|
91
|
-
│ (children │ │
|
|
92
|
-
│ indented) │ │
|
|
93
|
-
│ ── souls ── │ │
|
|
94
|
-
│ spawnable │ │
|
|
95
|
-
├───────────────┴──────────────────────────────────────────────┤
|
|
96
|
-
│ status bar: ⬤ server · ws:oats · 4 running · branch · theme │
|
|
97
|
-
└──────────────────────────────────────────────────────────────┘
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
- **Sidebar (left, collapsible ⌘B)** — the roster, ported from the panel:
|
|
101
|
-
workspace → repo → instances, with spawn-children indented under parents
|
|
102
|
-
(the panel's `parentInstance` walk is kept verbatim). Below it, spawnable
|
|
103
|
-
souls with a Spawn action. A segmented control at the top switches the
|
|
104
|
-
sidebar between **Agents** (list) and **Hierarchy** (mini-tree; the full
|
|
105
|
-
graph opens as a view, §3).
|
|
106
|
-
- **Tab strip** — open facets. Tab title = `instance` (terminal),
|
|
107
|
-
`instance: diff`, `instance: brain`, or file name (markdown). Terminal
|
|
108
|
-
tabs carry the status dot. Middle-click / `⌘W` closes (detach only).
|
|
109
|
-
- **Status bar** — server reachability, workspace, running count. Clicking
|
|
110
|
-
the server segment reveals host/port; clicking the count filters to
|
|
111
|
-
running.
|
|
112
|
-
|
|
113
|
-
### The home surface
|
|
114
|
-
|
|
115
|
-
**Decision: home = the hierarchy view with an overview header**, not an
|
|
116
|
-
empty state and not a dashboard of widgets. On launch (no tabs open) the
|
|
117
|
-
stage shows the agent hierarchy graph (§3) topped by a one-line summary
|
|
118
|
-
("*oats workspace — 4 running, 2 idle, 1 retired today*") and a spawn button.
|
|
119
|
-
Rationale: it makes the app's thesis — *you are orchestrating a team* —
|
|
120
|
-
visible in the first second, and every node is one click from its terminal.
|
|
121
|
-
|
|
122
|
-
### Per-instance facet model
|
|
123
|
-
|
|
124
|
-
Selecting an instance (sidebar click, palette, or graph node) opens its
|
|
125
|
-
**terminal tab** — the hero facet. From the terminal tab's header (and the
|
|
126
|
-
context menu / palette) the sibling facets are one action away:
|
|
127
|
-
|
|
128
|
-
| Facet | Source | Opens as |
|
|
129
|
-
|----------|-------------------------------|-----------------------|
|
|
130
|
-
| Terminal | tmux attach via pty IPC | tab (default) |
|
|
131
|
-
| Brain | `GET /api/brain/<agent>` | tab `instance: brain` |
|
|
132
|
-
| Diff | `GET /api/diff/<instance>` | tab `instance: diff` |
|
|
133
|
-
| Files | `GET /api/file?path=…` | tab per file (markdown viewer) |
|
|
134
|
-
|
|
135
|
-
Cross-facet links use the contract's `ctx` verbs: brain view lists skills /
|
|
136
|
-
knowledge / STATE.md → `ctx.openFile(path)`; any view can
|
|
137
|
-
`ctx.openTerminal(instance)`. The hierarchy view is itself a view module and
|
|
138
|
-
uses the same two verbs — no new contract surface needed.
|
|
139
|
-
|
|
140
|
-
**Decision: tabs are per-facet, not per-instance-with-inner-tabs.** Inner
|
|
141
|
-
tab bars (an instance tab containing terminal/brain/diff sub-tabs) were
|
|
142
|
-
considered and rejected: they double the chrome, break `⌘W`/`⌘1..9`
|
|
143
|
-
uniformity, and fight the `mount(el, ctx)` contract, which is flat. Facet
|
|
144
|
-
association is expressed by tab naming + grouping tabs of the same instance
|
|
145
|
-
adjacently.
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## 3. Agent hierarchy visualization
|
|
150
|
-
|
|
151
|
-
**Decision: an interactive tree-of-trees (layered DAG), not a force-directed
|
|
152
|
-
graph.** Spawn parentage (`parentInstance` in the roster) is a forest —
|
|
153
|
-
force layouts add jitter and non-determinism for zero benefit on tree data.
|
|
154
|
-
Layout: **top-down tidy tree per workspace** (d3-hierarchy-style tidy layout;
|
|
155
|
-
implementable in ~150 lines without a dependency, or with `d3-hierarchy`
|
|
156
|
-
since desktop deps are allowed), workspaces side by side, SVG-rendered,
|
|
157
|
-
pan/zoom.
|
|
158
|
-
|
|
159
|
-
### Two relationship kinds, two visual languages
|
|
160
|
-
|
|
161
|
-
1. **Spawn parentage** (who spawned whom): solid edges, the tree structure
|
|
162
|
-
itself. Source: roster `parentInstance`.
|
|
163
|
-
2. **Coordination** (who works with whom): dashed accent edges *overlaid*
|
|
164
|
-
on the tree, shown on hover/selection (always-on is noisy). Source:
|
|
165
|
-
shared workspace/repo membership + aweb team metadata as exposed by
|
|
166
|
-
`/api/panel`; degrade gracefully if absent — the view must not depend on
|
|
167
|
-
a new endpoint (if richer comms data is wanted later, that is a phase-2
|
|
168
|
-
request to the coordinator, not an assumption).
|
|
169
|
-
|
|
170
|
-
### Node design
|
|
171
|
-
|
|
172
|
-
A compact card, not a bare circle — names and states must be readable
|
|
173
|
-
without hover:
|
|
174
|
-
|
|
175
|
-
```
|
|
176
|
-
┌──────────────────────────┐
|
|
177
|
-
│ ⬤ webpanel-dev-brain │ ⬤ status dot (see states)
|
|
178
|
-
│ webpanel-dev · repo:oats │ agent · repo, muted
|
|
179
|
-
└──────────────────────────┘
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
- **States** (same vocabulary app-wide): **running** = green dot +
|
|
183
|
-
full-opacity card; **idle** = hollow/gray dot, card at ~65% opacity
|
|
184
|
-
(matching the panel's `.inst.idle`); **retired** = dashed border,
|
|
185
|
-
faint text, only shown when the "show retired" toggle is on (retired
|
|
186
|
-
instances known from roster history if available; otherwise omitted).
|
|
187
|
-
- **Busy pulse** (phase-2 nice-to-have): subtle dot pulse when the session
|
|
188
|
-
produced output in the last N seconds — cheap liveness signal.
|
|
189
|
-
|
|
190
|
-
### Interactions
|
|
191
|
-
|
|
192
|
-
- **Click node → focus + detail popover** (task line, branch, dirty chip,
|
|
193
|
-
buttons: *Open terminal · Brain · Diff*). **Double-click / Enter → open
|
|
194
|
-
terminal tab** directly.
|
|
195
|
-
- **Hover → highlight lineage** (ancestors + descendants) and show
|
|
196
|
-
coordination edges for that node.
|
|
197
|
-
- Pan (drag), zoom (pinch/`⌘±`), `f` to fit. Keyboard: arrows walk the tree,
|
|
198
|
-
Enter opens.
|
|
199
|
-
- Search-as-you-type filters/highlights nodes (reuses the sidebar filter
|
|
200
|
-
semantics).
|
|
201
|
-
|
|
202
|
-
The hierarchy is both a **full view** (home surface / `⌘⇧H`) and a
|
|
203
|
-
**sidebar mini-mode** (same data, vertical indented tree — effectively the
|
|
204
|
-
roster's existing child-indentation, promoted).
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## 4. Theming
|
|
209
|
-
|
|
210
|
-
**Decision: extend the panel's existing token system — it is already
|
|
211
|
-
semantic, already dual-theme, already AA-audited.** The panel's `:root` /
|
|
212
|
-
`[data-theme]` token blocks become `packages/desktop/renderer/theme.css`,
|
|
213
|
-
the single source of truth. Views consume tokens only; a view containing a
|
|
214
|
-
hex literal fails review.
|
|
215
|
-
|
|
216
|
-
### Token architecture
|
|
217
|
-
|
|
218
|
-
Three tiers, one file:
|
|
219
|
-
|
|
220
|
-
1. **Core surface/text/interactive tokens** (exist today): `--bg`,
|
|
221
|
-
`--surface`, `--surface-2`, `--border`, `--fg`, `--muted`, `--faint`,
|
|
222
|
-
`--accent`, `--accent-fg`, `--ok`, `--warn`, `--danger`, `--chip-*`,
|
|
223
|
-
`--sel`, `--shadow`.
|
|
224
|
-
2. **Terminal tokens**: `--term-bg`, `--term-fg`, `--term-sel` (exist) plus
|
|
225
|
-
a **16-slot ANSI set** `--ansi-black … --ansi-bright-white` (new —
|
|
226
|
-
xterm.js takes a theme object; we generate it from these tokens so the
|
|
227
|
-
embedded terminal matches the app theme, including the solarized remap
|
|
228
|
-
the panel already ships for light mode).
|
|
229
|
-
3. **New component tokens** (thin aliases over tier 1, so themes rarely
|
|
230
|
-
need to override them): `--tab-active-bg`, `--tab-inactive-fg`,
|
|
231
|
-
`--statusbar-bg`, `--graph-edge`, `--graph-edge-coord`,
|
|
232
|
-
`--diff-add-bg`, `--diff-del-bg`, `--md-code-bg`.
|
|
233
|
-
|
|
234
|
-
### Themes
|
|
235
|
-
|
|
236
|
-
- **Dark** (default when OS is dark): the panel's GitHub-dark-adjacent
|
|
237
|
-
palette, unchanged.
|
|
238
|
-
- **Light**: the panel's **solarized-light** palette, unchanged —
|
|
239
|
-
compatibility with the web panel is a requirement and the palette already
|
|
240
|
-
passes AA (`--fg` 9.9:1, `--muted` 4.9:1 on surface).
|
|
241
|
-
- Theme = OS-follow by default, manual override persisted
|
|
242
|
-
(`localStorage`, same keys as the panel: `oatsweb.theme`) so panel and
|
|
243
|
-
desktop feel like one product. Room for future themes = adding one
|
|
244
|
-
`[data-theme="x"]` block; no component changes.
|
|
245
|
-
|
|
246
|
-
### Accessibility commitments (both themes, verified in phase 2)
|
|
247
|
-
|
|
248
|
-
- Body & secondary text ≥ 4.5:1 on their actual surfaces; UI glyphs/borders
|
|
249
|
-
≥ 3:1; status conveyed by **dot shape + label**, never color alone
|
|
250
|
-
(idle = hollow dot, retired = dashed border — already specified in §3).
|
|
251
|
-
- Visible `:focus-visible` ring (`--accent`, 2px) on every interactive
|
|
252
|
-
element; full keyboard reachability (tabs, sidebar, graph, palette).
|
|
253
|
-
- Diff colors get text labels (`+`/`−` gutters) in addition to
|
|
254
|
-
`--diff-add/del-bg`; ANSI light remap keeps terminal output ≥ 4.5:1 as
|
|
255
|
-
the panel already does.
|
|
256
|
-
- `prefers-reduced-motion`: disable graph pan-inertia, dot pulse, spinner
|
|
257
|
-
fades.
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## 5. Component inventory + interaction details
|
|
262
|
-
|
|
263
|
-
**Type & space.** UI font: system stack (as panel). Mono:
|
|
264
|
-
`"SF Mono", ui-monospace, Menlo` (as panel). Type scale (px):
|
|
265
|
-
11 (chips/status) · 12 (secondary) · 13 (body/controls) · 14 (view titles) —
|
|
266
|
-
matching the panel's proven density. Spacing scale: **4-px base**
|
|
267
|
-
(4/8/12/16/24/32); radii: 6 (small controls) / 8 (cards, inputs) / 999
|
|
268
|
-
(chips). Shadows: `--shadow` only.
|
|
269
|
-
|
|
270
|
-
**Components** (shell-owned unless noted):
|
|
271
|
-
|
|
272
|
-
- **Tabs**: 32px strip; active tab `--tab-active-bg` + 2px top accent
|
|
273
|
-
(mirrors the panel's focused-pane inset accent); dirty/status dot on
|
|
274
|
-
terminal tabs; overflow scrolls; drag-reorder phase-2. `⌘1..9` jump,
|
|
275
|
-
`⌘W` close, `⌃Tab` MRU cycle.
|
|
276
|
-
- **Sidebar**: as panel roster (filter input, collapsible groups, chips for
|
|
277
|
-
branch/dirty/runtime) + segmented Agents/Hierarchy header. `⌘B` toggle.
|
|
278
|
-
- **Command palette** (`⌘K`): single input, mode prefixes —
|
|
279
|
-
default = jump to instance (fuzzy, MRU-boosted); `>` commands
|
|
280
|
-
(spawn, toggle theme, open diff/brain of current instance, fit graph);
|
|
281
|
-
`#` open file within current instance's home. Esc closes; results show
|
|
282
|
-
status dots and repo chips.
|
|
283
|
-
- **Toasts**: bottom-right, `--surface` card + colored left border
|
|
284
|
-
(`--ok/--warn/--danger`), auto-dismiss 5s (errors sticky with a Close
|
|
285
|
-
button), max 3 stacked, `aria-live="polite"`. Used for: spawn result,
|
|
286
|
-
server lost/regained, pty exit.
|
|
287
|
-
- **Loading states**: reuse panel's `.spinner` + `.loading-block`; skeleton
|
|
288
|
-
rows (pulse animation) for roster and brain tree; terminals show
|
|
289
|
-
"attaching to `<session>` …" with spinner until first pty bytes.
|
|
290
|
-
- **Empty states**: reuse panel's `.empty` pattern (big glyph, one sentence,
|
|
291
|
-
one action). E.g. diff view with clean tree: "No changes on
|
|
292
|
-
`<branch>` — the work tree is clean."
|
|
293
|
-
- **Dialogs**: only for destructive/parameterized actions (spawn with task
|
|
294
|
-
text). Everything else is inline or palette.
|
|
295
|
-
- **Markdown viewer** (view module): panel typography, `--md-code-bg` code
|
|
296
|
-
blocks with syntax highlight, heading anchor links, relative links to
|
|
297
|
-
files resolved through `ctx.openFile`.
|
|
298
|
-
- **Diff viewer** (view module): file list (status/+/− counts) left or top,
|
|
299
|
-
unified diff with `--diff-*` tokens, per-file collapse, staged toggle.
|
|
300
|
-
- **Brain viewer** (view module): two columns — soul (AGENTS.md, skills,
|
|
301
|
-
knowledge tree) and instances (state/task/notes) — every leaf is an
|
|
302
|
-
`openFile` link; skills show their descriptions inline.
|
|
303
|
-
|
|
304
|
-
**Keyboard-first rules**: `⌘K` palette · `⌘B` sidebar · `⌘T` spawn ·
|
|
305
|
-
`⌘⇧H` hierarchy · `⌘W`/`⌘1..9`/`⌃Tab` tabs · `⌘F` filter. **Ctrl-B is never
|
|
306
|
-
bound** — it is the tmux prefix and always flows to the focused terminal
|
|
307
|
-
(the panel already enforces this rule; we keep it as law).
|
|
308
|
-
|
|
309
|
-
---
|
|
310
|
-
|
|
311
|
-
## 6. Phase-2 implementation plan (incremental, contract-compatible)
|
|
312
|
-
|
|
313
|
-
Each step lands independently on the integrated app; none changes the view
|
|
314
|
-
contract or the API contract. Order chosen so every step is visible value.
|
|
315
|
-
|
|
316
|
-
1. **Token foundation** — extract/extend `renderer/theme.css` (tiers 1–3,
|
|
317
|
-
ANSI variables), wire `data-theme` + OS-follow + persistence; generate
|
|
318
|
-
the xterm.js theme object from tokens; contrast-check both themes
|
|
319
|
-
(automated check script if feasible).
|
|
320
|
-
2. **Shell chrome polish** — tab strip (status dots, accents, keyboard
|
|
321
|
-
map), status bar, sidebar restyle to spec (segmented header, chips,
|
|
322
|
-
focus rings), toasts, loading/empty components as shared renderer
|
|
323
|
-
helpers views can import.
|
|
324
|
-
3. **Command palette** — jump/command/file modes as above; registered
|
|
325
|
-
commands provided by the shell; instance jump from roster data.
|
|
326
|
-
4. **Hierarchy view** — new view module `views/hierarchy.js` using only
|
|
327
|
-
roster data + `ctx.openTerminal`/`ctx.openFile`; tidy-tree layout,
|
|
328
|
-
node cards, states, lineage highlight, popover, keyboard nav; wire as
|
|
329
|
-
home surface and `⌘⇧H`.
|
|
330
|
-
5. **View polish pass** — apply tokens/typography/empty-loading patterns to
|
|
331
|
-
the four developer-built views (terminal header, brain, markdown, diff),
|
|
332
|
-
coordinating any needed hooks through dev-coordinator-1.
|
|
333
|
-
6. **Accessibility + reduced-motion audit** — keyboard walk of every
|
|
334
|
-
surface, focus-visible sweep, contrast verification, `prefers-reduced-
|
|
335
|
-
motion` guards; fix list executed before calling phase 2 done.
|
|
336
|
-
|
|
337
|
-
### Addendum — human directives (received via coordinator before phase-2
|
|
338
|
-
go-ahead; to be re-confirmed in the go-ahead mail)
|
|
339
|
-
|
|
340
|
-
Binding design directives that supersede anything conflicting above:
|
|
341
|
-
|
|
342
|
-
1. **Diff viewer surface removed** — no nav entry, no diff tabs. `/api/diff`
|
|
343
|
-
and `diff.mjs` stay in the tree, dormant; removing dead UI wiring is in my
|
|
344
|
-
scope. (Step 5 no longer polishes a diff view; `--diff-*` tokens remain
|
|
345
|
-
defined for a possible return.)
|
|
346
|
-
2. **Markdown reader is the flagship viewer** — `openFile → markdown` gets
|
|
347
|
-
the depth budget: typography, highlighting, anchors, relative-link
|
|
348
|
-
resolution via `ctx.openFile`, strong loading/empty states.
|
|
349
|
-
3. **Jira surface hidden entirely** — no nav entry or inline cards; code
|
|
350
|
-
stays unwired. Verify no remnants during the polish pass.
|
|
351
|
-
4. **Three first-class surfaces**: (a) hierarchy view = home + primary
|
|
352
|
-
navigation (extra investment beyond step 4); (b) a proper **souls
|
|
353
|
-
browser** stage view (descriptions + spawn affordances, palette-reachable)
|
|
354
|
-
— promoted from the sidebar-list sketch in §2; (c) a nice way into agent
|
|
355
|
-
brains.
|
|
356
|
-
5. Everything else (themes, tokens, palette, a11y) stands as written.
|
|
357
|
-
|
|
358
|
-
Dependencies/risks flagged to the coordinator up front: (a) step 5 touches
|
|
359
|
-
other developers' view code — I will work on the *integrated* branch only,
|
|
360
|
-
after their merges; (b) coordination-edge data for §3 uses whatever
|
|
361
|
-
`/api/panel` already exposes — if we want explicit aweb-team edges, that is
|
|
362
|
-
a small additive API request, not a blocker.
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# Launch configurations and launch recipes
|
|
2
|
-
|
|
3
|
-
A **launch configuration** is a named way to start a harness, declared by
|
|
4
|
-
the host under `launch-configs:` in the deployment's `oats-local.yaml` (see
|
|
5
|
-
docs/configuration.md; 0.26.0, lead decision 2 — earlier kernels read it
|
|
6
|
-
from a scope's `oats-config.yaml`): runtime, an executable, literal
|
|
7
|
-
arguments, environment (literals or `{fromEnv}` references), model, yolo.
|
|
8
|
-
It is independent of any soul, and a spawn, start or restart selects one by
|
|
9
|
-
name (`--launch-config`, or the Desktop's per-launch choice). A launch
|
|
10
|
-
configuration is a spawn-time host choice, never a soul field: `launch-config:`
|
|
11
|
-
is not a field of a workspace-model soul.yaml (docs/soul.schema.json; discovery
|
|
12
|
-
refuses it), so a v2 soul cannot name one, not even as a default. (A classic
|
|
13
|
-
0.25 soul.yaml could name a preferred entry; 0.26.0 reads no such field.)
|
|
14
|
-
|
|
15
|
-
A **launch recipe** is what a start is made of, recorded in the instance's
|
|
16
|
-
`instance.json` under `launch` beside the rendered `command`:
|
|
17
|
-
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"version": 1,
|
|
21
|
-
"runtime": "claude",
|
|
22
|
-
"launchConfig": "personal", "launchConfigSource": "/deployment",
|
|
23
|
-
"executable": "/deployment/tools/claude-wrapper.sh",
|
|
24
|
-
"executableDeclared": "./tools/claude-wrapper.sh", "executableResolvedFrom": "relative to /deployment",
|
|
25
|
-
"args": ["--settings", "/abs/settings.json"],
|
|
26
|
-
"env": { "KEY": { "fromEnv": "SRC" }, "LIT": "plain" },
|
|
27
|
-
"model": "claude-opus-5", "yolo": true,
|
|
28
|
-
"hooks": {
|
|
29
|
-
"launch": { "claude": "--dangerously-load-development-channels plugin:aweb-channel@awebai-marketplace" },
|
|
30
|
-
"env": { "AWEB_DELIVERY": "session" },
|
|
31
|
-
"contributions": [{ "capability": "oats.aweb", "layer": "messaging", "level": "/scope", "settings": { "delivery": "session" }, "trust": { "trusted": true, "integrity": "sha256-..." }, "launch": { "claude": "..." }, "env": ["AWEB_DELIVERY"] }]
|
|
32
|
-
},
|
|
33
|
-
"prompt": { "kind": "task-file", "file": "TASK.md" }
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The rendered `command` is produced by one renderer from the recipe. With no
|
|
38
|
-
configuration it is byte-identical to what spawn rendered before recipes
|
|
39
|
-
existed, so an older kernel starts such a home unchanged, and the golden
|
|
40
|
-
matrix freezes that. Configuration `args` go after the runtime's own
|
|
41
|
-
options and before capability launch arguments (for claude and codex the
|
|
42
|
-
`--` separator keeps them from consuming the task; for pi they follow the
|
|
43
|
-
task, like capability arguments). Every argument and literal value is
|
|
44
|
-
single-quoted: spaces, quotes and metacharacters are literal.
|
|
45
|
-
|
|
46
|
-
## Environment references
|
|
47
|
-
|
|
48
|
-
`{fromEnv: SRC}` renders as `NAME="$SRC"` in the command: the persisted
|
|
49
|
-
command, the pending receipt and every answer carry the reference, never a
|
|
50
|
-
value. At start the execution host checks each source variable is set
|
|
51
|
-
(`E_LAUNCH_ENV_MISSING` before anything is created or stopped) and hands the
|
|
52
|
-
source variables to the pane only (tmux `-e`; a Herdr launch exports them in
|
|
53
|
-
the launched shell). Literal values are non-secret by contract but no answer
|
|
54
|
-
shows them: `list` and `preview` redact every environment value.
|
|
55
|
-
|
|
56
|
-
## Selection rules
|
|
57
|
-
|
|
58
|
-
- A named configuration is a unit. `--launch-config NAME` with a `--runtime`
|
|
59
|
-
that disagrees with the configuration's runtime is refused
|
|
60
|
-
(`E_LAUNCH_CONFIG_MISMATCH`) before anything happens; the same runtime may
|
|
61
|
-
be repeated; `--model` and `--yolo` override the configuration's fields.
|
|
62
|
-
- Without `--launch-config`: a spawn uses no configuration (the runtime's
|
|
63
|
-
defaults; a soul names none); an existing home keeps its recorded configuration, except that
|
|
64
|
-
`--runtime` alone deliberately leaves it behind and renders the new
|
|
65
|
-
runtime's defaults (no old executable or args are carried).
|
|
66
|
-
- Model: explicit, else the configuration's, else on an existing home the
|
|
67
|
-
recorded model when the runtime is unchanged, else the runtime's native
|
|
68
|
-
default; a spawn without either uses the runtime's native default (a
|
|
69
|
-
workspace-model soul declares no model). A model never crosses runtimes.
|
|
70
|
-
- Executable: the configuration's (bare name on PATH; a path resolved against
|
|
71
|
-
the deployment directory when relative) or the runtime's default (claude through
|
|
72
|
-
`oats-claude-config`). It must be a regular executable file; it is never
|
|
73
|
-
run to probe it. Capability runtime-package requirements are checked with
|
|
74
|
-
the runtime's default binary, as at spawn.
|
|
75
|
-
|
|
76
|
-
## Capability boundary
|
|
77
|
-
|
|
78
|
-
Spawn hooks contribute `launch` arguments keyed by runtime and `env` values.
|
|
79
|
-
Launch arguments are runtime-specific by construction; environment is
|
|
80
|
-
runtime-neutral by contract. The recipe records both with per-capability
|
|
81
|
-
provenance (settings and trust at spawn). A later start on the same runtime
|
|
82
|
-
reuses them. A runtime switch reuses the environment and needs the new
|
|
83
|
-
runtime's launch arguments from the same capabilities: a capability that
|
|
84
|
-
answered arguments for the old runtime and none for the new one refuses the
|
|
85
|
-
switch (`E_LAUNCH_PREPARATION`) with the remedy (change that capability's
|
|
86
|
-
setting, or the provider declares a `launch` hook). Spawn hooks are never
|
|
87
|
-
re-run by a start or restart.
|
|
88
|
-
|
|
89
|
-
## `oats launch-config preview`
|
|
90
|
-
|
|
91
|
-
Read-only; nothing is locked or started. `--home ABS` describes an existing
|
|
92
|
-
home under a selection (`selection.source`: `frozen` when nothing was
|
|
93
|
-
selected, `config` when re-resolved, `frozen-command` for a home that
|
|
94
|
-
predates recipes, where a selection answers `E_LAUNCH_LEGACY`: re-spawn it);
|
|
95
|
-
`--soul NAME [--dir SCOPE] [--agents-root ABS]` describes a new instance.
|
|
96
|
-
Answer: `{context, selected, selection:{source, launchConfig, runtime,
|
|
97
|
-
model, yolo}, runtime, model, modelSource, yolo, launchConfig,
|
|
98
|
-
launchConfigSource, executable:{path, declared, resolvedFrom}, argv,
|
|
99
|
-
environment:[{name, redacted|fromEnv}], command (redacted rendering),
|
|
100
|
-
prompt:{kind:"task-file", file:"TASK.md"}, hooks (redacted),
|
|
101
|
-
preflight:[{check: executable|environment|model|capabilities, ok, detail}],
|
|
102
|
-
ok}`. The TASK body is never included.
|
|
103
|
-
|
|
104
|
-
## Starting and restarting an existing home
|
|
105
|
-
|
|
106
|
-
`oats session start --home ABS` runs the recorded recipe as it is (a
|
|
107
|
-
`--model` re-renders the model in place and the recipe follows). With
|
|
108
|
-
`--launch-config`, `--runtime` or `--yolo` the recipe is re-resolved by the
|
|
109
|
-
same planner preview uses, against the home's recorded context, and every
|
|
110
|
-
check runs before anything is observed: the recipe's shape, the executable
|
|
111
|
-
(regular file, executable), the references (set on this host), the
|
|
112
|
-
capabilities' contributions (below), the runtime packages. A recorded
|
|
113
|
-
reference is re-checked on every start path, model-only starts included,
|
|
114
|
-
and the pane receives the source's value under the kernel alias.
|
|
115
|
-
|
|
116
|
-
`oats session restart --home ABS [same flags] [--stop-grace SECONDS]` stops
|
|
117
|
-
the running harness and starts again in place under the one per-home lock:
|
|
118
|
-
|
|
119
|
-
1. Every preflight above, first. A refusal leaves the harness running.
|
|
120
|
-
2. The stop: SIGTERM to every process under the pane's launcher (a wrapper
|
|
121
|
-
that does not exec, the harness, their children), then a bounded wait
|
|
122
|
-
(default 20 s) for the signalled processes to be gone and the session to
|
|
123
|
-
read as a bare shell or stopped. Nothing is escalated: a harness still
|
|
124
|
-
there when the wait ends is reported (`E_SESSION_STOP_FAILED`, with the
|
|
125
|
-
processes still running) and nothing is launched. Elapsed time is never
|
|
126
|
-
taken as exit; a turn interruption is never taken as exit.
|
|
127
|
-
3. The in-place start, with the pending receipt carrying the new recipe,
|
|
128
|
-
runtime and yolo, exactly as a start does; `.oats-restart.json` keeps the
|
|
129
|
-
stop's facts (what was signalled, when, whether exit was observed).
|
|
130
|
-
|
|
131
|
-
What the harnesses do on SIGTERM, from their installed sources and
|
|
132
|
-
documentation as read by the operating lead on 2026-09-07 (no live process
|
|
133
|
-
signalled): pi (@earendil-works/pi-coding-agent 0.84.2) registers
|
|
134
|
-
SIGTERM/SIGHUP handlers that end tracked children, dispose extensions and
|
|
135
|
-
exit; Claude Code's documentation makes Ctrl-C state-dependent (interrupt,
|
|
136
|
-
clear, double-press exit) and does not establish that an external SIGTERM
|
|
137
|
-
runs its SessionEnd hook; Codex's documentation establishes no SIGTERM
|
|
138
|
-
cleanup guarantee. So the contract is the request and the observation, not
|
|
139
|
-
a promise that a harness flushes its latest conversation: OATS preserves
|
|
140
|
-
the home, work, identity and notes; an old native conversation's unsaved
|
|
141
|
-
state is the harness's own. Wrappers should exec the harness or forward
|
|
142
|
-
signals. A longer `--stop-grace` can accommodate hook cleanup.
|
|
143
|
-
|
|
144
|
-
## Homes that predate recipes
|
|
145
|
-
|
|
146
|
-
A home with a recorded `command` and no `launch` is converted narrowly when
|
|
147
|
-
a start selects something: only the kernel's own generated shapes are
|
|
148
|
-
recognized (identity environment, the binary, the runtime's template
|
|
149
|
-
arguments, `--model`, yolo, the task prompt). Other environment is kept and
|
|
150
|
-
attributed to the capability whose recorded declaration (`environment`,
|
|
151
|
-
`environmentNamespaces` in `capabilityRuntime`) owns it, so a session-delivery
|
|
152
|
-
home switches runtime with its `AWEB_DELIVERY` intact; spawn hooks are never
|
|
153
|
-
re-run. Any other argument is unclassified: the start is refused, naming the
|
|
154
|
-
arguments, unless an active trusted capability declares a `launch` hook that
|
|
155
|
-
prepares the launch anew (then its answer replaces them). The conversion is
|
|
156
|
-
recorded (`launch.legacy`) by the start that uses it.
|
|
157
|
-
|
|
158
|
-
## The `launch` hook
|
|
159
|
-
|
|
160
|
-
A capability may declare `hooks.launch`. It runs on a start or restart of an
|
|
161
|
-
existing home (never at spawn, never spawn's identity work), side-effect-free
|
|
162
|
-
by contract, with `OATS_RUNTIME` set to the target runtime and
|
|
163
|
-
`OATS_PREVIOUS_RUNTIME` to the recorded one, and answers `{launch:{<runtime>:
|
|
164
|
-
args}, env:{...}}` for that runtime; its answer replaces the capability's
|
|
165
|
-
recorded contribution. Without it, a capability that contributed
|
|
166
|
-
runtime-specific arguments at spawn cannot follow a runtime change
|
|
167
|
-
(`E_LAUNCH_PREPARATION`), and a capability the scope no longer trusts has its
|
|
168
|
-
recorded arguments withheld the same way.
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Internal: finalizing the OKF mirror's source provenance
|
|
2
|
-
|
|
3
|
-
The standalone `oats.okf` distribution is authoritative. The framework's
|
|
4
|
-
`capabilities/oats-okf/` and `scripts/okf-source-inventory.json` are generated
|
|
5
|
-
mirrors, not authoring surfaces. This procedure does not publish the source,
|
|
6
|
-
accept a PR, update the catalog, commit, fetch, or change branches.
|
|
7
|
-
|
|
8
|
-
## Development versus publication
|
|
9
|
-
|
|
10
|
-
- `node scripts/check-okf-mirror.mjs --generate --source <standalone-repository>`
|
|
11
|
-
captures current exported working bytes, including dirty/untracked files.
|
|
12
|
-
It always records `release.status: pending`, null final refs and
|
|
13
|
-
`published: false`, even when HEAD happens to have a published tag.
|
|
14
|
-
- `node scripts/check-okf-mirror.mjs --verify` uses only the checked-in inventory
|
|
15
|
-
and mirror. No Git, clone, credentials or network is needed for either a
|
|
16
|
-
pending or finalized inventory. It checks exact file sets (including empty
|
|
17
|
-
directories), file bytes, portable Git executable modes, literal symlink
|
|
18
|
-
targets, wrapper hashes, and consistent release metadata.
|
|
19
|
-
- `--verify-source --source <standalone-repository>` verifies pending snapshots
|
|
20
|
-
against their exact recorded working state, including branch/dirty metadata.
|
|
21
|
-
For published inventories it rechecks the immutable commit, payload, origin
|
|
22
|
-
tag object and peeled commit, ignoring the recorded local branch name. The
|
|
23
|
-
checkout must still be clean at the recorded accepted commit; renamed
|
|
24
|
-
branches and detached HEAD are supported. This published-source check needs
|
|
25
|
-
origin access. It does not depend on cached remote-tracking refs.
|
|
26
|
-
|
|
27
|
-
Offline verification is an integrity check of a reviewed checked-in inventory,
|
|
28
|
-
not independent proof that a remote still advertises a tag. The explicit source
|
|
29
|
-
check supplies that evidence. No boolean flag is a publication attestation.
|
|
30
|
-
|
|
31
|
-
## Post-publication command
|
|
32
|
-
|
|
33
|
-
Only after source review/merge and actual publication of `v2.0.0`:
|
|
34
|
-
|
|
35
|
-
1. Obtain the **accepted full merged commit ID** from the source review/release
|
|
36
|
-
record. Do not substitute a mutable branch name, abbreviated hash, or whatever
|
|
37
|
-
HEAD happens to resolve to. The legacy inventory field `finalMergedCommit`
|
|
38
|
-
records this caller-supplied acceptance; Git cannot prove human PR approval.
|
|
39
|
-
2. Have a clean standalone checkout at that commit, with the published tag
|
|
40
|
-
available locally and `origin` pointing to `awebai/oats-okf`. Fetch/check out
|
|
41
|
-
deliberately through the parent release procedure; the checker never does it.
|
|
42
|
-
3. From the framework checkout, run:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
node scripts/check-okf-mirror.mjs --finalize \
|
|
46
|
-
--source .agents/knowledge-rework/repos/okf \
|
|
47
|
-
--final-tag v2.0.0 \
|
|
48
|
-
--final-commit "${OKF_V2_ACCEPTED_COMMIT:?set the reviewed full merged source commit ID}" &&
|
|
49
|
-
node scripts/check-okf-mirror.mjs --verify-source \
|
|
50
|
-
--source .agents/knowledge-rework/repos/okf &&
|
|
51
|
-
node --test test/okf-mirror-parity.test.mjs
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
The relative source path above is the existing ignored work-view convention;
|
|
55
|
-
substitute an explicitly resolved standalone repository path in other work
|
|
56
|
-
views. The command must not be run while source acceptance is still changing.
|
|
57
|
-
|
|
58
|
-
4. Review the resulting payload/inventory diff, run the remaining release gates,
|
|
59
|
-
then advance the catalog through the parent integration process. Finalization
|
|
60
|
-
itself never touches the catalog.
|
|
61
|
-
|
|
62
|
-
`--finalize` requires both `--final-tag` and a full SHA-1/SHA-256 `--final-commit`.
|
|
63
|
-
It replaces only the mirrored capability and inventory, just like `--generate`,
|
|
64
|
-
but stamps `release.status: published` only after all checks succeed:
|
|
65
|
-
|
|
66
|
-
- The version tag is exactly `v<distribution version>`; HEAD is the explicitly
|
|
67
|
-
accepted commit and Git reports a clean source tree. Masked index entries
|
|
68
|
-
(`assume-unchanged`/`skip-worktree`) are not accepted.
|
|
69
|
-
- Actual exported files and wrappers match raw objects at that commit, not just
|
|
70
|
-
Git status or filtered checkout content. Ignored exported extras, untracked
|
|
71
|
-
empty directories, CRLF/filter changes, hidden byte changes, mode drift with
|
|
72
|
-
`core.filemode=false`, and literal symlink-target differences fail closed.
|
|
73
|
-
Git replacement objects are disabled. Published inventories also record and
|
|
74
|
-
hash wrapper file modes; materialization preserves those modes and bytes.
|
|
75
|
-
- Exactly one effective origin fetch URL identifies the official source. The
|
|
76
|
-
usual official GitHub HTTPS/SSH spellings are equivalent. URL rewrites to an
|
|
77
|
-
unrelated repository are rejected. The remote query uses canonical public
|
|
78
|
-
HTTPS with source-local Git configuration disabled, so local upload-pack/SSH
|
|
79
|
-
overrides cannot fabricate its response. Prompts/helpers are disabled and
|
|
80
|
-
Git commands have a bounded timeout.
|
|
81
|
-
- The local tag resolves to the accepted commit. A fresh `ls-remote` query must
|
|
82
|
-
advertise the same tag object and the same peeled commit (or direct commit
|
|
83
|
-
for a lightweight tag). Both annotated and lightweight tags are supported.
|
|
84
|
-
Missing/unreachable origin, unpublished tags or mismatched refs fail closed.
|
|
85
|
-
- The source is checked again after staging the copy, before replacing the
|
|
86
|
-
mirror or inventory. Failed acceptance checks leave both untouched. Ordinary
|
|
87
|
-
filesystem failures during replacement are not a multi-file transaction.
|
|
88
|
-
|
|
89
|
-
The published record retains `source.head`, clean-state metadata, the branch
|
|
90
|
-
observed at generation (informational during immutable verification), the
|
|
91
|
-
accepted final tag/commit, `remote: origin`, and the exact `tagObject`. Thus
|
|
92
|
-
changing an annotated tag object without changing its commit still invalidates
|
|
93
|
-
`--verify-source`. Remote checks attest what was advertised when queried; they
|
|
94
|
-
cannot prevent an upstream tag from being moved later. Do not move released
|
|
95
|
-
tags, and re-run source verification at the release gate.
|
|
96
|
-
|
|
97
|
-
## Isolated regression coverage
|
|
98
|
-
|
|
99
|
-
`test/okf-mirror-parity.test.mjs` uses temporary source repositories and local bare
|
|
100
|
-
origins only, including tag creation/deletion/movement solely inside fixtures.
|
|
101
|
-
The JavaScript `finalizeOkfMirror`/`verifyOkfSource` APIs accept an explicit
|
|
102
|
-
`repository` expectation for these fixtures and record their real source
|
|
103
|
-
identity; the CLI cannot override the official repository. No tests publish to
|
|
104
|
-
GitHub. Checked-in mirror tests accept consistent pending **or** published
|
|
105
|
-
provenance, so finalizing the source does not require weakening those tests.
|