fix(LTX25-DEVICE-RESIDENCY): name the load prologue load.open, because a floor wide enough to hide it is a mute switch (#1439) - #1622
Merged
Conversation
…use a floor wide enough to hide it is a mute switch (#1439) `CHECK(leaves >= 0.95 * wall)` in `ltx2 video: a render through the ABI emits a phase table that SUMS to wall` reds `main` intermittently, and it failed at `0.702349 >= 0.702944` — 0.08% short. Two earlier sessions deliberately left it alone and recorded why: 91% of its residue is ONE contiguous ~11.3 ms interval at the head of the `load` span, before `load.dit` opens. It is a real startup phase. Any slack big enough to stop the flapping would exceed 12 ms and would hide it. So this names the phase instead of widening the floor. The assertion is byte-for-byte unchanged. `ltx2_video.cpp` opens `phase::Scope open_phase("load.open")` immediately after the `load` span and closes it immediately before the `load.dit` block, over the prologue the probe already identified: device resolution, the platform probe, the two refusals, the device-byte probe install, the DiT safetensors header open and the LoRA option parsing. `Scope::Close` rather than a nested block is the shape `render_phase_log.h` documents for this driver, whose regions are sequential statements in one function. Red first, and the red IS the reachability mutation. The test change was built alone, so the red arm is this tree with the gate asking for the name and no production scope to answer it: 447 assertions, 1 failed, `the phase table names no 'load.open' phase`. With the scope: 459 assertions, 0 failed. Deleting the production call site is precisely that first arm. A second mutation pins the CLOSE and not only the OPEN. Sinking `open_phase.Close()` below the `load.dit` block compiles and keeps the SUM case green at 459/459, and is caught instead by the #1440 nested-record rule: the carrying-phases case reds at 595/1 with `'load.dit' is emitted NESTED`. Tree md5-verified restored between arms. The residue, six runs per arm on one binary each, Release CPU: median `unaccounted_seconds` 2.91 ms before, 0.94 ms after; `load.open` is emitted as a leaf at `t=0.000` and measures about 1.3 ms. Two limits on that number, in the spec and repeated here because they bound the claim. The box was at loadavg 24-31, so the render's wall is 7-10 s rather than the 0.22-0.58 s of #1439's population — the flattering regime the issue itself identified, where a slower render passes. And the 11.3 ms head is not reproduced at this build type with the fixture warm; the prologue is about 1.3 ms here. The direction and the mechanism are measured; the magnitude at which the floor bites is inherited from the earlier probe, and a quiet-box run at fixture scale stays owed. The order case gains `load.open` as its first entry, so a swapped scope name reds there the way `load.dit` and `load.prompt_embeds` already do. Not owed: a `docs/models/ltx-2-5.md` edit. The spec said this change owes the phase names published there. That document publishes none — `## Inspect a render` names `sum_leaf_seconds`, `unaccounted_seconds` and two switches and no individual phase. Checked rather than assumed. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…anchor list must be re-derived at the FINAL head
`build-test-cpu` reds on `ltx2 video: the recorded reader anchors are the ones in
the source`. This branch inserted `phase::Scope open_phase("load.open")` into
`src/vllm/multimodal/ltx2_video.cpp` and moved every reader below it, so the
READER ANCHORS comment now points at the wrong lines. The guard did its job.
The repair is a new anchor list, and a list is only correct at the head it was
derived from. `origin/main` moved eight commits since this branch forked, so
deriving the numbers before the merge would record a set that the merge itself
invalidates -- which is the exact defect this gate exists to catch. So the merge
lands first and the derivation follows it.
The merge is textually trivial. `.agents/issue-index.md` is the only shared
record either side touched: `origin/main` appends four rows (#1183, #1613, #1614,
#1502) and this branch appends none, so the union driver has nothing to
reconcile and the result is main's file byte-for-byte. No other path conflicts.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
… row's own `load.open` scope moved (#1439) `ltx2 video: the recorded reader anchors are the ones in the source` reds `build-test-cpu` and `sanitize-cpu (thread)` on this branch. The cause is this branch: `phase::Scope open_phase("load.open")` and its `Close` went into `ResolveAndRender` above every accepted-key reader, so all fourteen readers moved down by 28 to 31 lines and the recorded list stopped naming any of them. Nothing is wrong with the code the comment describes. The readers are the same fourteen, in the same order, reading the same keys; only their line numbers changed. So the repair is the list, and the gate that caught it stays exactly as it is. It has now fired three times for three different insertions, which is the argument for deriving the numbers rather than trusting them. The new list is the one the test itself printed, at the head that carries it rather than at the head that broke it. `origin/main` had moved eight commits, so this branch merged first and the derivation ran after the merge -- recording a set that a pending merge would invalidate is the same defect in a new costume. The merge turned out not to touch `ltx2_video.cpp`, so the numbers are equal to the ones the pre-merge run reported, but that was checked and not assumed. Only the fourteen digits on the comment line change, so the edit cannot move an anchor it is recording: one line in, one line out, and the derived set is identical either side of it. Release CPU, whole `test_ltx2_video` binary, one build per arm. Stale list: 102 cases, 101 passed, 1 failed; 4227 assertions, 4226 passed, 1 failed. Corrected list: 102 cases, 102 passed, 0 failed; 4225 assertions, 4225 passed, 0 failed. The anchor case alone is 26 assertions in both arms, 25 passed before and 26 after, so it is the only case whose verdict this changes. The two-assertion difference in the totals is not this edit, and a control says so rather than an argument: a third run of the corrected binary, same bytes and same source, reported 4227 of 4227. So a render case's assertion count follows the phase records that run emits, it moves between 4225 and 4227 on its own, and the box was at load 28-75 throughout. Only the failure counts are stable. Not owed: `.agents/specs/ltx25-retire-dead-arms.md` section 2.1. Its table is declared "as of `3c6706cd0`", a dated record rather than a live one, and the test's own failure text says it stays. Checked rather than assumed. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… the anchors it could have moved `origin/main` advanced to `0822160f5` while this branch's gate was running, so the trailer gates refused to report and asked for a merge. This is that merge. It carries one commit, SPEC-DFLASH2 W6 (#1314, #1637). It touches neither `src/vllm/multimodal/ltx2_video.cpp` nor `tests/vllm/multimodal/test_ltx2_video.cpp`, so the READER ANCHORS list this branch just re-derived still names the fourteen readers. That was checked against the merged tree and not assumed from the subject line, because an anchor list is only true at the head it was derived from and this is a different head. `.agents/issue-index.md` takes six appended rows from main and none from this branch, so the union driver has nothing to reconcile again. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…e the anchors at the merged head `origin/main` advanced five commits while this pull request's continuous integration settled. None of them edits `src/vllm/multimodal/ltx2_video.cpp` or `tests/vllm/multimodal/test_ltx2_video.cpp`, so the recorded `READER ANCHORS` line should still hold. That is a prediction, not a result, and this row has already been caught twice by exactly this staleness. The anchor list is therefore re-derived by running `test_ltx2_video` at the merged head rather than by reading the diff. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Claude:claude-opus-5 [Claude Code]
localai-bot
pushed a commit
that referenced
this pull request
Aug 22, 2026
GitHub refused the squash with a conflict on `.agents/issue-index.md`. That file carries `merge=union` in `.gitattributes`, and the forge does NOT honour the driver -- so two branches that each append a row conflict there even though the union resolves cleanly. Doing the merge locally is what applies the driver. `#1622` landed between this branch's last merge and the squash attempt. The only shared file is that append-only index, and both sides only append. No source file is touched by both. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Claude:claude-opus-5 [Claude Code]
This was referenced Aug 22, 2026
localai-bot
added a commit
that referenced
this pull request
Aug 22, 2026
… request, and ten open issues had no index row (#1670) PR #1556 is being closed rather than merged, and this lands the record it would otherwise have taken with it. ## Why that pull request cannot merge `squash_merge_commit_message = PR_BODY`, so its body becomes the permanent commit message. That body argues at length for a `load.setup` anchor that `519303d15` (#1622, row `LTX25-DEVICE-RESIDENCY`) had already landed as `load.open` — same region, same open and close statements, same `Scope::Close` shape. Merging it writes a materially false narrative onto `main` irreversibly. **That is a defect in the message, not in the code.** ## Why the code alone was not enough to salvage Verified on `db648fb88` by a tree-wide grep over `src/`, `include/`, `tests/` and `docs/`: | symbol | occurrences on `main` | |---|---:| | `load.dit_config` | 0 | | `artifacts.mux` | 0 | | `sampler_updates` | 0 | | `Record::instrument_seconds` | 0 | | `denoise.update` | 1 — `test_ltx2_video.cpp:4325`, which is `6b48edb2c`'s comment ASKING for it | So the supersession covers ONE anchor, not the branch: three anchors plus a ~193-line change to shared instrument semantics and 583 lines of test remain genuinely new. That is a fresh row's work with its own red-first tests and its own fresh review, on a branch that conflicts in three files — not a small salvage. It is owed under #1668. ## What this commit preserves Ten issues are open on the forge and **none of them had a row in `.agents/issue-index.md`**: #1470, #1536, #1567, #1568, #1569, #1570, #1571, #1572, #1619 and #1668. Closing the pull request without this would have left all ten invisible in the record, along with 809 lines of measurement. Two things in there are worth more than the anchors: **The residue decomposition.** 92.09% of the un-named time is ONE region — the load prologue, 17.661 ms of a 19.178 ms residue. The other four gaps are 4.95%, 1.30%, 1.09% and 0.56%, and the sixteen gaps between adjacent named phases hold 6.8 us each, which is the instrument and nothing else. #1536's own first hypothesis, `d995c52f0`'s temporal x2 upsampler, is **refuted** rather than deprioritised: it runs inside `phase.upsample_latent`, a named leaf, and is not in the residue at all. **A rejected gate design, with its distributions.** `residue <= 2 * instrument` measured red 4 in 45 at the table bound (load 88, max 4.115), 3 in 200 at the conservation case, 2 in 200 at `unit.parent`, and 28 in 160 (17.5%, max 5.55) on a standalone probe at load 125. The un-instrumented remainder of a boundary dilates faster than the instrumented part under contention, so the ratio has a heavy right tail — and the 20-run distribution that read 1.021 to 1.464 saw none of it. Three fresh reviews paid for that. `## Design` 3 exists so nobody measures it again. ## The spec is written to today's position No `## Gates` section, because the row is not runnable and a `## Gates` edit moves a row into the runnable population as a side effect. No `## Outcome`, because there is no outcome yet. `## Now` states plainly that the implementation is not on `main`, and names `refs/pull/1556/head` = `b45ea3bbb`, where the reference implementation, the full gate report, the mutation table and the three review threads stay readable. Two index rows are corrected **before** they are appended rather than after. The branch wrote #1470 and #1536 as closed by anchoring the sampler step — true of the branch, never true of the tree. They now say what actually landed instead, and say that an earlier draft claimed otherwise. ## Five inherited claims the fresh review falsified, and this record does not repeat A record pull request whose sentences are wrong is entirely defective, and four of these came verbatim from #1556's spec without being re-verified. Two were landing in append-only rows. Repaired in `2f2fc2dc7`. **`check-agent-record.py` never passed the duplicate.** #1556's spec said `git merge-tree`, `check-agent-record.py` and `check-issue-index-append-only.py` all accepted the 538-line union output. Reproduced, and false: that checker returns **rc=1** with `issue #1546 listed twice`, and the refusal has existed since `8dd6508da` (2026-08-09) — before the merge in question. Verified twice, restored byte-for-byte both times. The gap is real and **narrower**: one checker is blind, not two. **"Three months" is arithmetically impossible.** #1439, #1470, #1494 and #1536 were filed between `2026-08-20T05:23Z` and `2026-08-21T04:40Z` — under 24 hours. This repository's first commit is `accfae2de`, 2026-07-02, so nothing in it can be three months old. **`ltx2_res2s.cpp` has never existed.** `git log --all --diff-filter=A` finds no such file. `Ltx2Res2sDenoisingLoop` lives in `ltx2_samplers.cpp`, declared in `ltx2_samplers.h` beside `Ltx2Res2sHooks`, called from `ltx2_video.cpp`. #1567's forge text names no file, so the wrong anchor was invented by the spec. **The `#838` recurrence is withdrawn as unreproducible.** Re-running `git merge-file --union` at every later merge where `#838` sat on a side leaves it present in all of them. A union driver cannot drop a line that is an addition on one side. That sentence was what turned a measured one-off into a recurring class. **`d27639e71` is not a `build-newest-gcc` repair.** It is `BACKEND-TENSTORRENT-HOST-FREE-FORWARD` (#1476/#1595) and added the same `<unistd.h>` in passing; only `13548db8f` (#1581) is that lane's fix. And "records that as a holding action, in terms" claimed a quotation the tree does not contain — right in substance, not in those words. ## A fifth claim — this one was mine, not inherited While waiting on CI I re-measured the one assertion in this PR I had taken from the reviewer rather than run myself. It was overstated, and it was landing in an append-only row. Repaired in `72589fe6e`. The #1619 row said `check-issue-index-append-only.py` reds a correct de-duplication. Measured on a scratch branch off this head, **with commits** — that checker diffs `merge_base..HEAD` from Git objects and ignores a working tree: | committed mutation | `check-issue-index-append-only.py` | `check-agent-record.py` | |---|---|---| | duplicate a row | **rc=0** (blind) | **rc=1**, `listed twice` | | then remove the duplicate | **rc=0** | — | | relocate a **base-reachable** row | **rc=1**, `removed: ... #168` | — | Add-then-remove nets to nothing against the merge base, so it passes. **And the de-duplication claim needs a condition, which a re-review supplied and which I had not measured.** The rows above all use `origin/main` as the base — a base that *predates* the duplicate. Run at three pairings: ``` --base e2a9e03 --head <real canonical 537> -> OK rc=0 --base e2a9e03 --head <synthetic 537> -> OK rc=0 --base <committed 538> --head <537 de-dup> -> FAIL rc=1 ``` So the checker reds a de-duplication **only when the duplicate is already reachable from the base** — when you are repairing a corruption that already landed. It does not fire on someone who fixes union output before committing it, which is the ordinary case and the shape this branch used. The same range property is what makes relocating a base-reachable row red. Two lessons recorded rather than absorbed silently. Mine: three earlier probes edited the **working tree** and read rc=0 from all of them, including one that deleted a base row — that is not evidence about a checker that reads commits. The reviewer's, which it volunteered: it first marked this half confirmed from **reading** `removed = [...]`, and reading the collector says what it collects, not what the diff *range* puts in front of it. Recorded because the method matters: my first three probes edited the working tree and read rc=0 from all of them, **including one that deleted a base row**. That is not evidence about the checker, it is a restatement of the fact that it reads commits. The `check-agent-record.py` rc=1 result re-confirms the F1 correction above in the same run. ## Evidence ``` git diff --numstat <merge-base> HEAD 10 0 .agents/issue-index.md .agents/specs/ltx25-phase-residue.md (new file) issue-index: 592 rows, 592 unique issue ids, 0 duplicates, additions-only this branch's ten rows are 598-607 (#1470 .. #1668); main's #1666/#1667 follow at 608-609 and #1131 at 610, so the file ends at neither side's append scripts/agent-preflight.sh exit=0, All gates green, none skipped ``` The evidence quotes a **merge-base sha, not `origin/main`** — deliberately. `main` moved three times during this work (`db648fb88` → `5539686c7` → `9712ab77f` → `3e5d2f370`), and the same command against a moved main measures a different thing: `git diff --numstat 5539686 3d6a0a4` reads **`10 1`**, where the lone deletion is main's own `#1131` row that the pre-merge head did not yet have. Against the merge base it reads `10 0`. A number derived from a name that resolves differently every few minutes describes whichever main was current when the command ran, not the change. (An earlier revision of this body said that reading was `1 1`. It is not reproducible at any pairing, and it is corrected here rather than carried — the index did not move at all between `5539686c7` and `9712ab77f`.) **On the row placement, stated rather than glossed:** the canonical procedure the #1619 row prescribes is to append at the true end and re-verify. That is not what this head looks like — the union merge placed main's `#1131` after this branch's ten. Additions-only and duplicate-free both hold, and no row was lost or edited, so the result is correct; but the ordering is the driver's, not the procedure's, and saying otherwise would repeat exactly the kind of unchecked claim this PR exists to correct. Zero-duplicate ids is asserted rather than assumed. It is **not** the detector #1619 was filed about — that was this PR's own earlier position, and the repair overturned it: `check-agent-record.py` has refused duplicate ids since `8dd6508da`. #1619's remaining ask is row **multiplicity**. `test_cpu_x86_llamacpp_floor` red once during this work at loadavg 31.79, `NO_QUIET_WINDOW` (4) where the case expects `GIVING_UP` (2). That is #618 verbatim and load-dependent: it passed on a clean tree and then passed again on this tree at lower load. A records-only diff of two Markdown files cannot reach a CPU floor harness. One scope correction while we are here: "neither red reproduces" means the two floors this row was filed against. It is **not** a claim that `test_ltx2_video` is quiet — #1572, one of the rows in this batch, records assertion (1c)'s span slack redding intermittently on `main`, which this row neither causes nor repairs. This row has no matrix row and therefore no lifecycle state, so `scripts/now.py` and `audit-live-rows` will not surface it. That is deliberate while the implementation is unlanded: creating a row now would put an empty one in the runnable population. #1668 is the forward owner and creates the row with the code. ## Nothing is closed here #1439, #1470, #1536, #1567, #1568, #1569, #1570, #1571, #1572 and #1619 all stay open. #1668 stays open and carries the implementation. This commit records #1668 rather than discharging it. ## Why this merged without a complete rollup on its exact SHA Recorded because a reader six months from now will see a merge on a partially-settled rollup and needs to know it was a judgement, not an oversight. `main` moved five times while this branch was in review (`db648fb88` → `5539686c7` → `9712ab77f` → `3e5d2f370` → `d25730fbb` → `4ede6bdfd`). GitHub does not honour the `merge=union` driver on `.agents/issue-index.md`, so each move marked this PR `CONFLICTING` and forced a real merge commit, which restarts a ~75-minute CI cycle. At ~10 commits/hour into main, that loop has no fixed point. **The gated tree is `d25730fbb`** — a commit on `main`, carrying `main`'s own CI verdict. This branch's head `b3761b976` is that tree plus this change, and the delta cannot reach anything CI compiles or runs: ``` git diff --stat d25730f b3761b9 -- src include tests examples [empty] git diff --stat d25730f b3761b9 .agents/issue-index.md | 10 ++ .agents/specs/ltx25-phase-residue.md | 285 +++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) ``` Two Markdown files, **295 insertions, zero deletions**. The compiled artifacts at this head are byte-identical to `d25730fbb`'s by construction, so `d25730fbb`'s verdict is not "probably still valid" — it is a verdict about the same binaries. Both SHAs are pinned deliberately: `origin/main` is a moving ref, and diffing it instead of a pinned commit made this same branch appear to delete 768 lines of `vocoder1d.cpp`, `cpu_conv1d_*` and three test files, when the deletions were `4ede6bdfd` landing between two commands. What did settle on this branch's own rollups was verified by failure **text**, not job name, against `main`'s baseline `90e8c3c85`: `build-test-cpu` and `sanitize-cpu (address,undefined)` each fail one test of 590, test #282, on a **byte-identical 335-byte** assertion at `test_runner.cpp:1557`, with **zero** sanitizer diagnostics on both sides (#1602/#1608); `windows-msvc-cpu` and `-vulkan` fail on the `/W4 /WX ... negated by /w` checker refusal (#1649) that fires before any compilation, with zero `error C####` and zero `error LNK####`. `build-newest-gcc` — the one job that can never be called inherited, since `main-baseline.py`'s newest row predates #1581 — is **green**. Records verified on the merged result rather than against the moving ref: 594 rows, 594 unique issue ids, zero duplicates, and `git diff --numstat` additions-only for this branch's ten rows. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [claude-code] --------- Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CHECK(leaves >= 0.95 * wall)inltx2 video: a render through the ABI emits a phase table that SUMS to wallredsmainintermittently, and it failed at0.702349 >= 0.702944— 0.08% short. Two earlier sessions deliberately left italone and recorded why: 91% of its residue is ONE contiguous ~11.3 ms interval at
the head of the
loadspan, beforeload.ditopens. It is a real startup phase.Any slack big enough to stop the flapping would exceed 12 ms and would hide it.
So this names the phase instead of widening the floor. The assertion is
byte-for-byte unchanged.
ltx2_video.cppopensphase::Scope open_phase("load.open")immediately after theloadspan and closes itimmediately before the
load.ditblock, over the prologue the probe alreadyidentified: device resolution, the platform probe, the two refusals, the
device-byte probe install, the DiT safetensors header open and the LoRA option
parsing.
Scope::Closerather than a nested block is the shaperender_phase_log.hdocuments for this driver, whose regions are sequentialstatements in one function.
Red first, and the red IS the reachability mutation. The test change was built
alone, so the red arm is this tree with the gate asking for the name and no
production scope to answer it: 447 assertions, 1 failed,
the phase table names no 'load.open' phase. With the scope: 459 assertions, 0 failed. Deleting theproduction call site is precisely that first arm.
A second mutation pins the CLOSE and not only the OPEN. Sinking
open_phase.Close()below theload.ditblock compiles and keeps the SUM casegreen at 459/459, and is caught instead by the #1440 nested-record rule: the
carrying-phases case reds at 595/1 with
'load.dit' is emitted NESTED. Treemd5-verified restored between arms.
The residue, six runs per arm on one binary each, Release CPU: median
unaccounted_seconds2.91 ms before, 0.94 ms after;load.openis emitted as aleaf at
t=0.000and measures about 1.3 ms.Two limits on that number, in the spec and repeated here because they bound the
claim. The box was at loadavg 24-31, so the render's wall is 7-10 s rather than
the 0.22-0.58 s of #1439's population — the flattering regime the issue itself
identified, where a slower render passes. And the 11.3 ms head is not reproduced
at this build type with the fixture warm; the prologue is about 1.3 ms here. The
direction and the mechanism are measured; the magnitude at which the floor bites
is inherited from the earlier probe, and a quiet-box run at fixture scale stays
owed.
The order case gains
load.openas its first entry, so a swapped scope name redsthere the way
load.ditandload.prompt_embedsalready do.Not owed: a
docs/models/ltx-2-5.mdedit. The spec said this change owes thephase names published there. That document publishes none —
## Inspect a rendernames
sum_leaf_seconds,unaccounted_secondsand two switches and noindividual phase. Checked rather than assumed.
Refs #1439, which stays OPEN. The repair is measured; the regime where the
floor bites is not, and one quiet-box run at fixture scale is what closes it.
That run is owed by
LTX25-DEVICE-RESIDENCYand is named in its## Owedrow.FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]