Skip to content

Commit ac24dd8

Browse files
committed
verona-rt
Verona-RT-style work-stealing scheduler, C source split into per-subsystem translation units, and a portable atomics / threading layer. **New Features** - **Work-stealing scheduler** — the single behavior queue has been replaced with a Verona-RT-inspired distributed scheduler. Each worker owns a Multi-Producer Multi-Consumer behavior queue (`boc_bq_*`, ported from `verona-rt/src/rt/sched/mpmcq.h`), pops work from its own queue first, and steals from peers when empty. Idle workers park on a per-worker condition variable and are signalled directly by the producer / victim, eliminating the central wakeup broadcast. Per-worker statistics (steals, parks, fast/slow pops, dispatches) are exposed for benchmarking. - **Per-worker fairness tokens** — each worker advances a token node through its own queue so that long-running behaviors cannot monopolise dispatch slots. The token is also used to drive the cooperative shutdown handshake. - **`compat.h` / `compat.c` portability layer** — a single header now exposes uniform `BOCMutex`, `BOCCond`, `boc_atomic_*_explicit`, monotonic-time, and sleep primitives across MSVC, pthreads, and C11 `<threads.h>`. The work-stealing scheduler depends on the typed-atomics API for ARM64-correct memory ordering on Windows. - **`xidata.h` cross-interpreter shim** — the `#if PY_VERSION_HEX` ladders for the `_PyXIData_*` / `_PyCrossInterpreterData_*` APIs that previously lived in both `_core.c` and `_math.c` have been centralised in one header covering CPython 3.12 through 3.15 (including free-threaded builds). - **`fanout_benchmark` example** — a fan-out / fan-in benchmark harness exercising scheduler throughput under heavy producer load. **Improvements** - **In-memory transpiled-module loading** — workers no longer write the transpiled module to a temporary directory and import it through `importlib.util.spec_from_file_location`. Instead, the transpiled source is embedded as a string literal in the worker bootstrap and `exec`'d into a fresh `types.ModuleType` registered in `sys.modules`. The source is also published to `linecache` so tracebacks still point at the transpiled lines. This removes the `export_dir` argument from `start()` (and the matching tempdir cleanup in `wait()`/`stop()`), eliminates a filesystem round-trip on every worker startup, and avoids leaving `.py` files behind on abnormal exit. Module names are validated as dotted Python identifiers at the boundary, and `__main__` is re-aliased to `__bocmain__` inside workers so a follow-up `start()` observes a clean `sys.modules`. - **Nested `@when` capture** — the transpiler now recurses into `@when`-decorated nested functions when computing the outer behavior's captures, so a behavior body can schedule child behaviors that close over the outer frame's free names without raising `NameError` at dispatch time. - **C extension split into subsystem TUs** — `_core.c` has been reduced from ~5,000 lines to ~3,500 by extracting `sched.{c,h}` (work-stealing scheduler), `noticeboard.{c,h}`, `terminator.{c,h}`, `tags.{c,h}` (message-queue tag table), `cown.h` (cown refcount helpers), and `compat.{c,h}` / `xidata.h` into separate translation units. Every public function now has a header declaration with Doxygen-style documentation. - **Direct dispatch on cown release** — `behavior_release_all` now hands a resolved successor directly to a worker via the work-stealing dispatch path (`boc_sched_dispatch`) instead of re-entering the central scheduler, removing one queue hop per cown handoff. - **Cooperative worker shutdown** — `boc_sched_worker_request_stop_all` and `boc_sched_unpause_all` provide a clean stop/drain protocol that interacts correctly with parked workers and the terminator. **Internal Test Modules** - **`_internal_test_atomics`** — pytest-driven correctness tests for the `compat.h` typed-atomics API on every supported platform. - **`_internal_test_bq`** — torture tests for the MPMC behavior queue (`boc_bq_*`), covering segmented dequeue, FIFO fairness, and concurrent producer / consumer races. - **`_internal_test_wsq`** — tests for the work-stealing primitives (fast pop, slow pop, steal, park / unpark handshake). **Test Suite** - New scheduler test files — `test_scheduler_integration.py`, `test_scheduler_mpmcq.py`, `test_scheduler_pertask_queue.py`, `test_scheduler_stats.py`, `test_scheduler_steal.py`, `test_scheduler_wsq.py` — exercise the distributed scheduler end to end and per primitive. - `test_compat_atomics.py` — Python-level smoke tests for the portable atomics layer. - `test_stop_retry_composition.py` — covers `stop()` / `start()` / `wait()` retry composition across multiple runtime cycles. - `test_scheduling_stress.py` substantially expanded with new fan-out, work-stealing, and shutdown stress scenarios. - `test_boc.py` and `test_transpiler.py` extended with regression cases discovered during the scheduler rewrite. Signed-off-by: Matthew A Johnson <matthew@matthewajohnson.org>
1 parent 37e1fb5 commit ac24dd8

47 files changed

Lines changed: 12992 additions & 3195 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ inline-quotes = double
44
import-order-style = google
55
docstring-convention = google
66
max-line-length = 120
7+
application-import-names = bocpy,examples
78

89
extend-ignore = E203, N812, N817
910

.github/skills/branch-review/SKILL.md

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: branch-review
3-
description: "Multi-perspective code review for a branch before merging. Use when: reviewing a branch, preparing a PR, pre-merge review, auditing a feature branch, or when /branch-review is invoked. Spawns three constructive reviewer subagents (correctness, security, usability), then runs an adversarial gap analysis to find what they missed, and synthesizes all findings into a unified review report."
3+
description: "Multi-perspective code review for a branch before merging. Use when: reviewing a branch, preparing a PR, pre-merge review, auditing a feature branch, or when /branch-review is invoked. Spawns three constructive reviewer subagents (correctness, security, usability), then runs an adversarial gap analysis to find what they missed, and synthesizes all findings into a unified review report. All intermediate artifacts are persisted to .copilot/ so the process can be restarted from any step."
44
argument-hint: "Branch name or merge target (e.g. 'main' or 'feature/foo -> main')"
55
---
66

@@ -27,19 +27,68 @@ Findings use the same severity scale as the **review-loop** skill:
2727
| **medium** | Code smell, unclear logic, missing edge case, or maintainability concern. Recommended fix. |
2828
| **low** | Style nit, naming suggestion, minor improvement. Fix at discretion. |
2929

30+
## Persistence and Restart
31+
32+
Every intermediate artifact produced by this skill is written to disk under
33+
`.copilot/reviews/<slug>/`, where `<slug>` is a short kebab-case name derived
34+
from the branch under review (e.g. `work-stealing-scheduler` for a branch
35+
named `feature/work-stealing-scheduler`). This makes the process **fully
36+
resumable**: if any step fails, is interrupted, or produces an unsatisfactory
37+
result, you can re-run only the affected step using the on-disk artifacts
38+
from prior steps as input.
39+
40+
### Directory layout
41+
42+
```
43+
.copilot/reviews/<slug>/
44+
├── 00-context.md # Step 2 output (shared context block)
45+
├── 00-diff.patch # Step 1 raw diff
46+
├── 00-changed-files.txt # Step 1 file list
47+
├── 10-review-correctness-lens.md # Step 3 outputs (one per lens)
48+
├── 10-review-security-lens.md
49+
├── 10-review-usability-lens.md
50+
├── 20-adversarial.md # Step 4 output
51+
├── 30-synthesis.md # Step 5 output (deduped findings)
52+
├── 40-report.md # Step 6 output (final unified report)
53+
├── 50-fixes-iter1.md # Step 7 notes (per fix pass, optional)
54+
├── 50-fixes-iter2.md
55+
└── ...
56+
```
57+
58+
Numeric prefixes preserve chronological order. The `<slug>` directory is
59+
created at step 1 and reused for the whole run. If the same branch is
60+
re-reviewed after fixes (step 8 loop-back), append a generation suffix
61+
(e.g. `<slug>-r2/`) rather than overwriting the prior review.
62+
63+
### Restart contract
64+
65+
At the start of every step, **check whether the corresponding output file
66+
already exists**. If it does:
67+
68+
- Either reuse it (skip re-running the step), or
69+
- Explicitly overwrite it (re-run the step from scratch).
70+
71+
Ask the user which to do if the choice is non-obvious. Never silently discard
72+
an existing artifact.
73+
74+
When the user asks to "restart from step N", load all artifacts numbered
75+
below N into context and re-run from step N onward.
76+
3077
## Procedure
3178

3279
### 1. Gather the Diff
3380

34-
Determine the branch and its merge target (default: `main`). Collect the diff
35-
using one of these methods, in order of preference:
81+
Determine the branch and its merge target (default: `main`) and derive the
82+
slug. Create `.copilot/reviews/<slug>/` if it does not already exist.
83+
84+
Collect the diff using one of these methods, in order of preference:
3685

3786
1. `git diff <merge-target>...<branch> -- . ':!*.lock'` — full diff against
38-
the merge base.
87+
the merge base. Save to `00-diff.patch`.
3988
2. `get_changed_files` — if the working tree has uncommitted changes that are
4089
part of the review.
4190

42-
Also collect the list of changed files:
91+
Also collect the list of changed files and save to `00-changed-files.txt`:
4392

4493
```
4594
git diff --name-only <merge-target>...<branch>
@@ -50,23 +99,31 @@ diff and the surrounding context.
5099

51100
### 2. Build the Context Block
52101

53-
Assemble a context block that every reviewer will receive. It must include:
102+
Assemble a context block that every reviewer will receive and write it to
103+
`.copilot/reviews/<slug>/00-context.md`. This file must be self-contained:
104+
any subagent reading it should have everything it needs without further file
105+
lookups (beyond the diff/changed-files artifacts referenced by path). Include:
54106

55-
- **Diff** — the full unified diff.
56-
- **Changed files** — full current content of each modified file.
107+
- **Branch and merge target** — branch name, base, commit range.
108+
- **Diff** — the full unified diff (or a reference to `00-diff.patch` if
109+
large, with key hunks inlined).
110+
- **Changed files** — list from `00-changed-files.txt` plus full current
111+
content of each modified file (or excerpts with line ranges if very large).
57112
- **Related tests** — content of test files that cover the changed code, if
58113
identifiable.
59114
- **Project conventions** — brief summary of relevant conventions from
60115
`copilot-instructions.md` (style, commenting, error handling, etc.).
116+
- **Prior audits** — pointers to any prior review artifacts the user has
117+
flagged as already-covered (so reviewers know what is in/out of scope).
61118

62119
Keep the context block identical across all four reviewers to ensure a fair
63120
comparison.
64121

65122
### 3. Spawn Three Constructive Reviewer Lens Subagents
66123

67124
Launch three subagents **in parallel**, each using a named lens agent operating
68-
in **review mode**. Each receives the context block and must return findings in
69-
the severity-tagged format defined above.
125+
in **review mode**. Each receives the context block (by path) and must return
126+
findings in the severity-tagged format defined above.
70127

71128
| # | Agent | Focus |
72129
|---|-------|-------|
@@ -76,8 +133,11 @@ the severity-tagged format defined above.
76133

77134
Each subagent prompt must include:
78135

79-
- The shared context block
136+
- A directive to read `.copilot/reviews/<slug>/00-context.md` as its context
80137
- An instruction to operate in **review mode**
138+
- A directive to **write the resulting findings to**
139+
`.copilot/reviews/<slug>/10-review-<lens>.md` and return a brief
140+
confirmation plus the file path
81141
- These instructions:
82142

83143
> Review the diff and changed files from the perspective described above.
@@ -94,6 +154,9 @@ Each subagent prompt must include:
94154
> Do NOT fabricate issues. Only report genuine problems.
95155
> Order findings by severity (critical first).
96156
157+
After the subagents return, verify all three `10-review-*.md` files exist
158+
before continuing.
159+
97160
### 4. Adversarial Gap Analysis
98161

99162
After the three constructive reviewers return, spawn a fresh `adversarial-lens`
@@ -103,13 +166,15 @@ others missed.
103166

104167
The adversarial subagent prompt must include:
105168

106-
- The shared context block
107-
- The full list of findings from the three constructive reviewers
169+
- A directive to read `.copilot/reviews/<slug>/00-context.md` and all three
170+
`.copilot/reviews/<slug>/10-review-*.md` files
171+
- A directive to write its findings to
172+
`.copilot/reviews/<slug>/20-adversarial.md`
108173
- These instructions:
109174

110-
> You are the adversarial reviewer. The findings below were produced by three
111-
> constructive reviewers (correctness, security, usability). Your job is to
112-
> find what they missed.
175+
> You are the adversarial reviewer. The findings in the `10-review-*.md`
176+
> files were produced by three constructive reviewers (correctness,
177+
> security, usability). Your job is to find what they missed.
113178
>
114179
> Focus on:
115180
> - Code sections covered by NO existing finding (overlooked areas)
@@ -128,14 +193,16 @@ The adversarial subagent prompt must include:
128193
>
129194
> where SEVERITY is one of: critical, high, medium, low.
130195
>
131-
> If the existing findings are comprehensive and you find no gaps, state
132-
> explicitly: "No additional issues found."
196+
> If the existing findings are comprehensive and you find no gaps, the
197+
> file must contain exactly: "No additional issues found."
133198
> Do NOT duplicate issues already reported. Only report NEW problems.
134199
> Order findings by severity (critical first).
135200
136201
### 5. Deduplicate and Synthesize
137202

138-
After all four reviewers (three constructive + adversarial) have returned:
203+
Read all four reviewer outputs (`10-review-*.md` and `20-adversarial.md`)
204+
and write a synthesized findings list to
205+
`.copilot/reviews/<slug>/30-synthesis.md`:
139206

140207
1. **Merge duplicates.** If multiple reviewers flag the same issue, keep the
141208
most detailed version and note which perspectives flagged it (higher
@@ -148,10 +215,13 @@ After all four reviewers (three constructive + adversarial) have returned:
148215
or construct a minimal reproduction. Mark any finding you cannot verify as
149216
**[unverified]**.
150217

218+
Each synthesized finding should retain its severity tag and a "Flagged by"
219+
attribution listing the contributing lenses.
220+
151221
### 6. Present the Report
152222

153-
Present a single unified review report to the user with these sections, in
154-
order:
223+
Assemble the final report at `.copilot/reviews/<slug>/40-report.md` and
224+
present it to the user. The report must contain these sections, in order:
155225

156226
1. **Summary** — one-paragraph overview: number of findings by severity, overall
157227
assessment (e.g., "ready to merge with minor fixes" or "has blocking issues").
@@ -191,7 +261,14 @@ For each approved finding:
191261
2. Confirm each fix briefly as it is applied.
192262
3. Run relevant tests after each fix to verify no regressions.
193263

194-
If a fix is ambiguous or touches architecture, ask the user for guidance.
264+
Record a short summary of the pass to
265+
`.copilot/reviews/<slug>/50-fixes-iter<i>.md` (incrementing `i` for each
266+
re-review pass) noting which findings were addressed, which were deferred,
267+
and any test results. This makes it possible to resume mid-remediation if
268+
the session is interrupted.
269+
270+
If a fix is ambiguous or touches architecture, ask the user for guidance and
271+
record the decision in the same `50-fixes-iter<i>.md` file.
195272

196273
### 8. Check Exit or Re-review
197274

@@ -200,7 +277,9 @@ After all approved fixes are applied:
200277
> All approved fixes have been applied and tests pass. Should I run another
201278
> review pass on the updated diff, or is the branch ready to merge?
202279
203-
- If the user wants another pass → go to **step 1** with the updated diff.
280+
- If the user wants another pass → create a new generation directory
281+
(e.g. `<slug>-r2/`) and go to **step 1** with the updated diff. The prior
282+
review's artifacts remain on disk for reference.
204283
- If the user is satisfied → exit.
205284

206285
## Guidelines

0 commit comments

Comments
 (0)