loki-mode 9.59.0 → 9.64.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/browser-open.sh +51 -0
- package/autonomy/lib/deadline.py +46 -5
- package/autonomy/lib/proof-check.sh +17 -2
- package/autonomy/loki +41 -69
- package/autonomy/run.sh +662 -51
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/dev/release-checklist.md +11 -32
- package/docs/v10/BOARD.md +69 -41
- package/docs/v10/DECISIONS.md +19 -0
- package/docs/v10/GUARDS.md +435 -0
- package/docs/v10/PROGRESS.md +9 -0
- package/docs/v10/TODO.md +43 -0
- package/learning/suggest.sh +1 -1
- package/loki-ts/dist/loki.js +307 -307
- package/loki-ts/package.json +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
package/docs/v10/DECISIONS.md
CHANGED
|
@@ -209,3 +209,22 @@ One entry per decision: context, choice, why, how to reverse. Newest last.
|
|
|
209
209
|
- Release Manager exception, disclosed: until S-16 makes `scripts/release.sh` bump every checklist file without prompting or pushing, the Release Manager bumps VERSION with the editor tool (not a shell command) as part of the release commit. v9.57.0 (5332bfc3) was bumped this way. This is the only permitted VERSION write outside release.sh, and it ends when S-16 merges.
|
|
210
210
|
- Evidence: train 2 push, `PRE_PUSH_SKIP=1 git push origin main` at 15:48:18Z: rc=0; `git rev-parse HEAD` = `git ls-remote origin refs/heads/main` = 89e350bd641a4b659faa405587a9db5bb7bcc201. Release push at 15:50:09Z: rc=0; both = 5332bfc35ccf801bdf8c67bff9fc07537ac4240f. The per-SHA concurrency from S-80 held on its first real push: Tests on 89e350bd kept running (`in_progress`) after 5332bfc3 was pushed.
|
|
211
211
|
- Reverse: keep local CI as a precondition. Not chosen: it cannot finish inside the 10-minute command cap under swarm load, and it duplicates GitHub CI.
|
|
212
|
+
|
|
213
|
+
## D28. 2026-09-27: Loki P0 directive -- restore green, release only verified trees, protect the machine
|
|
214
|
+
|
|
215
|
+
- Context: v9.57.0, v9.58.0 and v9.59.0 were bumped and pushed but none had published (npm 9.56.0 at 16:18Z; `npm view loki-mode version`). Causes:
|
|
216
|
+
- `pytest -n auto` (S-86) turned the test_build_supervisor lineage race into a near-certain failure (runs 36330898897, 36331204715, 36332036570, 36333026958).
|
|
217
|
+
- A shell shard failed on the runtime-gate port-scoping positive control.
|
|
218
|
+
- The release job could not push its tag for releases that change workflow files.
|
|
219
|
+
- Machine load reached 136: a stale kind cluster (loki-smoke-control-plane) was crash-looping, and an orphaned tests/detect-mock-problems.sh had run for 12.5 hours; Loki stopped both. At 16:30Z a second orphan, PID 79553 tests/test-resource-monitor-sleep-reaped.sh (PPID 1, etime 23:48:17) with its child sleep 69161, was stopped by exact PID (0 remaining).
|
|
220
|
+
- Choice (Loki approved):
|
|
221
|
+
1. Restore green by the fastest path. `pytest -n auto` is reverted as its own commit (b01bd36c); item 9 returns after S-102. The shard 0 suite, tests/test-runtime-gate-port-scoping.sh (not moat, not review), is quarantined until 2026-10-03 (ea8ecf1c) while S-106 fixes the race.
|
|
222
|
+
2. Release rule: never bump VERSION on a tree without a green Tier B run on that exact tree; a release is a lookup of a verified commit. Enforced by S-108 (release.sh refuses the bump without a green Tests and Bun Parity run for HEAD) and S-109 (RELEASE_ON_RED pulse violation). Versions bumped but never published are recorded as such in CHANGELOG.
|
|
223
|
+
3. Machine protection:
|
|
224
|
+
- Local load must stay under 2x the core count (28 on 14 cores).
|
|
225
|
+
- Engineers run only their slice's tests locally, never full suites, and no local `pytest -n auto`.
|
|
226
|
+
- Every swarm container gets --cpus=2 and a memory limit, no restart policy, and is removed when done. The S-102 container s102-repro-a167 was capped at 16:30Z (`docker update --cpus 2 --memory 4g`; restart=no).
|
|
227
|
+
- New pulse violations HIGH_LOAD (load > 28), ORPHAN_TEST (a tests/* process with PPID 1 or running more than 30 min) and STRAY_CONTAINER (a swarm container older than 1 hour) (S-109).
|
|
228
|
+
4. Release the first green tree, then continue the 20-minute trains.
|
|
229
|
+
- Found while acting: train 5 (S-18) introduced a P9 moat regression on Linux: the opt-out positive control, "the hosts.yml probe is blind under the opt-out" (moat job 108658485224). It fails closed (no leak) but blocks every tree from 1cde81a7 onward. P0 S-107 is fixing it forward in a capped Linux container.
|
|
230
|
+
- Version accounting: tags v9.57.0 through v9.62.0 were pushed at 16:25Z and 16:29Z to work around the release job's tag-permission failure (S-105), before this rule. v9.60.0 is already tagged at 1cde81a7 (red: P9 and the Python race), so the "first green tree" cannot reuse 9.60.0 without moving a published tag. Train 4 (08d64f4e, v9.59.0) went green on Tests after reruns and contains no S-18, so its full Release rerun is the first verified-tree release. The next release after S-107 takes the next unused version.
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# Guards
|
|
2
|
+
|
|
3
|
+
D26 guard 5 (incident-to-guard). One entry per incident, four fields each:
|
|
4
|
+
incident, root cause with evidence, the guard, and the test that proves it
|
|
5
|
+
fires. A guard with no checked-in test is marked PENDING with the slice ID
|
|
6
|
+
that owns building it -- never claimed as done. Newest last.
|
|
7
|
+
|
|
8
|
+
MERGED status is judged by whether the change is reachable from main,
|
|
9
|
+
INCLUDING a patch-equivalent cherry-pick under a different SHA -- never by
|
|
10
|
+
whether the original commit SHA is literally an ancestor of main. Check
|
|
11
|
+
both: `git merge-base --is-ancestor <sha> main` for a direct ancestor, and
|
|
12
|
+
`git cherry main <sha>` (a `-` line means an equivalent patch already
|
|
13
|
+
exists on main) or `git log main --grep 'cherry picked from commit <sha>'`
|
|
14
|
+
for a cherry-pick. A stale re-verification using only the ancestor check
|
|
15
|
+
previously mismarked two merged guards (S-16, S-74) as PENDING.
|
|
16
|
+
|
|
17
|
+
## 1. Unscoped `pkill` terminated unrelated sessions (D14, D15)
|
|
18
|
+
|
|
19
|
+
- **Incident:** an unscoped `pkill -f` pattern match, in a test and
|
|
20
|
+
separately in the session-teardown path, killed unrelated processes --
|
|
21
|
+
including, three times in one session, the session's own CLI process, and
|
|
22
|
+
separately, other users' unrelated Claude Code sessions on the same
|
|
23
|
+
machine at the end of any signal-path session close.
|
|
24
|
+
- **Root cause with evidence:** D14 -- `tests/test-backend-floor.sh:43` ran
|
|
25
|
+
`pkill -f "index.mjs"` with no PID or path scoping; reproduced directly by
|
|
26
|
+
starting a decoy process with `index.mjs` in its argv and confirming the
|
|
27
|
+
bare `pkill -f` killed it. Root-caused three unexplained mid-session
|
|
28
|
+
terminations in about 25 minutes, each landing 2-4 minutes into a
|
|
29
|
+
HIGH-tier 4-agent council review (DECISIONS.md D14). D15 -- a sibling bug:
|
|
30
|
+
`kill_provider_child()` in `autonomy/run.sh` ran
|
|
31
|
+
`pkill -f "^${proc}( |$)"` for claude/codex/aider/cline on every
|
|
32
|
+
signal-path session end, with no scoping to a PID, process group, or
|
|
33
|
+
working directory; reproduced with a decoy process sharing no relationship
|
|
34
|
+
to the run except the matching command-line substring (DECISIONS.md D15).
|
|
35
|
+
- **The guard:** D14 -- `tests/test-backend-floor.sh` (commit `61547203`)
|
|
36
|
+
finds the PID actually LISTENing on the target port via
|
|
37
|
+
`lsof -ti tcp:$PORT -sTCP:LISTEN` and kills only that PID (TERM then KILL);
|
|
38
|
+
the already-scoped trap-line pkill on the unique mktemp path was left
|
|
39
|
+
unchanged. D15 -- `kill_provider_child()` in `autonomy/run.sh` (commit
|
|
40
|
+
`9cd51d1a`) scopes its sweep to processes sharing this run's own process
|
|
41
|
+
group id, never a bare name/pattern match across the whole machine. Both
|
|
42
|
+
merged to main.
|
|
43
|
+
- **The test that proves it fires:** `tests/test-backend-floor.sh` (the D14
|
|
44
|
+
fix's decoy-process case, comment-anchored as "ROUND 3: the D14 fix"), and
|
|
45
|
+
`tests/test-kill-provider-child-scoping.sh`, which proves both directions:
|
|
46
|
+
a same-process-group leak is still cleaned up, and a different-process-group
|
|
47
|
+
"unrelated session" decoy survives. That test itself needed two further
|
|
48
|
+
hardening rounds (D16, D17) after review found its own decoy-selection and
|
|
49
|
+
process-group isolation could reproduce the exact bug it was meant to
|
|
50
|
+
guard against -- see those decisions for why a process-killing test must
|
|
51
|
+
be reviewed at the same severity as the product code it tests.
|
|
52
|
+
|
|
53
|
+
## 2. `docs/v10/BOARD.md` emptied by a python heredoc (D18)
|
|
54
|
+
|
|
55
|
+
- **Incident:** commit `de3a8503` committed `docs/v10/BOARD.md` as 0 bytes,
|
|
56
|
+
silently destroying 13189 bytes of real coordination state (every GF/PF/S-NN
|
|
57
|
+
row), with no diff review, no size check, and no read-back before the
|
|
58
|
+
commit.
|
|
59
|
+
- **Root cause with evidence:** a
|
|
60
|
+
`python3 -c <<'EOF' ... open(p,'w').write(s) ... EOF` heredoc pattern
|
|
61
|
+
applied a targeted edit via `re.sub` guarded only by `assert old in s`; an
|
|
62
|
+
assertion failure aborts the script, but if the write happens (or a prior
|
|
63
|
+
failed attempt already wrote a partial/empty `s`) before or independent of
|
|
64
|
+
that guard, nothing catches it (DECISIONS.md D18).
|
|
65
|
+
- **The guard:** interim discipline, in force today: every edit to a hot
|
|
66
|
+
coordination file (BOARD.md, PROGRESS.md, DECISIONS.md, BACKLOG.md,
|
|
67
|
+
METRICS.md) uses Read then Edit (which refuses to run unread and fails
|
|
68
|
+
loudly on a no-match) or, if a script is genuinely needed, checks the
|
|
69
|
+
resulting file's byte size against a sane lower bound and runs
|
|
70
|
+
`git diff --stat` before `git add`, never committing a docs file whose diff
|
|
71
|
+
shows only deletions with no matching insertions (DECISIONS.md D18).
|
|
72
|
+
Mechanical enforcement at commit time -- a PreToolUse hook blocking a
|
|
73
|
+
BOARD.md commit that drops existing rows (D26 guard 1) -- is
|
|
74
|
+
`scripts/v10-guard.sh`, **MERGED (S-73)**: `db51311a`..`e9170698` are all
|
|
75
|
+
direct ancestors of main (`git merge-base --is-ancestor <sha> main`),
|
|
76
|
+
landing in release train 2 (v9.57.0, commit `5332bfc3`). A narrower
|
|
77
|
+
mechanical guard for one specific write path (`board-row-status` in
|
|
78
|
+
`scripts/v10-ops.sh`, which verifies the target row changed in exactly its
|
|
79
|
+
Status cell and restores the original on any other mismatch) is also
|
|
80
|
+
**MERGED (S-74)**, via cherry-pick `8fbbbb31` (verified below, section 7).
|
|
81
|
+
- **The test that proves it fires:** none checked in for the general Read
|
|
82
|
+
then Edit discipline -- it is a process rule, not code, so there is
|
|
83
|
+
nothing to unit-test. `scripts/v10-guard.sh`'s BOARD.md-row-drop block and
|
|
84
|
+
its test are **MERGED (S-73)**: `tests/test-v10-guard.sh` is present on
|
|
85
|
+
main (925/640-line files respectively). `board-row-status`'s byte-for-byte
|
|
86
|
+
post-write verification and its tests in `tests/test-v10-ops.sh` are
|
|
87
|
+
**MERGED (S-74)** (same `8fbbbb31` cherry-pick).
|
|
88
|
+
|
|
89
|
+
## 3. CI self-cancellation on every push to main (D25)
|
|
90
|
+
|
|
91
|
+
- **Incident:** pushing to main routinely cancelled the Tests workflow's own
|
|
92
|
+
in-progress run on main -- 10 of the last 12 Tests runs on main were
|
|
93
|
+
cancelled by the swarm's own subsequent pushes, not by any real code
|
|
94
|
+
defect, against a real Tests runtime of 26-34 minutes and a push cadence
|
|
95
|
+
of roughly 20 minutes, so main effectively never got a green verdict.
|
|
96
|
+
- **Root cause with evidence:** `test.yml` (and, identically,
|
|
97
|
+
`bun-parity.yml` and `security-audit.yml`) keyed its concurrency group on
|
|
98
|
+
`${{ github.workflow }}-${{ github.ref }}` with `cancel-in-progress: true`
|
|
99
|
+
unconditionally -- every push to main resolves to the same `ref`, so every
|
|
100
|
+
push shared one group with the prior push's still-running job and
|
|
101
|
+
cancelled it (DECISIONS.md D25).
|
|
102
|
+
- **The guard:** first attempt, S-69 (commit `8cfa1eae`), scoped
|
|
103
|
+
`cancel-in-progress` to `pull_request` events only in `test.yml`, leaving
|
|
104
|
+
the group key unchanged -- this left a THIRD push able to still cancel a
|
|
105
|
+
still-pending (queued, not yet running) main run, and covered only
|
|
106
|
+
`test.yml`. Superseded before merge by S-80 (commit `d5d6bfa7`, also
|
|
107
|
+
`3bd01787`), which instead keys the concurrency GROUP itself on
|
|
108
|
+
`github.sha` for non-pull_request events, in all three gating workflows
|
|
109
|
+
(`test.yml`, `bun-parity.yml`, `security-audit.yml`): every main commit
|
|
110
|
+
gets its own group and can never be queued behind or cancelled by another
|
|
111
|
+
commit's run, while PR runs keep the ref-keyed group and
|
|
112
|
+
`cancel-in-progress: true` so a stale run of the SAME PR still cancels.
|
|
113
|
+
- **The test that proves it fires:** verified with one real push landing
|
|
114
|
+
without cancelling a concurrent run, per the S-80 slice's own acceptance
|
|
115
|
+
check -- a GitHub Actions concurrency block cannot be exercised by a local
|
|
116
|
+
unit test; it only takes effect on the real Actions runner. No fixture
|
|
117
|
+
test exists or is planned for this guard.
|
|
118
|
+
|
|
119
|
+
## 4. Pulse's UNKNOWN main-CI reading suppressed UNRELEASED_MERGE (S-71, `59118705`)
|
|
120
|
+
|
|
121
|
+
- **Incident:** `scripts/v10-pulse.sh`'s UNRELEASED_MERGE violation never
|
|
122
|
+
fired while main's CI status read UNKNOWN, even once the unreleased age
|
|
123
|
+
was well past its 30-minute budget -- an UNKNOWN CI reading silently read
|
|
124
|
+
as "CI is fine, do nothing."
|
|
125
|
+
- **Root cause with evidence:** UNRELEASED_MERGE's only firing condition was
|
|
126
|
+
`age > 30 and ci_status == "green"`; `ci_status` is `None` when main CI
|
|
127
|
+
reads UNKNOWN, so that comparison is always false and the violation can
|
|
128
|
+
never fire under UNKNOWN. This was the single shared point causing the
|
|
129
|
+
suppression -- every OTHER violation in the script already evaluated
|
|
130
|
+
independently of `ci_status` (commit `59118705`'s own message).
|
|
131
|
+
- **The guard:** commit `59118705` (cherry-picked from `b8f43d08`) adds a
|
|
132
|
+
CI-independent `elif age > 45: ...` path alongside the existing
|
|
133
|
+
green-CI-gated 30-minute branch, so UNRELEASED_MERGE can now fire on its
|
|
134
|
+
own past 45 minutes regardless of CI status. The same commit also adds
|
|
135
|
+
CI_CANCELLED_STREAK (3+ consecutive cancelled Tests runs on main),
|
|
136
|
+
computed from its own dedicated `PULSE_GH_STREAK_CMD` call, independent of
|
|
137
|
+
the main-CI-status lookup, so it too can fire when that lookup reads
|
|
138
|
+
UNKNOWN.
|
|
139
|
+
- **The test that proves it fires:** `tests/test-v10-pulse.sh` T18/T18b/T18c
|
|
140
|
+
(streak fires at 3+ consecutive cancellations, does not fire on a
|
|
141
|
+
non-consecutive run, reads UNKNOWN with no completed runs), T19/T19b
|
|
142
|
+
(unreleased-merge fires at 45+ minutes under UNKNOWN main CI, does not
|
|
143
|
+
fire at the 40-minute threshold), and T20 (LOW_READY still fires under
|
|
144
|
+
UNKNOWN main CI, proving the fix did not just move the suppression
|
|
145
|
+
elsewhere). Full suite 40/40, confirmed red against the pre-fix script.
|
|
146
|
+
|
|
147
|
+
## 5. Hung worktree classifier: `git status` touched the mtimes it measured (S-72)
|
|
148
|
+
|
|
149
|
+
- **Incident:** S-72's worktree-cleanup pass used "the worktree's directory
|
|
150
|
+
modified in the last 90 minutes" as its liveness signal for deciding which
|
|
151
|
+
of 112 accumulated `.claude/worktrees` entries were safe to remove. That
|
|
152
|
+
signal went dead mid-run -- pulse's own "Active builder worktrees" reading
|
|
153
|
+
jumped to "123 of 129" -- because the cleanup pass's own `git -C <wt>
|
|
154
|
+
status` calls refresh each worktree's index and touch its mtimes, so a
|
|
155
|
+
live agent that has not yet committed or written a file looked exactly as
|
|
156
|
+
safe to remove as a genuinely abandoned one, by every other rule the pass
|
|
157
|
+
checked.
|
|
158
|
+
- **Root cause with evidence:** PROGRESS.md, "Drift audit, turn 180": "S-72's
|
|
159
|
+
worktree cleanup used 'directory modified in the last 90 minutes' as its
|
|
160
|
+
liveness signal. Its own `git -C <wt> status` calls refresh each
|
|
161
|
+
worktree's index and touch mtimes... the signal went dead... Caught before
|
|
162
|
+
any removal (agent reported '0 worktrees removed so far')."
|
|
163
|
+
- **The guard:** applied ad hoc, in the moment, during that same S-72
|
|
164
|
+
cleanup pass: an explicit exclusion list of live and approved-unmerged
|
|
165
|
+
worktrees, plus `.git` file birth time (`stat -f %B`) in place of mtime as
|
|
166
|
+
the recency signal (PROGRESS.md, turn 180). This is a one-time operational
|
|
167
|
+
fix, not a standing, checked-in guard -- no code in this repo enforces
|
|
168
|
+
"never use mtime as a worktree-liveness signal" today. A real
|
|
169
|
+
worktree-cleanup tool that takes the live-agent list as input and
|
|
170
|
+
structurally cannot use mtime is cut as the follow-up, **PENDING (S-94)**
|
|
171
|
+
(commit `e80819d5`).
|
|
172
|
+
- **The test that proves it fires:** none checked in. **PENDING (S-94).**
|
|
173
|
+
|
|
174
|
+
## 6. Over-budget trivial agents, no violation surfaced it (S-75, AGENT_OVER_BUDGET, `c16d875f`)
|
|
175
|
+
|
|
176
|
+
- **Incident:** nothing in `scripts/v10-pulse.sh` compared an agent's real
|
|
177
|
+
elapsed time on a BOARD.md row against its role/tier's time budget
|
|
178
|
+
(founder-specified: builder LOW 15m, MEDIUM 30m, HIGH 60m; reviewer LOW
|
|
179
|
+
and MEDIUM 30m, HIGH 60m), so a trivial agent running well past its budget
|
|
180
|
+
produced no violation and nothing surfaced it.
|
|
181
|
+
- **Root cause with evidence:** `scripts/v10-pulse.sh` had no per-role/tier
|
|
182
|
+
time-budget check at all before this slice; BOARD.md rows already carry a
|
|
183
|
+
Tier column and a status timestamp, but nothing computed elapsed time
|
|
184
|
+
since that timestamp against a budget (commit `c16d875f`'s own message;
|
|
185
|
+
D26 guard 3).
|
|
186
|
+
- **The guard:** commit `c16d875f` (cherry-picked from `5c9a16f2`) extends
|
|
187
|
+
`parse_board()` to also return each row's Tier (found the same
|
|
188
|
+
position-independent way as its existing Status-cell scan, since BOARD.md
|
|
189
|
+
has used at least four different column layouts), and adds a new
|
|
190
|
+
AGENT_OVER_BUDGET violation: for every row currently `building` (builder)
|
|
191
|
+
or `review` (reviewer), compute elapsed time since its status timestamp
|
|
192
|
+
and compare to its (role, tier) budget, naming over-budget rows
|
|
193
|
+
oldest-first. A row with no parseable Tier cell reports UNKNOWN
|
|
194
|
+
(`agent_budget`) rather than being silently treated as in-budget.
|
|
195
|
+
- **The test that proves it fires:** `tests/test-v10-pulse.sh` T21 (a LOW
|
|
196
|
+
builder at 20 minutes fires), T21b (10 minutes does not), T21c/T21d (a
|
|
197
|
+
HIGH review at 45 minutes does not fire, 65 minutes fires), T21e (a row
|
|
198
|
+
with no Tier cell reports UNKNOWN, never silently in-budget). Full suite
|
|
199
|
+
45/45 (up from 40/40), confirmed red against the pre-fix script, and a
|
|
200
|
+
budget-value mutation (LOW 15 -> 25 minutes) confirmed red on T21.
|
|
201
|
+
|
|
202
|
+
## 7. File-mode narrowing from mktemp+mv, 644 became 600 (S-16, recurred S-74)
|
|
203
|
+
|
|
204
|
+
- **Incident:** a temp-file-then-move write pattern silently narrowed a
|
|
205
|
+
tracked file's permissions from 644 to 600 on every write. First found in
|
|
206
|
+
`scripts/release.sh`'s `apply_sed()` (S-16): every real
|
|
207
|
+
`bump_all_version_files` release run silently narrowed all 14
|
|
208
|
+
version-bumped files (VERSION, package.json, Dockerfile, and so on).
|
|
209
|
+
Recurred in `scripts/v10-ops.sh`'s `board-row-status` (S-74 round 3): the
|
|
210
|
+
identical bug class, in a different file, on a different write path --
|
|
211
|
+
the S-16 fix's own verification did not generalize into a lesson that
|
|
212
|
+
caught the second occurrence before review did.
|
|
213
|
+
- **Root cause with evidence:** `mktemp` (and Python's `tempfile.mkstemp`)
|
|
214
|
+
always creates its temp file at mode 600 regardless of umask; a
|
|
215
|
+
same-directory `mv` (or `os.replace`) over the original keeps the TEMP
|
|
216
|
+
file's own mode, not the original's. Git does not track non-exec mode
|
|
217
|
+
bits, so the commit itself looks unchanged while the working tree's real
|
|
218
|
+
permissions quietly regress (S-16 fix commit `254c3c85`; S-74 fix commit
|
|
219
|
+
`e5dc3d28`, same underlying mechanism).
|
|
220
|
+
- **The guard:** S-16, originally commit `254c3c85`, is **MERGED** -- re-
|
|
221
|
+
verified against CURRENT main (this entry had gone stale: an earlier
|
|
222
|
+
re-verification found `254c3c85` not an ancestor and `apply_sed` absent
|
|
223
|
+
from main, which was true of main AT THAT TIME but is no longer true).
|
|
224
|
+
`git log main --grep 254c3c85` finds `c681a726` ("fix(release): preserve
|
|
225
|
+
file permissions in apply_sed (BACKLOG 22, S-16 rework)"), a rebase of the
|
|
226
|
+
same fix, and `scripts/release.sh` on main today has `apply_sed()` with
|
|
227
|
+
`cp -p "$file" "$tmp"` immediately after `mktemp`, before the
|
|
228
|
+
`sed -E ... > "$tmp"` redirect (verified by reading main's
|
|
229
|
+
`scripts/release.sh` directly, lines 144-153) -- `cp -p` copies the
|
|
230
|
+
original's mode onto the temp file, and the subsequent `>` redirect
|
|
231
|
+
truncates that inode's content in place rather than recreating it, so the
|
|
232
|
+
copied mode survives. Judged correctly this time by whether the change
|
|
233
|
+
(not the original SHA) is on main. S-74 (originally commit
|
|
234
|
+
`e5dc3d28`) is **MERGED** -- landed on main as cherry-pick `8fbbbb31`
|
|
235
|
+
(`git log main --grep 'cherry picked from commit e5dc3d28'` finds it, and
|
|
236
|
+
`git cherry main e5dc3d28` reports it patch-equivalent, "-"): status must
|
|
237
|
+
be judged by whether the change is on main INCLUDING patch-equivalent
|
|
238
|
+
cherry-picks, not by whether the original SHA is literally an ancestor --
|
|
239
|
+
`254c3c85` above genuinely has neither, `e5dc3d28` has the cherry-pick.
|
|
240
|
+
`shutil.copymode(board, tmp_path)` before EACH `os.replace` call (the main
|
|
241
|
+
write and the corruption-restore path), shared through one
|
|
242
|
+
`_atomic_write()` helper so both preserve the real board file's mode, is
|
|
243
|
+
live in `scripts/v10-ops.sh` on main today (`grep -c shutil.copymode` ->
|
|
244
|
+
2).
|
|
245
|
+
- **The test that proves it fires:** S-16 -- `tests/test-release-sh.sh` is
|
|
246
|
+
checked in on main and wired into `tests/run-all-tests.sh`
|
|
247
|
+
("release.sh version-bump preserves file mode (BACKLOG 22)", line 1180),
|
|
248
|
+
added in commit `00a9425c`. **MERGED (S-16).** The manual-only
|
|
249
|
+
verification this entry previously described (an isolated 644-in/600-out
|
|
250
|
+
repro against the `s16-rework-permission-fix` branch, not main) is
|
|
251
|
+
superseded by that checked-in test now running on every main commit --
|
|
252
|
+
this is exactly the regression-suite gap the S-74 recurrence exposed,
|
|
253
|
+
now closed. S-74 -- `tests/test-v10-ops.sh`'s
|
|
254
|
+
"a 644 board stays 644 after a flip" and "...after a corruption-triggered
|
|
255
|
+
restore" cases; **MERGED (S-74)** via `8fbbbb31`, same cherry-pick
|
|
256
|
+
verification as above.
|
|
257
|
+
|
|
258
|
+
## 8. BOARD cell located by header index broke on short/long rows (S-74)
|
|
259
|
+
|
|
260
|
+
- **Incident:** `board-row-status`'s Status-cell lookup, having just been
|
|
261
|
+
fixed to locate the column via the table's header row instead of scanning
|
|
262
|
+
cell shapes (closing a different bug -- a Branch/SHA cell shaped like
|
|
263
|
+
`main@abc123` being mistaken for the Status cell), broke on real BOARD.md
|
|
264
|
+
rows whose column count differs from their header's. A dropped or added
|
|
265
|
+
column shifts every later cell, so a fixed header-derived index landed on
|
|
266
|
+
the wrong cell (Notes, not Status); a legitimate call such as
|
|
267
|
+
`board-row-status S-07 approved` exited 2 with a false "does not match"
|
|
268
|
+
refusal instead of flipping the row.
|
|
269
|
+
- **Root cause with evidence:** commit `9f8389b9`'s own measurement --
|
|
270
|
+
`awk -F'|' '/^\| [A-Z]+-[0-9]+ /{print NF}' docs/v10/BOARD.md | sort | uniq -c`
|
|
271
|
+
-> `2 10 / 30 8 / 47 9` -- roughly 40% of the real table's rows have a
|
|
272
|
+
cell count that does not match their header's (30 missing the Acceptance
|
|
273
|
+
checks column, 2 with an extra cell from an embedded `|` inside Notes), so
|
|
274
|
+
a fixed header-column index is invalid on those rows.
|
|
275
|
+
- **The guard:** commit `9f8389b9` (originally stacked on `e5dc3d28`) is
|
|
276
|
+
**MERGED** -- its diff is patch-equivalent to what shipped on main
|
|
277
|
+
(`git cherry main 9f8389b9` reports it "-"): `8fbbbb31`'s own commit
|
|
278
|
+
message (section C) describes this exact header-lookup fallback as part
|
|
279
|
+
of the same squashed cherry-pick that landed `e5dc3d28`'s mode-preservation
|
|
280
|
+
fix, so both original SHAs are represented by the one `8fbbbb31` commit on
|
|
281
|
+
main. It keeps the header-index lookup as the primary path only when the
|
|
282
|
+
row's cell count equals its header's; when the counts differ, it falls
|
|
283
|
+
back to locating the Status cell as the one cell matching a KNOWN
|
|
284
|
+
lifecycle token plus a full UTC timestamp (never a loose shape scan), and
|
|
285
|
+
refuses (exit 2) if zero or more than one cell matches either path.
|
|
286
|
+
- **The test that proves it fires:** `tests/test-v10-ops.sh`'s sweep over
|
|
287
|
+
all 79 real slice rows in `docs/v10/BOARD.md` (each on a fresh copy,
|
|
288
|
+
asserting exactly one line and exactly one cell changed per flip,
|
|
289
|
+
independent of the tool's own internal verification), plus isolated
|
|
290
|
+
short-row and embedded-pipe-in-notes reproductions (originally commit
|
|
291
|
+
`9f8389b9`, now part of `8fbbbb31` on main). Full suite 52/52 per
|
|
292
|
+
`8fbbbb31`'s own message; a mutation forcing the fallback path always
|
|
293
|
+
(`if len(cells) == len(header_cells): -> if True:`) sent tests red.
|
|
294
|
+
**MERGED (S-74)** via `8fbbbb31`.
|
|
295
|
+
|
|
296
|
+
## 9. Push reported success through a pipe while the remote held the old SHA (D27)
|
|
297
|
+
|
|
298
|
+
- **Incident:** train 2's first push attempt was killed by its own 10-minute
|
|
299
|
+
command timeout. The second attempt reported success -- piped through a
|
|
300
|
+
filter, exit code read 0 -- while `git ls-remote origin refs/heads/main`
|
|
301
|
+
still showed the PRIOR head `b651b98d`, not the pushed SHA (DECISIONS.md
|
|
302
|
+
D27 context). A push can read green while the remote never moved.
|
|
303
|
+
- **Root cause with evidence:** the push command's real exit status was
|
|
304
|
+
taken from the pipeline's last stage (the filter it was piped through),
|
|
305
|
+
not from `git push` itself -- the same exit-code-through-a-pipe class this
|
|
306
|
+
repo's own memory already names (`feedback-pipefail-sigpipe-inverts-probe`,
|
|
307
|
+
`feedback-i-cancelled-my-own-release`): a pipe silently discards the
|
|
308
|
+
left-hand command's real exit code unless `pipefail` is set and checked.
|
|
309
|
+
D27's own fix direction is explicit: "never pipe git push."
|
|
310
|
+
- **The guard:** D27 (Loki-approved) mandates (1) never pipe `git push`, and
|
|
311
|
+
(2) a push counts as done only when `git ls-remote origin refs/heads/main`
|
|
312
|
+
equals `git rev-parse HEAD`, recorded as evidence and mechanically
|
|
313
|
+
enforced by a push helper in `scripts/v10-ops.sh` -- cut as slice **S-98
|
|
314
|
+
push-main** (D27 items 3 and 6), `ready@2026-09-27T15:53Z` on BOARD.md as
|
|
315
|
+
of this writing, not yet built. The train-2 and release pushes that
|
|
316
|
+
followed D27 were manually verified this way instead (D27's own evidence
|
|
317
|
+
line: `git rev-parse HEAD` = `git ls-remote origin refs/heads/main` =
|
|
318
|
+
`89e350bd...` at 15:48:18Z, and `= 5332bfc3...` at 15:50:09Z), which is the
|
|
319
|
+
discipline S-98 is meant to make structural instead of manual.
|
|
320
|
+
- **The test that proves it fires:** **MERGED (S-98)** -- shipped in train 5
|
|
321
|
+
as `cd1fb044` ("feat(S-98): TRAIN_LATE pulse violation + v10-ops push-main
|
|
322
|
+
(D27 items 3, 6)"); `git cherry main b44571ba` on this repo reports `-
|
|
323
|
+
b44571ba8a44527abdc183c189617d992b976bac` (equivalent patch already on
|
|
324
|
+
main).
|
|
325
|
+
|
|
326
|
+
## 10. Local CI's fast tier exceeded the 10-minute command cap under swarm load (D27)
|
|
327
|
+
|
|
328
|
+
- **Incident:** the "Local CI Before Every Push" fast-tier gate (mandated
|
|
329
|
+
2026-07-31) took more than 10 minutes to run under swarm load -- 90 of 173
|
|
330
|
+
checks hit the 600-second cap and reported `EXIT=124` -- and the
|
|
331
|
+
`.githooks/pre-push` hook's own serial `pytest` run alone exceeded 10
|
|
332
|
+
minutes by itself. Train 2 sat unpushed for more than 89 minutes waiting
|
|
333
|
+
on a gate that could not finish inside the timeout budget every command in
|
|
334
|
+
this repo is bound to.
|
|
335
|
+
- **Root cause with evidence:** the fast tier's own justification (this
|
|
336
|
+
file's CLAUDE.md predecessor, "Local CI Before Every Push," 2026-07-31)
|
|
337
|
+
was sized against a much smaller swarm; DECISIONS.md D27's own context
|
|
338
|
+
line states both measurements directly ("90 of 173 checks at the 600s
|
|
339
|
+
cap, EXIT=124" and "the pre-push hook's serial pytest alone exceeded 10
|
|
340
|
+
minutes"). A gate that cannot finish inside the hard command cap is not a
|
|
341
|
+
fast pre-push gate, it is a second full CI run duplicating GitHub Actions'
|
|
342
|
+
own Tier B.
|
|
343
|
+
- **The guard:** D27 (Loki-approved) retires the local-ci fast-tier mandate
|
|
344
|
+
outright: before a push, only syntax checks (`bash -n`, `py_compile`) plus
|
|
345
|
+
the slice's own tests, capped at 60 seconds, run locally; GitHub CI (Tier
|
|
346
|
+
B) becomes the sole release gate. The mandate's retraction is already in
|
|
347
|
+
force per DECISIONS.md D27 (choice 1). The corresponding hook change --
|
|
348
|
+
`.githooks/pre-push` reduced to identity check + `bash -n` + a red-main
|
|
349
|
+
warning only, no `pytest`, target under 5 seconds -- is cut as slice
|
|
350
|
+
**S-97** (D27 item 2), `ready@2026-09-27T15:53Z` on BOARD.md as of this
|
|
351
|
+
writing, not yet built.
|
|
352
|
+
- **The test that proves it fires:** **MERGED (S-97)** -- shipped in train 5
|
|
353
|
+
as `f85c643a` ("S-97: retire pytest from pre-push hook per D27"); `git
|
|
354
|
+
cherry main b72e9ab7` on this repo reports `-
|
|
355
|
+
b72e9ab7e730fc856766c0296a2f709a6f6af83b` (equivalent patch already on
|
|
356
|
+
main).
|
|
357
|
+
|
|
358
|
+
## 11. A builder's glob `rm -f` ran in the shared scratchpad root (S-18)
|
|
359
|
+
|
|
360
|
+
- **Incident:** during the S-18 build (Rule-of-Two SSH/credential hardening),
|
|
361
|
+
a builder ran a glob-matched `rm -f` directly against the shared
|
|
362
|
+
scratchpad root instead of a run-owned subdirectory, risking deletion of
|
|
363
|
+
other concurrent agents' files in that same shared root. Disclosed inline
|
|
364
|
+
on BOARD.md's S-18 row ("Incidents during the build: a glob rm in the
|
|
365
|
+
shared scratchpad root ... (removed)").
|
|
366
|
+
This is the same incident class this repo's own memory already names
|
|
367
|
+
(`feedback-tmp-cleanup-glob-deleted-worktree`: `rm -rf /tmp/loki-*` matched
|
|
368
|
+
and deleted an unrelated worktree) recurring in a different shared
|
|
369
|
+
location.
|
|
370
|
+
- **Root cause with evidence:** a glob pattern scoped only to a shared root
|
|
371
|
+
directory (not to a single mkdir-created, ownership-marked, permission-
|
|
372
|
+
narrowed subdirectory) matches every sibling file or directory any other
|
|
373
|
+
concurrent agent has placed there at the same moment -- there is no
|
|
374
|
+
per-run isolation boundary for the glob to respect. This repo's own
|
|
375
|
+
`loki_run_tmp_create`/`loki_run_tmp_cleanup` convention (CLAUDE.md, "Test
|
|
376
|
+
and Resource Cleanup") exists precisely to close this class for `/tmp`;
|
|
377
|
+
the scratchpad root had no equivalent discipline applied at the time of
|
|
378
|
+
this incident.
|
|
379
|
+
- **The guard:** none yet. No slice has been cut to extend the
|
|
380
|
+
`loki_run_tmp_create`/`loki_run_tmp_cleanup` discipline (or an equivalent
|
|
381
|
+
per-agent-subdirectory convention) to the shared scratchpad root, and no
|
|
382
|
+
mechanical guard (for example, a `scripts/v10-guard.sh` PreToolUse rule
|
|
383
|
+
blocking an unscoped `rm -f`/`rm -rf` with a glob directly under a shared
|
|
384
|
+
root) exists today. **PENDING, no slice cut.**
|
|
385
|
+
- **The test that proves it fires:** none. **PENDING, no slice cut.**
|
|
386
|
+
|
|
387
|
+
## 12. A test fixture wrote synthetic `insteadOf` lines to the real `~/.gitconfig` (S-18)
|
|
388
|
+
|
|
389
|
+
- **Incident:** during the same S-18 build, a test/fixture for the P9
|
|
390
|
+
Rule-of-Two credential work wrote 4 synthetic `insteadOf` lines directly
|
|
391
|
+
into the operator's real `~/.gitconfig` instead of an isolated config file
|
|
392
|
+
scoped to the test. Disclosed and remediated inline on BOARD.md's S-18 row
|
|
393
|
+
("4 synthetic insteadOf lines written to the real ~/.gitconfig (removed;
|
|
394
|
+
grep of ~/.gitconfig for loki-test/insteadOf found none at 15:40)").
|
|
395
|
+
- **Root cause with evidence:** a git-credential/URL-rewrite fixture used
|
|
396
|
+
the ambient `$HOME` (and therefore the real `~/.gitconfig`) as its target
|
|
397
|
+
instead of pointing git at an isolated config via `GIT_CONFIG_GLOBAL` or a
|
|
398
|
+
scratch `HOME` override -- the exact hazard this session's own current
|
|
399
|
+
task instructions explicitly call out ("Never touch the real
|
|
400
|
+
`~/.gitconfig`; scratch files only in your own subdirectory"), confirming
|
|
401
|
+
this is a known, recurring risk class for any test that touches git
|
|
402
|
+
config, not a one-off.
|
|
403
|
+
- **The guard:** none yet. No slice has been cut to enforce, mechanically,
|
|
404
|
+
that a test writing git config (`insteadOf`, `url.*.insteadOf`,
|
|
405
|
+
credential helpers, or similar) must set `GIT_CONFIG_GLOBAL`/`HOME` to a
|
|
406
|
+
scratch path before writing rather than touching the ambient one. **NO
|
|
407
|
+
GUARD.**
|
|
408
|
+
- **The test that proves it fires:** none. **PENDING, no slice cut.**
|
|
409
|
+
|
|
410
|
+
## 13. Slices marked released before `publish-npm` had actually succeeded (D27)
|
|
411
|
+
|
|
412
|
+
- **Incident:** 11 BOARD.md rows (S-67, S-68, S-71, S-73, S-74, S-75, S-78,
|
|
413
|
+
S-80, S-86, S-87, S-90) were each written as `released@2026-09-27T15:54Z`
|
|
414
|
+
immediately after train 2's push landed and was `ls-remote`-verified, then
|
|
415
|
+
each row's own Notes cell carries the identical self-correction:
|
|
416
|
+
"Correction 15:54: I had marked this released too early." "Pushed and
|
|
417
|
+
verified on the remote" was conflated with "released," before the
|
|
418
|
+
`publish-npm` CI job had actually completed.
|
|
419
|
+
- **Root cause with evidence:** DECISIONS.md D27 (choice 5) defines
|
|
420
|
+
"released" precisely: "a train counts as released when publish-npm
|
|
421
|
+
succeeds. The next train opens immediately, without waiting for npm's
|
|
422
|
+
availability lag, Docker or Homebrew." At the moment those 11 rows were
|
|
423
|
+
stamped `released`, only the push itself (verified via `ls-remote`) had
|
|
424
|
+
happened -- a necessary but not sufficient condition under D27's own
|
|
425
|
+
definition. Nothing mechanically checked `publish-npm`'s CI conclusion
|
|
426
|
+
before the BOARD.md write, so a human (or agent) stamping the row could
|
|
427
|
+
and did jump the gun on all 11 rows in the same train.
|
|
428
|
+
- **The guard:** D27's own definition is the standing rule; enforcing it
|
|
429
|
+
mechanically (for example, a `board-row-status` precondition, or a pulse
|
|
430
|
+
check, that refuses/flags a `released` write unless the corresponding
|
|
431
|
+
`publish-npm` GitHub Actions run for that train's SHA has `conclusion:
|
|
432
|
+
success`) has not been built. **PENDING, no slice cut** for the
|
|
433
|
+
mechanical check; the manual self-correction on all 11 rows is the only
|
|
434
|
+
remediation applied so far.
|
|
435
|
+
- **The test that proves it fires:** none. **PENDING, no slice cut.**
|
package/docs/v10/PROGRESS.md
CHANGED
|
@@ -1208,3 +1208,12 @@ sample.
|
|
|
1208
1208
|
| 15:50 | S-80 verified on a real push: Tests on 89e350bd stayed in_progress after 5332bfc3 landed | gh run list |
|
|
1209
1209
|
| 15:53:23-26 | Train 3 (S-79, S-81, S-82, S-83, S-85) plus release commit v9.58.0 pushed, rc=0 | HEAD = ls-remote = c2eccb21c1273b27a385aa785fedee3269c4f605 |
|
|
1210
1210
|
- Next: each train counts as released when its publish-npm job succeeds. Train 4 opens now: S-84 (Part C items 3 and 5) once approved, plus S-97 and S-98 (D27 hook and cadence guard). Target push by 16:13 (20-minute cadence).
|
|
1211
|
+
| 16:05 | Train 3 Tests run 36331204715 FAILED: test_build_supervisor lineage race on Python 3.10+3.11 (also 3.11+3.12 on 89e350bd; identical code passed on 5332bfc3), so the Release required-ci failed. Failed jobs rerun at 16:05:48Z; P0 S-102 opened | gh run view |
|
|
1212
|
+
| 16:06:59-07:02 | Train 4 (S-49, S-91, S-89, S-16, S-77) plus release commit v9.59.0 pushed, rc=0 | HEAD = ls-remote = 08d64f4e05b2a475ecde30a393d3f660963f95a9 |
|
|
1213
|
+
| 16:20 | Founder: "just release everything asap, no more tests for development work completed so far". Review workflows for S-97/S-98 and S-18 round 6 stopped | |
|
|
1214
|
+
| 16:22:47-51 | Train 5 (S-18 r1-6, S-84 r1-4, S-97, S-98) plus release commit v9.60.0 pushed, rc=0 | HEAD = ls-remote = 1cde81a773ae2fe3942edbc92d94abaa18b4ac3e |
|
|
1215
|
+
| 16:24:29-32 | Train 6 (S-54) plus release commit v9.61.0 pushed, rc=0 | HEAD = ls-remote = 64676dce0d78c9d1d1a34ef89e022846185c808e |
|
|
1216
|
+
| 16:25 | Train 2 Release: required-ci passed, but the release job failed. The bot token cannot push tag v9.57.0 because the release changes .github/workflows ("without workflows permission"). Release Manager pushed v9.57.0..v9.61.0 at their release commits (ls-remote ^{} verified) and fully reran train 2 Release (36331009098) at 16:25:43Z. S-105 opened | release job log |
|
|
1217
|
+
| 16:26 | Trains 3 and 4 Tests: the build_supervisor flake again (3.10; 3.13); failed jobs rerun at 16:26:04Z. P0 S-102 in progress | |
|
|
1218
|
+
| 16:39 | v9.57.0 published: Release run 36331009098 publish-npm success (after the Release Manager tag push and a full rerun). v9.59.0 published: Release run 36332036567 publish-npm success, update-homebrew success (S-83), native Docker builds running (S-85). npm dist-tags still read 9.56.0 at 16:39 (processing lag) | gh run view |
|
|
1219
|
+
| 16:39 | Never published: v9.58.0 (superseded by v9.59.0, which contains it); v9.60.0 (1cde81a7), v9.61.0 (64676dce), v9.62.0 (9218ea04) carry the S-18 P9 regression; their Release runs were cancelled or failed. Tags exist from the 16:25/16:29 workaround | |
|
package/docs/v10/TODO.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# v10 TODO lists (Chief of Staff and every team member)
|
|
2
|
+
|
|
3
|
+
Updated by the Chief of Staff every turn it changes. Each agent also reports
|
|
4
|
+
its own numbered TODO checklist (done / pending) at the top of every reply;
|
|
5
|
+
that checklist is copied here when the agent reports. Status comes from
|
|
6
|
+
docs/v10/BOARD.md; this file is the per-person view.
|
|
7
|
+
|
|
8
|
+
Target: 3-5 releases per hour (CEO 2026-09-27 17:05Z), 60 per day.
|
|
9
|
+
|
|
10
|
+
## Chief of Staff (orchestrator)
|
|
11
|
+
|
|
12
|
+
1. [done 17:05:02Z] Release v9.63.0 from green tree 1bc02bce (release.sh --bump-only guard passed; tag and main pushed, ls-remote verified).
|
|
13
|
+
2. [pending] Confirm v9.63.0 publish-npm success (Release run 36335603628).
|
|
14
|
+
3. [pending] Release 2: cc105687 (S-104 cache + S-109 violations) -> Tests green -> release.sh --bump-only -> push + tag.
|
|
15
|
+
4. [pending] Release 3: next green content push (batch-1 slices as each is approved).
|
|
16
|
+
5. [running] Keep 10+ builders busy: batch-1 pipeline (S-30, S-88, S-94, S-96, S-99, S-100, S-105, S-106, S-110, S-111), each build then review.
|
|
17
|
+
6. [running] Architect cutting S-112..S-131 to keep the ready queue at 2x builders.
|
|
18
|
+
7. [pending] Cherry-pick each approved slice onto main within the same turn it is approved; push content immediately (Tests start at once).
|
|
19
|
+
8. [pending] Every green main SHA with unreleased code gets a --bump-only release; never bump on red (D28).
|
|
20
|
+
9. [pending] Drift audit every 6 turns; guard review every 50 turns.
|
|
21
|
+
|
|
22
|
+
## Release cadence loop (the mechanism for 3-5 per hour)
|
|
23
|
+
|
|
24
|
+
- Content push: every approved slice lands on main as soon as it is approved (no batching wait).
|
|
25
|
+
- Tier B (Tests, about 6-15 min with 8 shards) runs per SHA; nothing is cancelled on main (S-80).
|
|
26
|
+
- As soon as any main SHA with unreleased code is green: `bash scripts/release.sh minor --bump-only`, commit, tag, push. The bump reuses the parent's verdict (S-84), so publish follows in minutes.
|
|
27
|
+
- Pipelined: content N+1 is in Tier B while release N publishes.
|
|
28
|
+
|
|
29
|
+
## Team members
|
|
30
|
+
|
|
31
|
+
| Agent | Slice | Role | TODO |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| Engineer | S-30 | P7 ternary-null bypass | build, red/green, mutate, commit; then Tech Lead review |
|
|
34
|
+
| Engineer | S-88 | parallelize moat P5/P6/P9 | measure before/after, identical CASE lines, commit; then review |
|
|
35
|
+
| Engineer | S-94 | WORKTREE_COUNT pulse violation | fixtures 15/16, commit; then review |
|
|
36
|
+
| Engineer | S-96 | Tier A caches + 10-commit METRICS table | commit; then review |
|
|
37
|
+
| Engineer | S-99 | guard follow-ups (4 fixes) | fixtures per repro, commit; then review |
|
|
38
|
+
| Engineer (opus) | S-100 | refuse the repo default branch in trusted push | test develop/feature, commit; then HIGH review |
|
|
39
|
+
| Engineer (opus) | S-105 | release.yml tag step: reuse a pre-pushed tag, fail loudly otherwise | stub-driven test, commit; then HIGH review |
|
|
40
|
+
| Engineer | S-106 | runtime-gate port race, unquarantine | 20/20 in capped Linux, commit; then review |
|
|
41
|
+
| Engineer | S-110 | fix the 3 suites S-93 registered, unquarantine | per-suite root cause, commit; then review |
|
|
42
|
+
| Engineer | S-111 | bring back pytest -n auto after proving S-102 | 10 runs 0 failures in capped container, then test.yml; then review |
|
|
43
|
+
| Architect (opus) | S-112..S-131 | cut 20 ready slices | read-only; returns 20 BOARD rows |
|
package/learning/suggest.sh
CHANGED
|
@@ -250,7 +250,7 @@ print(suggestions_gen.to_json(suggestions, context=context))
|
|
|
250
250
|
else
|
|
251
251
|
script+="
|
|
252
252
|
# Output text
|
|
253
|
-
verbose = ${VERBOSE
|
|
253
|
+
verbose = ${VERBOSE^} # Convert bash true/false to Python True/False
|
|
254
254
|
print(suggestions_gen.format_suggestions_text(suggestions, verbose=verbose))
|
|
255
255
|
"
|
|
256
256
|
fi
|