orchestrator-workflow 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +329 -0
- package/INSTALL-AGENT.md +44 -4
- package/README.md +125 -8
- package/assets/agents/reviewer.md +6 -0
- package/assets/agents-md-section.md +22 -3
- package/assets/skill/SKILL.md +96 -8
- package/assets/templates/00-goal.md +1 -0
- package/assets/templates/03-decisions.md +13 -0
- package/assets/templates/05-review-findings.md +3 -0
- package/dist/cli-inputs.d.ts +71 -0
- package/dist/cli-inputs.js +253 -0
- package/dist/cli.js +883 -183
- package/dist/detect.d.ts +11 -0
- package/dist/detect.js +30 -0
- package/dist/doctor.d.ts +222 -0
- package/dist/doctor.js +411 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/init.d.ts +35 -0
- package/dist/init.js +106 -6
- package/dist/operator-manifest.d.ts +277 -0
- package/dist/operator-manifest.js +538 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,335 @@ All notable changes to `orchestrator-workflow` are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.26.0] - 2026-08-30
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- The orchestrator now writes a per-worktree run pointer, `.ai/run`: a plain
|
|
15
|
+
text file whose first non-empty line is the absolute path of the run
|
|
16
|
+
directory, one written in every repository or worktree a run touches
|
|
17
|
+
(`SKILL.md` Run state, step 1, and all three Harness notes bullets;
|
|
18
|
+
`agents-md-section.md` Run state gained the matching bullet). For a run
|
|
19
|
+
spanning more than one repository, `00-goal.md` now also carries one keyed
|
|
20
|
+
`run-base[<repo-basename>]` marker per repository alongside the existing
|
|
21
|
+
unkeyed one, exact form `<!-- solution-acceptance: run-base[<repo-basename>]
|
|
22
|
+
= <sha> -->`; the shipped template line uses the placeholder key
|
|
23
|
+
`<repo-basename>` and value `<sha>` as a documentation example. Both are
|
|
24
|
+
written for a new consumer: the `.ai/run` pointer and the keyed marker are
|
|
25
|
+
read by grounding-mcp's `ow-run-completeness` reader, released as
|
|
26
|
+
`@lannguyensi/grounding-mcp` 0.9.0 (agent-grounding task
|
|
27
|
+
`design/ow-run-pointer-binding`, agent-tasks 43a7ef58, PR #198). The
|
|
28
|
+
reader resolves a run through the pointer first and falls back to scanning
|
|
29
|
+
the repository's own `.ai/runs/` (newest by name) only when no pointer file
|
|
30
|
+
exists, so kits and repos without the pointer keep working exactly as
|
|
31
|
+
before; the run-base marker's own date-heuristic fallback for a `TODO`
|
|
32
|
+
value is a separate mechanism and is unchanged. `README.md` ("What gets
|
|
33
|
+
installed") and `INSTALL-AGENT.md`
|
|
34
|
+
("Write surface" and the manual scaffold list) now note that `.ai/run`
|
|
35
|
+
should be added to the repository's `.gitignore` (the installer does not
|
|
36
|
+
edit `.gitignore` itself). Pinned by new tests in
|
|
37
|
+
`test/template-markers.test.ts` (the keyed placeholder line's exact text,
|
|
38
|
+
its whole-line-comment shape, its position directly below the unkeyed
|
|
39
|
+
marker, and that the existing unkeyed `run-base` regex still matches
|
|
40
|
+
exactly once) and a new `test/docs-consistency.test.ts` describe block
|
|
41
|
+
(the pointer contract's phrases in SKILL.md Run state, the exact keyed
|
|
42
|
+
example string, step 1, each of the three Harness notes bullets
|
|
43
|
+
individually, the agents-md-section bullet, and the README/INSTALL-AGENT
|
|
44
|
+
gitignore notes). Anchors in `docs/okf/*.md` that cite line ranges in
|
|
45
|
+
`SKILL.md`, `test/docs-consistency.test.ts`, and
|
|
46
|
+
`test/template-markers.test.ts` drifted out of range because of the line
|
|
47
|
+
shifts this change introduces; those anchors were re-pointed in the same
|
|
48
|
+
PR, and `run-state-lifecycle-and-markers.md` gained a section documenting
|
|
49
|
+
the pointer and the keyed marker.
|
|
50
|
+
- Two review rounds on the run-pointer change above corrected inaccurate
|
|
51
|
+
claims and hardened the pinning tests. `SKILL.md` Run state now states the
|
|
52
|
+
pointer contract as a short lead sentence plus three bullets (what the
|
|
53
|
+
pointer's content is, when to write, overwrite, and remove it, and to
|
|
54
|
+
make sure it is ignored before writing it), followed by a separate
|
|
55
|
+
paragraph on how the run-completeness reader uses it: pointer first,
|
|
56
|
+
falling back to that repository's own `.ai/runs/` (the run there that
|
|
57
|
+
sorts newest by directory name) only when no pointer file exists, with a broken pointer rejected outright
|
|
58
|
+
rather than falling back; the exact accept/reject rules are left to the
|
|
59
|
+
consuming gate's (grounding-mcp) own documentation, not restated here.
|
|
60
|
+
The keyed-marker grammar sentence is now a single generalised rule: write
|
|
61
|
+
the marker exactly in its documented form, on its own line; a deviating
|
|
62
|
+
line is either rejected, which blocks the run, or not recognised at all
|
|
63
|
+
(for example inside a list bullet), which leaves the binding for that
|
|
64
|
+
repository silently missing. The consumer detail that a real key left
|
|
65
|
+
with the placeholder value `<sha>` is read as-is and blocked by the
|
|
66
|
+
verdict layer lives in `docs/okf/run-state-lifecycle-and-markers.md`,
|
|
67
|
+
not in the skill text. `test/docs-consistency.test.ts`'s pointer-doc
|
|
68
|
+
describe block now routes six of its eight checks through one shared
|
|
69
|
+
`expectPointerMention` helper that asserts the exact phrase `` `.ai/run`
|
|
70
|
+
pointer `` (a bare `.ai/runs/` mention alone cannot satisfy it); the
|
|
71
|
+
SKILL.md Run state contract check and the exact-keyed-example check keep
|
|
72
|
+
their own specific phrases instead, and a further check pins the
|
|
73
|
+
grammar rule's wording ("on its own line", both deviation outcomes).
|
|
74
|
+
`test/template-markers.test.ts`'s property test now carries
|
|
75
|
+
grounding-mcp's `KEYED_RUN_BASE_STRICT` and `PLACEHOLDER_KEY` regexes
|
|
76
|
+
verbatim, kept in sync by hand, instead of a locally tightened mirror,
|
|
77
|
+
and still asserts that two constructed near-miss variants (uppercase,
|
|
78
|
+
space before the colon) do not match. `agents-md-section.md`'s
|
|
79
|
+
run-directory bullet still notes the run directory can live "in the
|
|
80
|
+
workspace or a touched repository". `docs/okf/run-state-lifecycle-and-markers.md`
|
|
81
|
+
carries the corrected claims plus the consumer's own test-measured
|
|
82
|
+
evidence for the scan fallback and the malformed/not-seen split, and
|
|
83
|
+
every `docs/okf/*.md` anchor that cited a line range shifted by either
|
|
84
|
+
round's edits was re-pointed in the same PR.
|
|
85
|
+
- An operator-level install layer: a new `operator-manifest.ts` module and
|
|
86
|
+
an operator home directory (default `~/.orchestrator-workflow/`,
|
|
87
|
+
overridable via the `ORCHESTRATOR_WORKFLOW_HOME` environment variable)
|
|
88
|
+
hold one manifest per operator (`{ kit, schemaVersion: 1, defaults: {
|
|
89
|
+
harnesses, profile, tiers, models }, targets: [{ path,
|
|
90
|
+
lastAppliedVersion, lastAppliedAt }], createdAt, updatedAt }`), separate
|
|
91
|
+
from each repository's own `.ai/workflow/manifest.json`. Four new
|
|
92
|
+
subcommands sit alongside the existing per-repository `init`/`uninstall`,
|
|
93
|
+
which stay fully supported and unchanged: `setup` writes or updates the
|
|
94
|
+
operator defaults without touching any repository; `apply --target
|
|
95
|
+
<repo>` projects those defaults, and the target's own previously
|
|
96
|
+
recorded settings, onto one repository through the same
|
|
97
|
+
option-resolution logic `init` uses (`resolveInitInputs`, extracted for
|
|
98
|
+
reuse), and registers the target, by its resolved real path, in the
|
|
99
|
+
operator manifest, with `--sync` inverting precedence so the operator's
|
|
100
|
+
defaults win over the target's recorded profile/tiers/models, and
|
|
101
|
+
`--pin`/`--unpin`/`--force-pin` controlling the new per-repo kit-version
|
|
102
|
+
pin (below); `doctor [--json] [--prune]` walks the registry and reports
|
|
103
|
+
each target's status (`clean`, `divergent`, `version-lag`, `drift`,
|
|
104
|
+
`missing`, `no-manifest`, `unverifiable`), exiting `2` when the operator
|
|
105
|
+
manifest is missing or unreadable (or, with `--prune`, when the manifest
|
|
106
|
+
lock cannot be acquired or the rewrite fails), `1` when any target is
|
|
107
|
+
`drift`/`missing`/`no-manifest`/`unverifiable`, else `0`, and `--prune`
|
|
108
|
+
removes `missing`/`no-manifest` targets (never `unverifiable`) and
|
|
109
|
+
rewrites the manifest in normalized form; `adopt [dir] [--json]` registers an
|
|
110
|
+
already-installed repository verbatim, touching nothing in it,
|
|
111
|
+
bootstrapping the operator manifest from the repository's own recorded
|
|
112
|
+
settings when none exists, recording the repository's own version as
|
|
113
|
+
`lastAppliedVersion`, and printing that target's `doctor` report (exit
|
|
114
|
+
`1` only on drift, exit `2` for a precondition failure). Design
|
|
115
|
+
decisions: no new binary, all four subcommands live on the existing
|
|
116
|
+
`orchestrator-workflow` CLI; the registry is implicit, `apply`/`adopt`
|
|
117
|
+
register as a side effect of a real run and `doctor --prune` is the only
|
|
118
|
+
way to remove an entry; a multi-repo workspace root is an ordinary
|
|
119
|
+
target, nothing special. `README.md` gained a new "Operator-level
|
|
120
|
+
install" section and `INSTALL-AGENT.md` gained the operator path (an
|
|
121
|
+
installing agent runs `apply` instead of `init` when an operator
|
|
122
|
+
manifest already exists, and `adopt` for an already-installed
|
|
123
|
+
repository) plus the new operator-home and `pin` entries in its Write
|
|
124
|
+
surface list. Consumer-side evidence: agent-tasks `b457ee55`, PRs
|
|
125
|
+
#142-#147.
|
|
126
|
+
- The repo manifest (`.ai/workflow/manifest.json`) gained one optional
|
|
127
|
+
field, `pin`: a kit-version string. `apply --pin <version>` sets or
|
|
128
|
+
replaces it (trimmed; empty, whitespace-only, or containing internal
|
|
129
|
+
whitespace rejected as a usage error, exit `2`, writing nothing),
|
|
130
|
+
`--unpin` clears it, and `--force-pin` advances an existing pin to the
|
|
131
|
+
running version (a no-op on an unpinned target); read by `apply`'s pin
|
|
132
|
+
gate and by `doctor`, which on a pinned target compares the pin against
|
|
133
|
+
the installed version instead of the installed version against the
|
|
134
|
+
running kit. Purely additive: a
|
|
135
|
+
caller that never sets it sees a byte-identical manifest to before.
|
|
136
|
+
- `init --harness none` (the literal word `none`, alone): a templates-only
|
|
137
|
+
mode that writes only `.ai/workflow/**` and `.ai/runs/.gitkeep`, records
|
|
138
|
+
`harnesses: []` in the manifest, and touches no `AGENTS.md`, `CLAUDE.md`,
|
|
139
|
+
or per-harness directory. `none` combined with a real harness name
|
|
140
|
+
(`none,claude`, either order) is a usage error rather than an implicit
|
|
141
|
+
precedence rule. A plain re-run (no `--harness` flag) after a recorded
|
|
142
|
+
`harnesses: []` install stays templates-only instead of falling back to
|
|
143
|
+
filesystem detection; a later `init --harness <list>` on the same target
|
|
144
|
+
adds harness files and manifest entries additively, without touching the
|
|
145
|
+
already-installed templates. `apply` shares the same option parsing (an
|
|
146
|
+
explicit `--harness none` on an `apply` call resolves to templates-only
|
|
147
|
+
too) but not the re-run stickiness: `apply`'s own harness fallback chain
|
|
148
|
+
(target's recorded harnesses, else the operator defaults, else detection)
|
|
149
|
+
is unchanged, so a target `apply`-installed as templates-only is not
|
|
150
|
+
guaranteed to stay that way on a flagless `apply` re-run, a gap left open
|
|
151
|
+
by this change rather than closed. The closing summary line prints
|
|
152
|
+
`templates only` instead of `installed for: ` followed by nothing.
|
|
153
|
+
Motivated by friction filed 2026-08-28 while refreshing an agent-tasks
|
|
154
|
+
install that had ended up in the templates-only manifest shape (`harnesses:
|
|
155
|
+
[]`, produced by a 0.14.0-era install with no harness configured) with no
|
|
156
|
+
supported way to reproduce or re-render that state: `--harness none`
|
|
157
|
+
rejected the literal value, and `--harness ""` fell back to detection,
|
|
158
|
+
which under `--yes` installed `claude` unasked. Documented in `README.md`
|
|
159
|
+
("Non-interactive") and `docs/okf/install-fence-mechanics.md` (new
|
|
160
|
+
"`--harness none` (templates-only mode)" section). Agent-tasks 613316c9.
|
|
161
|
+
|
|
162
|
+
### Changed
|
|
163
|
+
|
|
164
|
+
- `setup`, `apply`'s registration step, `doctor --prune`, and `adopt` all
|
|
165
|
+
write the operator manifest through the same locked write API,
|
|
166
|
+
`updateOperatorManifest`/`withOperatorManifestLock`, backed by one
|
|
167
|
+
advisory lock (`.manifest.lock` in the operator home, stale after 30s)
|
|
168
|
+
so concurrent `orchestrator-workflow` invocations on one machine cannot
|
|
169
|
+
race each other's writes.
|
|
170
|
+
|
|
171
|
+
## [0.25.0] - 2026-08-27
|
|
172
|
+
|
|
173
|
+
### Added
|
|
174
|
+
|
|
175
|
+
- A "Review-round escalation budget" (`SKILL.md`, new section right after
|
|
176
|
+
the existing Round-2 halt rule): by the second round-2 halt signal on a
|
|
177
|
+
task, or its third `fix_required` review round, whichever comes first,
|
|
178
|
+
the orchestrator now picks one of three escalations, tier/model
|
|
179
|
+
escalation, an advisor spawn, or an operator merge-hold, instead of
|
|
180
|
+
running another round unaided, and records the choice in
|
|
181
|
+
`03-decisions.md`'s new Review-round escalation section (the
|
|
182
|
+
`review-round-escalation` marker: `n/a | tier_escalation | advisor |
|
|
183
|
+
merge_hold`, `n/a` a deliberately fail-open default since most runs
|
|
184
|
+
never trigger the budget at all, unlike the `TODO` fail-closed sentinel
|
|
185
|
+
the `solution-acceptance:` marker family uses). Which of the three is
|
|
186
|
+
picked stays a judgment call; only that one is picked and recorded is
|
|
187
|
+
now mandatory, and escalating never substitutes for a review round.
|
|
188
|
+
`agents-md-section.md` carries the same rule in short form. The
|
|
189
|
+
reviewer output contract (`SKILL.md` and `reviewer.md`) gained a
|
|
190
|
+
`recurrence: new | repeated` field per finding, and step 7 now has the
|
|
191
|
+
orchestrator name the review round number in the briefing when it is
|
|
192
|
+
not the task's first, so the reviewer can classify each finding against
|
|
193
|
+
the rounds it was told about instead of the orchestrator re-deriving
|
|
194
|
+
recurrence by hand. `03-decisions.md`'s new marker is a documented
|
|
195
|
+
convention only: nothing in this package's own code reads it today
|
|
196
|
+
(unlike the `solution-acceptance:` markers, which grounding-mcp's
|
|
197
|
+
run-completeness reader does parse); wiring it into that reader, if
|
|
198
|
+
wanted, is a follow-up in the consuming project, not part of this
|
|
199
|
+
change.
|
|
200
|
+
|
|
201
|
+
Evidence: agent-tasks d03af8f6 (pandora run
|
|
202
|
+
`.ai/runs/2026-08-26-open-pool-batch30`, a harness risk-gate deletion
|
|
203
|
+
arm) ran five implementer rounds on the same effort tier (rounds 1-5, the
|
|
204
|
+
default-tier implementer, Sonnet) before this rule existed; each reviewer
|
|
205
|
+
round found one new HIGH on the permissive side of the same detection layer
|
|
206
|
+
(first-segment matching, wrapper flags, xargs flags, a find-root premise
|
|
207
|
+
twice, xargs `-i`/append), and the Round-2 halt rule's split-or-redesign
|
|
208
|
+
response was applied three times (D-014, D-019, D-022/D-023) without ever
|
|
209
|
+
escalating tier, model, or to the advisor, and without a merge-hold. Only
|
|
210
|
+
after round 5 did the operator suggest a stronger model (D-024); round 6, on
|
|
211
|
+
Fable with the `-xhigh` variant, found and closed twelve further fail-open
|
|
212
|
+
classes in one round by its own 248-probe audit, and the following review
|
|
213
|
+
found only one remaining, a documentation-only medium. A same-run comparison
|
|
214
|
+
task, agent-tasks da823721, needed three rounds with one round-2 halt and
|
|
215
|
+
was accepted after it, well inside this budget. This is the first data
|
|
216
|
+
point relating implementer model strength to round count on a
|
|
217
|
+
permissive-security-parser class of task; the 2026-08-24 tier A/B (see
|
|
218
|
+
`[0.23.0]` below) measured only
|
|
219
|
+
`implementer-low` against the default tier on a different task shape,
|
|
220
|
+
not model strength, so whether a stronger model generally shortens
|
|
221
|
+
these rounds remains open.
|
|
222
|
+
- A new `okf-anchor-guard` job in `.github/workflows/ci.yml` (this repo)
|
|
223
|
+
runs okf-kit's anchor check against `docs/okf` and fails the build (no
|
|
224
|
+
branch-protection change; master has no required checks today) when an
|
|
225
|
+
edit to `SKILL.md`, an agent template under `assets/agents/`,
|
|
226
|
+
`src/models.ts`, a `test/*.test.ts` file, any other `src/*.ts` module,
|
|
227
|
+
a run template under `assets/templates/`, or `assets/agents-md-section.md`
|
|
228
|
+
shifts a cited range out of the section or text an anchored bundle
|
|
229
|
+
citation names, instead of only the existing warn-only `okf-staleness.yml`
|
|
230
|
+
drift watch (which never blocks by design and stays untouched). Every
|
|
231
|
+
in-scope bundle citation into those source categories now carries a
|
|
232
|
+
string-form anchor (up from a first-round draft that review round 2
|
|
233
|
+
found had missed 44 bare, non-backtick-delimited citations in two of the
|
|
234
|
+
five docs/okf siblings; the citation parser was corrected to match
|
|
235
|
+
okf-kit's own backtick-optional shape; scope later widened from the
|
|
236
|
+
original four categories to every `src/*.ts` module and every
|
|
237
|
+
`assets/templates/*.md` plus `assets/agents-md-section.md`, agent-tasks
|
|
238
|
+
ca9d5048); the `CHANGELOG.md` citations still carry heading anchors from
|
|
239
|
+
the prior round (that mechanism is untouched, but every CHANGELOG entry
|
|
240
|
+
added above them, this one included, re-points all of them -- see
|
|
241
|
+
`docs/okf/log.md` for the live count and the re-point history, not
|
|
242
|
+
hand-copied here since it drifts with every CHANGELOG edit).
|
|
243
|
+
- Every anchor now satisfies two mechanically-checked properties review
|
|
244
|
+
round 2 added (a first-round anchor sitting on a wide range's first line,
|
|
245
|
+
as 107 of 121 did, survives an insertion shorter than the range itself --
|
|
246
|
+
measured: round 1 had 46 SKILL.md-targeting anchors, and a 1-line
|
|
247
|
+
insertion near the top of SKILL.md left 24 of them silently green): (a)
|
|
248
|
+
the anchor text occurs on the LAST line of its cited range (ranges were
|
|
249
|
+
narrowed where needed to end on real content rather than a
|
|
250
|
+
blank/closing-brace line), and (b) it occurs at most 3 times in the
|
|
251
|
+
whole target file (23 first-round anchors used a too-common token, e.g.
|
|
252
|
+
`describe(`, and were
|
|
253
|
+
replaced). Two anchors were additionally re-pointed because the text
|
|
254
|
+
they carried did not match the claim their citing sentence made, not
|
|
255
|
+
just its mechanical position; see `docs/okf/log.md` for both. Pinned by
|
|
256
|
+
three new tests in `test/docs-consistency.test.ts` (version-pin
|
|
257
|
+
coverage extended to every `.github/workflows/*.yml` file, not just
|
|
258
|
+
`okf-staleness.yml`; the last-line/occurrence-cap rule, verified red
|
|
259
|
+
against the first-round anchors and green against this round's; and an
|
|
260
|
+
erosion brake asserting zero unanchored in-scope citations going
|
|
261
|
+
forward). `ci.yml`'s anchor-finding jq filter now matches any
|
|
262
|
+
`anchor-*`-tagged finding by pattern instead of four hardcoded rule
|
|
263
|
+
ids, guarded by a new self-test step that builds a throwaway fixture
|
|
264
|
+
bundle with one deliberately drifted anchored citation and requires the
|
|
265
|
+
filter to catch it before the real check runs.
|
|
266
|
+
`okf-kit check` reports the same 0 errors / 13 warnings / 22 notices
|
|
267
|
+
before and after this round's full anchor rewrite (0 anchor findings
|
|
268
|
+
either way; the 13 pre-existing warnings are unrelated
|
|
269
|
+
`install-fence-mechanics.md` short-form findings against `init.test.ts`
|
|
270
|
+
and `init.ts`). Differential mutation probe, replacing the first
|
|
271
|
+
round's single 27-finding number: inserting `k` dummy lines near the
|
|
272
|
+
top of SKILL.md, 52/52 (100%) of its unique cited ranges now produce a
|
|
273
|
+
finding at `k=1`; 51/52 (98%) at `k=2`, one named exception (a
|
|
274
|
+
same-block token collision, see `docs/okf/log.md`). A `package.json`
|
|
275
|
+
patch-version bump still leaves the anchor-finding count at 0,
|
|
276
|
+
confirming no false positive. Residual gaps named in `docs/okf/log.md`:
|
|
277
|
+
a content change inside a cited range that neither shifts its line
|
|
278
|
+
count nor disturbs the anchor text stays invisible to this check
|
|
279
|
+
(mechanical, never semantic, the same limit okf-kit's own README
|
|
280
|
+
documents), plus the one named same-block token collision above
|
|
281
|
+
(agent-tasks task 578f5bfd, review round 2; following the
|
|
282
|
+
anchored-citations feature itself, task 5c8013c0, and its release, task
|
|
283
|
+
c0effc67).
|
|
284
|
+
|
|
285
|
+
### Changed
|
|
286
|
+
|
|
287
|
+
- `docs/okf/subagent-contracts-superset.md`: rewrote its 22 sibling short-
|
|
288
|
+
form citations (21 initially, plus one missed and fixed this round) from
|
|
289
|
+
the parenthesized form (`(N-M)`) to the colon form (`, :N-M`) so
|
|
290
|
+
`citations-resolve` checks them again. Neither form was ever machine-
|
|
291
|
+
checked in a released `okf-kit`: the colon-form gate and the drop of
|
|
292
|
+
paren-form collection landed in the same `[Unreleased]` entry, so
|
|
293
|
+
"dropped" overstates it. Inserting this entry shifts every later line
|
|
294
|
+
number in this file, so any absolute-line `CHANGELOG.md` citation below
|
|
295
|
+
it breaks until re-pointed; this round re-points all sixteen such
|
|
296
|
+
citations across the three touched docs/okf siblings
|
|
297
|
+
(`subagent-contracts-superset.md`, `review-gate-and-waivers.md`,
|
|
298
|
+
`run-state-lifecycle-and-markers.md`), each checked against the
|
|
299
|
+
`## [x.y.z]` section its own sentence names, not against a byte-diff of a
|
|
300
|
+
moving base. `okf-kit check` against a repo build (not the published
|
|
301
|
+
package) reports 0 errors / 13 warnings / 22 notices; all 13 are
|
|
302
|
+
pre-existing `install-fence-mechanics.md` short-form findings unrelated
|
|
303
|
+
to this change, so the three touched docs carry no citations-resolve or
|
|
304
|
+
sources-fresh finding of their own (log.md records the fuller
|
|
305
|
+
sources-fresh investigation, since that count depends on this round's
|
|
306
|
+
commit shape, not on the citations themselves). Coverage holds only
|
|
307
|
+
against a repo build: CI's `okf-staleness.yml` still pins the published
|
|
308
|
+
`okf-kit@0.5.0`, which predates short-form colon resolution, so it
|
|
309
|
+
reports 0 short-form findings until that release ships (agent-tasks task
|
|
310
|
+
2e3e5f4b).
|
|
311
|
+
- All sixteen `CHANGELOG.md` citations across the three `docs/okf` siblings
|
|
312
|
+
above now also carry a heading anchor (`` `CHANGELOG.md:N-M#x.y.z` ``, a
|
|
313
|
+
new `citations-resolve` form -- see okf-kit's own CHANGELOG for the
|
|
314
|
+
design), pinning each one to the release section its own sentence names
|
|
315
|
+
instead of only to a line range that a future top-of-file insertion can
|
|
316
|
+
silently shift into the wrong section. `okf-kit check` against a repo
|
|
317
|
+
build still reports the same 0 errors / 13 warnings / 22 notices as
|
|
318
|
+
above (all pre-existing, unrelated to this change); a mutation probe that
|
|
319
|
+
moved one migrated citation's range into its neighbouring release
|
|
320
|
+
section, and a second probe that inserted a dummy entry at the top of
|
|
321
|
+
this file (shifting every citation below it), were both caught by the
|
|
322
|
+
new anchor check and reverted (agent-tasks task 5c8013c0).
|
|
323
|
+
|
|
324
|
+
### Corrections
|
|
325
|
+
|
|
326
|
+
- Correction to the "Known limit of the pack" note in the 0.24.0 entry
|
|
327
|
+
below: this is not an `orchestrator-workflow` behavior change, it
|
|
328
|
+
documents a `slop-detector` fix. The 0.24.0 note described a known limit
|
|
329
|
+
of `placement-slop`, that an `allow` match suppressed every placement
|
|
330
|
+
rule on the line it matched, not just the marker span it was meant to
|
|
331
|
+
excuse. `slop-detector` has since fixed this (`placement.allow` is now
|
|
332
|
+
span-scoped, not line-wide). Consumer-visible effect: a config that
|
|
333
|
+
reported clean before can now report a `block`-severity finding (e.g.
|
|
334
|
+
`placement-slop/home-path`) when a home path, a date, or a tally phrase
|
|
335
|
+
shares a line with an allowed marker.
|
|
336
|
+
|
|
8
337
|
## [0.24.0] - 2026-08-24
|
|
9
338
|
|
|
10
339
|
### Changed
|
package/INSTALL-AGENT.md
CHANGED
|
@@ -31,10 +31,23 @@ which is mutable. For a stable audit, pin the URL to a commit SHA instead
|
|
|
31
31
|
3. **Run the non-interactive installer** with your answers:
|
|
32
32
|
`npx orchestrator-workflow init --yes --harness ... --profile ... --models ... [--tiers]`.
|
|
33
33
|
If the installer reports conflicts with locally edited files, the agent
|
|
34
|
-
shows them to you and asks before any `--force` re-run.
|
|
34
|
+
shows them to you and asks before any `--force` re-run. **The operator
|
|
35
|
+
path**: when an operator has already run `orchestrator-workflow setup`
|
|
36
|
+
on this machine (an operator manifest exists at
|
|
37
|
+
`<operator home>/manifest.json`, where the operator home is
|
|
38
|
+
`~/.orchestrator-workflow/` unless `ORCHESTRATOR_WORKFLOW_HOME` names a
|
|
39
|
+
different directory), the agent runs
|
|
40
|
+
`orchestrator-workflow apply --target <repo>` instead of `init`, which
|
|
41
|
+
sources its defaults from that operator install and registers the
|
|
42
|
+
repository under it. A repository that already has the kit installed
|
|
43
|
+
and only needs bringing under that management, with nothing in it
|
|
44
|
+
changed, is registered with `orchestrator-workflow adopt <repo>`
|
|
45
|
+
instead of either command.
|
|
35
46
|
4. **Manual fallback only when npx or the registry is unavailable**: create
|
|
36
47
|
the same files by hand from this repository's `assets/` directory,
|
|
37
|
-
following the byte-precise rules in step 4 below.
|
|
48
|
+
following the byte-precise rules in step 4 below. This manual path
|
|
49
|
+
covers `init` only; there is no manual equivalent for `apply` or
|
|
50
|
+
`adopt`, both of which require the installed CLI.
|
|
38
51
|
5. **Report back**: which harnesses were installed, which profile and model
|
|
39
52
|
each role uses, whether effort-tier variants were rendered, and any
|
|
40
53
|
conflicts left in place.
|
|
@@ -44,7 +57,18 @@ which is mutable. For a stable audit, pin the URL to a commit SHA instead
|
|
|
44
57
|
The install creates or touches only these paths:
|
|
45
58
|
|
|
46
59
|
- `.ai/workflow/templates/00-goal.md` through `06-handoff.md`,
|
|
47
|
-
`.ai/workflow/manifest.json`, `.ai/runs/.gitkeep` (new files)
|
|
60
|
+
`.ai/workflow/manifest.json`, `.ai/runs/.gitkeep` (new files). The
|
|
61
|
+
orchestrator later writes a per-worktree `.ai/run` pointer at run time (a
|
|
62
|
+
machine-local absolute path, not written by the installer); add it to the
|
|
63
|
+
repository's `.gitignore`. This repository's own `.ai/workflow/manifest.json`
|
|
64
|
+
can additionally carry one optional field, `pin`: a kit version recorded
|
|
65
|
+
by `apply --pin`/`--unpin`/`--force-pin`, absent when no pin was ever set.
|
|
66
|
+
- **Operator path only** (`apply`/`adopt`, not `init`): the operator's own
|
|
67
|
+
home's manifest, `<operator home>/manifest.json`, where the operator home
|
|
68
|
+
is `~/.orchestrator-workflow/` unless `ORCHESTRATOR_WORKFLOW_HOME` names a
|
|
69
|
+
different directory, gains or updates its record of this repository,
|
|
70
|
+
guarded by a transient `.manifest.lock` directory held only for the
|
|
71
|
+
duration of that write. Neither path lives inside the target repository.
|
|
48
72
|
- `AGENTS.md`: the marker-fenced workflow section is appended (file created
|
|
49
73
|
when missing); content outside the
|
|
50
74
|
`<!-- orchestrator-workflow:begin -->` / `<!-- orchestrator-workflow:end -->`
|
|
@@ -126,6 +150,19 @@ steps in the repository you were asked to install into.
|
|
|
126
150
|
on a re-run. If the command reports conflicts, show them to the operator
|
|
127
151
|
and ask before re-running with --force.
|
|
128
152
|
|
|
153
|
+
**Operator path**: before running `init`, check whether an operator
|
|
154
|
+
manifest already exists on this machine, at
|
|
155
|
+
`<operator home>/manifest.json` (the operator home is
|
|
156
|
+
`~/.orchestrator-workflow/` unless `ORCHESTRATOR_WORKFLOW_HOME` names a
|
|
157
|
+
different directory). If it does, run
|
|
158
|
+
`orchestrator-workflow apply --target <repo>` with the same flags in
|
|
159
|
+
place of `init --yes` instead: it sources its defaults from the operator
|
|
160
|
+
install and the target's own prior settings, and registers the
|
|
161
|
+
repository. If the repository already has the kit installed and the
|
|
162
|
+
operator only wants it brought under that management without any file
|
|
163
|
+
changes, run `orchestrator-workflow adopt <repo>` instead and skip the
|
|
164
|
+
rest of this step.
|
|
165
|
+
|
|
129
166
|
4. Only if npx or the registry is unavailable, scaffold manually from
|
|
130
167
|
https://github.com/LanNguyenSi/agent-dx/tree/master/packages/orchestrator-workflow/assets.
|
|
131
168
|
This manual path does not cover `--tiers`: it never renders
|
|
@@ -135,7 +172,10 @@ steps in the repository you were asked to install into.
|
|
|
135
172
|
|
|
136
173
|
- `.ai/workflow/templates/00-goal.md` through `06-handoff.md` from
|
|
137
174
|
`assets/templates/`, unchanged.
|
|
138
|
-
- `.ai/runs/.gitkeep`, empty.
|
|
175
|
+
- `.ai/runs/.gitkeep`, empty. The orchestrator later writes a
|
|
176
|
+
per-worktree `.ai/run` pointer at run time (a machine-local absolute
|
|
177
|
+
path, not written by the installer); add it to the repository's
|
|
178
|
+
`.gitignore`.
|
|
139
179
|
- Append the content of `assets/agents-md-section.md` to `AGENTS.md`
|
|
140
180
|
(create the file when missing; the installer starts a fresh file with a
|
|
141
181
|
`# Agent instructions` heading). Never change anything outside the
|
package/README.md
CHANGED
|
@@ -73,6 +73,26 @@ npx orchestrator-workflow init --harness claude,codex,opencode --models "impleme
|
|
|
73
73
|
npx orchestrator-workflow init --profile minimal --yes
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
**Templates-only mode.** `--harness none` (the literal word `none`, on its
|
|
77
|
+
own) installs only `.ai/workflow/**` and `.ai/runs/.gitkeep`: no
|
|
78
|
+
`AGENTS.md`, no `CLAUDE.md`, no harness-specific directory, and a manifest
|
|
79
|
+
recording `harnesses: []`. Use it for a repo that wants the run-state
|
|
80
|
+
templates and the workflow itself, but no per-harness subagent files yet
|
|
81
|
+
(e.g. no harness has been chosen, or the files were dropped by hand).
|
|
82
|
+
`none` combined with a real harness name (`--harness none,claude`) is
|
|
83
|
+
rejected as ambiguous rather than silently picking one. A plain
|
|
84
|
+
**non-interactive** re-run (no `--harness` flag) after a templates-only
|
|
85
|
+
install stays templates-only; add a harness back with an explicit
|
|
86
|
+
`--harness <list>` on a later run, the same explicit-flag-wins rule
|
|
87
|
+
`--profile`/`--models`/`--tiers` use, applied to the no-harness case. An
|
|
88
|
+
**interactive** re-run is different: it still prompts, with nothing forced
|
|
89
|
+
pre-selected, instead of silently skipping straight back to templates-only
|
|
90
|
+
without asking; deselect every checkbox to stay templates-only.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx orchestrator-workflow init --harness none --yes
|
|
94
|
+
```
|
|
95
|
+
|
|
76
96
|
To let a coding agent do the install, give it this single line:
|
|
77
97
|
|
|
78
98
|
```text
|
|
@@ -97,6 +117,10 @@ to a commit SHA for a stable audit.
|
|
|
97
117
|
AGENTS.md marker-fenced "Agentic Coding Workflow" policy section
|
|
98
118
|
```
|
|
99
119
|
|
|
120
|
+
The orchestrator writes a `.ai/run` pointer file in every worktree a run
|
|
121
|
+
touches (a machine-local absolute path, not written by the installer); add
|
|
122
|
+
it to the repository's `.gitignore`.
|
|
123
|
+
|
|
100
124
|
Per selected harness:
|
|
101
125
|
|
|
102
126
|
| Harness | Files | Notes |
|
|
@@ -329,14 +353,107 @@ effort actually taking effect.
|
|
|
329
353
|
The pin is also emitted unconditionally regardless of which model the role
|
|
330
354
|
resolves to via `--models`, including a model with no effort support at all
|
|
331
355
|
(e.g. `--models reviewer=haiku` still renders `model: haiku` followed by
|
|
332
|
-
`effort: high`).
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
356
|
+
`effort: high`). On Haiku 4.5, which does not support the `effort`
|
|
357
|
+
parameter, the harness ignores the pinned value rather than rejecting it
|
|
358
|
+
(anchored by a measurement, see CHANGELOG 0.23.0).
|
|
359
|
+
|
|
360
|
+
## Operator-level install
|
|
361
|
+
|
|
362
|
+
Alongside `init`, which installs the kit into one repository from that
|
|
363
|
+
repository's own working directory, an operator who maintains many
|
|
364
|
+
repositories can set defaults once and project them onto each target
|
|
365
|
+
instead of re-answering the same prompts per repo. This layer adds no new
|
|
366
|
+
binary: `setup`, `apply`, `doctor`, and `adopt` below are subcommands of the
|
|
367
|
+
same `orchestrator-workflow` CLI `init` and `uninstall` already ship as, and
|
|
368
|
+
`init`/`uninstall` remain fully supported and unchanged for a
|
|
369
|
+
single-repository install.
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
orchestrator-workflow setup --yes
|
|
373
|
+
orchestrator-workflow apply --target /path/to/repo
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**`setup`** writes or updates this operator's default install options
|
|
377
|
+
(harnesses, profile, models, tiers) as the baseline for future installs; it
|
|
378
|
+
touches no repository. A flag always wins; a flag-less re-run keeps the
|
|
379
|
+
previously stored values; a first-ever `setup` falls back to `claude` /
|
|
380
|
+
`full` / the kit's default models / tiers off. `setup` takes the same
|
|
381
|
+
option flags as `init` (`--harness`, `--profile`, `--models`, `--tiers` /
|
|
382
|
+
`--no-tiers`, `--opencode-provider`, `--yes`). The defaults live in
|
|
383
|
+
`<operator home>/manifest.json`, where the operator home is
|
|
384
|
+
`~/.orchestrator-workflow/` unless the `ORCHESTRATOR_WORKFLOW_HOME`
|
|
385
|
+
environment variable names a different directory.
|
|
386
|
+
|
|
387
|
+
**`apply --target <repo>`** projects the operator's install onto a target
|
|
388
|
+
repository and registers that target, by its real resolved path, in the
|
|
389
|
+
operator manifest. It requires a prior `orchestrator-workflow setup`;
|
|
390
|
+
without one it exits `1` with "No operator setup found". Option resolution
|
|
391
|
+
follows one precedence order: an
|
|
392
|
+
explicit flag wins, then the target's own previously recorded settings,
|
|
393
|
+
then the operator's defaults (harnesses fall back one step further, to
|
|
394
|
+
what `init` would have auto-detected). Pass `--sync` to invert that for
|
|
395
|
+
profile, tiers, and models: the operator's defaults then win over whatever
|
|
396
|
+
the target already had recorded. A target pinned to a kit version other
|
|
397
|
+
than the one being applied is skipped rather than touched (see the pin
|
|
398
|
+
rule below). `apply` also takes the same install options as `init` (`--harness`,
|
|
399
|
+
`--profile`, `--models`, `--tiers` / `--no-tiers`, `--opencode-provider`,
|
|
400
|
+
`--force`, `--yes`), which feed the precedence rule above.
|
|
401
|
+
|
|
402
|
+
**`doctor [--json] [--prune]`** reports every operator-registered target's
|
|
403
|
+
status: `clean`, `divergent` (from the operator defaults), `version-lag`,
|
|
404
|
+
`drift` (installed files edited, deleted, or unreadable since install),
|
|
405
|
+
`missing`, `no-manifest`, or `unverifiable`. It exits `2` when the operator
|
|
406
|
+
manifest is missing or unreadable, or, with `--prune`, when the operator
|
|
407
|
+
manifest lock cannot be acquired or the rewrite fails; `1` when any target
|
|
408
|
+
is `drift`, `missing`, `no-manifest`, or `unverifiable`; and `0` otherwise.
|
|
409
|
+
`--json` prints one JSON object instead
|
|
410
|
+
of human output, with one entry per target plus the operator home and
|
|
411
|
+
version. `--prune` removes `missing` and `no-manifest` targets from the
|
|
412
|
+
registry before reporting (never an `unverifiable` one, since that status
|
|
413
|
+
means the check itself was inconclusive, not that the target is confirmed
|
|
414
|
+
gone) and rewrites the manifest file in its normalized form.
|
|
415
|
+
|
|
416
|
+
**`adopt [dir] [--json]`** brings a repository that already has the kit installed,
|
|
417
|
+
by hand or by an earlier `init`, under the operator's management without
|
|
418
|
+
changing anything in that repository: it registers the repository
|
|
419
|
+
verbatim, using the repository's own recorded settings to bootstrap the
|
|
420
|
+
operator manifest when none exists yet, records the repository's own
|
|
421
|
+
installed version as its baseline, and prints that one target's `doctor`
|
|
422
|
+
report. It exits `1` only when the freshly adopted target itself reports
|
|
423
|
+
drift, and `2` for a precondition failure (no repo manifest, an unreadable
|
|
424
|
+
or foreign manifest, or a lock or write failure).
|
|
425
|
+
|
|
426
|
+
**The kit-version pin.** A repository's own manifest can additionally
|
|
427
|
+
carry an optional `pin`: a kit version that `apply` must match before it
|
|
428
|
+
will touch that repository again. `apply` skips (exit `0`) a target pinned
|
|
429
|
+
to a different version than the one being applied. `--pin <version>` sets
|
|
430
|
+
or replaces the pin and applies regardless of any existing one; `--unpin`
|
|
431
|
+
clears it and applies; `--force-pin` advances an existing pin that
|
|
432
|
+
differs, but has no effect on a target with no pin recorded (it stays
|
|
433
|
+
unpinned). `doctor` reports `version-lag` when the installed version
|
|
434
|
+
differs from the running kit version; on a pinned target the pin is
|
|
435
|
+
compared against the installed version instead, so a pin equal to the
|
|
436
|
+
installed version is `clean` and a pin that no longer matches it is
|
|
437
|
+
`version-lag`.
|
|
438
|
+
|
|
439
|
+
**The registry is implicit**, not a separate command: `apply` and `adopt`
|
|
440
|
+
register a target as a side effect of a real run, and `doctor --prune` is
|
|
441
|
+
how a registry entry is removed again; there is no bare register or
|
|
442
|
+
unregister command. The workspace root of a multi-repo checkout is treated
|
|
443
|
+
as an ordinary target, nothing special.
|
|
444
|
+
|
|
445
|
+
All writes to the operator manifest, by `setup`, `apply`, `doctor --prune`,
|
|
446
|
+
and `adopt` alike, go through one advisory lock in the operator home, so
|
|
447
|
+
concurrent orchestrator-workflow commands on the same machine cannot
|
|
448
|
+
corrupt each other's state.
|
|
336
449
|
|
|
337
450
|
## Ownership and re-runs
|
|
338
451
|
|
|
339
|
-
`init` is idempotent: a second run changes nothing.
|
|
452
|
+
`init` is idempotent: a second run changes nothing. `apply` installs
|
|
453
|
+
through that same `runInit` path and is subject to the same
|
|
454
|
+
conflict/`--force`/ownership rules; on the repository side it changes
|
|
455
|
+
nothing either, but it refreshes this target's entry in the operator
|
|
456
|
+
manifest on every run. The rules:
|
|
340
457
|
|
|
341
458
|
- `AGENTS.md` and `CLAUDE.md` belong to you. The installer only appends its
|
|
342
459
|
fenced section or the import line, and on re-run replaces only the content
|
|
@@ -347,9 +464,9 @@ run-time error.
|
|
|
347
464
|
updates files you never touched and reports files you edited as conflicts
|
|
348
465
|
instead of overwriting them; `--force` overwrites those too.
|
|
349
466
|
- `.ai/workflow/manifest.json` is the kit's state file. It records the applied
|
|
350
|
-
version, harnesses, role profile, models, the `--tiers` flag,
|
|
351
|
-
hashes, and is rewritten whenever that state
|
|
352
|
-
hand.
|
|
467
|
+
version, harnesses, role profile, models, the `--tiers` flag, the optional
|
|
468
|
+
kit-version pin, and file hashes, and is rewritten whenever that state
|
|
469
|
+
changes; do not edit it by hand.
|
|
353
470
|
|
|
354
471
|
## Uninstall
|
|
355
472
|
|
|
@@ -26,6 +26,11 @@ Check, at minimum:
|
|
|
26
26
|
reusable instruction file (a skill, an agent prompt, an AGENTS.md section, a
|
|
27
27
|
template)? Report it; the fix is to move the evidence to the changelog, the
|
|
28
28
|
run files, or the consuming workspace and leave a one-line pointer.
|
|
29
|
+
- Recurrence: when the briefing tells you this is not the task's first
|
|
30
|
+
review round, classify each finding as `new` or `repeated` against the
|
|
31
|
+
earlier rounds you were told about; on a first round every finding is
|
|
32
|
+
`new` by definition. The orchestrator uses this to detect the
|
|
33
|
+
review-round escalation budget's trigger.
|
|
29
34
|
|
|
30
35
|
Rules:
|
|
31
36
|
|
|
@@ -73,6 +78,7 @@ findings:
|
|
|
73
78
|
category: correctness | architecture | security | tests | maintainability | performance | docs
|
|
74
79
|
description: ""
|
|
75
80
|
suggested_fix: ""
|
|
81
|
+
recurrence: new | repeated
|
|
76
82
|
acceptance_recommendation: accept | accept_with_notes | fix_required | reject
|
|
77
83
|
missing_tests:
|
|
78
84
|
- ""
|
|
@@ -103,6 +103,21 @@ trivial change.
|
|
|
103
103
|
the Accepted Waivers section of `06-handoff.md`.
|
|
104
104
|
- Medium and low findings are addressed or consciously accepted at the
|
|
105
105
|
orchestrator's judgment.
|
|
106
|
+
- Review-round escalation budget: by the second round-2 halt signal on a
|
|
107
|
+
task, or its third `fix_required` review round, whichever comes first,
|
|
108
|
+
the orchestrator picks one of tier/model escalation (raise the
|
|
109
|
+
implementer to at least `-xhigh` where installed, or to the strongest
|
|
110
|
+
model available, until that is exhausted), an advisor spawn (where the
|
|
111
|
+
advisor is installed, `full` profile only; under a `minimal` profile
|
|
112
|
+
the exhausted tier path falls straight to the merge-hold), or an
|
|
113
|
+
operator merge-hold, and adds a row (task, choice, reason) to
|
|
114
|
+
`03-decisions.md`'s Review-round escalation table, then sets the
|
|
115
|
+
`review-round-escalation` marker to the most recent choice. A counted
|
|
116
|
+
round is a completed reviewer return recommending `fix_required` or
|
|
117
|
+
`reject`; a misfired review is not a round. Which of the three is
|
|
118
|
+
picked is judgment; that one is picked and recorded is not. Escalating
|
|
119
|
+
never substitutes for a review round and comes in addition to the halt
|
|
120
|
+
rule's split-or-redesign response, not instead of it.
|
|
106
121
|
|
|
107
122
|
### Instruction trust boundary
|
|
108
123
|
|
|
@@ -135,11 +150,15 @@ Workflow state lives under `.ai/`:
|
|
|
135
150
|
|
|
136
151
|
- `.ai/workflow/templates/` holds the canonical file templates
|
|
137
152
|
(`00-goal.md` through `06-handoff.md`).
|
|
138
|
-
- Each unit of work gets a run directory `.ai/runs/YYYY-MM-DD-<slug
|
|
139
|
-
|
|
140
|
-
one; older ones are the auditable
|
|
153
|
+
- Each unit of work gets a run directory `.ai/runs/YYYY-MM-DD-<slug>/` (in
|
|
154
|
+
the workspace or a touched repository), created by copying the templates.
|
|
155
|
+
The newest run directory is the active one; older ones are the auditable
|
|
156
|
+
history.
|
|
141
157
|
- `.ai/workflow/manifest.json` records the installed kit version, the chosen
|
|
142
158
|
harnesses, and the per-role model preferences.
|
|
159
|
+
- Every worktree a run touches carries a `.ai/run` pointer (absolute path of
|
|
160
|
+
the run directory, gitignored) and `00-goal.md` carries one
|
|
161
|
+
`run-base[<repo-basename>]` marker per repository for multi-repo runs.
|
|
143
162
|
|
|
144
163
|
### Models
|
|
145
164
|
|