Skip to content

Install other symbols' bars for request.security in the Docker harness (--symbol-feeds) - #327

Merged
luisleo526 merged 5 commits into
mainfrom
symfeeds/run-json-symbol-feeds
Oct 4, 2026
Merged

luisleo526 merged 5 commits into
mainfrom
symfeeds/run-json-symbol-feeds

Conversation

@luisleo526

@luisleo526 luisleo526 commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

What

docker/run_json.py gains --symbol-feeds <index.json>, and docker/entrypoint.sh maps PINEFORGE_SYMBOL_FEEDS to it. The flag installs other symbols' bars for request.security on another symbol. Engine and codegen have supported such requests since 1.0.0 (engine #292, codegen #146/#148). Until now the release harness had no way to hand them the bars, so every such run whose request value reaches an order stopped with exit 4 (request.security(...) at line N: no data is pinned for this request, and its value was read).

{"symbols": {"BINANCE:ETHUSDT": {"syminfo": {...the symbol's catalog object...},
                                 "feeds": {"240": "ethusdt-240.csv", "1D": "ethusdt-1D.csv"}}}}
  • Keys. A key is the exact string the script passes at run time, compared byte for byte by the engine (pine_security_eval.cpp:1031). BINANCE:ETHUSDT, ETHUSDT and BINANCE:ETHUSDT.P are three symbols. For input.symbol, the key is the input's value.
  • Feeds. One CSV per requested timeframe, in the chart's CSV format, with paths relative to the index. Timeframes use the engine's spelling: whole minutes as a bare integer ("240", never "4h"), else <n>D|W|M|S, and bare D/W/M/S fold to 1D/1W/1M/1S.
    • A bar's close is its open plus the timeframe, or the optional time_close column.
    • Bars before the chart's first bar are warm-up history.
  • Facts. From syminfo: type, timezone, session, currency and mintick are what syminfo.* reads inside the request. tickerid is set as the canonical fact, which no syminfo.* reads: inside the request syminfo.tickerid is always the key, and syminfo.ticker is the key after its last : (pine_security_eval.cpp:1089-1109).
  • Checked before any strategy state exists: the index, the spelling, CSV columns and numbers, increasing opens, each close after its open and at or before the next open, ±(2^53−1) ms, a positive finite mintick, at most 256 symbols and 256 feeds. Then a library without the setters, or a feed the engine refuses. Every refusal is one {"engine":"pineforge","error":"--symbol-feeds: ..."} line (harness exit 1, entrypoint exit 4).
  • Record. What was installed goes in applied_runtime.symbol_feeds: the facts, and per feed the bar count, first and last open, and a value hash under pf-symbol-feed-barc-close-le-v1. It is fingerprinted, so such a run has its own digest.
  • Unset, or {"symbols": {}}: the report is byte-identical, apart from elapsed_seconds.

The engine library and the C ABI are unchanged; the harness calls the existing strategy_set_symbol_facts and strategy_set_symbol_feed. Docs: docker/README.md ("Other symbols' bars": field, keys, spelling, the missing-feed error, refusals, limits, record), the entrypoint header and CHANGELOG.md (Unreleased, the 1.1.0 entry). The release repo's own entrypoint line is pineforge-4pass/pineforge-release#23.

One feed per requested timeframe (the 1m question)

The app asked whether a feed may be 1m bars for a request at 240 or D, with the harness or engine aggregating it. Answer: no, not in 1.1.0. Each requested timeframe needs its own feed.

  • No C call aggregates another symbol's bars, and none returns aggregated bars.
    • None of the 77 PF_API declarations in pineforge.h (62 implemented in the static runtime, the rest emitted per strategy), nor anything in native_c_api.h, takes raw bars and hands back aggregated ones.
    • strategy_set_symbol_feed copies the bars verbatim, keyed by (key, tf); the only change is folding D to 1D (pine_security_eval.cpp:1251-1294). The lookup is exact (:1031).
    • The kernel contract says the feed is "delivered bar for bar and aggregated by nothing" (native_run_spec.hpp:481-484, native_execution_consumer.cpp:8574-8600).
    • The one setter that aggregates, strategy_set_native_security_feed, works on the chart symbol's own daily feed (a W/M request reads it folded per week or month).
  • Where the chart aggregation lives. The chart's input→script fold is NativeExecutionConsumer::contribute_input (native_execution_consumer.cpp:8340-8400), aligned to session and timezone by native_calendar::interval_containing. It is hidden C++. The only C-reachable route to it is a whole native-kernel run per feed through the native-host API (strategy_native_host_create_v1 / strategy_configure_native_ext_v1 / strategy_native_run_v1 with an on_bar callback). That means mirroring four structs in ctypes and running a broker kernel just to bucket bars, so it is not taken. Per the brief, there is no second aggregator in Python either.
  • The engine refuses it for the chart too. Once a script requests another symbol, the chart must be its own input: input '1' aggregated to chart '240' is not supported (pine_security_eval.cpp:1045-1051). So an app that runs such a script already fetches the chart at the script timeframe, and can fetch the other symbols the same way.
  • Proposed for a later release (about 100 lines of engine code, about 220 with tests and docs): PF_API int pf_aggregate_bars_v1(bars, n, input_tf, target_tf, timezone, session, out_bars, out_close_ms, capacity). It runs the chart's own fold through a private NativeStrategyHost, so its output matches the chart path by construction. The harness would then accept a "1" feed and aggregate it with that call. The acceptance test is ready: the case below fed 1m bars must give the same 12 rows. On this window Binance's 4h and 1d klines equal the UTC aggregation of its 1m klines (E2E data check), so the test is well posed.

E2E (AWS spot box, c6a.2xlarge, ap-southeast-1): PASSED on 6cc8247 with release #23 head 3475b0c

The rebase onto main 7b59662 (#325) gives head 673e95b and leaves docker/ byte-identical: git diff 6cc82475 673e95b8 -- docker/ is empty, and both heads have the same docker/ tree 9c6ccaa1. Only the CHANGELOG bullet moved, to follow #325's. So these results hold for this head.

Two images from pineforge-release's docker/Dockerfile (engine 1.0.1 static library + codegen 1.0.1, the latest releases). run_json.py is synced from the engine commit, as scripts/sync-harness.sh does from a tag:

  • sf-pr: release PR head (its entrypoint) + this PR's run_json.py (sha256 afaa6952…, the same file as the prototype's final pass);
  • sf-main: release main + engine main's run_json.py.

The shared XSYM case (BTCUSDT 4h chart; input.symbol("BINANCE:ETHUSDT") requested at timeframe.period and at D), with check_case.py:

run result
feeds (ETHUSDT at 240 and 1D) exit 0, 12 rows, equal to the recorded rows and to the independent reference model (TradingView's merge rule); applied_runtime.symbol_feeds hashes recomputed from the CSVs: CASE PASSED
no_feeds exit 4, request.security(other, timeframe.period, ...) at line 7: no data is pinned for this request, and its value was read: PASSED
bare_key (keyed ETHUSDT) exit 4, the line-7 error: PASSED
no_daily (240 only) exit 4, the line-8 "D" error: PASSED
sol_input (input BINANCE:SOLUSDT) exit 4, the line-7 error: PASSED
"4h" timeframe in the index exit 4, one --symbol-feeds: a timeframe is whole minutes ... line: PASSED
sf-main with PINEFORGE_SYMBOL_FEEDS set ignored, exit 4 line-7 error (red on main, for the right reason)

The qty-step case (#322) is unchanged on sf-pr: 22 rows with mincontract, 27 without, with null and with no syminfo (its check_case.py PASSED ×4).

Scripts that request no other symbol give reports byte-identical to sf-main (elapsed_seconds zeroed): the four qty-step runs (digests sha256:b9e00cb9… with the grid, sha256:e4315ec2… without), the no_feeds error line, and a qty-step run with {"symbols": {}} set. applied_runtime has no symbol_feeds key without the variable. The 101 harness tests pass on the box (Linux).

The 1m question on the same case (same sf-pr image; Binance ETHUSDT and BTCUSDT 1m klines over the case window, 573,120 and 525,600 bars):

run result
ETHUSDT fed only as a 1 feed exit 4, request.security(other, timeframe.period, ...) at line 7: no data is pinned .... A 1m feed serves neither the 240 nor the D request
ETHUSDT fed as 1 plus 240 and 1D exit 0, the same 12 trades as the tf-fed run; the 1m feed is installed (573,120 bars in the record) and inert
chart fed 1m (PINEFORGE_INPUT_TF=1, PINEFORGE_SCRIPT_TF=240) with the tf feeds exit 4, request.security of another symbol needs the chart's own bars as input; input '1' aggregated to chart '240' is not supported
data check (kit only, not shipped) Binance's 4h and 1d klines equal the UTC aggregation of its 1m klines: 0 of 2,190 and 0 of 398 bars differ. A future pf_aggregate_bars_v1 fed 1m must therefore reproduce the 12 rows

Tests

  • docker/run_json_symbol_feeds_test.py (new, pytest): index and entry shapes, duplicate keys, timeframe spelling and folding, CSV columns, numbers, BOM, empty volume, time_close, monotonic opens and closes, caps, facts and mintick, setter order and arguments, refusal by the engine with its last error, a library without the setters, the record and its hash, main() with the report and fingerprint, the structured failure in the body run and in both bench loops, and no change without the flag. All 101 tests in docker/ pass on this head, on macOS and on Linux (the box). As with the older docker/*_test.py, nothing registers them with ctest or CI; they run with python3 -m pytest docker/.
  • Gate: the PR touches only docker/run_json.py, docker/run_json_symbol_feeds_test.py, docker/entrypoint.sh, docker/README.md and CHANGELOG.md, the release-harness category of rule no-behaviour-diff/v3. The six-step lab job rj-20261004t045310-66dd70 (preflight, release, debug, sanitizers, kernel, docs) runs on this exact head (tree 48100d11, 5 files since 7b59662: docs 2, release harness 3); pineforge/verify and pineforge/parity are posted from it via the diff rule. The pre-rebase head 6cc8247 passed the same gate (job rj-20261004t034744-44c80c).

🤖 Generated with Claude Code

luisleo526 and others added 5 commits October 4, 2026 12:51
docker/run_json.py --symbol-feeds (PINEFORGE_SYMBOL_FEEDS in the entrypoint)
reads a JSON index of other symbols' bars, keyed by the exact symbol string a
script passes to request.security and by timeframe, and installs each symbol's
catalog syminfo (tickerid as canonical, type, timezone, session, currency,
mintick) and feeds through strategy_set_symbol_facts and
strategy_set_symbol_feed, which engine and codegen have shipped since 1.0.0
but no release harness called. A feed is an OHLCV CSV like --ohlcv; each
bar's close is its open plus the timeframe unless a time_close column gives it.

Everything is checked before the first strategy state: timeframe spelling
(bare D/W/M/S folded, "4h" refused), one feed per timeframe, CSV columns and
numbers, increasing opens, closes at or before the next open, mintick, the
256-feed cap. A refusal, a library without the setters or a feed the engine
refuses is the structured {"engine","error"} line (harness exit 1, entrypoint
exit 4), like a rejected --syminfo. What was installed is recorded as
applied_runtime.symbol_feeds (facts, bar counts, first/last open, a value
hash), so such a run has its own fingerprint; without --symbol-feeds the
report is unchanged.

Stacked on harness/syminfo-mincontract (#322): it reuses that change's
structured-failure path in main().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Every refusal is the structured line, never a traceback: a feed that is not
  UTF-8 (or a CSV error), a time outside +-(2^53-1) ms or a monthly close
  outside the calendar, a mintick integer beyond binary64, a symbol or fact
  string with a lone surrogate, an index nested past the recursion limit.
- A header-only feed is installed without bars, as the engine documents it
  (its requests read na), instead of refused.
- An empty time_close cell falls back to open plus timeframe; a UTF-8 BOM is
  read; error line numbers are the CSV's own (blank lines counted).
- Install-time refusals carry the same "--symbol-feeds:" prefix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The harness README gains a limits bullet (256 symbols and 256 feeds, the chart
as its own input with the engine's exact error, historical runs only, the cost
of a feed, request.security_lower_tf) and states that a feed must be at the
timeframe it serves: the engine aggregates only the chart's own input and the
C ABI has no call that aggregates bars, so a 1m feed serves neither a 240 nor a
D request. The CHANGELOG entry says the same.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review fixes. Inside the request syminfo.tickerid is always the key and
syminfo.ticker the key after its last ":"; the catalog tickerid is set as the
canonical fact, which no syminfo.* reads. The no-aggregation bullet now says
why (the engine looks a feed up by exact symbol and timeframe and installs its
bars as given) instead of claiming no C call aggregates. The missing-feed
sentence covers an index that lacks the requested symbol or timeframe, and the
refusal list is marked as examples ("timestamps that do not strictly
increase").

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s one

After the rebase onto #325 the entry sat at the top of Unreleased; it now
follows #325's entry, as the merge order asks. Wording unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@luisleo526
luisleo526 force-pushed the symfeeds/run-json-symbol-feeds branch from 6cc8247 to 673e95b Compare October 4, 2026 04:52
@luisleo526
luisleo526 merged commit 4f2a475 into main Oct 4, 2026
17 checks passed
luisleo526 added a commit that referenced this pull request Oct 4, 2026
Brings the branch up to date with main 4f2a475 (#325 7b59662, #327
4f2a475) so the release notes merge last, as the merge order now asks.

Conflicts resolved neutrally; the next commit does the editing:
- CHANGELOG.md: this branch's 1.1.0 section, with main's two new
  Unreleased bullets ("Confirmed-bar streams compute what the batch
  computes:" from #325, "Harness symbol feeds:" from #327) kept verbatim
  inside it; main's "## Unreleased" heading and its older copies of the
  bullets this branch already rewrote are not taken.
- README.md: #325's known-issue lines replace this branch's
  "Known issue (v1.0.0, v1.0.1, v1.1.0)" line from a80485c.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
luisleo526 added a commit that referenced this pull request Oct 4, 2026
… rule

#325 (confirmed-bar streams compute what the batch computes) and #327
(docker/run_json.py --symbol-feeds) merged before the release notes, so
their Unreleased bullets join the 1.1.0 section, rewritten and linked; no
Unreleased heading stays.

- CHANGELOG.md: the lead names the stream fix and, in the pairing
  sentence, codegen 1.1.0's request discovery (transpile_full()["requests"],
  codegen #164). #325's bullet says what a stream user sees; #327's bullet
  and its Report keys entry (applied_runtime.symbol_feeds, the
  --symbol-feeds: failure messages). A new State hashes section lists the
  four recipe additions since v1.0.1 (#315, #316, #319, #325; none removed,
  renamed or re-encoded; domain tags unchanged). #315's range-end
  equity-extreme change moves to the Pine adapter parity bullet as a
  behaviour fix. The #319 bullet named the broker-state hash; the change is
  in the native continuation hash, which the broker-state hash folds. The
  known-issue bullet now says it is fixed in 1.1.0 (#325). Migration gains
  a line on stream results and hashes.
- README.md: the known issue is fixed in 1.1.0 (#325); the v1.1.0 Releases
  line gains the stream fix, request discovery and the harness's
  multi-symbol request.security feeds. Fact markers rendered from the facts
  export that maps releases[1.1.0] to
  pineforge-parity-baseline-20261004-engine-7b596622 (7,951 excellent / 38
  strong of 7,989); the active scoreboard moves to the same baseline, here
  and in docs/pages/contributing-llm.md.
- docs/pages/streaming.md: the known issue affected v1.0.0 and v1.0.1 and
  is fixed in 1.1.0.
- docs/pages/public-contract.md: the state-hash rule, amended by the
  owner's ruling for 1.1.0. It covers the recipe only: a minor release may
  add a hashed field (domain tags unchanged, the added field changing no
  trade or report, disclosed under State hashes); removing, renaming or
  re-encoding a hashed field is a new epoch and a major release; behaviour
  changes follow the normal release and parity rules. The first uses are
  #315 and #316. The semver rule is unchanged.

Replaces text introduced by 7b59662 (#325): CHANGELOG.md's
"Confirmed-bar streams compute what the batch computes:" bullet, and the
"Fixed on main (#325); included in the next release." lines of README.md
and streaming.md; by 4f2a475 (#327): CHANGELOG.md's "Harness symbol
feeds:" bullet; by d093560 (#290): public-contract.md's "State-hash
values are stable within the epoch." and "a new recipe is a new epoch and
a major release"; by a80485c (this branch's first commit): the "Known
issue, as in v1.0.0 and v1.0.1" bullet, streaming.md's "(v1.0.0, v1.0.1,
v1.1.0)", the #319 bullet's "A tick stream's broker-state hash folds the
new accumulator state only where it adds information, so the existing
tick, bar and batch hash pins hold.", the Report keys failure-output
bullet and the v1.1.0 Releases line; by 66be240 and 83d64dc: the lead's
state-hash sentences ("Three changes also change what the hashes fold");
and, as git attributes them through this branch's merge of main, by
e59c09f: README.md's v1.1.0 Releases line and streaming.md's
"(v1.0.0, v1.0.1, v1.1.0)".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@luisleo526
luisleo526 deleted the symfeeds/run-json-symbol-feeds branch October 4, 2026 05:45
luisleo526 added a commit that referenced this pull request Oct 4, 2026
* docs: release notes and version scoping for v1.1.0

v1.1.0 is a minor release: <pineforge/pineforge.h> declares six more
functions, the checked settings calls that a strategy generated by
pineforge-codegen 1.1.0 exports (#317). It pairs with pineforge-codegen
1.1.0. PF_ABI_VERSION stays 4 (pineforge.h only gains declarations;
native_c_api.h and the native C++ host headers are unchanged) and the
script ABI epoch stays engine_script_run_v19.

- CHANGELOG.md: "## Unreleased" becomes "## 1.1.0 — 2026-10-04": a lead
  paragraph, one bullet per change a user can observe since v1.0.1
  (#312-#324), each linking its PR, a Report keys subsection
  (docker/run_json.py v1.0.1 -> v1.1.0) and a Migration subsection. The
  three Unreleased bullets stay; the lot-grid bullet now gives both
  failure messages.
- README.md: pineforge-codegen==1.1.0, the v1.1.0 tarballs, the pairing
  sentence, the stream known issue's scope, the benchmark refresh line,
  the release scoreboard sentence (releases[1.1.0] markers) and a v1.1.0
  line in Releases. The public corpus sweep's "311 excellent + 1 declared
  anomaly" is scoped to the v1.0.1 library it was measured on. Facts
  rendered from the facts file that adds releases[1.1.0]; the active
  scoreboard markers move to baseline
  pineforge-parity-baseline-20261003-engine-dbd17b38.
- docs/pages/install.md: the v1.1.0 tarballs and the hub tag
  engine1.1.0-codegen1.1.0.
- docs/pages/public-contract.md: 1.1.0's release line, engine v1.1.0 with
  codegen 1.1.0 among the supported pairs, and the four C-boundary rows
  that were planned for 1.1.0 are not in it.
- docs/pages/streaming.md: the known issue's scope includes v1.1.0.

Lines that state what an earlier version shipped or did stay.

Replaces text introduced by dc74e63 (#318): README.md's "Release 1.0.1
still grades ... until the next release" sentence, now 1.1.0's; by
d093560 (#290): public-contract.md's "Four of its rows are planned for
1.1.0"; by 783bb39 (#322): CHANGELOG.md's "The engine library is
unchanged."; by dbd17b3 (#320): CHANGELOG.md's "The engine is
unchanged."; by b2a578c (#300): README.md's "this repository's sweep:
311 excellent + 1 declared anomaly"; by 271d687 (#311): README.md's
"its releases 1.0.0 and 1.0.1 do".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: state the 1.1.0 hash folds and scope two runner sentences

The 1.1.0 lead now says how state-hash values change while the epoch and
the domain tags stay: a run whose fills an adapter change alters hashes
to new values, and three changes fold more state, so a run can hash
differently from 1.0.1 with byte-identical trades: #315 (an unbatched
same-bar entry request and placement; the stream report's terminal
re-mark leaves the hashed extremes; witness row Stream/0/1 re-pinned),
#316 (an opening stop's next waypoint; Random44/0/0 and /1 re-pinned)
and #319 (tick-volume state, every existing pin kept).

In the runner tooling bullet, "No versioned engine PF_API export ...
changes" and "Plugin-free ledger identity bytes remain unchanged" read
as release-wide; they now speak for #320 itself and for a strategy
without the checked settings calls. The Report keys intro points at the
report schema page. The terminal-quote bullet names the chart feed that
PINEFORGE_RUN_REPORT_CHART_QUOTE points at, and two runner bullet
headings are re-wrapped.

Replaces text introduced by a80485c (this branch's first commit): the
lead's "A run whose fills one of the Pine adapter changes below alters
hashes to new values, and [#316] adds one placement field to the
adapter's hashed state, for which two witnesses with byte-identical
trades were re-pinned.", the Report keys intro and the terminal-quote
harness clause; and text introduced by dbd17b3 (#320): "No versioned
engine PF_API export, native C++ surface, script ABI epoch or engine
behavior changes." and "Plugin-free ledger identity bytes remain
unchanged".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: #315's range-end change folds less, not more

The 1.1.0 lead said three changes "fold more state"; #315's range-end
change instead stops folding a stream report's terminal re-mark into the
hashed extremes. The sentence now says the three changes change what the
hashes fold, and names Stream/0/1 as a re-pinned witness row without
claiming it is #315's only one.

Replaces text introduced by 66be240 (this branch's second commit): "Three
changes also fold more state" and "re-pinning one witness row
(`Stream/0/1`, whose recorded-row digest alone moves)".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: fold #325 and #327 into 1.1.0, add State hashes, amend the hash rule

#325 (confirmed-bar streams compute what the batch computes) and #327
(docker/run_json.py --symbol-feeds) merged before the release notes, so
their Unreleased bullets join the 1.1.0 section, rewritten and linked; no
Unreleased heading stays.

- CHANGELOG.md: the lead names the stream fix and, in the pairing
  sentence, codegen 1.1.0's request discovery (transpile_full()["requests"],
  codegen #164). #325's bullet says what a stream user sees; #327's bullet
  and its Report keys entry (applied_runtime.symbol_feeds, the
  --symbol-feeds: failure messages). A new State hashes section lists the
  four recipe additions since v1.0.1 (#315, #316, #319, #325; none removed,
  renamed or re-encoded; domain tags unchanged). #315's range-end
  equity-extreme change moves to the Pine adapter parity bullet as a
  behaviour fix. The #319 bullet named the broker-state hash; the change is
  in the native continuation hash, which the broker-state hash folds. The
  known-issue bullet now says it is fixed in 1.1.0 (#325). Migration gains
  a line on stream results and hashes.
- README.md: the known issue is fixed in 1.1.0 (#325); the v1.1.0 Releases
  line gains the stream fix, request discovery and the harness's
  multi-symbol request.security feeds. Fact markers rendered from the facts
  export that maps releases[1.1.0] to
  pineforge-parity-baseline-20261004-engine-7b596622 (7,951 excellent / 38
  strong of 7,989); the active scoreboard moves to the same baseline, here
  and in docs/pages/contributing-llm.md.
- docs/pages/streaming.md: the known issue affected v1.0.0 and v1.0.1 and
  is fixed in 1.1.0.
- docs/pages/public-contract.md: the state-hash rule, amended by the
  owner's ruling for 1.1.0. It covers the recipe only: a minor release may
  add a hashed field (domain tags unchanged, the added field changing no
  trade or report, disclosed under State hashes); removing, renaming or
  re-encoding a hashed field is a new epoch and a major release; behaviour
  changes follow the normal release and parity rules. The first uses are
  #315 and #316. The semver rule is unchanged.

Replaces text introduced by 7b59662 (#325): CHANGELOG.md's
"Confirmed-bar streams compute what the batch computes:" bullet, and the
"Fixed on main (#325); included in the next release." lines of README.md
and streaming.md; by 4f2a475 (#327): CHANGELOG.md's "Harness symbol
feeds:" bullet; by d093560 (#290): public-contract.md's "State-hash
values are stable within the epoch." and "a new recipe is a new epoch and
a major release"; by a80485c (this branch's first commit): the "Known
issue, as in v1.0.0 and v1.0.1" bullet, streaming.md's "(v1.0.0, v1.0.1,
v1.1.0)", the #319 bullet's "A tick stream's broker-state hash folds the
new accumulator state only where it adds information, so the existing
tick, bar and batch hash pins hold.", the Report keys failure-output
bullet and the v1.1.0 Releases line; by 66be240 and 83d64dc: the lead's
state-hash sentences ("Three changes also change what the hashes fold");
and, as git attributes them through this branch's merge of main, by
e59c09f: README.md's v1.1.0 Releases line and streaming.md's
"(v1.0.0, v1.0.1, v1.1.0)".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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