Skip to content

1.0 prep: CI flake fix, docs-only CI skip, benchmark refresh (supersedes #303, #304, #307) - #308

Merged
luisleo526 merged 11 commits into
mainfrom
release/1.0-prep
Sep 30, 2026
Merged

luisleo526 merged 11 commits into
mainfrom
release/1.0-prep

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

The three changes that stand between 1.0.0-rc.1 and 1.0.0, in one PR so they share one verification. Supersedes #303, #304 and #307.

1. CI flake fix (was #303, test only)

  • Main's CI failed test_adapter_lookup_index_scaling on its applied-reversals ratio. That was runner load, not a regression: instructions per bar are flat and identical before and after XAU-CAL, and tree-identical re-runs passed.
  • The row timed its two tapes in blocks, so a load rise slowed only the large one. It now alternates them over six rounds (large first and last) and times in user CPU. The bound stays 5.

2. Docs-only CI skip (was #304; proof runs are on #304)

  • A new changes job runs the base's copy of scripts/ci_docs_only.py.
  • On a change to docs/** or *.md only, the proof jobs are skipped: build ×4 (macOS included), sanitizers, kernel-only, native-live, corpus-parity-subset.
  • Preflight (doc-lint, anchors, doc-reverts) and Doxygen still run.
  • Any doubt, or a change to one of the four doc files the tests compile, runs everything.

3. Benchmark refresh (was #307)

  • Re-measured at engine 35db01c8 with codegen 121b3e6a: PineForge 201/201 excellent; median 36× over PyneCore 6.10.3 on a dedicated AWS c7a.8xlarge (p5 15×, p95 131×). 35db01c8 takes 0.35× the time of 063e4460 on the same host.
  • benchmarks/assets is pinned at its main (5759bf2, the same tree as the measured e564cb9, which stays reachable under the tag engine-pin-e564cb9).

No change under src/, include/ or CMake, and no gitlink other than the assets pin moving. Parity is by the no-behaviour diff rule (v2), since a sweep cannot see any of these files. Verify covers preflight, release, debug, sanitizers, kernel and docs.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QFVRQ4gcJCLbjfYqGtmy4k

luisleo526 and others added 11 commits September 30, 2026 10:25
…ser CPU (lane pf-perf-scale)

Engine CI failed test_adapter_lookup_index_scaling's applied-reversals
ratio on main at 35db01c (run 36554781580 attempt 1: 5.50, 6,000 bars
0.1179 s, 24,000 bars 0.6488 s) and 4dc496d (run 36621162191: 5.31,
0.2432 s, 1.2927 s). Not a regression: the same trees passed on the same
runner class -- 35db01c's re-run 3.97 (0.1178 s, 0.4672 s), XAU-CAL's PR
head 27c2d8e (same tree) 4.01, FIX-E1E2's PR head b045b96 (same tree as
4dc496d) 3.64 (0.2375 s, 0.8642 s). The small block matched; the large
block ran 39 and 50 % dearer. 32 earlier main/PR Release runs read
2.81-4.38 (ci-diagnostics LastTest.log).

On idle spark cores (pinned, base/XAU-CAL/head in turn, 12 runs each):
0411892 / 35db01c / 4dc496d read 3.85-3.94 / 3.89-3.93 / 3.91-3.97
(Cortex-A725, CI's 6,000 / 24,000 bars) and 4.03-4.07 / 4.03-4.05 /
4.04-4.07 (Cortex-X925, 24,000 / 96,000); the reversal leg costs
104,512 -> 104,322 user instructions a bar from 6,000 to 96,000 bars at
all three (perf stat instructions:u), the bracket leg ~66,300 flat. XAU-CAL
adds no per-bar lookup on this path: day_label_origin returns at once with
no day labels, and prepare_day_labels returns before any work for a
non-"D" script.

The row timed its legs in blocks (five small runs, then five large), so a
load that rises after the first small run and before the first large one
ends slows the large block alone. It now times the tapes in turn, the
large tape first and last (six rounds, the order alternating): no single
rise or fall of the load gives the small tape a quiet sample the large one
lacks. Migrated from a Cortex-X925 to a Cortex-A725 core (2.3x the CPU a
bar) 1.25-7 s into the row, the unchanged row failed for a move 1.75-3 s
in (5.93-9.26, 6 of 24) and this one for none (at most 4.04). The legs
are timed in user CPU (ratio_timing::user_cpu_seconds, as INT27 did for
the lower-lookup row) because the in-turn order moves the allocator's page
faults between the tapes: process CPU read in-turn at 4.13 against the
blocks' 4.00, user CPU 4.04 against 4.01 (A725, 12,000 / 48,000 bars).

After (same spark cores, 12 runs each, unchanged/fixed in turn): reversals
3.90-3.97 -> 4.02-4.08 (A725), 4.02-4.06 -> 3.94-4.01 (X925); brackets
3.94-4.02 -> 3.99-4.04. Mutant sensitivity kept: with every adapter lookup
walking (kIndexedFrom unbounded) the fixed row reads 6.37-6.43 and fails,
the unchanged row 6.19-6.27. The bound stays 5. No src/ or include/
change.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A new first job, changes, runs scripts/ci_docs_only.py on the standard
runner and answers docs_only. A changed path is documentation when it is a
Markdown file or lies under docs/, unless it lies under .github/,
benchmarks/, scripts/ or tests/, is a CMake file, or is one of the four
files a proof job reads (docs/pages/pine-to-native.md and
docs/pages/native-engine.md, whose code blocks CTest rows compile and run;
ADR-0001, which test_kernel_residuals, test_native_feature_rulings and the
kernel profile's kernel-residuals stage read; docs/build.sh, whose retry
self-test is a CTest row). A pull request is its tested merge against the
base it merged into, a push is before..after; every doubt (a dispatch, a
created or forced push, a merge of another head, an unreadable commit, an
empty change, a failed classification) answers no.

Each proof job (the four build legs, sanitizers, kernel-only, native-live,
corpus-parity-subset) now needs changes alone and skips only a docs-only
answer; preflight, which holds the documentation guards, and docs.yml run
as before. The build aggregate passes a proof lane that succeeded or was
skipped after changes succeeded and answered docs-only, and fails any other
skip or result; preflight must always succeed.

Pushes to main follow the same rule: release.yml is dispatch-only and
builds its own tarballs, promote-baseline.yml reads the maintainers'
pineforge/verify and pineforge/parity statuses on the PR head, no workflow
starts on workflow_run, and the ruleset requires only those two statuses.

The ci-workflow-contract stage pins the new wiring; test_ci_preflight.py
runs the aggregate's shell over every lane outcome; the new docs-only-tests
stage holds the rule against real git histories and fails when a CMake
file reads a path the rule would call documentation.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…-pick) (lane pf-ci-docs)

- The changes job runs the base's copy of scripts/ci_docs_only.py (the
  pull request's base, or the pushed commit's parent) with --root, so a
  change to the rule is judged by the rule it changes; a base without the
  script runs every job. The classification step is pinned verbatim, and
  test_ci_preflight.py runs its shell in throwaway repositories.
- A push must carry one commit whose parent is before; anything else is a
  doubt, so the shallow fetch of an older before is gone. git calls time
  out as a doubt. Git control files (.gitattributes) are not documentation.
- Proof jobs skip only when changes succeeded and answered docs-only, the
  exact skip the build aggregate accepts.
- No job of ci.yml, native-live.yml or corpus-parity.yml, nor any step,
  may continue on error.
- docs/ci.md: the base copy, the one-commit push, the aligned condition,
  the badge after a documentation merge, and what the CMake scan checks;
  the start-order sentences no longer contradict the wait on changes:
  116c461's "The compilation lanes start alongside preflight" and
  "Preflight and all proof jobs start in parallel" now say that the
  proof jobs start once the few-second changes job has answered.
  AGENTS.md: a documentation-only change runs preflight alone, written
  inside the existing lines so the pinned AGENTS.md:144-145 stays put.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…gate column is the rubric's

A closed slot's directory, NNN-<author>-<title>, carries the TradingView
author's handle, and fourteen committed files repeated it: the six result
files under results/ (five reports and the compile log), seven raw timing
files and the throughput package's JSON. Every harness step that writes a committed file now prints
the slot as NNN-closed:

- paths.public_name() is the one rule; compare.py (summary.md,
  trade_comparison.md) and speed/time_pynecore.py (its JSON keys) use it,
  and speed/pineforge_bench.cpp registers a closed-root slot as NNN-closed.
- select_population.py writes the public view of the manifest to
  results/selection.{json,md} (closed slots lose their probe id and
  replacement queue) and the full manifest beside the closed root, in
  assets-closed/_selection/; --render-public re-renders the public view
  without a new draw. The committed selection is re-rendered that way from
  its own full manifest (the draw is unchanged).
- The seven raw timing files and results/pynesys-compile-log.md are
  rewritten in place (closed names only); manifest.json keeps each
  measured file's sha256 as origin_sha256 and names the edit.
  results/raw/README.md's Edits paragraph, b2a578c's (#300) "Two edits
  were made", now counts three and describes the third.
- tests/test_public_names.py fails when any committed result spells a
  closed slot otherwise. speed.md and throughput/benchmark_results.json
  still do until the refresh regenerates them.

compare.py also printed a probe's declared inputs.json "notes" in the
failing-gates column of every engine's row: analyze_strategy returns the
declared note as its notes. Slots 023 and 168 showed PineForge's own
history in PyneCore's gate cell (DOCS-ENGINE fixed the two cells by hand
in b2a578c, #300; regeneration would put them back). failing_gates() prints the
rubric's gate booleans instead. A slot without strategy_pyne.py reads its
PyneSys compile error from the committed compile log when the maintainer's
request ledger is absent, so a fresh checkout reports slot 192 as the
compile rejection it is, not as a runner error carrying a local path.

compare_indicators.py links canonical.pine in the assets repository at the
last assets commit that changed it: GitHub does not resolve a relative link
into a submodule path (DOCS-ENGINE fixed that cell by hand as well).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
uv.lock pinned pynesys-pynecore 6.10.2 (2026-09-20). 6.10.3 (2026-09-28)
is the latest release, so the refresh measures it: `uv lock
--upgrade-package pynesys-pynecore`, nothing else moves. Its fixes are in
the code the bench exercises: `pyne data convert-from` wrote schedules on
the wrong weekdays (Monday fell outside the session, so an unlagged daily
request.security showed Monday bars that day's own close) and
request.security aggregation resolves timezones like the runner. It also
ships compiled wheels (a native math module).

With 6.10.3 every compiled slot runs: 140, 166 and 197 raised a
RuntimeError in request.security on 6.10.2, and 143 did intermittently.
Only 192 has no trade list (PyneSys rejects its source). The committed
strategy_pyne.py files are unchanged: no PyneSys request was made.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…degen 121b3e6a -- PineForge 201/201 excellent, PyneCore 6.10.3 137

The release pair: engine main 35db01c running every slot's generated.cpp
re-emitted by codegen main 121b3e6a (transpile(strategy.pine,
filename="strategy.pine"), the call that reproduces all 201 files of the
previous codegen 89645d6 byte for byte; 159 of 201 files change). The
benchmarks/assets gitlink moves to e564cb9 (branch bench/refresh-2026-09-30
of pineforge-benchmarks-assets); the closed half is in a new
evidence tarball.

TradingView changed three Pine v6 strategy() defaults on 2026-09-24
(initial_capital 1000000 -> 100000, default_qty_type fixed ->
percent_of_equity, default_qty_value 1 -> 100); codegen 121b3e6a declares
the new values when a script omits them (codegen #147). Every bench tape
predates the change (closed tapes 2026-06-28..08-12), so a slot whose script
omits one runs with the tape's value, pinned in inputs.json
strategy_overrides as the corpus does: 64 slots (2 public, 62 closed).
Without the pins the regenerated closed half graded 45 excellent and 42
weak (PnL p90 ~90 % on capital, extra trades on percent-of-equity sizing).
PyneCore's own defaults are the pre-change values, so both engines run the
tape's settings.

Tiers (results/summary.md), against 2026-09-22 (engine 063e446):
- PineForge: 201/201 excellent (was 200 + 1 strong). Slot 181's extra
  opening long is gone with the regeneration.
- PyneCore 6.10.3: 137 excellent, 46 strong, 12 moderate, 4 weak,
  1 minimal, 1 n/a (was 6.10.2: 133 / 42 / 8 / 12 / 2 / 4). 140, 166 and
  197 now run; 192 stays a PyneSys compile rejection.
- vectorbt: unchanged (13 ports, 4 / 6 / 2 / 1).

Trade lists against the 2026-09-22 run (the old engine rebuilt and run
through its own run_strategy.py reproduces those lists byte for byte):
173 of 201 are byte-identical. 27 move with the engine and its runner, not
the regeneration (the same lists from the old generated.cpp on the new
engine): 22 only in the favorable/adverse excursion columns, 2 only in the
engine's incarnation column, and three in fills: 010 (six trades exit one
bar earlier), closed 103 (90 grid-bot trade quantities) and closed 191
(one trade exits a bar earlier). One moves with the regeneration: closed
181 loses the extra opening trade. Every slot grades excellent.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…he pool stays full

A PyneCore slot that runs for a minute per backtest (178, then 162) takes
20 runs x its time in one worker. Submitted in slot order it started late
and ran on alone after the queue drained, so the 2026-09-22 window re-timed
162 and 178 across tool calls, 178 partly beside other chunks. --first
submits the named slots first; the other workers work through the rest, and
the sweep keeps --workers processes running until its last minutes.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
….json pins apply, and each benchmark reports its trade count

TradingView changed three Pine v6 strategy() defaults on 2026-09-24, after
every bench tape was recorded; codegen 121b3e6a declares the new values for
a script that omits them, and 64 slots pin the tape's values in inputs.json
strategy_overrides. run_strategy.py applies those pins to the graded run,
but the Google Benchmark harness ran strategy_create with defaults only, so
on those slots it timed a configuration no tape has: slot 108 books 4,078
trades over the feed unpinned and 3,553 pinned.

The harness now reads each slot's flat strategy_overrides object and applies
it through the library's strategy_set_override after every strategy_create,
as run_strategy.py does (values as the JSON writes them); a slot that pins
settings its library cannot take is skipped with that error. It prints how
many slots pin settings (64 of 201). The three benchmark kinds share one
symbol table per dlopen, and each reports the last iteration's closed-trade
count as a "trades" counter: the workload its time was measured on.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…e -- 36x over PyneCore 6.10.3 on that host; 35db01c takes 0.35x the time of 063e446 there

The timing window (2026-09-29, 20:36-23:27 UTC) ran on a dedicated AWS
c7a.8xlarge (AMD EPYC 9R14, 32 cores, SMT off, Ubuntu 24.04), nothing else on
it: the Mac the 2026-06-11 and 2026-09-22 tables were timed on (Apple M4 Max)
never got quiet (load 28-40 from Spotlight reindexing, a VM and other
projects), and a shared NVIDIA GB10 was given up once another supervisor's
suites started there (its partial timings are a cross-check only, not
published). Times from different hosts are not compared; every comparison
the READMEs print was measured in this window.

Measured (results/raw/2026-09-29-35db01c8, manifest.json):
- PineForge 35db01c with generated.cpp from codegen 121b3e6a, magnifier on,
  pinned to one core: median 66.8 ms per strategy, 807k bars/s (505k-1133k).
  Build g++ 13.3 Release; its 201 trade lists on this host are byte-identical
  to the graded (Mac) ones.
- PyneCore 6.10.3, 8 concurrent on eight pinned cores: median 2,629 ms, 200
  slots (192 has no strategy_pyne.py; 143 ran all 20 runs). Median speedup
  36x (p5 15x, p95 131x); vectorbt 13 ports 209.3 ms (4.2x); PineTS
  1416.2 ms.
- Same-window A/B, all 201 slots, each engine on its own generated.cpp,
  new/old/old/new: 35db01c takes 0.35x the time of 063e446 at the median
  (p10 0.28, p90 0.50), faster on all 201. A perf profile of two slots shows
  063e446's per-bar continuation-hash fold, event-journal scans,
  dynamic_cast and out-of-line accessors, none of which 35db01c keeps.
- The 2026-06-11 engine, rebuilt there: 4-8x faster than 35db01c on its
  three probes. PyneCore 6.10.3 vs 6.10.2 on 26 public slots: 1.01x.
- Throughput package: five runs 0.782/0.786/0.778/0.779/0.777 M bars/s; run 4
  published (0.78). A first run 1 was stopped: reproduce.sh's configure found
  the fetched Eigen as a system package, changed every compile command and
  began rebuilding the tree on the pinned core. After an all-core rebuild
  (then a no-op), identical trade lists, and a recheck of the 26 A/B slots
  (1.00x), the five runs built nothing.
- Every batch passed the quiet gate (load < 6, no build/test process, the
  pinned cores idle); gate.tsv and a load trace per batch are committed.

Harness: aggregate.py takes the timing host's facts (--host host.json) and
prints the busiest pinned core per batch; check_provenance.py derives the new
headline from the window (the host line, the host change, the 201-slot A/B,
the PyneCore release A/B, the 2026-09-22 table read from 35db01c, the tier
changes against its summary.md, the June engine on this host) and drops the
cross-host comparisons; test_check_provenance.py reads its targets from the
README.

Docs: benchmarks/README.md headline, non-excellent rows (PineForge none;
PyneCore 63, the window explanation re-measured, the multi-timeframe rows
after 6.10.3), methodology (pins in the timed run, pinning, same-host
comparisons), Fairness (the 2026-09-24 strategy() defaults the tapes predate);
the engine README's speed badge, the Fast bullet and the cross-engine
section; throughput/README.md and results/raw/README.md for the new window.

Rebased onto main 112c134 (DOCS-ENGINE b2a578c #300, 7d33942 #301, 112c134
#302). The engine README keeps main's text outside the speed badge, the Fast
bullet and the cross-engine section, #302's counts and badges included. The
Fast bullet keeps b2a578c's framing (engine, date, PyneCore timed as a
subprocess with its interpreter start-up) with this window's numbers, and
names both populations: the speedup's 200 strategies and the bars/s median's
201 slots. The section keeps b2a578c's PyneCore-sources paragraph and its
"main has moved on since" clause (4dc496d, #299, changed src/ after
35db01c, and nothing was re-measured on it). Its PineForge paragraph names
the engine and codegen the tiers were graded at, and its vectorbt bullet
keeps b2a578c's form with this window's numbers: a 4.2x median per-strategy
speedup, and vectorbt is still faster on 2 of the 13 (021, 064).
results/raw/README.md's Edits section replaces the paragraph b2a578c wrote
(and the previous commit extended) with one paragraph per window.

Sentences this commit deletes or rewrites past recognition in README.md,
named by the commit that introduced them (scripts/check_doc_reverts.py):
- 471a113 (the README carries the 200-strategy refresh, lane BENCH2): 7 --
  the strong row 181 and its extra trade, "to the tick", the compile
  rejection, the three runtime errors, 143 "could not be timed", and "the
  ratio fell because the engine is slower per bar".
- a02160f (PineForge re-timed at engine 063e446, lane BENCH3): 3 -- the
  speed paragraph's host, engine and window.
- f867096 (the multi-timeframe PyneCore rows reproduce 0-85.5 %, lane F10): 1
  -- the nine multi-timeframe scripts, rewritten for 6.10.3.
- b2a578c (make every README and doc page true before the release,
  DOCS-ENGINE, #300): 1 -- the 2026-06-11 engine "still runs close to its
  June timings", measured on the Apple M4 Max; this window's same-host
  timing of that engine replaces it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- benchmarks/README.md: of the 16 count-only PyneCore rows, 11 carry a
  position opened before TradingView's range: 7 hold it past the bar
  TradingView's first trade opens and 4 close it on that bar.
- results/raw/manifest.json: the 2026-09-22 throughput run 2 was the
  published benchmark_results.json until the 2026-09-29 window replaced it
  (sha256 unchanged).

The review's third note, README.md's Fast bullet pairing "200 timed
strategies" (the speedup's population) with the bars/s median (over
PineForge's 201 slots), is resolved in the previous commit: the rebase onto
112c134 rewrote that bullet there, in DOCS-ENGINE's framing, naming both
populations.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…e564cb9

The assets commit landed on the assets repository's main by a rebase merge
(pineforge-benchmarks-assets#2), which gave it a new id with the same tree
(2ee1fefd). Pin the id main carries; e564cb9 stays reachable under the tag
engine-pin-e564cb9.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFVRQ4gcJCLbjfYqGtmy4k
@luisleo526
luisleo526 marked this pull request as ready for review September 30, 2026 03:35
@luisleo526
luisleo526 merged commit 133f571 into main Sep 30, 2026
17 checks passed
@luisleo526
luisleo526 deleted the release/1.0-prep branch September 30, 2026 03:37
luisleo526 added a commit that referenced this pull request Sep 30, 2026
…309)

v1.0.0 (tag 5718c5d, built from main 133f571) and pineforge-codegen 1.0.0
shipped on 2026-09-30, and the hub image pineforge-release:1.0.0 carries the
pair. The pages still said "Unreleased", "main is ahead of v0.13.1",
"codegen main (not in a release yet)" and "1.0.0-rc.1". What is now true:

- CHANGELOG.md: "Unreleased" is "1.0.0 — 2026-09-30", opened by a summary:
  the first stable release under semantic versioning, engine and codegen
  on one version (engine v1.0.0 + codegen 1.0.0, hub image 1.0.0), the
  three prebuilt tarballs, v1.0.0-rc.1 (bb9ec14) and the one commit after
  it (133f571, #308: the test_adapter_lookup_index_scaling CI flake fix,
  the docs-only CI skip, the benchmark refresh; no src/, include/, cmake/,
  examples/ or CMake file changed), and that the notes below are the
  notable changes since v0.13.1. The planned-1.0 hedges are present
  tense; codegen "main branch" is 1.0.0.
- README.md: a "Prebuilt library" subsection names the v1.0.0 release and
  its three tarballs; front door 1 installs pineforge-codegen==1.0.0; the
  MCP image bundles engine v1.0.0 with codegen 1.0.0; the Releases list
  opens with v1.0.0; the scoreboard and the benchmark refresh line name
  the release (neither was re-measured on it; the releases changed no
  grade).
- docs/pages/install.md: a "Prebuilt tarballs" section (asset names,
  checksum, layout, Eigen) and the hub's engine1.0.0-codegen1.0.0 tag.
- docs/pages/integration-cmake.md: find_package pins are 1.0, and the page
  states the rule the package installs (write_basic_package_version_file,
  SameMajorVersion over MAJOR.MINOR.PATCH; FILE and git-describe versions).
- docs/pages/abi-stability.md: version.h as v1.0.0 ships it (FULL "1.0.0",
  sha 5718c5d; rc.1 reads "1.0.0-rc.1"); ABI v4 and the v19 epoch ship in
  v1.0.0.
- public-contract, live-surface, native-engine (prose), pine-to-native
  (table text), report-schema, ffi-python, examples-multi, configuration,
  mtf, tutorial-macd, tutorial/README.md, docker/README.md, docs/coverage.md,
  docs/pine_v6_audit_master.md, docs/pine_v6_coverage_detail.md: "main" /
  "not in a release yet" / "the last tagged release" become v1.0.0 or
  codegen 1.0.0; the four recorded request.* rows of the coverage detail
  are "✅ Runtime" (the legend's bucket for strategy_set_recorded_series)
  and request.footprint is "❌ Unsupported" like the footprint.* rows; the
  "Fundamentals and external data" list says 0.10.4 rejects the four and
  1.0.0 reads recorded answers.
- CHANGELOG.md: time()/time_close() with bars_back/timeframe_bars_back:
  0.10.4 accepted both arguments but ignored them and read the current
  bar's time (checked with PyPI 0.10.4: it emits
  pine_time(current_bar_.timestamp, ...)), so the note no longer says they
  were refused.
- abi-stability.md: the v18 -> v19 step (both epochs are development
  builds after v0.13.1, PF_ABI_VERSION 4 at ab9714b and fc7aad6) is the
  internal epoch transition; native-engine.md: the Coof / MagnifierCoof
  enumerators existed only in development builds (no tag has them).

Checked against the tagged trees and artifacts, not memory: VERSION at
v1.0.0 is 1.0.0; PF_ABI_VERSION 4 at v1.0.0, 3 at v0.13.1; v0.13.1 has no
native_c_api.h; codegen v1.0.0 (5bf595b) differs from 70c2b4af only in
docstrings and metadata, attaches the Pine adapter, lowers varip, imports,
foreign request.security and the recorded requests, and has no CLI; the
three tarballs pass their .sha256 and hold lib/, include/pineforge/ and
lib/cmake/PineForge/; codegen 1.0.0 from PyPI plus the macOS tarball runs
front door 1 (50 trades, net 569.97) and 0.10.4's output fails to compile
against v1.0.0; find_package 1.0 / 1 / 1.0.0 EXACT find the tarball and
0.13 / 0.14 / 1.1 / 2.0 do not; the hub 1.0.0 image prints the documented
tutorial report and provenance (engine 1.0.0, codegen 1.0.0).

Replaces or deletes text introduced by (scripts/check_doc_reverts.py's
History.introducer for judged pages; git blame / git log -S at origin/main
for CHANGELOG.md, docker/README.md, tutorial/README.md and code blocks):
- b2a578c (DOCS-ENGINE, #300): CHANGELOG.md, README.md, docker/README.md,
  tutorial/README.md, docs/coverage.md, docs/pine_v6_audit_master.md,
  docs/pine_v6_coverage_detail.md, docs/pages/abi-stability.md,
  configuration.md, examples-multi.md, ffi-python.md, install.md,
  integration-cmake.md, live-surface.md, mtf.md, native-engine.md,
  pine-to-native.md, public-contract.md, report-schema.md, tutorial-macd.md
- 133f571 (#308): README.md (the benchmark "Last refresh" sentence)
- 0d76a09 (Wave G, #289): docs/pages/abi-stability.md (the V19-FIX
  sentence)
- d093560 (INT26, #290): docs/pages/abi-stability.md (the H-THIN sentence,
  the version-macros text), docs/pages/native-engine.md (a line of the 1.0
  C boundary paragraph)
- 2fcbb52 (R5 lane F2): code-block lines in docs/pages/abi-stability.md
  (PINEFORGE_GIT_SHA) and docs/pages/integration-cmake.md (pkg-config
  Version)
- 112c134 (#302): README.md (the scoreboard paragraph, extended only)
- b1fbf0b (detailed Pine v6 coverage report): docs/pine_v6_coverage_detail.md
  (the "(hard reject)" heading and the request.financial bullet)
- e7cdf05 (native execution terms): docs/pages/abi-stability.md (the
  "PF_ABI_VERSION remains 4" clause)
Three rewrites bring back d093560's wording, which b2a578c made "planned
1.0" and which is true again now: README.md's "the 1.0 C surface does not
spell", and docs/pages/native-engine.md's "does not spell in 1.0" and
"Deprecated public spellings, removed for 1.0".

docs/pages/native-engine.md and docs/pages/pine-to-native.md are
ci_docs_only.py PROOF_READS, so this change runs CI's full lanes; no code
block of either page changed.

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 18, 2026
…415)

* ci: keep every verification job on standard runners

Apply the owner cost stop of 2026-10-18 to pushes, schedules, dispatches and every pull request until the ci-spot pool is live. Replace the paid-runner routing introduced by d093560 and carried into native-live by 065ef1d; retain the standard image matrix and all existing timeouts.

No tests, builds or workflows run locally per the executor brief.

* ci: enforce the standard runner contract in preflight

Replace the event-based runner contract and mutation cases introduced by d093560 with ubuntu-24.04 and matrix.os. Refuse pf-linux-x64-16, every *-xlarge or *-large label and every larger_runner key, including in the release matrix, while retaining the remaining workflow checks.

Add rejection cases for paid labels, obsolete keys and conditional paid routing. Preserve comment tolerance and core-count checks. Tests intentionally not run under the executor no-run rule.

* docs: record the standard runner cost stop and ci-spot handoff

Reword the runner-selection and timing assumptions introduced by d093560 (#290) and the documentation-only runner sentences introduced by 133f571 (#308). Keep the platform job limits recorded by 2394ba2 (#373).

Record the owner decision of 2026-10-18 after larger-runner costs exceeded US$3,000: every event uses free standard runners until the ci-spot pool is live. Describe the unconditional runner contract and remove obsolete larger-runner timing estimates while retaining measured standard-runner durations.

No local verification run, as required by the executor brief.

* test(ci): pin the standard-runner mutations precisely

Target the full runs-on line in both build-runner rejection cases. The bare matrix.os expression matched the earlier leg name, leaving runs-on unchanged and producing the wrong finding in PR #415 CI run 39119916194.

Preserve the build leg name and the expected runner-finding assertion. Leave scripts/ci_preflight.py unchanged. No tests or verification run locally under the executor no-run rule.
luisleo526 added a commit that referenced this pull request Oct 18, 2026
* ci: route CI Linux x64 jobs through the live ci-spot pool

* ci: route corpus parity through the ci-spot build class

* ci: route native live profiles through the ci-spot pool

* ci: route documentation through the public ci-spot class

* ci: route manual baseline promotion through ci-spot

* ci: route release Linux x64 jobs through ci-spot

* ci: require exact ci-spot routing and job labels in preflight

Replace the CR-170 standard-only runner contract with the public and engine-x64-16 fragments, including fork and untrusted-event fallback. Require one matching PF_CI_LABELS string at job scope; pin the Linux-only build and release matrix routing and the unchanged hosted legs. Retain larger-runner, timeout, core-count and reusable-workflow guards.

Update mutation and stage tests for missing, duplicate and incorrect PF_CI_LABELS, wrong label lists, unsafe fragment changes, paid labels and hosted exceptions. No tests, builds, linters or verification scripts run locally under the executor no-run rule.

* docs: record the live ci-spot pool and hosted fallbacks

Supersede the stopgap sentences from 3484a7c, squash-merged as 693fd9e (#415, CR-170). Reword the runner-selection and timing assumptions from d093560 (#290) and the documentation-only runner sentence from 133f571 (#308); preserve the platform limits from 2394ba2 (#373).

Record the 2026-10-18 live-pool bulletin, exact fragment and environment labels, class allocation, actor allowlist, hosted matrix legs and event fallbacks. Keep historical timings separate from unmeasured pool performance. No local verification run under the executor no-run rule.

* ci: restore release and deployment jobs to their original hosted runners

Apply the L6 production-credential ruling to Cloudflare docs deployment, baseline promotion and every release job. Restore all three workflow files byte-for-byte from origin/main, including their original hosted labels, and remove pool environment labels. No steps, permissions, timeouts or matrix populations change.

No tests, builds, linters, preflight, corpus verification or workflows run locally under the executor no-run rule. Nothing pushed.

* ci: adopt the b240f6d7 hosted fallback for pool jobs

Match the current pf-ci-spot public and engine-x64-16 fragments from bulletin #635. Change the hosted fallback to ubuntu-24.04 for all ten pool job definitions and preserve their matching PF_CI_LABELS, actor checks, fork protection and macOS routing.

No tests, builds, linters, preflight, corpus verification or workflows run locally under the executor no-run rule. Nothing pushed.

* ci: require hosted runners for credential-bearing jobs

Pin the b240f6d7 expressions and original hosted release/deployment routes. Detect non-GITHUB_TOKEN secrets, inherited workflow environment secrets, job or workflow OIDC write permissions and deployment environments. Require hosted routing without PF_CI_LABELS for credentials and current fragments with matching labels for other Linux x64 jobs. Preserve the larger-runner, timeout and core-count guards. Add must-fail credential and old-fallback cases and a must-pass case for the current hosted release workflow.

No tests, builds, linters, preflight, corpus verification or workflows run locally under the executor no-run rule. Nothing pushed.

* docs: record the L6 hosted credential rule and current pool fallback

Reword the pool-allocation, release/deploy routing and fallback sentences introduced by 28fe3466a and carried into f9bee22. Cite pf-ci-spot b240f6d7 and bulletin #635, retain the Dependabot and historical policy references, and explain the exact original hosted labels and updated preflight contract.

No tests, builds, linters, preflight, corpus verification or workflows run locally under the executor no-run rule. Nothing pushed.

* test(ci): anchor pool label mutations to job-level env

An unanchored four-space env search matched the tail of step-level env in promotion and release jobs, so the negative fixture never put PF_CI_LABELS in the job environment. Anchor the env and steps keys to complete job-level lines in both label fixture builders.

Assert the injected label at job scope and require the exact hosted-job diagnostic. Keep the existing hosted release baseline and the production guard unchanged. No tests, builds, linters or verification scripts run locally under the executor no-run rule. Nothing pushed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant