@open-agent-toolkit/cli 0.2.50 → 0.2.52
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/bootstrap.md +6 -2
- package/assets/docs/cli-utilities/tool-packs.md +87 -33
- package/assets/docs/provider-sync/commands.md +30 -2
- package/assets/docs/provider-sync/config.md +19 -0
- package/assets/docs/provider-sync/manifest-and-drift.md +37 -0
- package/assets/docs/provider-sync/providers.md +69 -2
- package/assets/docs/provider-sync/scope-and-surface.md +44 -0
- package/assets/docs/reference/cli-reference.md +21 -5
- package/assets/docs/reference/file-locations.md +8 -2
- package/assets/docs/reference/oat-directory-structure.md +25 -9
- package/assets/docs/workflows/projects/artifacts.md +9 -4
- package/assets/docs/workflows/projects/evidence-layers.md +110 -1
- package/assets/docs/workflows/projects/implementation-execution.md +13 -0
- package/assets/docs/workflows/projects/lifecycle.md +17 -5
- package/assets/docs/workflows/projects/orchestration-model.md +18 -0
- package/assets/docs/workflows/projects/picking-up-projects.md +26 -9
- package/assets/docs/workflows/projects/pr-flow.md +5 -3
- package/assets/docs/workflows/projects/reviewing-oat-prs.md +12 -8
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +57 -1
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +77 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +3 -3
- package/assets/skills/oat-project-complete/SKILL.md +193 -26
- package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +306 -0
- package/assets/skills/oat-project-complete/scripts/finalize-synced-archive.mjs +125 -0
- package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +106 -0
- package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +110 -0
- package/assets/skills/oat-project-complete/scripts/resolve-synced-archive-entry.mjs +164 -0
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +24 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +11 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-review-provide/SKILL.md +12 -1
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -1
- package/dist/agents/canonical/index.d.ts +2 -0
- package/dist/agents/canonical/index.d.ts.map +1 -1
- package/dist/agents/canonical/index.js +1 -0
- package/dist/agents/canonical/resolve.d.ts +45 -0
- package/dist/agents/canonical/resolve.d.ts.map +1 -0
- package/dist/agents/canonical/resolve.js +175 -0
- package/dist/commands/decision/agents-guidance.d.ts +2 -2
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +1 -4
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +25 -6
- package/dist/commands/docs/init/index.d.ts +7 -1
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +53 -20
- package/dist/commands/doctor/index.d.ts +8 -2
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +157 -46
- package/dist/commands/init/index.d.ts +8 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +64 -26
- package/dist/commands/init/tools/index.d.ts +12 -12
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +430 -99
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-guidance.d.ts +49 -0
- package/dist/commands/init/tools/project-guidance.d.ts.map +1 -0
- package/dist/commands/init/tools/project-guidance.js +144 -0
- package/dist/commands/init/tools/workflows/index.d.ts +7 -0
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +160 -7
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +28 -3
- package/dist/commands/pjm/init.d.ts +5 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +19 -3
- package/dist/commands/project/archive/archive-utils.d.ts +8 -1
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +147 -50
- package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
- package/dist/commands/project/archive/push-runner.js +15 -2
- package/dist/commands/project/dispatch/index.d.ts +10 -0
- package/dist/commands/project/dispatch/index.d.ts.map +1 -0
- package/dist/commands/project/dispatch/index.js +137 -0
- package/dist/commands/project/dispatch/record.d.ts +91 -0
- package/dist/commands/project/dispatch/record.d.ts.map +1 -0
- package/dist/commands/project/dispatch/record.js +402 -0
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +2 -0
- package/dist/commands/project/links/compute.d.ts +1 -0
- package/dist/commands/project/links/compute.d.ts.map +1 -1
- package/dist/commands/project/links/compute.js +5 -4
- package/dist/commands/project/links/index.d.ts +9 -0
- package/dist/commands/project/links/index.d.ts.map +1 -1
- package/dist/commands/project/links/index.js +71 -2
- package/dist/commands/project/list.d.ts +10 -2
- package/dist/commands/project/list.d.ts.map +1 -1
- package/dist/commands/project/list.js +205 -29
- package/dist/commands/project/open/index.d.ts +2 -0
- package/dist/commands/project/open/index.d.ts.map +1 -1
- package/dist/commands/project/open/index.js +16 -1
- package/dist/commands/project/prune/index.d.ts +10 -4
- package/dist/commands/project/prune/index.d.ts.map +1 -1
- package/dist/commands/project/prune/index.js +85 -15
- package/dist/commands/project/pull/index.d.ts +4 -0
- package/dist/commands/project/pull/index.d.ts.map +1 -1
- package/dist/commands/project/pull/index.js +82 -3
- package/dist/commands/project/sync/git.d.ts +9 -0
- package/dist/commands/project/sync/git.d.ts.map +1 -1
- package/dist/commands/project/sync/git.js +18 -0
- package/dist/commands/project/sync/ref-sync.d.ts +16 -1
- package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
- package/dist/commands/project/sync/ref-sync.js +288 -17
- package/dist/commands/project/sync/resolve-target.d.ts +10 -0
- package/dist/commands/project/sync/resolve-target.d.ts.map +1 -1
- package/dist/commands/project/sync/resolve-target.js +56 -1
- package/dist/commands/providers/inspect/inspect.d.ts +8 -1
- package/dist/commands/providers/inspect/inspect.d.ts.map +1 -1
- package/dist/commands/providers/inspect/inspect.js +146 -26
- package/dist/commands/providers/list/list.d.ts +8 -1
- package/dist/commands/providers/list/list.d.ts.map +1 -1
- package/dist/commands/providers/list/list.js +139 -23
- package/dist/commands/providers/providers.types.d.ts +25 -1
- package/dist/commands/providers/providers.types.d.ts.map +1 -1
- package/dist/commands/providers/set/index.d.ts +9 -1
- package/dist/commands/providers/set/index.d.ts.map +1 -1
- package/dist/commands/providers/set/index.js +43 -33
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +11 -0
- package/dist/commands/shared/agents-md.d.ts +42 -14
- package/dist/commands/shared/agents-md.d.ts.map +1 -1
- package/dist/commands/shared/agents-md.js +364 -70
- package/dist/commands/shared/project-scope.d.ts +2 -0
- package/dist/commands/shared/project-scope.d.ts.map +1 -1
- package/dist/commands/shared/project-scope.js +5 -0
- package/dist/commands/state/generate.d.ts +2 -0
- package/dist/commands/state/generate.d.ts.map +1 -1
- package/dist/commands/state/generate.js +93 -28
- package/dist/commands/status/index.d.ts +8 -3
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +147 -32
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +220 -29
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +30 -6
- package/dist/commands/sync/index.d.ts +17 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +106 -41
- package/dist/commands/sync/sync.types.d.ts +39 -2
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts +5 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +73 -0
- package/dist/commands/tools/info/info-tool.d.ts +2 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +34 -12
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +19 -3
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +36 -7
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +150 -21
- package/dist/commands/tools/remove/remove-tools.d.ts +20 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +122 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +19 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +109 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +66 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-evidence.js +132 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts +1 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +44 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +91 -0
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +74 -4
- package/dist/commands/tools/update/update-tools.d.ts +5 -0
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +64 -2
- package/dist/config/oat-config.d.ts +5 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +17 -5
- package/dist/config/user-sync-config.d.ts +1 -0
- package/dist/config/user-sync-config.d.ts.map +1 -1
- package/dist/config/user-sync-config.js +8 -0
- package/dist/drift/detector.d.ts +2 -2
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/drift/detector.js +18 -0
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +5 -0
- package/dist/engine/collection-sync.d.ts +14 -0
- package/dist/engine/collection-sync.d.ts.map +1 -0
- package/dist/engine/collection-sync.js +282 -0
- package/dist/engine/compute-plan.d.ts +8 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +303 -12
- package/dist/engine/engine.types.d.ts +61 -0
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/execute-plan.d.ts +22 -2
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +459 -27
- package/dist/engine/provider-path-safety.d.ts +1 -0
- package/dist/engine/provider-path-safety.d.ts.map +1 -1
- package/dist/engine/provider-path-safety.js +15 -0
- package/dist/engine/scanner.d.ts +2 -2
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +21 -4
- package/dist/fs/io.d.ts +67 -0
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +536 -3
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/manager.d.ts +2 -2
- package/dist/manifest/manager.d.ts.map +1 -1
- package/dist/manifest/manager.js +20 -3
- package/dist/manifest/manifest.types.d.ts +704 -13
- package/dist/manifest/manifest.types.d.ts.map +1 -1
- package/dist/manifest/manifest.types.js +131 -15
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +41 -10
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/cursor/codec/sync-extension.js +41 -10
- package/dist/providers/identity/absolute-paths.d.ts +68 -0
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -0
- package/dist/providers/identity/absolute-paths.js +144 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts +105 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +40 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +146 -0
- package/dist/providers/identity/claude-runtime-observation.js +229 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts +75 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts +37 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.js +539 -0
- package/dist/providers/identity/codex-runtime-observation.js +255 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts +313 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/generic-dispatch-record.js +539 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts +1964 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/oat-dispatch-record.js +691 -0
- package/dist/providers/identity/runtime-observation.d.ts +100 -0
- package/dist/providers/identity/runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/runtime-observation.js +169 -0
- package/dist/providers/shared/index.d.ts +2 -0
- package/dist/providers/shared/index.d.ts.map +1 -1
- package/dist/providers/shared/index.js +1 -0
- package/dist/providers/shared/materialization-extension.d.ts +12 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -1
- package/dist/providers/shared/registry.d.ts +69 -0
- package/dist/providers/shared/registry.d.ts.map +1 -0
- package/dist/providers/shared/registry.js +252 -0
- package/dist/providers/shared/restart-adviser.d.ts +26 -0
- package/dist/providers/shared/restart-adviser.d.ts.map +1 -0
- package/dist/providers/shared/restart-adviser.js +96 -0
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -92,8 +92,10 @@ Config ownership note:
|
|
|
92
92
|
- Synced checkout: `.oat/projects/synced/<project>/` (gitignored nested
|
|
93
93
|
worktree)
|
|
94
94
|
- Synced record: `.oat/projects/synced/<project>.json` (tracked on the parent
|
|
95
|
-
branch)
|
|
96
|
-
-
|
|
95
|
+
branch while the project is active; removed after durable archived closeout)
|
|
96
|
+
- Active synced ref: `refs/oat/projects/<project>` on `origin`
|
|
97
|
+
- Completed synced ref: `refs/oat/completed/<project>` on `origin` (the
|
|
98
|
+
authoritative terminal reachability root after archive)
|
|
97
99
|
- Local: `.oat/projects/local/<project>/`
|
|
98
100
|
- Archived: `.oat/projects/archived/<project>/`
|
|
99
101
|
|
|
@@ -108,6 +110,10 @@ Archive sync surfaces:
|
|
|
108
110
|
- Remote archive base: `archive.s3Uri` in `.oat/config.json`
|
|
109
111
|
- Archive sync command: `oat repo archive sync` or `oat repo archive sync <project-name>`
|
|
110
112
|
- Remote archive snapshot shape: `<archive.s3Uri>/<repo-slug>/projects/YYYYMMDD-<project-name>/`
|
|
113
|
+
- Terminal archive metadata:
|
|
114
|
+
`.oat/projects/archived/<project>/.oat-archive-source.json` binds the
|
|
115
|
+
snapshot to its synced source-ref SHA so a recordless interrupted closeout
|
|
116
|
+
can retry without recreating the active record or checkout.
|
|
111
117
|
- Summary export target:
|
|
112
118
|
`<repo>/<archive.summaryExportPath>/YYYYMMDD-<project-name>.md` when
|
|
113
119
|
configured. The archive report returns this absolute filesystem path, while
|
|
@@ -58,14 +58,21 @@ Project scope is used for project workflows and repo-local sync state. User scop
|
|
|
58
58
|
|
|
59
59
|
## `.oat/sync/` details
|
|
60
60
|
|
|
61
|
-
| Path | Purpose
|
|
62
|
-
| ------------------------- |
|
|
63
|
-
| `.oat/sync/manifest.json` | Records sync-managed
|
|
64
|
-
| `.oat/sync/config.json` | Project sync behavior, provider settings, and known-stray choices
|
|
61
|
+
| Path | Purpose |
|
|
62
|
+
| ------------------------- | ------------------------------------------------------------------- |
|
|
63
|
+
| `.oat/sync/manifest.json` | Records sync-managed entries, collection ownership, and drift state |
|
|
64
|
+
| `.oat/sync/config.json` | Project sync behavior, provider settings, and known-stray choices |
|
|
65
65
|
|
|
66
66
|
The equivalent user files are `~/.oat/sync/manifest.json` and
|
|
67
67
|
`~/.oat/sync/config.json`.
|
|
68
68
|
|
|
69
|
+
Manifest version 2 stores `collections` alongside per-entry evidence. Each
|
|
70
|
+
collection record uses scope-relative canonical/provider paths and records
|
|
71
|
+
whether OAT created the exact alias or adopted an existing one. Its inherited
|
|
72
|
+
entries refer back to that collection; the manifest never authorizes deletion
|
|
73
|
+
through the alias target. Writes are atomic, and unchanged manifests from the
|
|
74
|
+
older per-entry schema normalize in memory before the next successful sync.
|
|
75
|
+
|
|
69
76
|
`config.json` currently includes:
|
|
70
77
|
|
|
71
78
|
- `version`
|
|
@@ -181,7 +188,8 @@ Each OAT project lives under:
|
|
|
181
188
|
- `.oat/projects/synced/<project>/` for a gitignored nested worktree whose
|
|
182
189
|
history is published to `refs/oat/projects/<project>`
|
|
183
190
|
- `.oat/projects/synced/<project>.json` for the tracked discovery record that
|
|
184
|
-
identifies the ref, remote, and active
|
|
191
|
+
identifies the ref, remote, and active transaction state; archived closeout
|
|
192
|
+
deletes this record after terminal durability is verified
|
|
185
193
|
- `.oat/projects/local/<project>/`
|
|
186
194
|
- `.oat/projects/archived/<project>/`
|
|
187
195
|
|
|
@@ -189,16 +197,24 @@ Completion and archive sync behavior:
|
|
|
189
197
|
|
|
190
198
|
- When archiving is selected, `oat-project-complete` archives locally into
|
|
191
199
|
`.oat/projects/archived/<project>/`. For a synced project, the snapshot omits
|
|
192
|
-
the nested checkout's `.git` pointer and `reviews
|
|
193
|
-
|
|
194
|
-
project
|
|
200
|
+
the nested checkout's `.git` pointer and `reviews/`. After required local and
|
|
201
|
+
configured S3 durability succeeds, completion makes
|
|
202
|
+
`refs/oat/completed/<project>` authoritative, removes the nested worktree,
|
|
203
|
+
and deletes the tracked JSON record. Full-SHA links remain reachable through
|
|
204
|
+
the completed ref.
|
|
205
|
+
- Both a completed-only ref and completed plus same-SHA active alias are valid
|
|
206
|
+
terminal shapes. The alias is inert and ignored by list, pull, and open;
|
|
207
|
+
differing SHAs are a hard mismatch with explicit recovery guidance.
|
|
195
208
|
- When archiving is disabled or declined, completion leaves the synced
|
|
196
209
|
checkout and ref in place, pushes the finalized artifacts, and exact-path
|
|
197
210
|
commits the tracked record as complete.
|
|
198
|
-
- If `archive.s3SyncOnComplete=true` and `archive.s3Uri` is configured, completion
|
|
211
|
+
- If `archive.s3SyncOnComplete=true` and `archive.s3Uri` is configured, completion must successfully upload a dated snapshot such as `<archive.s3Uri>/<repo-slug>/projects/20260401-<project>/` before it retires the active record and checkout.
|
|
199
212
|
- `oat repo archive sync` syncs all repo archived projects down from S3 into `.oat/projects/archived/`.
|
|
200
213
|
- `oat repo archive sync <project-name>` syncs the latest dated remote snapshot for a single project into `.oat/projects/archived/<project-name>/`.
|
|
201
214
|
- Default archive sync is non-destructive toward unrelated local-only archive data, but it does replace a local project archive when a newer dated remote snapshot is selected for that same project.
|
|
215
|
+
- `oat project prune` is separate and destructive: for a terminal project it
|
|
216
|
+
removes the completed ref and any matching active alias, while leaving local
|
|
217
|
+
and S3 archive snapshots intact. A ref mismatch blocks deletion.
|
|
202
218
|
|
|
203
219
|
Typical contents:
|
|
204
220
|
|
|
@@ -28,10 +28,15 @@ rebases it on the fetched project ref, and pushes only that ref. Arrival skills
|
|
|
28
28
|
run `oat project pull` before reading artifacts so a record or remote ref can
|
|
29
29
|
materialize the checkout first.
|
|
30
30
|
|
|
31
|
-
The tracked JSON record is routing metadata, not a copy of the project.
|
|
32
|
-
identifies the slug, `origin`, ref, status
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
The tracked JSON record is active routing metadata, not a copy of the project.
|
|
32
|
+
It identifies the slug, `origin`, active ref, and status. The active project ref
|
|
33
|
+
remains the source of truth for active artifact content and history.
|
|
34
|
+
|
|
35
|
+
Archived closeout transitions terminal identity to
|
|
36
|
+
`refs/oat/completed/<project>`, deletes the active record and checkout, and
|
|
37
|
+
persists source-ref identity in local archive metadata. Arrival and pull flows
|
|
38
|
+
never rematerialize a completed project as active state: the completed ref and
|
|
39
|
+
archive metadata own terminal reachability and retry identity.
|
|
35
40
|
|
|
36
41
|
## Core artifacts
|
|
37
42
|
|
|
@@ -63,7 +63,7 @@ launched**, and it records:
|
|
|
63
63
|
`gate-target` (adapters may add a more specific diagnostic but never replace
|
|
64
64
|
or rename these);
|
|
65
65
|
- the ordered `candidates_considered` before launch (never sorted);
|
|
66
|
-
- launch acceptance status (`accepted` or `
|
|
66
|
+
- launch acceptance status (`accepted` or `blocked-before-start`) and mechanism.
|
|
67
67
|
|
|
68
68
|
Because the launcher constructs the invocation payload itself, this layer does
|
|
69
69
|
not depend on any child cooperation. A launch is judged consistent only when its
|
|
@@ -75,6 +75,20 @@ This layer maps to Dispatch Report V1 and its provenance record; see the
|
|
|
75
75
|
[Dispatch Report V1 / producer provenance](dispatch-ceiling.md#dispatch-report-v1-and-producer-provenance)
|
|
76
76
|
section.
|
|
77
77
|
|
|
78
|
+
For project-aware work, OAT persists this native dispatch lineage as one
|
|
79
|
+
generic record per request under the project's `dispatch/` directory. The
|
|
80
|
+
generic snake-case fields remain authoritative. A namespaced `oat` block adds
|
|
81
|
+
only canonical-role identity, proven pre-start rejection, fallback linkage,
|
|
82
|
+
and optional runtime observation. `DispatchReportV1` and the parseable
|
|
83
|
+
`Dispatch:` compatibility stamp keep their existing byte shape.
|
|
84
|
+
|
|
85
|
+
The launcher constructs and redacts the complete payload before calling the
|
|
86
|
+
native host, then records the host's accepted or `blocked-before-start` result
|
|
87
|
+
immediately. Only a provider-wrapper attestation proving that no child started
|
|
88
|
+
can authorize one fresh, exact-target fallback record. Timeout, `BLOCKED`,
|
|
89
|
+
refusal after acceptance, runtime mismatch, missing telemetry, and malformed
|
|
90
|
+
output cannot authorize replacement.
|
|
91
|
+
|
|
78
92
|
## Layer 3 — Runtime-observed identity (optional corroboration)
|
|
79
93
|
|
|
80
94
|
Layer 3 is the only layer that reflects what a runtime said about itself, and it
|
|
@@ -90,6 +104,95 @@ missing or `not-reported` runtime identity **never invalidates** the
|
|
|
90
104
|
launcher-owned configured-invocation evidence in Layer 2. Selected model and
|
|
91
105
|
effort axes stay exact even when runtime producer identity is not reported.
|
|
92
106
|
|
|
107
|
+
### Provider metadata observation
|
|
108
|
+
|
|
109
|
+
`oat project dispatch record` accepts an optional post-launch observation event
|
|
110
|
+
whose `metadata` is a provider envelope — `provider`, `observedAt`, and
|
|
111
|
+
`entries` — and normalizes it against the record's own immutable configured
|
|
112
|
+
invocation. `entries` may be raw, unmodified provider output. The result is stored under the record's `oat.runtimeObservation`.
|
|
113
|
+
|
|
114
|
+
The channel is metadata-only and capability-gated:
|
|
115
|
+
|
|
116
|
+
| Provider | Observed axes | Notes |
|
|
117
|
+
| -------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| Codex | child lineage, role, model, effort | Read from `session_meta` and `turn_context` metadata entries. No captured Codex rollout reports a service tier, so that axis never populates today. |
|
|
119
|
+
| Claude | role, model, effort, service tier; lineage is root-or-child | Read from on-disk `assistant` entry metadata (`attributionAgent`, `effort`, `isSidechain`) plus `message.model` and `message.usage.service_tier`. |
|
|
120
|
+
| Cursor | none | Explicitly `not-reported`; requested values are never copied into it. |
|
|
121
|
+
|
|
122
|
+
Parsers classify entries by their `type` discriminator alone, so a conversation
|
|
123
|
+
entry's body is never read, and only bounded provider identifiers are extracted.
|
|
124
|
+
The Claude parser reads `assistant` entry metadata, which is not the same as
|
|
125
|
+
reading a conversation: it reaches inside `message` by exactly two explicit key
|
|
126
|
+
paths and never spreads, enumerates, or filters that object, so
|
|
127
|
+
`message.content` is never touched rather than being dropped afterwards.
|
|
128
|
+
|
|
129
|
+
Claude reports lineage only as a binary: `root` for a main session and
|
|
130
|
+
`depth-unknown` for a subagent turn. No depth, nesting, or ancestry field exists
|
|
131
|
+
on any captured assistant entry and `parentUuid` links messages within one agent
|
|
132
|
+
rather than agents to each other, so a depth number is reported unknown rather
|
|
133
|
+
than derived.
|
|
134
|
+
|
|
135
|
+
The guarantee is the projection, not caller discipline. Provider parsing happens
|
|
136
|
+
entirely inside the provider module, and what comes back is a flat, closed set
|
|
137
|
+
of neutral facts — lineage, role, model, effort, service tier, correlation —
|
|
138
|
+
whose key names are owned by OAT rather than by the provider. That projection,
|
|
139
|
+
never the raw input, is what the sensitive-content boundary inspects and what is
|
|
140
|
+
compared against the configured invocation. `entries` are never persisted in any
|
|
141
|
+
form.
|
|
142
|
+
|
|
143
|
+
Emitting neutral keys rather than mirroring the provider's own entry shape is
|
|
144
|
+
deliberate. Mirroring a source shape means inheriting its field names, and a
|
|
145
|
+
provider is free to name a field anything: an earlier revision passed the
|
|
146
|
+
provider's shape through and carried `sessionId` and `message` into the output,
|
|
147
|
+
both of which classify as sensitive, which made every real Claude transcript
|
|
148
|
+
unrecordable.
|
|
149
|
+
|
|
150
|
+
A caller may therefore hand over an unmodified rollout or session log: every
|
|
151
|
+
field outside the fact set, including instruction text, conversation bodies,
|
|
152
|
+
working directories, and repository identity, is dropped before the record
|
|
153
|
+
boundary and is never read in the first place. Requiring pre-sanitized input
|
|
154
|
+
instead would push the stripper into every caller, which is a larger leak
|
|
155
|
+
surface than the one it removes.
|
|
156
|
+
|
|
157
|
+
Comparison covers only the axes both sides report, and `comparedAxes` records
|
|
158
|
+
exactly which ones. This qualifier is load-bearing: `matching` means "every axis
|
|
159
|
+
in `comparedAxes` agreed", never "the configured invocation was confirmed". An
|
|
160
|
+
observation reporting only a service tier can be `matching` while model, role,
|
|
161
|
+
and effort are all unknown, so read `comparedAxes` — or the `on role+model`
|
|
162
|
+
qualifier in human output — before treating a match as corroboration. With no
|
|
163
|
+
comparable axis the match is `not-comparable`, because silence is not agreement.
|
|
164
|
+
|
|
165
|
+
An axis a provider genuinely does not expose (`not-exposed`) is excluded rather
|
|
166
|
+
than compared as a literal. That value is reserved for a truly absent axis: an
|
|
167
|
+
axis a provider does report is recorded with its observed value, and an axis it
|
|
168
|
+
simply did not mention on a given run is left unreported. An axis the configured invocation names under two equally
|
|
169
|
+
authoritative spellings — a canonical role name and its materialized native
|
|
170
|
+
selector — matches either.
|
|
171
|
+
|
|
172
|
+
`match` and `comparedAxes` are always derived at the durable-write boundary from
|
|
173
|
+
the record's own configured invocation. A caller that submits a finished
|
|
174
|
+
observation cannot assert its own verdict, and an observation naming a provider
|
|
175
|
+
the record does not use is refused.
|
|
176
|
+
|
|
177
|
+
Request correlation is verified only when the provider declares one: a session
|
|
178
|
+
that names a different request is declined, and a session that declares none is
|
|
179
|
+
attributed to the request the caller paired it with. In practice neither
|
|
180
|
+
provider declares an OAT request id today — no captured Codex rollout carries
|
|
181
|
+
`session_meta.request_id`, and Claude's own `requestId` is a per-turn API
|
|
182
|
+
identifier rather than a dispatch request — so correlation is caller-asserted
|
|
183
|
+
for both, and the declared-correlation check is a forward-compatible guard.
|
|
184
|
+
|
|
185
|
+
A parse failure, a declined request correlation, an unsupported provider, or an
|
|
186
|
+
envelope too large to project all produce `not-reported`. A `runtime-observation`
|
|
187
|
+
event carrying neither `metadata` nor `observation` is a malformed event and is
|
|
188
|
+
rejected by the schema rather than degraded. None of them copies a requested
|
|
189
|
+
argument or a materialized pin into observed state, and `mismatching` is
|
|
190
|
+
evidence only: it authorizes no replacement, retry, or fallback, and leaves
|
|
191
|
+
`launch_status`, `child_outcome`, and every configured control untouched. The
|
|
192
|
+
`--json` result reports `runtimeIdentity.configured` and
|
|
193
|
+
`runtimeIdentity.observed` as separate objects that are never merged into one
|
|
194
|
+
"effective" identity.
|
|
195
|
+
|
|
93
196
|
## How the smoke runner consumes these layers
|
|
94
197
|
|
|
95
198
|
The smoke runner's evidence pipeline reads all three layers and asserts only on
|
|
@@ -108,6 +211,12 @@ collection. The collector then flows the evidence through three stages:
|
|
|
108
211
|
artifacts, carrying `reported` / `not-reported` runtime status without
|
|
109
212
|
letting a missing Layer 3 fail a Layer 2 assertion.
|
|
110
213
|
|
|
214
|
+
The collector projects `runtimeObservation` the same way: it reads committed
|
|
215
|
+
records and never launches a provider, so an observation appears in a bundle
|
|
216
|
+
only because a launcher-owned record already carried one. A partially filled
|
|
217
|
+
observation normalizes to `not-reported` rather than being completed from any
|
|
218
|
+
other layer.
|
|
219
|
+
|
|
111
220
|
For how to run this end to end and when to refresh the fixture, see
|
|
112
221
|
[Smoke testing](../../contributing/smoke-testing.md).
|
|
113
222
|
|
|
@@ -32,6 +32,9 @@ and updates project state.
|
|
|
32
32
|
third tier.
|
|
33
33
|
- **Parallelism:** plan-declared phases may run concurrently in separate
|
|
34
34
|
worktrees. Tasks inside one phase remain serial.
|
|
35
|
+
- **Dispatch evidence:** project-aware launches persist one generic request
|
|
36
|
+
record plus namespaced OAT native dispatch lineage without changing native
|
|
37
|
+
model or provider selection.
|
|
35
38
|
|
|
36
39
|
Tasks execute serially in one worktree for the phase.
|
|
37
40
|
|
|
@@ -69,6 +72,16 @@ The root:
|
|
|
69
72
|
The root does not implement phase tasks while an accepted phase launch owns
|
|
70
73
|
that scope.
|
|
71
74
|
|
|
75
|
+
Before a native launch, the root constructs and redacts the complete generic
|
|
76
|
+
dispatch record and OAT role event. Immediately after the host returns, it runs
|
|
77
|
+
`oat project dispatch record --project <project-path> --event-file - --json`
|
|
78
|
+
with the accepted or `blocked-before-start` result. An accepted launch closes
|
|
79
|
+
replacement. Only an explicit rejection proving no child started permits one
|
|
80
|
+
fresh request that preserves the exact target and controls and is labeled as
|
|
81
|
+
an approximation. Timeout, `BLOCKED`, refusal after acceptance, runtime
|
|
82
|
+
mismatch, missing telemetry, and malformed output are terminal evidence, not
|
|
83
|
+
fallback triggers.
|
|
84
|
+
|
|
72
85
|
### Phase implementer
|
|
73
86
|
|
|
74
87
|
The phase implementer receives one `Phase Scope`, reads the relevant artifacts
|
|
@@ -84,14 +84,26 @@ On completion, OAT treats archive handling as an explicit closeout choice:
|
|
|
84
84
|
- For a synced project, closeout first finalizes the project artifacts and
|
|
85
85
|
pushes them to `refs/oat/projects/<project>`. Archive then requires a clean,
|
|
86
86
|
fully pushed checkout; copies it without the `.git` pointer or `reviews/`;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
87
|
+
seals configured durable exports; transitions terminal reachability to
|
|
88
|
+
`refs/oat/completed/<project>`; removes the nested checkout; and deletes the
|
|
89
|
+
tracked JSON record in the parent lifecycle commit. This order keeps
|
|
90
|
+
SHA-pinned PR links valid without leaving active discovery state behind.
|
|
91
|
+
- A completed-only ref and a completed ref plus same-SHA active alias are both
|
|
92
|
+
valid terminal shapes. The active alias is inert: list omits it and pull/open
|
|
93
|
+
reject it. Differing SHAs are a hard mismatch with recovery guidance.
|
|
94
|
+
- If `.oat/config.json` enables `archive.s3SyncOnComplete` and sets `archive.s3Uri`, completion requires the S3 upload of a dated snapshot such as `<archive.s3Uri>/<repo-slug>/projects/20260401-<project>/` to succeed before terminal record/ref cleanup. A failed configured upload leaves retry identity intact and does not claim closeout.
|
|
91
95
|
- If `.oat/config.json` sets `archive.awsProfile` and/or `archive.awsRegion`, those values are forwarded to every `aws` invocation triggered by completion (preflight checks + `aws s3 sync`) and override any ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` / `AWS_REGION` / `AWS_DEFAULT_REGION` values. The repo's archive-scoped credentials are treated as deliberate intent so users don't have to unset shell env vars before running completion. See [`config-and-local-state.md`](../../cli-utilities/config-and-local-state.md) for the full precedence chain.
|
|
92
96
|
- If `.oat/config.json` sets `archive.summaryExportPath`, completion copies `summary.md` to `<archive.summaryExportPath>/20260401-<project>.md`.
|
|
93
|
-
- Missing or unusable AWS CLI configuration
|
|
97
|
+
- Missing or unusable AWS CLI configuration blocks synced terminal cleanup when S3 durability is configured; when S3 sync is not configured, it is not part of the durability requirement.
|
|
94
98
|
- `oat repo archive sync` can later sync all archived projects, or one named archived project, back down from S3; it selects the latest dated remote snapshot and materializes it into the local bare archive tree.
|
|
99
|
+
- Persisted archive metadata binds the snapshot to the source-ref SHA, allowing
|
|
100
|
+
an interrupted closeout or legacy complete record to resume without
|
|
101
|
+
rematerializing an active project. Dashboard and list surfaces omit fully
|
|
102
|
+
retired projects and report precise cleanup or ref-mismatch diagnoses for
|
|
103
|
+
remaining legacy state.
|
|
104
|
+
- `oat project links` continues to render full-SHA links through the completed
|
|
105
|
+
ref. `oat project prune` is a separate destructive choice that removes
|
|
106
|
+
terminal ref reachability but preserves local and S3 archive snapshots.
|
|
95
107
|
|
|
96
108
|
### Phase status: `pr_open`
|
|
97
109
|
|
|
@@ -76,12 +76,14 @@ sequenceDiagram
|
|
|
76
76
|
participant Root as Project root
|
|
77
77
|
participant Adapter as Project adapter
|
|
78
78
|
participant Engine as Dispatch engine
|
|
79
|
+
participant Journal as Project dispatch journal
|
|
79
80
|
participant Phase as Phase implementer
|
|
80
81
|
|
|
81
82
|
Root->>Adapter: Phase + lifecycle authority
|
|
82
83
|
Adapter->>Engine: Provider-neutral dispatch request
|
|
83
84
|
Engine-->>Root: Exact route + request ID
|
|
84
85
|
Root->>Phase: Phase Scope
|
|
86
|
+
Root->>Journal: Accepted or blocked-before-start record
|
|
85
87
|
Phase-->>Root: Phase report + commits
|
|
86
88
|
```
|
|
87
89
|
|
|
@@ -118,6 +120,22 @@ original `request_id`.
|
|
|
118
120
|
This preserves continuity without allowing replacement after an accepted failed
|
|
119
121
|
launch.
|
|
120
122
|
|
|
123
|
+
## Native Dispatch Lineage
|
|
124
|
+
|
|
125
|
+
The launcher constructs and redacts the complete generic record plus the
|
|
126
|
+
namespaced OAT role event before it calls the native host. Immediately after
|
|
127
|
+
the host returns, the project adapter validates and persists the accepted or
|
|
128
|
+
`blocked-before-start` state with `oat project dispatch record`. The command is
|
|
129
|
+
a recorder only; it never launches a provider or changes selection authority.
|
|
130
|
+
|
|
131
|
+
An accepted handle owns the scope and closes replacement. One fresh fallback
|
|
132
|
+
record is legal only when the native wrapper proves no child started, links the
|
|
133
|
+
trigger and fallback request IDs, preserves the exact provider/model/effort/
|
|
134
|
+
route/authority controls, resolves canonical role identity, and labels the
|
|
135
|
+
fresh child as an approximation. Timeout, `BLOCKED`, refusal after acceptance,
|
|
136
|
+
runtime mismatch, missing telemetry, interruption, and malformed output never
|
|
137
|
+
authorize a fallback.
|
|
138
|
+
|
|
121
139
|
## Optional Third Tier
|
|
122
140
|
|
|
123
141
|
Nested work is appropriate when the work itself benefits:
|
|
@@ -25,6 +25,14 @@ the nested checkout. When the selected project is a coordination parent, pull
|
|
|
25
25
|
also discovers and pulls its child projects by default. Pass `--no-children`
|
|
26
26
|
only when you intentionally want the selected project alone.
|
|
27
27
|
|
|
28
|
+
Completed projects are not adoption candidates. Their authoritative ref is
|
|
29
|
+
`refs/oat/completed/<project>`; both `pull` and `open` return a terminal
|
|
30
|
+
diagnosis instead of recreating an archived checkout or record. A same-SHA
|
|
31
|
+
active ref may remain as an inert alias and is ignored. Differing active and
|
|
32
|
+
completed SHAs require repair before lifecycle work continues. The same guard
|
|
33
|
+
applies to coordination children: a terminal child discovered while pulling
|
|
34
|
+
its parent is reported and skipped rather than adopted.
|
|
35
|
+
|
|
28
36
|
After adoption, set or open the project through the normal lifecycle command
|
|
29
37
|
you are using. Arrival-aware project skills pull before reading its artifacts.
|
|
30
38
|
|
|
@@ -47,17 +55,19 @@ you are using. Arrival-aware project skills pull before reading its artifacts.
|
|
|
47
55
|
project ref during sync operations such as `pull`; do not expect a generic
|
|
48
56
|
clone or `git fetch` to materialize the checkout.
|
|
49
57
|
|
|
50
|
-
## Why
|
|
58
|
+
## Why completed refs remain durable
|
|
51
59
|
|
|
52
|
-
`refs/oat/
|
|
60
|
+
`refs/oat/completed/<project>` is a real Git ref locally and on `origin`. The
|
|
53
61
|
objects reachable from it remain garbage-collection roots even when no nested
|
|
54
62
|
checkout exists. Branch pruning, remote-tracking-ref pruning, and
|
|
55
|
-
`git worktree prune` do not delete the
|
|
56
|
-
retains
|
|
63
|
+
`git worktree prune` do not delete the completed ref. Completion deliberately
|
|
64
|
+
retains this terminal reachability root so pinned PR links remain valid.
|
|
57
65
|
|
|
58
|
-
Only the explicit destructive operation `oat project prune` removes the
|
|
59
|
-
and
|
|
60
|
-
review its warnings before using
|
|
66
|
+
Only the explicit destructive operation `oat project prune` removes the
|
|
67
|
+
completed ref and any matching active alias. Treat that as permanent Git
|
|
68
|
+
project-history reachability deletion and review its warnings before using
|
|
69
|
+
`--force`. Prune does not remove durable local or S3 archive snapshots, and it
|
|
70
|
+
refuses to delete either ref when their SHAs differ.
|
|
61
71
|
|
|
62
72
|
## Archive contents
|
|
63
73
|
|
|
@@ -65,8 +75,15 @@ When archive is selected, completion copies a synced project into
|
|
|
65
75
|
`.oat/projects/archived/<project>/` without the nested checkout's `.git`
|
|
66
76
|
pointer or `reviews/`. S3 snapshots also omit `pr/`, following the existing
|
|
67
77
|
archive policy. When archive is disabled or declined, the active synced
|
|
68
|
-
checkout remains in place.
|
|
69
|
-
|
|
78
|
+
checkout remains in place. Successful archived closeout instead uploads the S3
|
|
79
|
+
snapshot first when configured, makes the completed ref authoritative, removes
|
|
80
|
+
the checkout, and deletes the tracked JSON record. The local archive metadata
|
|
81
|
+
retains the source-ref identity needed for recordless retries and later S3
|
|
82
|
+
restore without recreating active state.
|
|
83
|
+
|
|
84
|
+
If closeout is interrupted after terminal archive identity exists, rerun
|
|
85
|
+
completion so it can resume from the completed ref and archive metadata. Do not
|
|
86
|
+
use `pull` or `open` to recreate an active record or checkout.
|
|
70
87
|
|
|
71
88
|
## Related
|
|
72
89
|
|
|
@@ -76,9 +76,11 @@ Both completion orderings are supported:
|
|
|
76
76
|
|
|
77
77
|
An open PR is not a completion blocker. When completion archives project
|
|
78
78
|
artifacts, the archive-aware flow regenerates and synchronizes the open PR body
|
|
79
|
-
so its artifact links remain valid. Synced completion
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
so its artifact links remain valid. Synced completion makes
|
|
80
|
+
`refs/oat/completed/<project>` authoritative at the verified source SHA. A
|
|
81
|
+
same-SHA `refs/oat/projects/<project>` ref may remain only as an inert alias;
|
|
82
|
+
the completed ref keeps the SHA-pinned links resolvable after the nested
|
|
83
|
+
checkout and tracked record are removed.
|
|
82
84
|
|
|
83
85
|
## Reference artifacts
|
|
84
86
|
|
|
@@ -6,17 +6,21 @@ description: Understand synced-project records, SHA-pinned artifact links, and t
|
|
|
6
6
|
# Reviewing OAT PRs
|
|
7
7
|
|
|
8
8
|
A PR for a synced OAT project contains the implementation diff without placing
|
|
9
|
-
the agent-facing project tree on the feature branch.
|
|
10
|
-
|
|
11
|
-
the PR body.
|
|
9
|
+
the agent-facing project tree on the feature branch. While the project is
|
|
10
|
+
active, reviewers discover its context through a small tracked record and a
|
|
11
|
+
generated links block in the PR body.
|
|
12
12
|
|
|
13
13
|
## The synced record
|
|
14
14
|
|
|
15
|
-
`.oat/projects/synced/<project>.json` is tracked on the feature branch
|
|
16
|
-
names the project slug, `origin`,
|
|
17
|
-
project
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
`.oat/projects/synced/<project>.json` is tracked on the feature branch while
|
|
16
|
+
the project is active. It names the project slug, `origin`, and
|
|
17
|
+
`refs/oat/projects/<project>`. The record and active ref are discovery and
|
|
18
|
+
lifecycle metadata; the project artifacts themselves live on the project ref.
|
|
19
|
+
|
|
20
|
+
Successful archived closeout deletes the tracked record and makes
|
|
21
|
+
`refs/oat/completed/<project>` the authoritative terminal reachability root.
|
|
22
|
+
The PR's existing SHA-pinned artifact links remain valid through that completed
|
|
23
|
+
ref even after the active checkout and record are gone.
|
|
20
24
|
|
|
21
25
|
## The artifact links block
|
|
22
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-dispatch-subagents
|
|
3
|
-
version: 1.2.
|
|
3
|
+
version: 1.2.4
|
|
4
4
|
description: Use when an OAT skill or workflow needs provider-neutral selection, launch, recovery, or evidence for bounded subagent work without project lifecycle policy.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: false
|
|
@@ -129,6 +129,62 @@ decomposition.
|
|
|
129
129
|
The optional policy and ceiling are already-resolved inputs. Do not infer where
|
|
130
130
|
they came from or resolve project state to obtain them.
|
|
131
131
|
|
|
132
|
+
## Native Dispatch Lineage
|
|
133
|
+
|
|
134
|
+
For a project-aware dispatch, the calling workflow records native dispatch
|
|
135
|
+
lineage through the project adapter; this provider-neutral engine never writes
|
|
136
|
+
project state itself.
|
|
137
|
+
|
|
138
|
+
1. Construct the complete generic record and namespaced OAT event, redact it,
|
|
139
|
+
and validate sensitive-content exclusion before the native host call or
|
|
140
|
+
launch. Construction is in memory; do not claim a launch result yet.
|
|
141
|
+
2. Invoke the exact native target once. Immediately after the host returns,
|
|
142
|
+
record either `launch_status: accepted` or
|
|
143
|
+
`launch_status: blocked-before-start` in the generic dispatch record. A
|
|
144
|
+
blocked result also requires the provider-wrapper attestation
|
|
145
|
+
`provesNoChildStarted: true`.
|
|
146
|
+
3. Preserve the exact target and controls: provider, model, effort, reasoning
|
|
147
|
+
mode, service tier, route, authority, sandbox/tool payload, deadline, and
|
|
148
|
+
retry limit. Namespaced evidence cannot redefine any generic field.
|
|
149
|
+
4. Only a proven pre-start rejection permits one fresh fallback record; that
|
|
150
|
+
one fallback requires `provesNoChildStarted: true`. It preserves the exact
|
|
151
|
+
target and controls, links both request IDs,
|
|
152
|
+
includes resolved canonical role identity, and says `approximation: true`.
|
|
153
|
+
5. Timeout, `BLOCKED`, refusal after acceptance, runtime mismatch, missing
|
|
154
|
+
telemetry, malformed output, and interruption never authorize fallback or
|
|
155
|
+
replacement. Continue only through the accepted handle or stop.
|
|
156
|
+
|
|
157
|
+
Pre-start native-selection rejection is a closed event set, disjoint from
|
|
158
|
+
terminal child-outcome codes. Use exactly one of `native-role-unavailable`,
|
|
159
|
+
`native-target-unavailable`, `native-selector-unsupported`,
|
|
160
|
+
`native-catalog-unsatisfying`, `capability-unresolved-or-unsupported`,
|
|
161
|
+
`wrapper-payload-rejected`, or `wrapper-launch-refused`. The recorder rejects
|
|
162
|
+
every other code, and it names the prohibited outcome family when a terminal
|
|
163
|
+
code such as `timeout` is submitted. A fallback additionally requires the
|
|
164
|
+
trigger record to carry resolved canonical role evidence, and the fallback's
|
|
165
|
+
role evidence must equal it exactly.
|
|
166
|
+
|
|
167
|
+
`wrapper-launch-refused` covers only conditions in which the launch surface
|
|
168
|
+
declined the request and no child process was ever created: a rejected or
|
|
169
|
+
unsupported payload, a refused authorization scope, an unavailable or
|
|
170
|
+
unregistered target, or a wrapper precondition failure raised before spawn. Any
|
|
171
|
+
condition in which a child process was created — including spawn success
|
|
172
|
+
followed by immediate exit, a crash, a broken handle, or a lost transport — is a
|
|
173
|
+
terminal outcome, not a pre-start rejection, and must be recorded through
|
|
174
|
+
`child_outcome`. If you cannot prove the child never existed, you cannot set
|
|
175
|
+
`provesNoChildStarted: true`, and no fallback is authorized.
|
|
176
|
+
|
|
177
|
+
Project-aware callers pass the validated record and event on standard input:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
oat project dispatch record \
|
|
181
|
+
--project "$PROJECT_PATH" \
|
|
182
|
+
--event-file - \
|
|
183
|
+
--json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The command validates and persists evidence only. It never launches a provider.
|
|
187
|
+
|
|
132
188
|
## Capability and Authorization
|
|
133
189
|
|
|
134
190
|
Classify delegation before launch:
|
|
@@ -191,7 +191,9 @@ current nested dispatcher. It does not imply a stable enum or authorize
|
|
|
191
191
|
reconstruction of a materialized lifecycle variant.
|
|
192
192
|
|
|
193
193
|
`role_selector` is the exact provider or harness agent-type selector, when that
|
|
194
|
-
surface exists. Preserve opaque selectors byte-for-byte
|
|
194
|
+
surface exists. Preserve opaque selectors byte-for-byte, within the
|
|
195
|
+
256-character identifier bound described under
|
|
196
|
+
[Size and Content Bounds](#size-and-content-bounds).
|
|
195
197
|
|
|
196
198
|
Use the stable selection reasons `native-catalog`,
|
|
197
199
|
`native-catalog-unsatisfying`, `pre-start-rejection`, `inherit`, and
|
|
@@ -257,3 +259,77 @@ the interpreted service tier when known.
|
|
|
257
259
|
A service tier never changes `model_class_floor` or `floor_satisfaction`.
|
|
258
260
|
Unknown tier semantics must be recorded as a diagnostic and may block a
|
|
259
261
|
consequential route.
|
|
262
|
+
|
|
263
|
+
## Size and Content Bounds
|
|
264
|
+
|
|
265
|
+
A dispatch record is evidence, not a document. Validation enforces these bounds
|
|
266
|
+
and fails closed; know them before authoring a record rather than discovering
|
|
267
|
+
them at a durable write.
|
|
268
|
+
|
|
269
|
+
Caller-authored text, by kind:
|
|
270
|
+
|
|
271
|
+
- 256 characters — identifiers, names, selectors, routes, and statuses.
|
|
272
|
+
- 512 characters — a single explanatory field such as `classification_reason`
|
|
273
|
+
or one `escalate_when` entry.
|
|
274
|
+
- 1024 characters — the longest free-form fields: `objective`,
|
|
275
|
+
`expected_output`, and `verification_evidence`.
|
|
276
|
+
|
|
277
|
+
Six container fields carry short references and identifiers, never narrative
|
|
278
|
+
text: `payload`, `candidates_considered`, `configured_invocation_evidence`,
|
|
279
|
+
`continuation_events`, `diagnostics`, and `escalate_when`. Each is validated as
|
|
280
|
+
a closed JSON projection bounded on four independent axes, so no one axis can
|
|
281
|
+
be traded against another:
|
|
282
|
+
|
|
283
|
+
- nesting depth at most 4 levels;
|
|
284
|
+
- each string at most 512 characters;
|
|
285
|
+
- at most 512 values per field, which closes chunking one body into many short
|
|
286
|
+
strings; and
|
|
287
|
+
- at most 16 KiB serialized per field.
|
|
288
|
+
|
|
289
|
+
The whole record is additionally capped at 64 KiB, measured as the **published**
|
|
290
|
+
bytes — the pretty-printed JSON plus trailing newline that is actually written
|
|
291
|
+
to the journal, not compact `JSON.stringify` output. The two differ by roughly a
|
|
292
|
+
tenth on a nested record, so size against the published form. Per-field
|
|
293
|
+
projection limits above remain compact measurements, because they bound the
|
|
294
|
+
shape of a field rather than the size of a file. A realistically rich record
|
|
295
|
+
measures a few kilobytes, so these limits bind prompt bodies, transcripts, and
|
|
296
|
+
chunked logs rather than legitimate evidence.
|
|
297
|
+
|
|
298
|
+
Keys are classified against credential, token, prompt/message, transcript, and
|
|
299
|
+
role-content families after Unicode folding, and a spelling the normalizer
|
|
300
|
+
cannot fully account for is treated as sensitive rather than classified on a
|
|
301
|
+
partial token. Store references, identifiers, and digests; never role content, message bodies,
|
|
302
|
+
or credentials.
|
|
303
|
+
|
|
304
|
+
Absolute filesystem paths are handled by field class, because the journal is
|
|
305
|
+
committed and a home path in it is permanent:
|
|
306
|
+
|
|
307
|
+
- **Identity and control fields reject them.** `caller`, `scope`, every
|
|
308
|
+
selector, `selected_route`, the `guidance_*` fields, `authority`,
|
|
309
|
+
`authorization_scope`, `catalog_snapshot`, `candidates_considered` and
|
|
310
|
+
`fallback` refuse a record containing an absolute path, including
|
|
311
|
+
colon-prefixed forms such as `cwd:/Users/alice`. A path is never a legitimate
|
|
312
|
+
identifier there, so ambiguity resolves to rejection. Pass a repository-relative
|
|
313
|
+
path or a redacted form like `<user>/agents/<role>.md`.
|
|
314
|
+
- **Prose and nested evidence redact them best-effort.** `objective`,
|
|
315
|
+
`expected_output`, `verification_evidence`, `classification_reason`,
|
|
316
|
+
`escalate_when`, and the bounded container fields replace a detected path with
|
|
317
|
+
`<redacted-path>`. This is deliberately conservative rather than complete: it
|
|
318
|
+
skips candidates inside an `http`/`https` URL and candidates ending in `/`, so
|
|
319
|
+
a URL route (`?next=/dashboard`) and a regex literal (`/foo/bar/`) survive
|
|
320
|
+
intact. Colon-prefixed forms also survive. Corrupting a legitimate value is
|
|
321
|
+
worse than leaving a path in prose, so do not rely on this to sanitize
|
|
322
|
+
caller-authored text — redact before submitting.
|
|
323
|
+
|
|
324
|
+
Optional runtime observation is metadata-only and subject to the same
|
|
325
|
+
identifier bound, which admits letters, digits, `.`, `_`, and `-` only, so no
|
|
326
|
+
observation value can carry a path or a URL. Its `match` and `comparedAxes` are
|
|
327
|
+
always derived from the record's configured invocation rather than supplied by
|
|
328
|
+
the caller, and `matching` covers only the axes listed in `comparedAxes`.
|
|
329
|
+
It records what a provider reported about its own child and never restates the
|
|
330
|
+
request. An axis the provider did not report is simply absent from the
|
|
331
|
+
observation; an absent or unparseable observation is `not-reported` as a whole;
|
|
332
|
+
and `not-exposed` is reserved vocabulary for an axis a provider genuinely has
|
|
333
|
+
no selectable control for, with no producer today. None of the three is ever
|
|
334
|
+
filled in from `model_selector`, `effort_selector`, `service_tier_selector`, or
|
|
335
|
+
`role_selector`.
|