Repository navigation
R5 documentation wave: doc guards, complete Pine-to-native map, LLM onboarding, native reference and ADR re-derived, Doxygen over the whole public surface - #272
Merged
Conversation
…ints at (R5 lane L14-A, item 1) The pages cite the tree by `file:line`. Every header edit moves those lines, so the citations rot silently: the second claimed-vs-actual audit found 108-115 of ~304 anchors wrong after a single campaign, and a reader who follows a stale anchor lands on an unrelated declaration and concludes the page is lying. One more hand re-derivation buys one more campaign; a gate is the durable fix. scripts/check_doc_anchors.py reads the anchor grammar the pages already use - bare name, explicit path, range, and the bare `:line` continuation - resolves it through a stated search order, and, when a backticked symbol precedes the anchor in the same table cell or sentence, requires that symbol on the cited line. The scope rules are what make the claim honest: a Pine column never lends its spelling to a Native column's anchor, a `strategy.risk.*` name is never read as a symbol the tree declares, and the `closed_trade_*` and `/ _exit_id` elisions are matched as the pages mean them. `--fix` rewrites digits and nothing else, and only where the answer is read rather than guessed: one occurrence of the symbol in the file's code (comments stripped, because a paragraph about a name is not the name), or exactly one type declaration of it. Everything else is reported with its candidate lines and left for whoever rewrites the sentence. The gate runs in ci_preflight as `doc-anchors`, advisory: it prints today's drift without failing the integration branch before lanes L14-B and L14-C remove it. `--strict-docs` makes it binding, which is how those lanes will leave it. Its self-tests are not advisory - a guard that cannot fail is decoration - and register as the `test_doc_anchors` CTest row; the row count moves, and the integrator recomputes the floors. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit de0a860c71072b07d9380219faa143263b7a297c)
…lane L14-A, item 2) `scripts/check_doc_anchors.py --fix` moved 257 of the 474 stale anchors onto the line their own cited symbol occupies today. Every one was read, not guessed: the symbol has exactly one occurrence in the resolved file's code, or exactly one type declaration there. The drift is the gap waves' own growth - `on_native_input` 440 -> 673, `native_marked_equity` 499 -> 913, `initial_capital` 159 -> 516 - so the pages' prose was right and only their coordinates were not. The diff is line numbers and nothing else, and it is checkable: 179 removed lines against 179 added, each pair identical once `:<digits>` is normalised away. No sentence, row or claim changes here; that is the work of lanes L14-B and L14-C, which now start from a 217-anchor residue instead of 474. The 217 left are the ones a script must not decide: a symbol on several equally plausible lines, a symbol that has vanished from the file it is cited in, and eleven citations of files the tree no longer has (`runner/examples/…` after the examples move, `include/pineforge/market_admission.hpp` after N14's header move). They are listed per page in the lane report. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 21b9745f05addfa6668559f3da36ca86cac81d77)
…is live (R5 lane L14-A, item 3)
The anchor gate catches a coordinate that moved. It cannot catch a sentence
that became false: fifteen `lane L…` rows in pine-to-native.md name work that
landed campaigns ago, four "there is no … in this slice" claims in
native-engine.md are contradicted by symbols the same page documents, and
`engine_script_run_v17` survives where the tree is at v18. Those are prose, so
they get their own guard with its own report.
scripts/check_doc_lint.py holds four rules. A `lane L<n>` on a published page
is an offender: the migration guide says what the tree does, the roadmap lives
in the campaign. A "there is no … yet / in this slice / today" claim is an
offender unless its line carries `<!-- verified HEAD -->`, an explicit claim
that somebody checked it - and the real pages wrap those sentences over a line
break, so the rule reads the page, not one line at a time. A relative link
whose file or `#anchor` is missing is an offender, with both anchor spellings
the pages use resolved: Doxygen's `{#id}` and a heading slug.
The epoch rule is derived rather than listed. The live set is read out of the
tree - every `inline namespace <family>_v<n>` and every `"pineforge-…/v<n>"`
hash domain - and only another version of a LIVE family is stale. A hardcoded
`native_order_v[1-5]` would have flagged `native_order_v1`, which is the live
identity epoch even though native_order.hpp is at v6; and a derived set needs
no edit the next time an epoch bumps.
41 offenders on HEAD across 9 files, which is the point: this guard is
expected red until lanes L14-B and L14-C rewrite those sentences, so
ci_preflight runs it advisory beside `doc-anchors` and `--strict-docs` makes
both binding. Its self-tests are binding now and register as `test_doc_lint`.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
(cherry picked from commit da5f7d83a7f167beb4646211eee3a84852ceb9b8)
…ad it (R5 lane L14-A, item 4) The published site was one header and 25 pages. native_c_api.h — the whole C host surface — was outside INPUT, ADR-0001 and the 944-line design document never published at all, and the three native C++ headers were invisible: they carry ~1000 lines of accurate, mechanism-level prose written as plain `//` comments, which Doxygen does not read. A contributor arriving at the site found a C ABI reference and no native API. Four changes. INPUT now covers the whole public surface: every header under include/pineforge (kernel, source layer and compat/pine), the ten native examples, the adapter's implementation units, the pages, the design document, the ADR and the settlement note that fill-model.md already links. 26 inputs became 96. pineforge.h is named FIRST, before the directory that also contains it, for the reason engine.hpp:37 already states about translation units: engine.hpp defines PINEFORGE_NO_STRATEGY_DECLS and Doxygen carries a define across the whole run, so parsed second, pineforge.h loses strategy_create / strategy_free / run_backtest / run_backtest_full / report_free and ~50 references to them resolve to nothing. Ordering is the same fix src/c_abi.cpp uses. docs/groups.dox declares the boundary the include graph cannot show: "Kernel / native API" and "Pine adapter (TradingView-parity policy layer)", 19 and 16 files, each with the paragraph that says which one a given reader wants. It groups files from one place rather than adding @InGroup to fifty headers. The doc comments themselves: the declaration-leading `//` blocks of native_host.hpp, native_run_spec.hpp and native_order.hpp are promoted to `///` — 1021 lines, 165 declarations — so the prose that was always there is now the API documentation. On top of that, the five parameters and two return contracts that native_c_api.h's submit, replace, cancel_where and execute_current never documented are written out, each naming tests/test_native_c_api.c, and three `*`-inside-backticks spellings that Doxygen parses as unbalanced markup are respelled. Nothing under include/ changed but comments: strip the comments from all six touched files at origin/main and at HEAD and the code is byte-identical. The gate is scoped, because Doxygen's WARN_AS_ERROR is global and a stale comment in a legacy adapter header must not stop the site from building. docs/build.sh reads WARN_LOGFILE and fails only on a warning in the guarded set — the kernel / native API headers, the C API header, the C ABI header, the layer map, the examples — and prints the rest. Warnings went 3 over 26 inputs to 0 over 96; injecting one broken @ref into native_host.hpp fails the build, so the gate is not decoration. build.sh also feeds doxygen a config file rather than stdin, which doxygen 1.18 aborts on. Two anchors in pine-to-native.md moved with native_c_api.h's new comments and were re-anchored by the checker; line numbers only, as before. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 67f3a44c60ee0adb11e29a101de350663866ab74)
…ne L14-A, item 5) docs/ci.md gains a "Documentation guards" section: what each of the three guards reads, the command to run it, what `--fix` will and will not do, and why `doc-anchors` and `doc-lint` are advisory in the preflight until lanes L14-B and L14-C clear the offenders they report. The section's own description of the "there is no …" rule trips that rule, so it carries the `<!-- verified HEAD -->` marker — which is the clearest possible demonstration of what the marker is for, in the one place a reader learns about it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 7485a40ad077809c67c4073d635e5b08c6086cfa)
…lane L14-B, item 1) The second audit named two landed kernel features with no runnable host: NativeRunSpec::auxiliary_feed (gap lane N7) and native_open_lots() (gap lane N18). The migration page has to name an example for every row it claims, so both get one, built exactly as lane P6 built its three. native_auxiliary_feed_strategy.cpp runs 15-minute inputs over a 1-minute auxiliary feed and declares a "5" series on it -- a series finer than the input, which is refused by name without the feed (NativeRunSpecError::SubscriptionWithoutAuxiliaryFeed). It checks each of the twelve buckets against the hand aggregation of its own five minutes, checks the routing rule by time (three buckets ride on the input whose period they opened in, oldest first, before its calculation) and then decides on the bucket the pull side answers. native_open_lots_strategy.cpp pyramids a long three times on flat bars with AfterCalculation close execution, so every number is exact, and reads the book lot by lot: ordinals oldest first, one row per physical_position().lot_count, native_marked_equity(mark) == balance + sum(unrealized_pnl) at every calculation, a NaN mark that keeps the booking facts and computes nothing, and a FIFO partial reduce that takes its share of the entry fee with the slice (L2 keeps 1.5 units and 1.5 of its 2.00 ticket). It then reads Pine's report namespace through the protected BacktestEngine accessors a host inherits, and runs the same tape twice to show who folds the extremes: KernelRecorded folds max_drawdown / max_runup / max_contracts_held_*, HostRecorded folds none of them, and both runs close the same trades for the same money. Registered as lane P6 registered its own: PINEFORGE_NATIVE_EXAMPLES, a _pf_example_line_<name> for the CTest row's assertion, and the manifest of scripts/check_native_include_independence.py. Two comments that counted the examples are made count-free rather than re-numbered, so the next example does not falsify them again. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit f4739a672d36c6fab8736d480cf01a15efa69d15)
…ete (R5 lane L14-B, item 2) Both audits measured docs/pages/pine-to-native.md against the tree and found the same two defects: 43 of 96 offered `strategy.*` names had no row at all (the whole trade-statistics namespace, strategy.margin_liquidation_price, strategy.default_entry_qty, the oca / direction / commission constants), and 15 rows routed a reader to a roadmap lane for a feature that shipped campaigns ago. The page is re-derived here against HEAD. Every offered Pine name now has a row: 131 of them -- the 96 `strategy.*`, 11 `request.*` and 4 `barmerge.*` rows of the repository's own Pine v6 inventory, `strategy()` itself, and the 19 named arguments of the declaration that the inventory collapses into one row. 113 map to a kernel symbol; 18 are ruled `none`, which is a decision with its reason and the place the behaviour lives instead, not a gap. Each row carries the C++ symbol with its file:line, the C spelling through native_c_api.h or pineforge.h, and a runnable host under examples/native/ (or the test) that exercises it. No row names a lane. Where a mapping is not one-to-one the row says which way it differs and cites the ruling of record -- ADR-0001's "Kernel capabilities the Pine adapter does not declare" and the design record's section 3.6 -- so a reader can tell a boundary decision from an omission. New sections the audits asked for: a coverage table with the three counts and how to recount them; "One strategy, three ways", the same trivial strategy in Pine, in C++ and in C, pointing at hello_kernel.cpp and hello_kernel_c.c with the three rules that make the C door behave (size-prefixed structs, a callback that must return 0, on_recalculate replacing on_bar); a full margin and liquidation map; and a six-feature worked migration -- cash sizing with a fee reserve, a bracket on a price grid, a trail in ticks, a maintenance-only margin model, a risk limit and a higher-timeframe series -- migrated end to end reading only this page. One fact the page states that no page stated before, found by writing examples/native/native_open_lots_strategy.cpp: the equity extremes and the position-size peaks are folded at the kernel's own report point, so they stand at zero under the default HostRecorded policy and are the host's own. The example runs the same tape under both policies and prints the difference. scripts/check_pine_to_native_coverage.py derives the offered set from the inventory and the covered set from the page's own first table column, checks that the page's printed totals are the counted ones, and runs as a non-advisory ci_preflight stage: a name added to the inventory without a row fails the gate. The anchor checker reports 550 anchors, 0 bad, on this page. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 6ce318ce83d234bfd5ff44425941719b8f3e3dca)
…(R5 lane L14-B, item 3) An agent handed a brief in this repository fails in two ways a human reader does not: it writes a plausible sentence that is not true of this tree, and it makes a test green without making it prove anything. docs/pages/contributing-llm.md is CONTRIBUTING.md's ground rewritten so that neither is easy. The boundary is ten numbered invariants, each paired with the script that enforces it and the ADR section that rules it, so an agent can check a rule rather than recall one. The repo map is a table of directory, purpose and the guard that watches it. The lane recipe is the worktree and corpus setup, the fail-before recipe against the previous header closure, the verification order with the four traps that have cost other lanes a cycle (ci_verify re-pins the corpus; never sweep beside a build; never checkout the LFS feed; ctest rebuilds nothing), one commit per step, and the report shape. Two sections exist only because agents get these wrong. The "never" list makes the expensive habits explicit -- never cite a symbol from memory, never loosen a pin without "expectation corrected", never change a lane's semantics in a merge, never widen a guard's scope to pass, never claim an unexecuted run. And "the places that look like duplicates but are ruled" names the nine pairs an agent reading this tree concludes are dead code, each with its ruling of record, because deleting one is a regression the guards catch late. A glossary closes it: kernel, adapter, front door, twin, ledgered assertion, floor, receipt, epoch, corpus pin, sweep, band 1 / band 2. Registered in the Doxyfile INPUT beside pine-to-native.md. The anchor checker reports 16 anchors, 0 bad, and the lint is clean on it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 9d2d59c43b0d590bbdc1f745d4bcebc35aa961c5)
…epository (R5 lane L14-B, item 4)
The previous file answered "how do I build and run ctest". It did not say what
the repository is for, where the boundary is, what the parity corpus actually
proves, or what a pull request has to show -- and three of its claims had gone
stale: a 30-binary suite "under a second", a 10-second ctest budget, and three
named functions that no longer exist.
The rewrite is the whole workflow. What the repo is, in a paragraph. The two
layers and the ONE rule, with the mechanical test for it ("if justifying the
change needs the word TradingView, it does not belong in the kernel") and the
two consequences that are easy to miss: every kernel capability is opt-in, and
a field the adapter never declares carries a ruling. A table saying where each
kind of change goes and what else it obliges. The test-first loop, with the
four shapes of non-evidence named. The gates as a checklist with the exact
commands and, for each, the specific way of being wrong it refuses. The floors
and the rule that adding rows means raising them in the same commit.
The parity contract gets its own section because it is the thing a newcomer
most reliably misunderstands: the corpus is a byte oracle at a pinned gitlink,
"moved" means any byte changed, the baseline rather than the corpus's own
trades is the oracle, and a refresh carries its evidence. Beside it, the
"expectation corrected: <old> -> <new>, because <mechanism>" rule for any
pinned number, spelled exactly so it stays greppable, and a pointer to the
epoch procedure for the internal C++ namespaces.
Commit and pull-request conventions are read off the history rather than
invented, and the campaign merge rule is stated in the terms it is actually
decided in: no individual regression, net movement >= 0, with the documented
net-0 exception and its recorded FAIL.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
(cherry picked from commit 7e6e2db9f42dd37e657369b705e07297ef7346fa)
…B, item 5) Two claims the second audit measured as false are removed. Line 38 said "one header, 65 extern "C" functions"; the surface is 97 across two headers, 65 to run a compiled strategy and 32 to drive the kernel yourself. The architecture bullet said a bare host "cannot size orders", that "the equity curve is recorded by the host", and that "request.security() feeds have no native registration API" -- all three false at HEAD, and each demonstrated by a shipped example. In their place the README states what is true and why it is true: every kernel capability is opt-in, which is what lets adapter runs stay byte-identical by construction, and a spec field the adapter never declares is a recorded decision held by scripts/check_native_feature_rulings.py rather than dead code. A new "Three front doors" section gives each way in its own short example -- Pine through codegen, C++ through NativeStrategyHost, C through the callback table -- with the example source referenced by path rather than pasted, so the README cannot drift from a file that compiles. It links the migration page the goal names, which the README never linked before. A new "Building, testing and the gates" section gives the commands as they are (ci_verify.py release and kernel, ci_preflight.py, plain CMake), the CMake options that matter including PINEFORGE_BUILD_SOURCE_LAYER=OFF and PINEFORGE_BUILD_EXAMPLES, and the gates a pull request passes as one line each with its script name and what it refuses: parity subset, row floors, kernel residuals, feature rulings, the two C surfaces, twin parity and the three documentation guards. It closes by pointing at CONTRIBUTING.md and the LLM onboarding page. The repository layout gains examples/native/ and the docs/design and docs/adr directories, and the scripts/ line names the verifier and the guards rather than only the corpus tooling. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 7dc3ae67a21a3d96244bc6642d8edae3012627d1)
…, item 6) docs/pages/index.md carried four defects the second audit measured. Its @note called the internal C++ headers "deliberately omitted ... not recommended for direct external consumption" while the migration page tells a native author to include native_host.hpp; it claimed "the entire public surface fits in one header and 65 public PF_API declarations" when it is 65 plus 32 across two; its worked-examples table had zero examples/native/ rows though the tree ships fifteen with CTest rows; and it had no index of its own pages. The page now opens on the two layers and the three front doors, and the @note says what is actually internal: the Pine adapter's own headers. The API section gives both inventories with the guard that pins each. The worked examples are split into driving a compiled strategy and driving the kernel yourself, the second listing every host under examples/native/ with what it demonstrates. A closing index lists all 31 pages under docs/pages/ once, in five groups, each with a one-line description -- including the two that carry no Doxygen label and are therefore named by path. docs/README.md described a docs/ tree that had moved on: a pages/ list of fourteen files (there are 31), no design/ or adr/, no groups.dox, no ci.md, and nothing about the guards a page has to pass. It now describes the tree as it is, says which loose docs/*.md are published and which are engineering records, explains build.sh's scoped warning gate, gives the anchor grammar an editor needs with a worked example, and lists the three documentation guards with their commands and their current binding state. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit a05208056a3da392c8b1c99f63478690a928484c)
…(R5 lane L14-B, item 7) The audit's acceptance for G3 is that a reviewer can migrate a six-feature strategy reading only the migration page. I did that: assembled the host from the page's own sections 1-6, compiled it against libpineforge_kernel.a alone and ran it. Three statements did not survive the exercise, and they are corrected here rather than explained away. 1. The margin rule was stated backwards. The page said `initial_short = 0.0` is legal "because maintenance_short is unset"; the header says the opposite -- `initial_* == 0.0` is the maintenance-only spelling and is legal only where that side's `maintenance_*` IS set. A side with neither states nothing at all, and configure_native refuses the whole spec with MarginSideUndeclared, which is what the assembled host hit first. The long-only example now declares an ordinary short requirement and the prose explains the waiver rule as the header has it. 2. An anchored trail needs its arm_price present, holding the placeholder 0.0. The page's snippet passed std::nullopt, and the leg was rejected with RequestRejectReason::InvalidTrigger while the rest of the strategy ran -- the worst kind of error, silent in the summary line. The snippet carries the placeholder and the comment that says why. 3. SubmitResult::handle is an optional, so the bracket owner is `*entry.handle`. With those three, the host runs: the entry sizes 24.5096 units from 2500 of cash net of the 0.1 % fee at the signal price on the 0.25 ladder, the take-profit arms at fill + 40 ticks = 112.00 and fills there, the trail and the stop are cancelled with it by their OCA group, the margin model admits the opening and never liquidates, and the risk limit is declared and not breached. The run and its output are recorded beside the lane's report. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit b4353d0bfc36cad4f2339db1d8c903e285bbf5b7)
…ection (R5 lane L14-C, item 1) Every sentence of docs/pages/native-engine.md re-read against the header or test it cites, and rewritten where the tree contradicts it. The false negatives are gone, each replaced by what HEAD offers: there IS a C request API (strategy_native_submit_v1 and its four siblings), there IS a partial-bar view (current_partial_bar, NativeOpenBarView::OpenOnly), there IS a native subscription API (the whole "Higher-timeframe series" section two screens above the sentence that denied it), there IS a kernel-only target (PINEFORGE_KERNEL_SOURCES, add_library(pineforge_kernel)), and generated Pine code has not been on a "compatibility route" since PineStrategyHost became a NativeStrategyHost. src/compat/pine/market_admission.cpp is in the source layer's own list, not outside it. A C host submits on a stream like any other. The host epoch is engine_script_run_v18 and the source-adapter hash domain is pineforge-source-adapter/v3. The "interim" self-aggregation recipe was true and mislabelled: a host that wants the running aggregate and none of a series' delivery rules still writes it. It moves next to the subscriptions it is an alternative to, says what it does not give you, and stops pretending the subscription API is unbuilt. New sections for the surface the page never named: the feed-shape and path-order policies, the intrabar path and its three alternatives, spec validation and its two result types, "Reading the run back" (every const query with its C spelling), the closed row's close cause, and cohorts. Roadmap labels are out. A published reference tells a reader what the tree does; "lane L8b" tells them nothing they can look up. The examples table's lane column is now the suite that pins the same surface. check_doc_anchors: 102 anchors, bad=0. check_doc_lint: clean. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 97926eadfa30046c49ed271cf4a7177d1874e79f)
…dard the waves applied (R5 lane L14-C, item 2) The seven false sections describe a tree that no longer exists, so they are gone: there is a kernel-only target and the two source sets are disjoint (no "boundary bug"); the C API trades (submit / replace / cancel / cancel_all / cancel_where / execute_current, and streaming needs no new symbol); the examples are a gated target whose rows assert exit code AND output; the run spec is no longer narrow; request.security series ARE reachable from a bare host; the equity curve is a report-policy choice, not a host chore; the domain is pineforge-broker-state/v18; there are six intents, not five; there are four margin seams, not one. Two of the "four rules" earlier drafts named are also gone, and saying so took reading the code rather than the comment: there is no set_margin_call_enabled in the tree, and closed_trade_close_cause compares no string — it reads a typed execution::CloseCause and answers 3 for a KERNEL liquidation. What is live is one hashed pair, the intrabar-fill excursion mask. The 1051-line path resolver is gone too; the repository holds one fill simulation. Rule 2 said "if justifying it needs the word 'TradingView' it belongs in the adapter", and the tree does not pass that. It never could: a calibrated number has to say what calibrated it. The amended rule asks two things instead — is the mechanism drivable for another venue by data, a spec field or a hook (else it is the adapter's), and would the alternative be a hash-visible knob over a choice the run already made (else it is a hook, not a field) — which is the standard that ruled the feed partition and the SymInfo::type vocabulary generic while the per-order-kind tick rules and strategy.risk.* stayed adapter-side. A new section accounts for every TradingView-justified kernel site against the amended rule. Taking that population found something the audits missed: of the ~20 sites they named as "compiled kernel", eight document functions the lowerings deleted — from engine_orders.cpp:560 to :697 the file has no code at all — so the deferred-flip growth rule, the opening margin guard, the same-tick sequencing, process_orders_on_close, the signal-bar sizing freeze and the intrabar liquidation are rule-5 comment residue, not rule-2 questions. The rest are live, each generic with its calibration recorded, and each pinned. No site is left unaccounted for; two are recorded as open questions rather than violations. The residual tables N14/P2/P6 wrote are byte-for-byte unchanged. check_kernel_residuals: 109 archive hits, 0 findings. check_native_feature_rulings: 10 ruled fields, exit 0. check_doc_anchors: 217 anchors, bad=0. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit d496afd14dba8e038b058126a04d5897dcda0cb9)
…them there (R5 lane L14-C, item 3) Thirty-eight §1 rows read **no** or **partial** for capabilities a passing kernel-profile test drives. The audit named five; reading the table against the tree found the rest — every sizing basis, the whole margin model, every risk limit, the calculation triggers, the subscriptions, the auxiliary feed, the price grid, the recorded curve, the per-bar hashes, the host hash extension, the C order API. The repair is the convention the table already used for N6 and N7, not a verdict rewrite: a row keeps the finding it recorded — that is the audit's own record of what the campaign found — and appends "**Closed:** <what landed> (`tests/…`)". Flipping the verdicts would have destroyed the record; leaving them alone left the document lying. Row g is rewritten: the legacy path resolver's move happened and then the thing itself was deleted, so engine_path_resolve.cpp is 95 lines of three generic functions and the repository holds ONE fill simulation. §2.ii items e, f, j, k and l are done too — the dead helpers, the dead stream path, four of five Pine-shaped lot flags, the margin-call toggle and the string-sentinel decoding are all gone from the tree — and §2.vi's correction list has been applied, which this lane did. §3.2 gains the twelve audit lanes that landed on main, each with the last commit of its own. scripts/check_design_inventory.py holds the convention. "Runs in the kernel profile" is not a heuristic: it is tests/CMakeLists.txt's own decision, transliterated — the TEST_SOURCES list operations replayed, then pineforge_test_reaches_source_layer's transitive quoted-include walk, plus the add_executable targets the reach filter does not cover. --ctest-list cross-checks that reimplementation against `ctest -N` from a real kernel build dir, in both directions, so a drift from CMake is reported rather than believed; on this tree the two agree, 125 TUs against the kernel profile's 192 rows. 22 self-tests: six must-fail (a no row with a kernel witness, a partial row, a qualified partial, a marker whose only witness is source-bound, a cited test that is not in the tree, and a ctest listing that disagrees each way), eight must-not-fire (the two marker spellings, an adapter-only gap, a transitive reach through a local header, a quirk row, a waiver row, a pure-C target, a REMOVE_ITEM'd member) and five shape cases that exit 2 rather than 0. Wired into ci_preflight as design-inventory plus its self-test stage, and fail-closed from the start: it holds a convention every row already follows, so it has no drift to report and nothing to wait for. ci_preflight --output-dir build-ci-preflight: PASS, 24 stages, both new ones passed. check_doc_anchors: 654 anchors on this page, bad=0. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit ab5b2ecc8114773f933eb427fc6841a18a457688)
…so in its own header (R5 lane L14-C, item 5) The docs build's warning count for the native headers was already zero, before this lane and after it: docs/Doxyfile sets WARN_IF_UNDOCUMENTED = NO deliberately, so an undocumented declaration is not a warning and there were none left to close. What there was instead: 132 top-level public declarations in the five headers the reference page's own sections describe, carrying no doc comment at all — the lifecycle and failure model, the whole query surface, every command, the FX curve, the feed-shape policies, the intrabar path, spec validation, the driver coordinate, and the request values a host actually writes. Each now carries a /// block in the standard L14-A set: what it is, when the kernel consults or answers it, what the return means, the C spelling beside the C++ one, and the test that exercises it. A reader who jumps from the page to the header lands on prose rather than on a bare signature, which is the point. Comment lines only, proven two ways: the diff of non-comment lines since this lane's base is empty, and stripping every comment from each touched file at origin/main and at HEAD leaves the code byte-identical. The kernel archive rebuilds and the docs build stays at 0 warnings. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 45101edc909d796bf1280262b82aaea6c7c00554)
… (R5 lane L14-C, item 4) Item 5's doc comments moved every line the three pages cite in native_host.hpp, native_run_spec.hpp, native_order.hpp, native_fx_curve.hpp and market_driver.hpp. 247 anchors re-anchored, digits and nothing else: 230 by check_doc_anchors.py --fix, which moves a citation only when the claimed symbol has one occurrence or one type declaration in the resolved file, and 17 by reading — twelve of them the `on_native_bar`, `cancel_where` and `replace` overload pairs, where the declaration is the first of the two and the second is its body or its options form. With this, every `file:line` in the three pages this lane owns names its symbol on this tree: native-engine.md 102/102, ADR-0001 217/217, native-feature-parity.md 654/654, bad=0 on all three. The lane's own repairs included the three NOFILE citations N14's header move created — the market_admission.hpp observation fields now cite include/pineforge/source/market_admission.hpp — and the historical citations into files the campaign deleted, which are spelled as `git show ab9714b:<path>` rather than as a coordinate no reader can follow. docs/pages/pine-to-native.md is L14-B's and is untouched here; 63 of its anchors moved for the same reason and `check_doc_anchors.py --fix` repairs them mechanically. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit bf6d607453ef3b8c90368d21e77df6299f310fb1)
…4-C, item 2 follow-up) "Roughly 250" was an estimate. Measured: engine_orders.cpp :200-224 and :556-697, engine_run.cpp :162-186, engine.hpp :1262-1381 — 312 lines, with zero code lines inside any of the four spans. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit 6b8776599ca6e374a3a9fe49ebf9f64cba3b8245)
… to say (R5 lane L14-C, item 1 follow-up) Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit cbf91a99101b353b6bcddcdfbe2b6033908c291d)
…a risk flatten carries (R5 lane L14-C, item 5 follow-up) Comment line only. The enumerator is set at native_execution_consumer.cpp:3332 and read back by tests/test_native_risk_limits.cpp:392. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit d0581cdc9debec86af35e4ce59d1a578780641d9)
…R5 lane L14-C, item 4 follow-up) Digits only. Every anchor of the three pages this lane owns names its symbol again: native-engine.md 102/102, ADR-0001 217/217, native-feature-parity.md 654/654. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> (cherry picked from commit dc8b57f9eb2ebe6bc929edef16052803a6f0532d)
…12, documentation wave)
The three documentation lanes are cherry-picked above this commit. Each one
passed its own gates on its own base; this is what the union of the three
needs, and nothing else.
The guards go binding. `--strict-docs` was L14-A's ruling that a guard may
report rather than fail while the drift it names is exactly what the next two
lanes exist to remove. Those lanes have landed: the anchor checker reports
bad=0 on every page and the lint 0 offenders, so the flag is removed rather
than flipped -- a guard that can be asked not to bind is decoration. The
advisory *mechanism* stays in `ci_preflight.py`, with its self-test, for the
next guard that lands before its drift is gone; no stage uses it today.
`CONTRIBUTING.md` joins both guards' globs: L14-B rewrote it whole and checked
it by hand, and nothing kept it true.
The anchors. L14-C's 528 header comment lines moved 307 of the anchors in
L14-B's rewritten `pine-to-native.md`, which is what happens when two lanes
branch from the same tip and one of them edits the headers the other cites.
`--fix` re-anchored 277 of them; the remaining 30 are symbols the checker
refuses to guess at (`side` on eight lines, `Cancel` on two). Each was
resolved by mapping its line through the 7485a40a..HEAD diff of the header it
cites and reading both texts: all 30 old lines survive verbatim, so the
coordinate moved and the claim did not. Two of the 30 differ from the
checker's first candidate -- `cancel_where` is the `NativeRequestField`
overload, not the one-argument one, and `FromOwnerFill::ticks` is the flag,
not `TrailTicks::ticks`.
The two page anchors `native-engine.md` links to, `{#pine_to_native_map}` and
`{#pine_to_native_map_trades}`, were dropped by L14-B's rewrite (it split the
one "Concept map" section into ten). Restored as `@anchor` commands so that
L14-B's per-section ids are kept as well.
Doxygen builds at 0 warnings over all inputs, not only over the guarded set.
Four references from L14-B's pages pointed at files outside `INPUT`. The
front doors are now published -- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`,
`LEGAL.md`, `SECURITY.md` -- and the two engineering records they also named
are cited by path instead, because `docs/README.md` states that split and a
record is not a page.
The lint's last offender was its own false positive: `Series<T>::operator[](k)`
inside a code span reads as a markdown link to a file named `k`. An inline code
span is not a link, for the same reason L14-A ruled that a fenced block is not
a citation; only the span's content is masked, so a real link whose label is
code is still read. Two self-tests, one each way. The fourteen other offenders
name their epoch correctly -- historical baselines, frozen providers, and P2c's
`lifecycle_v2` removal epoch, which is forward, not stale -- so each carries
the `<!-- verified HEAD -->` marker the rule provides.
P2c landed on main after all three lanes branched, so the migration page still
offered the deprecated spelling as the primary one: its `risk_free_rate` row
now names `sharpe_monthly` / `sortino_monthly` and records `sharpe_tv` /
`sortino_tv` as the deprecated aliases of the same two doubles, with the
serialized report key unchanged. ADR-0001 keeps both sections whole -- P2c's
"Deprecated public spellings" table and L14-C's rewritten feature-gate rulings
-- which `check_kernel_residuals.py` (109 archive hits against 119 ruled
identifiers and 11 ruled texts, 0 findings) and `check_native_feature_rulings.py`
both still parse.
The floors, recomputed on this tree under lane Q12's ran-rows rule:
`KERNEL_MIN_TESTS` 189 -> 193 (194 registered, the WebSocket row still skips)
and `RELEASE_MIN_TESTS` 554 -> 558. Both +4, the same four rows: L14-A's
`test_doc_anchors` and `test_doc_lint`, and L14-B's two example hosts.
Cross-lane corrections the union tree still needed: `native-engine.md`'s
"all thirteen sources" is fifteen (L14-B added two examples), `docs/ci.md`'s
"three guards" is four and its "ten native examples" fifteen, and the kernel
row floor the page quotes is the recomputed one. The three L14-C flagged in
L14-B's pages -- README's opt-in sentence and `index.md`'s two counts -- were
already true here: L14-B's later commits fixed them after L14-C read them.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
|
||
| import argparse | ||
| import re | ||
| import sys |
luisleo526
added a commit
that referenced
this pull request
Sep 22, 2026
The pages cite the tree by line number and both doc guards are binding since the documentation wave (PR #272). Wave D moves those lines a long way: `include/` loses 411 net lines to lanes E6 and E10 (engine.hpp alone -400), `native_c_api.h` gains E7's two enums, E11's symbol, E13's readout tail and E14's request tail, `native_order.hpp` and `native_execution_consumer.cpp` both grow, and `src/source/pine_adapter.cpp` moves under E5, E9 and E14. On the picked tree 574 of 1553 anchors were bad; none of that is a claim changing, only where the claim lives. Three passes, in this order: 1. `python3 scripts/check_doc_anchors.py --fix` until it converged (358 anchors re-anchored, 216 left that it refuses to guess at). 2. The 216 it refuses are ambiguous only to a symbol search. They are not ambiguous to the diff: every one of them was correct at origin/main, which the wave's own gate proved (bad=0), so each was mapped through `git diff -U0 origin/main..HEAD` for its own file and rewritten to the line the wave moved it to. 159 doc lines. 3. Five anchors survived that, because they were not line drift but claims the wave made false. Each is corrected by reading: - `native-engine.md` cited `record_script_report_point` at the call site lane E2 moved; it now cites the definition. - `native-feature-parity.md` row (e) cited `apply_slippage` "in the comment at engine.hpp:2129" — lane E10 deleted that comment; it now cites `src/native_matching.hpp:240`, where the function is. - `native-feature-parity.md` rows (j) and 7 and ADR-0001's "current state" bullet said the excursion mask pair is "written only by the adapter" at `pine_strategy_host.cpp:471`. Since lane E6 no host writes it: the excursion owner declares where its fill sat and the kernel derives the pair. The three citations now name `declare_opened_lot_entry_bar_mask`. Four citation corrections the lanes asked the integrator for, in files main owns after PR #272: - The ten-significant-digit money residue was `engine.hpp:918-952`, not `:73-180` — measured by lane E6, which deleted it; `:73-180` is and was live code (`ClosedLotExcursionFacts`, `PyramidEntry`, `Trade`). Corrected in all four places that carried the wrong span: ADR-0001's "current state" bullet and its residue-table row 8, `docs/pine-adapter-kernel-notes.md:16`, and `native-feature-parity.md` rows (d) and 7. - ADR-0001 said `<pineforge/native_c_api.h>` implements **32** additive symbols. Lane E11 added the 33rd. - ADR-0001 recorded two rule-2 open questions. The wave closed both: the C delivery words are typed (lane E7's `pf_native_lookahead_e` / `pf_native_gaps_e`), and the excursion mask pair has no host writer (lane E6, with E11's C spelling and E15's declared-order derivation). Both bullets now say so, and say what is left: the pair is still durable hashed lot state, so removing it is still an epoch decision. Also folded in, from the picks themselves rather than from a lane's own file list: lane E14's new `##` ADR section was moved into the documentation wave's "TradingView-calibrated kernel mechanisms" table B (a standalone section beside the residual vocabulary reads as stale to `scripts/check_kernel_residuals.py`), and the header's two asymmetry notes were reconciled — `pf_native_working_v1` did grow a readout tail (E13), and the trail seed is still deliberately not read back (E14). Gates: `check_doc_anchors.py` 1555 anchors, bad=0 on every page; `check_doc_lint.py` 0 offenders; `check_pine_to_native_coverage.py` offered=131 covered=131; `check_design_inventory.py` 0 findings; `check_native_feature_rulings.py`, `check_kernel_residuals.py` and `check_native_c_api_surface.py` all clean. One header edit rides here because it is the same kind of rot, caught by `bash docs/build.sh` rather than by the anchor gate: lanes E7 and E11 wrote their doxygen cross-references against the enum TAG (`#pf_native_lookahead_e`, `#pf_native_gaps_e`, `#pf_native_opened_lot_fill_point_e`), while this header indexes and every other row cites the typedef (`#pf_native_intent_t`, `#pf_native_size_price_t`). Doxygen could not resolve the three, and E11's block left `@param s` undocumented while documenting the other three parameters. Four warnings; with the references pointing at `..._t` and `s` named, `docs/build.sh` reports **0**. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The R5 documentation wave — the last lane group before release, run after the code lanes so it documents the tree as it is. Twenty-one lane commits + one integration commit on main
0a47cbf7:scripts/check_doc_anchors.py(everyfile:linecitation resolves to its symbol;--fixmoves digits only when the answer is read; 992 anchors, 474 were wrong),scripts/check_doc_lint.py(lane labels, stale negatives, epochs derived from the tree, dead links), Doxygen over the kernel headers, the C header, examples, design and ADR documents (INPUT 26 → 96, layer groups, a scoped warning gate indocs/build.sh), 1021 header comment lines promoted so Doxygen reads them,docs/ci.md"Documentation guards"docs/pages/pine-to-native.mdcomplete: 131 offered Pine names / 131 rows (113 native, 18 ruled none with the reason and where the behaviour lives), C++ symbol + anchor + C spelling + runnable host per row, "One strategy, three ways", the margin map, the six-feature worked migration EXECUTED against the kernel-only archive;scripts/check_pine_to_native_coverage.pyas a binding preflight stage; two new examples (auxiliary finer feed; open lots with marked equity);docs/pages/contributing-llm.md;CONTRIBUTING.mdrewritten; README front doors; site indexesdocs/pages/native-engine.mdre-derived section by section (every false negative replaced; new sections: policies, the intrabar path, spec validation, reading the run back, close causes); ADR-0001 rewritten with rule 2 amended to a two-part test (generic mechanism; no hash-visible knob) and every TradingView-justified kernel site ruled; design §1 closure markers held byscripts/check_design_inventory.py(fail-closed); 140 declarations documented--strict-docsremoved — the pages are clean), floors recomputed (kernel 193, release 558), Doxyfile inputs, the two page anchors restored, 30 read-resolved anchors, one lint false positive fixedEngine untouched: 8 headers changed in comments only (comment-strip byte comparison),
src/unchanged. Epochs unchanged.Evidence
doc-anchorsanddoc-lintbinding, release 558 (floor 558), debug 542, kernel 193 ran of 194 (floor 193), build-on 542; full corpus parity 312/312 with the pinned headline and the 30-probe subset (executor and supervisor runs).exp-r5-int12-docs-wave-20260922on this head: executionpineforge-experiment-run-kssz4, 72/72 cases, 0 failed; 4190 graded, 0 coverage lost, band1 +0/−0, band2 +0/−0, hard regressions 0, leavers 0 — net 0 vs baseline snapshot e5e887ed / population dd8841c9 (candidate snapshot97784230);pineforge-pr-gate-v4c5jreportstarget.not-positive, the neutral outcome at net 0 (a documentation wave cannot move a trade).Merge with rebase.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Lg1KP7RXkwcEP2wFxXooy9