@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,99 +1,41 @@
|
|
|
1
1
|
# OKF knowledge operations: harvest, maintenance, triggers, and the working-soul surface
|
|
2
2
|
|
|
3
|
-
**Status:**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
1. **Knowledge operations are split across three capabilities.**
|
|
9
|
-
- **oats.okf**: the working-soul surface.
|
|
10
|
-
- **oats.okf-harvest**: the harvester.
|
|
11
|
-
- **oats.okf-maintenance**: the maintainer.
|
|
12
|
-
- The harvester and the maintainer share a renamed **knowledge-theory** skill (today `memory-harvest`), and each has its own skills too.
|
|
13
|
-
- **oats.okf ships no harvest doctrine at all.**
|
|
14
|
-
2. **Working souls using OKF get exactly two okf skills and one inject.**
|
|
15
|
-
- A skill for *instance knowledge maintenance* (STATE/log/notes), **teaching the judgment and theory of what useful instance knowledge to capture** (amended by the human, 2026-09-26).
|
|
16
|
-
- A skill for *soul knowledge consultation* (`okf-consultation`).
|
|
17
|
-
- The inject teaches the work mode: query both before starting a task, before compaction, and every so often while working, to decide, situate and work coherently with the soul's knowledge.
|
|
18
|
-
3. **The harvester**:
|
|
19
|
-
- reads the harvested instance's **session transcript** (not only its notes), so its judgment has full context;
|
|
20
|
-
- opens a PR to the knowledge-base repo;
|
|
21
|
-
- **stays alive until that PR is merged (or closed), then self-retires.**
|
|
22
|
-
4. **The maintainer**: a **knowledge-maintainer soul** reviews each harvest PR.
|
|
23
|
-
- It situates the addition in the base.
|
|
24
|
-
- It reads the harvested instance's tasks, if that instance had a tasks capability.
|
|
25
|
-
- It reads the existing soul knowledge.
|
|
26
|
-
- It judges soundness, amends whatever needs amending, and merges.
|
|
27
|
-
5. **Triggers** (new concept).
|
|
28
|
-
- A deployment (laptop or server) can declare "on an event, spawn a NEW instance of soul X with this instruction, in these teams".
|
|
29
|
-
- The first use: *on a harvest PR opened → spawn the knowledge maintainer to review it.*
|
|
30
|
-
6. **Fully defined in the okf repo.**
|
|
31
|
-
- The maintainer (and harvester) souls live in oats-okf.
|
|
32
|
-
- Users who onboard with the defaults get the trigger that launches the maintainer, **sourced from the okf package**.
|
|
33
|
-
- The skills insist the trigger runs on a deployment whose GitHub credentials can approve/merge PRs on the KB repo.
|
|
34
|
-
7. **An `okf` team.**
|
|
35
|
-
- Workspaces using OKF get an `okf` team, so harvesters and maintainers talk without polluting the working teams.
|
|
36
|
-
- The okf onboarding teaches it.
|
|
37
|
-
|
|
38
|
-
## 1. What already exists (verified 2026-09-26)
|
|
39
|
-
|
|
40
|
-
- **Scheduler** (`docs/schedules.md`).
|
|
41
|
-
- Committable definitions per deployment scope.
|
|
42
|
-
- One host timer runs `oats schedule tick --host` every minute; there's no daemon.
|
|
43
|
-
- Kinds: `spawn`, `command`, `wake`.
|
|
44
|
-
- Scheduled spawns materialize exactly like `oats spawn`.
|
|
45
|
-
- okf already registers one `command` job per source (`oats okf run-source`).
|
|
46
|
-
- **Transcript capture.** okf's custody already copies **notes AND the record** (bounded `recall` windows of the session transcript, full text) into `<stateDir>/sources/<uuid>/inputs/<hash>.json`. It excludes privacy-excluded sessions. The harvester therefore needs no live source home. The gap is **doctrine and procedure**: the current skill does not make reading the transcript windows mandatory and systematic.
|
|
47
|
-
- **PR delivery.** okf's `complete` pushes a branch and runs `gh pr create` on the base's repository (title `memory-harvest: <run>`). It already tracks PR state by `gh pr view/list`.
|
|
48
|
-
- **The harvester today is a *capability agent*** (`agents/memory-harvest` in the okf manifest).
|
|
49
|
-
- It gets the whole oats.okf module (so every okf skill), no okf inject, and no hooks, so no messaging identity.
|
|
50
|
-
- It retires as soon as the completion receipt is written.
|
|
51
|
-
- **Souls from a non-member repo** exist only as `external:` (commit-pinned, not versioned with a package). **Packages cannot ship souls today.** This is the one real kernel gap for (6).
|
|
52
|
-
- **Teams:**
|
|
53
|
-
- labels are declared in `teams:`;
|
|
54
|
-
- `join=` at spawn exists (0.27.x);
|
|
55
|
-
- a soul's label must be declared, or it's `E_TEAM_UNKNOWN`.
|
|
56
|
-
|
|
57
|
-
## 2. Target design
|
|
58
|
-
|
|
59
|
-
### 2.1 Capabilities in the oats.okf package (4.0.0)
|
|
60
|
-
|
|
61
|
-
| Capability | Who gets it | Skills | Inject | Commands, hooks and the rest |
|
|
62
|
-
|---|---|---|---|---|
|
|
63
|
-
| **oats.okf** (knowledge slot) | every working soul with OKF knowledge | `okf-consultation` (soul knowledge: bases/index/cat/ls/links/search, receipts, citing); **`okf-instance-knowledge`** (instance memory: **the theory and judgment of what is worth capturing**, plus STATE.md/log.md/notes form and compaction discipline; §2.5a) | **the work-mode inject** (§2.5) | the consult commands; `setup`/`init`/`migrate`/binding; the spawn hook (source registration) and retire hook (custody) |
|
|
64
|
-
| **oats.okf-harvest** (additive) | the harvester soul only | **`knowledge-theory`** (the doctrine, renamed from `memory-harvest` §3.x); **`knowledge-harvest`** (the procedure: read input fully, transcript windows first-class, situate, stage, PR, lifecycle until merged); **`okf-authoring`** (OKF Markdown craft, today's `okf` skill) | a harvester inject: you are a judge, not a worker; the staged roots are your only write surface; stay alive until the PR is merged/closed | `complete`, `harvest-status`; no source registration |
|
|
65
|
-
| **oats.okf-maintenance** (additive) | the maintainer soul only | **`knowledge-theory`** (identical copy); **`knowledge-review`** (situate a PR, read provenance, the source soul's knowledge, its tasks, verdicts, amend, merge, notify); **`okf-authoring`** (identical copy); **`okf-trigger-setup`** (install/verify the review trigger on a host with merge-capable GitHub credentials) | a maintainer inject: one PR per instance; never merge what fails the doctrine; supersede, never silently overwrite | `review-context` (the PR's provenance → the reading list), `notify-harvester` |
|
|
3
|
+
**Status:** decided and implemented (kernel 0.28.0 and 0.29.0, oats.okf 4.x). This record decides how knowledge operations are split across the oats.okf package and which kernel mechanisms carry them: package souls, triggers and workspace automations. The reference pages ([knowledge.md](../knowledge.md#knowledge-operations), [schedules.md](../schedules.md#triggers), [packages.md](../packages.md#package-souls)) win on operator-visible behaviour.
|
|
4
|
+
|
|
5
|
+
## 2. Design
|
|
6
|
+
|
|
7
|
+
### 2.1 Capabilities in the oats.okf package
|
|
66
8
|
|
|
67
|
-
|
|
9
|
+
The package ships three capabilities, two package souls (§2.2) and one trigger template (`harvest-review`, §2.3).
|
|
10
|
+
|
|
11
|
+
| Capability | Who gets it | Skills | Inject | Commands and hooks |
|
|
12
|
+
|---|---|---|---|---|
|
|
13
|
+
| **oats.okf** (knowledge slot) | every working soul with OKF knowledge | `okf-consultation` (soul knowledge); `okf-instance-knowledge` (what instance knowledge is worth capturing, and its form; §2.5a) | the work mode (§2.5) | the consult commands; `setup`, `init`, `migrate`, the binding; `run-source`, `complete`, `harvest-status`; the spawn hook (source registration) and retire hook (custody) |
|
|
14
|
+
| **oats.okf-harvest** | the harvester soul only | `knowledge-theory` (the OKF promotion doctrine); `knowledge-harvest` (the procedure); `okf-authoring` (OKF Markdown craft) | a judge, not a worker; the staged roots are the only write surface; stay alive until the PR is merged or closed | `complete`, `harvest-status` |
|
|
15
|
+
| **oats.okf-maintenance** | the maintainer soul only | `knowledge-theory` and `okf-authoring` (identical copies); `knowledge-review` (situate, judge, amend, merge, notify); `okf-trigger-setup` (declare and verify the review trigger) | one PR per instance; never merge what fails the doctrine; supersede explicitly | `review-context`, `notify-harvester` |
|
|
68
16
|
|
|
69
|
-
**
|
|
17
|
+
- **Shared skills are identical copies** (a package is a Git tree with no build step); a package test fails if they differ. No soul composes both capabilities, so they never collide.
|
|
18
|
+
- **oats.okf ships no harvest doctrine.** Working souls get consultation and capture judgment only; the promotion doctrine belongs to the harvester and the maintainer.
|
|
19
|
+
- **Naming:** oats.framework ships an unrelated *capability* `oats.knowledge-theory` (for capability authors). The okf *skill* `knowledge-theory` describes itself as the OKF promotion doctrine so triggering does not confuse the two.
|
|
70
20
|
|
|
71
|
-
|
|
21
|
+
### 2.2 Package souls
|
|
72
22
|
|
|
73
|
-
|
|
23
|
+
A package ships souls beside its capabilities, so "sourced from the okf package" is one versioned pin.
|
|
74
24
|
|
|
75
|
-
- A package manifest
|
|
76
|
-
-
|
|
77
|
-
- **
|
|
78
|
-
- **
|
|
79
|
-
- **
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
- **Resolution:**
|
|
83
|
-
- `from: here` inside a package soul means *this package*.
|
|
84
|
-
- Workspace/team defaults apply as for any soul (the soul can opt out with `off`/`none`).
|
|
85
|
-
- **Workspace control:** `disabled:` in `oats-local.yaml` works as for member souls.
|
|
86
|
-
- **Trust:** the same as the package's capabilities. Declaring the package is the trust decision.
|
|
87
|
-
- **This replaces capability agents** (`agents:` in a capability manifest) once okf 4.0.0 is pinned. Removing the capability-agent path is a separate kernel PR, per "v2 becomes the classic" (no dual path), after the okf 4.0.0 mirror.
|
|
25
|
+
- A package manifest declares `souls: ["souls/knowledge-harvester", "souls/knowledge-maintainer"]`. Each is an ordinary soul directory (`soul.yaml`, `AGENTS.md`, `skills/`).
|
|
26
|
+
- **Versioned and locked with the package:** one pin (`packages: { oats.okf: <version> }`) versions the capabilities and the souls. The lock records each soul's name, path and digest; nothing drifts, unlike an `external:` commit pin.
|
|
27
|
+
- **Listed** with `kind: "package"` and its package origin (`oats souls`, the Desktop Souls page).
|
|
28
|
+
- **Named** `<package>/<soul>` (`oats.okf/knowledge-maintainer`); a bare name works when unique, otherwise `E_SOUL_AMBIGUOUS`. It homes in `agents/<package>--<soul>/`, never shared with a same-named member soul.
|
|
29
|
+
- **Resolved** like any soul (workspace defaults, `off`, `<slot>: none`, `souls.disabled`); `from: here` means *this package* at the locked commit.
|
|
30
|
+
- **Trusted** as the package's capabilities are: declaring the package is the trust decision.
|
|
31
|
+
- **Package souls replace capability agents.** A capability manifest that declares `agents:` is refused (`E_CAPABILITY_AGENTS_REMOVED`) with a remedy naming package souls.
|
|
88
32
|
|
|
89
|
-
### 2.3 Triggers
|
|
33
|
+
### 2.3 Triggers
|
|
90
34
|
|
|
91
|
-
**
|
|
92
|
-
- A trigger is **an event-driven schedule**: "when EVENT matches, spawn a NEW instance of SOUL with TASK, in TEAMS".
|
|
93
|
-
- It lives beside schedules: the same deployment scope, file and host tick (`oats schedule tick --host`), and the same spawn path. There's no new daemon, and it runs only on the host that holds the scope.
|
|
94
|
-
- Triggers are **per-deployment by design**: they need that machine's credentials.
|
|
35
|
+
A trigger is an **event-driven schedule**: "when EVENT matches, spawn a NEW instance of SOUL with TASK, in TEAMS".
|
|
95
36
|
|
|
96
|
-
|
|
37
|
+
- It lives beside schedules: the same deployment scope and file (`oats-schedules.json`, `kind: "trigger"`), the same host tick (`oats schedule tick --host`) and the same spawn path. There is no daemon and no webhook; it runs only on the host that holds the scope.
|
|
38
|
+
- Triggers are per-host by design: they act with that machine's `gh` credentials, and a definition carries none.
|
|
97
39
|
|
|
98
40
|
```json
|
|
99
41
|
{ "id": "okf-harvest-review", "enabled": true, "kind": "trigger",
|
|
@@ -101,289 +43,122 @@
|
|
|
101
43
|
"events": ["opened", "reopened", "ready_for_review"],
|
|
102
44
|
"labels": ["okf-harvest"], "base": "main", "poll": "2m" },
|
|
103
45
|
"spawn": { "soul": "oats.okf/knowledge-maintainer", "purpose": "review-pr-{number}",
|
|
104
|
-
"task": "Review knowledge-base PR {repo}#{number}. Load knowledge-review first.",
|
|
105
|
-
"
|
|
46
|
+
"task": "Review knowledge-base PR {repo}#{number} ({url}). Load the knowledge-review skill first.",
|
|
47
|
+
"harness": "claude", "model": "opus" },
|
|
106
48
|
"concurrency": { "max": 2, "perKey": 1 } }
|
|
107
49
|
```
|
|
108
50
|
|
|
109
|
-
- **
|
|
110
|
-
- **Dedup and delivery:**
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
- **
|
|
115
|
-
- **
|
|
116
|
-
- **
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
- **
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
-
|
|
130
|
-
- **locally**, in the deployment (§2.3 as built: `oats trigger add`, `oats schedule add`): machine-private, for personal or experimental jobs.
|
|
131
|
-
|
|
132
|
-
**A human is a GitHub account** (a person or a machine user). Every workspace automation says **which machine runs it** and **which account it acts as**.
|
|
133
|
-
|
|
134
|
-
**The canonical contract:**
|
|
135
|
-
- **Where it lives (the human, amended):**
|
|
136
|
-
- **Canonical folder:** `oats-triggers/` (and `oats-schedules/`) at a member's root. Every `*.yaml`/`*.yml` there is a candidate.
|
|
137
|
-
- **Also picked up anywhere in the repo:** any file that follows the contract by name, `*.oats-trigger.yaml` / `*.oats-schedule.yaml` (`.yml` too), e.g. `services/billing/nightly.oats-schedule.yaml` beside the code it concerns.
|
|
138
|
-
- **The contract is self-describing:** the file carries `kind: oats-trigger` (or `oats-schedule`) + `schemaVersion: 1`. A candidate without the right `kind` is an `E_AUTOMATION_SCHEMA` discovery problem, not silently ignored.
|
|
139
|
-
- **The id** is the file's `id:`, else the filename stem (without `.oats-trigger`). Two files in one member with the same id → `E_AUTOMATION_DUPLICATE`, naming both paths.
|
|
140
|
-
- **Discovery cost:** one recursive tree listing per member commit (names only, no blobs; cached per commit), then blob reads of the candidates only.
|
|
141
|
-
- **Never scanned:** `oats-package/` (package templates are not workspace automations), `.git/`, `node_modules/`.
|
|
142
|
-
- **Discovery:** they're discovered like souls (over the remote, from CONFIRMED members only), named `<member>/<id>`, and listed by `oats workspace status` / `oats trigger list` / `oats schedule list` with `origin: { kind: "workspace", repoKey, commit }`.
|
|
51
|
+
- **Source:** `github.pull_request` only, polled with the host's `gh` every `poll` (default `2m`, at least `1m`). Events are inferred poll over poll: `opened`, `reopened`, `ready_for_review`, `labeled`, `synchronize`. The shape stays open to other sources.
|
|
52
|
+
- **Dedup and delivery:** each event has a key `<trigger>:<repo>#<number>:<event>:<stamp>`. A key is recorded as fired only after a successful spawn, so a failed spawn is retried on the next poll. Delivery is at least once; `concurrency.perKey` (default 1) keeps one live instance per PR, and `concurrency.max` (default 1) bounds the trigger.
|
|
53
|
+
- **The event reaches the instance** as `OATS_TRIGGER_EVENT_FILE` (`<home>/.oats/trigger-event.json`: `{trigger, source, repo, number, url, event, headSha, labels, observedAt, key}`), plus the templated task.
|
|
54
|
+
- **Templates substitute only whitelisted structured fields:** `{repo} {number} {url} {event} {headSha} {trigger}`. A template naming any other field is refused. PR titles and bodies are never interpolated: they are untrusted data the soul reads from the event file and GitHub.
|
|
55
|
+
- **Teams:** `spawn.teams` becomes the messaging capability's `join=` provider setting at spawn.
|
|
56
|
+
- **CLI:** `oats trigger add | list | show | enable | disable | remove | test | status`, all with `--json`; `test` is a dry run (gh auth, repository permissions, the soul resolves, what would fire now). The kernel advertises feature `triggers` in `oats version --json`.
|
|
57
|
+
- **Package trigger templates:** a package declares `triggers: [{ id, file }]`, each file `{ parameters, definition }`. `oats trigger add --from oats.okf:harvest-review --set repo=…` instantiates one at the locked commit. This is how okf ships the review trigger.
|
|
58
|
+
- **Safety:** a trigger spawns only a soul that resolves in this workspace; a disabled soul refuses. The trigger runs with the host's own credentials.
|
|
59
|
+
|
|
60
|
+
### 2.3a Workspace automations: triggers and schedules declared in Git
|
|
61
|
+
|
|
62
|
+
Triggers and schedules are defined at one of two levels:
|
|
63
|
+
|
|
64
|
+
- **the workspace level**, a file committed in a confirmed member repository and shared through Git, named `<member>/<id>`: the default for anything a team relies on;
|
|
65
|
+
- **locally**, in the deployment's `oats-schedules.json` (`oats trigger add`, `oats schedule add`): machine-private, named `local/<id>`. A local schedule row keeps its bare `id` plus `qualifiedId: local/<id>`.
|
|
66
|
+
|
|
67
|
+
Triggers and schedules are separate modules sharing only the kind-neutral pieces (`lib/automations.mjs`): one contract, one rule set, one layout.
|
|
68
|
+
|
|
69
|
+
**Where a file lives:** every `*.yaml`/`*.yml` under the canonical folders `oats-triggers/` and `oats-schedules/` at a member's root, and any file named `*.oats-trigger.yaml` or `*.oats-schedule.yaml` anywhere in the member (beside the code it concerns). `oats-package/` (package templates are not workspace automations), `.git/` and `node_modules/` are never scanned. Discovery costs one tree listing per member commit, then blob reads of the candidates.
|
|
70
|
+
|
|
71
|
+
**The file describes itself.** It carries `kind: oats-trigger` (or `oats-schedule`) and `schemaVersion: 1`; a candidate without the right kind is an `E_AUTOMATION_SCHEMA` problem, never silently skipped. The id is `id:`, else the filename stem; the same id twice in one member and kind is `E_AUTOMATION_DUPLICATE`, naming both paths.
|
|
143
72
|
|
|
144
73
|
```yaml
|
|
145
74
|
# <member>/oats-triggers/okf-harvest-review.yaml
|
|
146
75
|
kind: oats-trigger
|
|
147
76
|
schemaVersion: 1
|
|
148
77
|
description: Review every harvest PR on the knowledge base
|
|
149
|
-
from: oats.okf:harvest-review #
|
|
78
|
+
from: oats.okf:harvest-review # a package template, then its parameters
|
|
150
79
|
set: { repo: github.com/acme/knowledge }
|
|
151
|
-
runsOn: kb-bot-server # the host
|
|
152
|
-
owner: github.com/acme-kb-bot # the GitHub account it acts as
|
|
153
|
-
# …or a full definition (on
|
|
80
|
+
runsOn: kb-bot-server # the host.name that runs it
|
|
81
|
+
owner: github.com/acme-kb-bot # the GitHub account it acts as, <host>/<login>
|
|
82
|
+
# …or a full definition (on, spawn, concurrency) as in §2.3, instead of from/set
|
|
154
83
|
```
|
|
155
84
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
85
|
+
A workspace schedule has the same header with `run: spawn | command`, `cron`, `tz`, `agent`, `task` and the spawn options; `wake` targets an instance home on one machine, so it stays local.
|
|
86
|
+
|
|
87
|
+
**Who runs it.** A GitHub account (a person or a machine user) acts; a named host runs. A host runs a workspace automation only when both hold:
|
|
88
|
+
|
|
89
|
+
- `runsOn` equals its `oats-local.yaml` `host: { name }` (a machine fact, never in Git);
|
|
90
|
+
- its authenticated `gh` account equals `owner` (asked once per tick).
|
|
91
|
+
|
|
92
|
+
Otherwise it is listed with the reason `assigned-elsewhere`, `owner-mismatch` (named here but logged in as someone else; nothing runs, and `oats trigger test` says so) or `host-unnamed`. So exactly one machine runs it, and consent is explicit: its operator named the host and is logged in as the account. Declaring the automation in a member is the trust decision for its definition, as for souls. A workspace trigger's `owner` and `on.repo` must be on the same GitHub host.
|
|
93
|
+
|
|
94
|
+
**Opting out** without a commit: `oats trigger disable <member>/<id>` and `oats schedule disable <member>/<id>` write `triggers.disabled` / `schedules.disabled` in `oats-local.yaml`. A workspace definition is never edited or removed locally (`E_AUTOMATION_WORKSPACE`): change the file in Git.
|
|
95
|
+
|
|
96
|
+
**Refresh.** `oats sync` discovers the workspace automations into a snapshot (`.agents/automations/snapshot.json`); the host tick reads it and refreshes it (`oats automations refresh`) when it is more than ten minutes old, so a change in Git reaches the named host within about ten minutes. A trigger template is instantiated when the snapshot is taken, at the locked commit. The run state (dedup keys, last poll, last run) stays per host and local.
|
|
168
97
|
|
|
169
|
-
**
|
|
170
|
-
|
|
171
|
-
**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
**
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
|
|
189
|
-
**
|
|
190
|
-
|
|
191
|
-
**Safety:** everything in §2.3 still holds (the soul must resolve here; only whitelisted fields are templated; PR text is never interpolated; there's no credential in any definition).
|
|
192
|
-
|
|
193
|
-
**Schedules are the same contract as triggers** (the human, 2026-09-26):
|
|
194
|
-
- A workspace schedule (`oats-schedules/<id>.yaml`, or `*.oats-schedule.yaml` anywhere) carries `runsOn` + `owner` and runs ONLY on the named host logged in as that account.
|
|
195
|
-
- The same `assigned-elsewhere` / `owner-mismatch` / `host-unnamed` reasons, the same per-kind opt-out (`schedules.disabled`), the same snapshot refresh, and local schedules as `local/<id>`.
|
|
196
|
-
- One rule set for both kinds; the kernel implements them together.
|
|
197
|
-
|
|
198
|
-
**Desktop: the Schedules tab (existing, redesigned) + a NEW Triggers tab** (the human, 2026-09-26; no unified "Automations" view):
|
|
199
|
-
- The existing **Schedules** tab is redesigned in place, and a new **Triggers** tab sits beside it.
|
|
200
|
-
- **Both show workspace AND local items together**, each row marked with its origin.
|
|
201
|
-
- **Sequencing:** the Desktop engineer's finished redesign ships FIRST (in 0.28.0). These tabs come after, on the kernel's `automations` JSON (0.29.0).
|
|
202
|
-
- In each tab the user sees **every workspace item defined in the member repos they can read**, plus their own machine's local ones.
|
|
203
|
-
- **Each row:**
|
|
204
|
-
- the id (`<member>/<id>` or `local/<id>`) and its origin (workspace/local);
|
|
205
|
-
- **the owner** (the GitHub account);
|
|
206
|
-
- **where it runs** (`runsOn`, and whether that's THIS machine, with the reason when not);
|
|
207
|
-
- **the soul** it spawns (with its origin: member/package);
|
|
208
|
-
- **the prompt** (the task template, shown verbatim, with the whitelisted fields highlighted);
|
|
209
|
-
- the event (a trigger's `on`) or the cron+tz (a schedule);
|
|
210
|
-
- teams, harness/model, concurrency;
|
|
211
|
-
- enabled/disabled here;
|
|
212
|
-
- the last run/fire and the next due (for automations this machine runs).
|
|
213
|
-
- **Where it comes from:** the repo + path + commit of the file, linking to the file.
|
|
214
|
-
- **Actions:**
|
|
215
|
-
- `test` (a dry run on this host);
|
|
216
|
-
- disable/enable here (`triggers.disabled` / `schedules.disabled`);
|
|
217
|
-
- open the defining file;
|
|
218
|
-
- for local ones: add/edit/remove.
|
|
219
|
-
- **Visibility follows repo access:** a member the user can't read contributes nothing (the standalone rule), so the Desktop never shows automations the user couldn't read in Git.
|
|
220
|
-
- **Data:** `oats trigger list --json` / `oats schedule list --json` (workspace + local, with origin, owner, runsOn, runsHere + reason, soul, task, and the last/next run). This JSON is part of PR 2b's contract, so the Desktop renders it and never re-derives it.
|
|
221
|
-
|
|
222
|
-
**Onboarding / okf:**
|
|
223
|
-
- The review trigger becomes a **workspace file** (`oats-triggers/okf-harvest-review.yaml` in the host repo, `from: oats.okf:harvest-review`, with `runsOn` + `owner` naming the merge-capable host and account).
|
|
224
|
-
- `oats trigger add --from … --workspace <member>` writes it (or prints it when that repo isn't the current checkout).
|
|
225
|
-
- `oats trigger test <member>/<id>` runs on the named host. This supersedes "install on ONE host" by hand.
|
|
226
|
-
|
|
227
|
-
**Delivery:**
|
|
228
|
-
- **PR 2b (kernel):** after #205. Discovery + the host identity + the owner/host matching + the snapshot + the CLI/JSON + docs.
|
|
229
|
-
- The target is **0.29.0**, released with okf 4.0.0, whose `okf-trigger-setup` teaches the workspace form first. The floor becomes `oats >= 0.29.0`.
|
|
230
|
-
- 0.28.0 ships the local triggers (#205) as the mechanism.
|
|
231
|
-
|
|
232
|
-
### 2.4 The harvester and the maintainer (oats.okf 4.0.0)
|
|
233
|
-
|
|
234
|
-
**`knowledge-harvester` soul** (a package soul; `work: directory`; `team: okf`; `knowledge: none`, so there's no recursive harvest; capability `oats.okf-harvest`).
|
|
235
|
-
1. okf's `run-source` job captures custody (unchanged) and **spawns the harvester soul** (not a capability agent) with the frozen input, joining `okf`.
|
|
236
|
-
2. **Reads the input fully:** notes AND the **transcript windows**. This is mandatory, and the judgment receipt must cite the turn ids it relied on.
|
|
237
|
-
- It also extracts **task references** (ticket ids/URLs seen in the transcript, notes and the source's `instance.json` tasks provider).
|
|
238
|
-
3. Judges with `knowledge-theory`; stages edits on the owned nodes; `complete` opens the PR:
|
|
239
|
-
- label `okf-harvest`;
|
|
240
|
-
- a **provenance block** in the body: a fenced `okf-harvest` JSON block, `{ run, input, source: { soul, soulId, instance, ownedNodes, readNodes, bases }, tasks: { provider, refs[] }, harvester: { instance, alias } }`.
|
|
241
|
-
4. **Stays alive** (idle; woken by messages in `okf`):
|
|
242
|
-
- It answers the maintainer's questions and pushes amendments on request.
|
|
243
|
-
- It retires on **merged/closed** (the maintainer's message, or its own PR check on each wake).
|
|
244
|
-
- A **max-age** (the setting `harvester-max-age`, default 7d) retires it after telling the team. It never closes the PR itself.
|
|
245
|
-
|
|
246
|
-
**The harvest switch (lead decision, 2026-09-26; L2 implements it):**
|
|
247
|
-
- **A setting, not a job toggle:** `harvest: on|off` for oats.okf, **default `off`**.
|
|
248
|
-
- **Where it's set:**
|
|
249
|
-
- Deployment-wide, in `oats-local.yaml` `settings.oats.okf.harvest` (a machine fact: the operator decides whether this host harvests).
|
|
250
|
-
- Per soul, as the opt-out: `soul.yaml` `knowledge: { harvest: off }`.
|
|
251
|
-
- **Effective = on only if the deployment says `on` AND the soul does not say `off`.** A soul's `off` cannot be overridden by the host. This deliberately departs from the usual later-wins merge, and L2 must implement it explicitly.
|
|
252
|
-
- **When it's off:** the spawn hook registers no source, and no capture or custody happens. Private transcripts are never accumulated "for later", and nothing drains when the switch flips; harvest starts from the next session. The per-source `run-source` job exists only when harvest is effectively on.
|
|
253
|
-
- **The verbs:**
|
|
254
|
-
- `oats okf setup --harvest on|off` writes the local setting (else it prints the line to add);
|
|
255
|
-
- `oats okf harvest-status [--soul X]` reports the effective value and why (the deployment/soul row), plus the registered sources.
|
|
256
|
-
- `oats schedule enable|disable <job>` remains the per-source emergency brake, not the switch.
|
|
98
|
+
**Writing one:** `oats trigger add` / `oats schedule add --workspace <member> --runs-on <host> --owner <host>/<login>` writes the file into a checkout of that member, or prints it. Everything in §2.3 still holds for workspace triggers.
|
|
99
|
+
|
|
100
|
+
**Data and Desktop.** `oats trigger list --json` and `oats schedule list --json` carry workspace and local items together, each with its origin, owner, `runsOn`, `runsHere` and reason, soul, task and last/next run. The Desktop renders these rows and never re-derives placement: one Automations item, Schedules and Triggers subtabs in one layout, rows grouped by where they run and marked with their origin. A member the user cannot read contributes nothing.
|
|
101
|
+
|
|
102
|
+
**okf onboarding.** The review trigger is a workspace file (`oats-triggers/okf-harvest-review.yaml`, `from: oats.okf:harvest-review`, with `runsOn` and `owner` naming the merge-capable host and account). `okf-trigger-setup` teaches this form first, and `oats trigger test <member>/<id>` verifies it on the named host.
|
|
103
|
+
|
|
104
|
+
### 2.4 The harvester and the maintainer
|
|
105
|
+
|
|
106
|
+
**`knowledge-harvester`** (a package soul; `work: directory`; `knowledge: none`, so there is no recursive harvest; capability `oats.okf-harvest`).
|
|
107
|
+
|
|
108
|
+
1. okf's per-source `run-source` job captures custody and spawns `oats.okf/knowledge-harvester` with the frozen input, as a child of the source instance. Its harness is the oats.okf `harvest-runtime` setting (optionally `harvest-model`).
|
|
109
|
+
2. It reads the input fully, the notes and the transcript windows; the judgment receipt cites the turn ids it relied on. It also extracts task references (ticket ids and URLs).
|
|
110
|
+
3. It judges with `knowledge-theory`, stages edits on the owned nodes, and `complete` opens the PR (title `okf-harvest: <run>`, label `okf-harvest`) with a **provenance block** in the body: a fenced `okf-harvest` JSON block, `{ version: 1, run, input[], source: { soul, soulId, owner, instance, ownedNodes, readNodes, bases }, tasks: { provider, refs[] }, harvester: { instance, alias } }`.
|
|
111
|
+
4. It stays alive, woken by messages, to answer the maintainer and push amendments. It retires when every PR is merged or closed (`oats okf-harvest harvest-status` says `retire`), or at `harvester-max-age` (default 7d) after telling its operator. It never closes the PR.
|
|
112
|
+
|
|
113
|
+
**The harvest switch.**
|
|
114
|
+
|
|
115
|
+
- `harvest: on|off` is an oats.okf setting, **default `off`**: a host fact, set in `oats-local.yaml` `settings.oats.okf.harvest`.
|
|
116
|
+
- A soul may only opt out, with `soul.yaml` `knowledge: { harvest: off }`, and that opt-out is absolute. **Effective = on only if the deployment says `on` and the soul does not say `off`.** A soul `on` is ignored. This departs deliberately from the later-wins settings merge, so okf reads the soul's own value from its `soul.yaml` and fails closed when it cannot read it with certainty.
|
|
117
|
+
- **Off** means no source registration, capture or custody (and no `run-source` job): private transcripts are never accumulated for later.
|
|
118
|
+
- **The verbs:** `oats okf setup --harvest on|off` writes the local setting; `oats okf harvest-status [--soul X]` reports the effective value, why, and the registered sources. `oats schedule enable|disable <job>` remains the per-source emergency brake, not the switch.
|
|
257
119
|
- **The review trigger is independent of the switch:** a trigger host can review PRs from other hosts' harvesters without harvesting itself.
|
|
258
120
|
|
|
259
|
-
**`knowledge-maintainer
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
- **
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
- **
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
- **
|
|
291
|
-
- **
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
- command logs and tool output;
|
|
304
|
-
- retries that taught nothing;
|
|
305
|
-
- secrets;
|
|
306
|
-
- third-party messages verbatim;
|
|
307
|
-
- things already in the tracker or the docs (link instead).
|
|
308
|
-
- **Form:**
|
|
309
|
-
- `STATE.md` = the current task picture (rewritten);
|
|
310
|
-
- `log.md` = dated events (append-only);
|
|
311
|
-
- `notes/` = **one concept per insight**, with type (Decision / Rejected / Discovery / Limitation / Conclusion / Lesson / Blocker), a one-line claim, the *why*, the evidence and provenance (what was observed, when, from what), and its **generality** (instance-only vs likely true for the soul, a hint to the harvester, not a verdict).
|
|
312
|
-
- **Timing:** capture as it happens, at the decision, not reconstructed at the end; update before compaction and before task boundaries.
|
|
313
|
-
- **Relation to soul knowledge:** consult first; a note that confirms, refines or contradicts an existing concept cites it (`alias/node/concept.md@oid`). That is what lets the harvester situate it.
|
|
314
|
-
- **The theory it teaches in brief:** decision vs description (descriptions drift and lie; decisions are superseded explicitly), code is truth about code, and indexical residue dies with the instance. This is a short version of `knowledge-theory`, taught from the capture side. **Working souls do NOT get the full promotion doctrine**, so there's no duplicate judge.
|
|
315
|
-
|
|
316
|
-
### 2.6 The `okf` team
|
|
317
|
-
|
|
318
|
-
- Onboarding (the oats.framework `oats-onboarding` skill + okf's `okf-trigger-setup`) adds `teams: { okf: { description: Knowledge operations } }` and the `messaging.byTeam.okf` mapping.
|
|
319
|
-
- The package souls carry `team: okf`. A workspace that does not declare `okf` gets the `E_TEAM_UNKNOWN` discovery problem on them (listed with the remedy; as for member souls it's not a spawn refusal, but their instances then land in no messaging team, so harvester↔maintainer talk fails). So onboarding must add it, and `oats trigger test` checks it.
|
|
320
|
-
- The label organises and gates nothing (the teams contract).
|
|
321
|
-
|
|
322
|
-
## 3. Delivery plan
|
|
323
|
-
|
|
324
|
-
**Order:** 3.0.0 (in flight) → kernel 0.28.0 contracts (C1, C2) frozen → the three lanes in parallel → okf 4.0.0 → the 0.28.0 release with the mirror + pin + onboarding.
|
|
325
|
-
|
|
326
|
-
**Contracts frozen first** (in this doc, by the lead; the co-lead ACKs):
|
|
327
|
-
- **C1, package souls:** §2.2.
|
|
328
|
-
- **C2, triggers:** §2.3 (the definition, the event file, the dedup, the CLI).
|
|
329
|
-
- **C3, the harvest provenance block:** §2.4.3.
|
|
330
|
-
- **C4, the okf-team messages:** `question`/`amend-request`/`amended`/`merged`/`closed` (a subject prefix `okf:` + a PR URL). This is prose-level and is owned by the skills.
|
|
331
|
-
|
|
332
|
-
**L1, kernel.** A **Claude kernel developer** (`cli-dev`, a new instance, Opus), in a worktree. Three PRs, each Class B, reviewed by the lead:
|
|
333
|
-
1. **Package souls** (C1): discovery, resolution, spawn by name, status/Desktop JSON `origin: package`, `oats capabilities` feature `package-souls`.
|
|
334
|
-
2. **Triggers** (C2): `kind: "trigger"`, `github.pull_request` polling in the host tick, dedup state, `OATS_TRIGGER_EVENT_FILE`, `oats trigger …`, package trigger templates, feature `triggers`.
|
|
335
|
-
3. **Remove capability agents** (after okf 4.0.0 is mirrored): `agents:` in manifests is refused with a remedy naming package souls.
|
|
336
|
-
|
|
337
|
-
Gates:
|
|
338
|
-
- test-first;
|
|
339
|
-
- scaffold-only probes;
|
|
340
|
-
- a real `gh` poll against a scratch repo in the PR's evidence;
|
|
341
|
-
- the full glob + `smoke:tarball` (kernel dev).
|
|
342
|
-
|
|
343
|
-
**L2, okf** (oats-okf; **the okf expert**, a new `integrations-expert` instance, or the 3.0.0 child continuing once 3.0.0 is tagged, lead's pick; the co-lead reviews and tags):
|
|
344
|
-
- the three capabilities (§2.1);
|
|
345
|
-
- the skill rework:
|
|
346
|
-
- rename memory-harvest → knowledge-theory;
|
|
347
|
-
- new knowledge-harvest, knowledge-review, okf-instance-knowledge, okf-trigger-setup;
|
|
348
|
-
- okf → okf-authoring;
|
|
349
|
-
- the two package souls;
|
|
350
|
-
- the trigger template `harvest-review`;
|
|
351
|
-
- the harvester lifecycle (spawn as a soul, stay alive, retire on merge);
|
|
352
|
-
- the provenance block (C3);
|
|
353
|
-
- the inject (§2.5);
|
|
354
|
-
- the identical-copy test;
|
|
355
|
-
- no symlinks.
|
|
356
|
-
|
|
357
|
-
Gate: **a real end-to-end run** against a scratch KB repo: a source is harvested → the PR opens with provenance → the trigger spawns the maintainer → it amends + merges → the harvester retires. Every step is read back. It requires kernel ≥ 0.28.0.
|
|
358
|
-
|
|
359
|
-
**L3, onboarding** (oats.framework `oats-setup`; **the Phase D driver** `oats-expert-phase-d`):
|
|
360
|
-
- `oats-onboarding` gains "Knowledge operations with OKF":
|
|
361
|
-
- the package pin;
|
|
362
|
-
- the `okf` team + mapping;
|
|
363
|
-
- where to install the trigger (a host with merge-capable credentials; `oats trigger add --from oats.okf:harvest-review`; `oats trigger test`);
|
|
364
|
-
- harvest stays opt-in.
|
|
365
|
-
- `docs/knowledge.md`, `docs/schedules.md` (triggers) and `docs/packages.md` (package souls) get updated.
|
|
366
|
-
- A framework 1.2.0 PR.
|
|
367
|
-
|
|
368
|
-
**L4, Desktop (later):** a Triggers section under the deployment (list, status, test, enable/disable), and package souls on the Souls page with their package origin.
|
|
369
|
-
|
|
370
|
-
**Review:**
|
|
371
|
-
- The lead reviews L1 and L3 and cross-reviews L2.
|
|
372
|
-
- The co-lead reviews and tags L2 and cross-reviews L1.
|
|
373
|
-
- The release: 0.28.0 = L1 + the L2 mirror/pin + L3 pin.
|
|
374
|
-
|
|
375
|
-
## 4. Decisions taken (lead, delegated authority), revisit on request
|
|
376
|
-
|
|
377
|
-
1. **Package souls, not `external:`**, for "sourced from the okf package". One pin versions everything.
|
|
378
|
-
2. **Triggers are schedules of `kind: trigger`**: the same store, tick and spawn path. There's no daemon and no webhook in v1.
|
|
379
|
-
3. **The harvester becomes a package soul** (it needs messaging + a lifetime past its PR). Capability agents are removed after okf 4.0.0.
|
|
380
|
-
4. **The maintainer merges autonomously** when the doctrine passes, **except** where it would supersede a human-accepted decision (`okf-needs-human`).
|
|
381
|
-
5. **The harvester and the maintainer hold no knowledge slot in v1** (no recursive harvest). Revisit when a maintainer's own lessons are wanted.
|
|
382
|
-
6. **okf 3.0.0 is not widened.** The working-soul skill split lands in 4.0.0 with the new capabilities. Removing `memory-harvest` from oats.okf before the harvester has another home would break harvest.
|
|
383
|
-
7. **Harvest stays OFF on the development deployment** until 0.28.0 + okf 4.0.0 pass the end-to-end gate.
|
|
384
|
-
|
|
385
|
-
## 5. Open questions
|
|
386
|
-
|
|
387
|
-
- The maintainer's `work` mode: `directory` + `gh pr checkout` (planned) vs a registered KB clone in worktree mode. The L2 implementer confirms in the first PR.
|
|
388
|
-
- Multi-base PRs: v1 keeps one base per PR (today's delivery). The maintainer's cross-base supersession is out of scope.
|
|
389
|
-
- `aweb.mail` as a trigger source (e.g. "on a mail to `okf-review`") is left for after v1.
|
|
121
|
+
**`knowledge-maintainer`** (a package soul; `work: directory`; `knowledge: none`; capability `oats.okf-maintenance`, plus the workspace's tasks capability when there is one, used read-only).
|
|
122
|
+
|
|
123
|
+
1. The trigger spawns one per PR. It reads `OATS_TRIGGER_EVENT_FILE`, fetches the knowledge-base repository and checks out the PR in its `./work`.
|
|
124
|
+
2. It **situates** the addition: from the provenance, the source soul's owned and read nodes at the accepted base, the neighbouring concepts (duplicates, supersession candidates, the canonical home) and the source soul's other knowledge.
|
|
125
|
+
3. **Tasks:** if the provenance names a tasks provider and refs, and its own tasks capability matches, it reads those tickets. Otherwise the verdict records `tasks: "unavailable"`. This is never a blocker.
|
|
126
|
+
4. **Verdict**, recorded as a structured `okf-review` PR comment: `merge`; `amend+merge` (it pushes fixes, supersession edits in other concepts of the same base, index and log to the PR branch); `request-changes` (it messages the harvester and waits, bounded); `close` (with the reason); `needs-human`. It checks the doctrine's two-part test, one canonical home, explicit supersession and provenance.
|
|
127
|
+
5. **Human-accepted decisions are never superseded silently.** A PR that would supersede a concept with human acceptance evidence is not merged: the maintainer labels it `okf-needs-human` and asks a human. That label is a hard stop that only a human removes.
|
|
128
|
+
6. It merges with the host's `gh` (squash, pinned to the reviewed head), notifies the harvester (`merged` or `closed`) and retires.
|
|
129
|
+
|
|
130
|
+
**Messaging:** the harvester and the maintainer talk through the soul's messaging capability, in the deployment's default team like every instance. There is no dedicated team to declare; a deployment that wants them in another team opts them in locally, as for any soul (see [the team model](2026-09-27-team-model-v2.md)).
|
|
131
|
+
|
|
132
|
+
**GitHub credentials:** the maintainer's host must be able to merge on the knowledge-base repository (`oats trigger test` checks). GitHub forbids self-approval, so with one account for both, either `main` requires no approving review or the trigger's `owner` is a separate reviewer account.
|
|
133
|
+
|
|
134
|
+
### 2.5 The working-soul inject
|
|
135
|
+
|
|
136
|
+
The oats.okf inject teaches a work mode over both kinds of knowledge:
|
|
137
|
+
|
|
138
|
+
- **At task start and after compaction:** read instance memory (`STATE.md`, recent `log.md`, relevant `notes/`), then consult soul knowledge (`oats okf index`, then `cat` what is relevant; follow links, do not bulk-load).
|
|
139
|
+
- **Before compaction and before a task boundary:** update `STATE.md`, `log.md` and `notes/` first.
|
|
140
|
+
- **Every so often while working, and always before a design decision or re-deriving something:** `oats okf search` / `cat`, and re-read your own notes.
|
|
141
|
+
- Use both to situate the task and stay coherent with the soul's accepted decisions. Cite what you relied on (`alias/node/concept.md@<short-oid>`).
|
|
142
|
+
- **Capture with judgment** (§2.5a). The harvester decides what is promoted. Never write accepted knowledge or soul knowledge.
|
|
143
|
+
|
|
144
|
+
### 2.5a Instance-knowledge judgment
|
|
145
|
+
|
|
146
|
+
`okf-instance-knowledge` teaches **what useful instance knowledge is**, not only where to put it. The capture bar is lower than the promotion bar (`knowledge-theory`); they do not compete.
|
|
147
|
+
|
|
148
|
+
- **The capture test:** would my future self after compaction, or the harvester judging this session, decide or act better for having it, and is it absent from the code, the tracker and the repository docs?
|
|
149
|
+
- **Capture:** decisions and why; rejected alternatives; costly discoveries; limitations and the workaround that worked; conclusions (not the investigation's transcript); blockers; human direction and corrections; surprises that contradict soul knowledge (flagged as candidate supersessions); process and environment lessons.
|
|
150
|
+
- **Do not capture:** code descriptions or repository maps; command logs and tool output; retries that taught nothing; secrets; third-party messages verbatim; what the tracker or docs already hold (link instead).
|
|
151
|
+
- **Form:** `STATE.md` is the current task picture (rewritten); `log.md` is dated events (append-only); `notes/` holds one concept per insight, with a type (Decision, Rejected, Discovery, Limitation, Conclusion, Lesson, Blocker), a one-line claim, the why, the evidence and provenance, and its generality (instance-only or likely true for the soul: a hint to the harvester, not a verdict).
|
|
152
|
+
- **Timing:** capture as it happens, at the decision; update before compaction and before task boundaries.
|
|
153
|
+
- **Relation to soul knowledge:** consult first; a note that confirms, refines or contradicts an existing concept cites it, which lets the harvester situate it.
|
|
154
|
+
- **The theory, from the capture side:** decisions versus descriptions (descriptions drift; decisions are superseded explicitly), code is the truth about code, and indexical residue dies with the instance. Working souls do not get the full promotion doctrine, so there is no second judge.
|
|
155
|
+
|
|
156
|
+
## 4. Decisions
|
|
157
|
+
|
|
158
|
+
1. **Package souls, not `external:`**, for "sourced from the okf package": one pin versions everything.
|
|
159
|
+
2. **Triggers are schedules of `kind: trigger`:** the same store, tick and spawn path; no daemon and no webhook.
|
|
160
|
+
3. **Workspace automations are placed by declaration:** `runsOn` names the one host, `owner` the account it acts as, and a host runs one only when both match.
|
|
161
|
+
4. **The harvester is a package soul** (it needs messaging and a lifetime past its PR); capability agents are removed.
|
|
162
|
+
5. **The maintainer merges autonomously** when the doctrine passes, except where it would supersede a human-accepted decision (`okf-needs-human`).
|
|
163
|
+
6. **The harvester and the maintainer hold no knowledge slot** (no recursive harvest).
|
|
164
|
+
7. **Harvest is opt-in per host and opt-out per soul**, and the soul's opt-out is absolute.
|