P3-DATA-ENGINE-002: Data Engine v1 implementation + qualification suite (QUALIFIED)
Implements the frozen P3_DATA_ENGINE_V1_SPEC (SHA 84bf0f217ffba51197112a6bbacbcc297058e04b5ca47f0459028fe33e0321e5).
Components: engine/ producer (certify, chunkmap, parse, canonical, worker,
dispatcher, aggregate, storage, journal, checkpoint, lock, evidence, manifest,
run_complete, dataset_builder, cli) + engine/verify independent verifier
(vparse, vaggregate, vinvariants, vcompare); headless CLI sniper-data; golden
corpus G01-G17; unit/property/adversarial/mutation/legacy-diff/CLI suites.
Qualification verdict: QUALIFIED (all 9 mandatory gates pass; independent
verifier accepted). Spec, governance record, and legacy checkpoint untouched.
G-14 NOT AUTHORIZED honored; no real-data processing, no pilot, no workload 46,
no chunk 760 access.
2026-09-07 14:15:25 +07:00 | | | """Producer parser: raw chunk bytes -> canonical ticks + malformed sidecars.
|
| | |
|
| | | Deterministic CSV interpretation per spec 8.1–8.3. Integer arithmetic only.
|
| | | This module is one of two independent parsing implementations that exist in
|
| | | the engine (the other is engine/verify/vparse.py); they must agree on every
|
| | | canonical row.
|
| | | """
|
| | |
|
| | | from . import versions
|
| | | from .util import (
|
| | | parse_timestamp_dotted,
|
 P3-DATA-ENGINE-004: source-grammar correction + re-qualification (QUALIFIED) - spec 1.1.0 controlled amendment (Appendix C): G_TICKSTORY_MT5 six-col YYYYMMDD,HH:MM:SS,bid,ask,last,volume; compact timestamp; mandatory volume; last preserved via source-preservation sidecar (spec 8.6; CTS_V1 unchanged; G-4/G-5 intact); SHA effbaf2624cd46137c22a246fdabff4067052807b6b6224be464366bec4745d9 (machine-verified) - implementation: grammar registry, source_grammar config identity + fail-closed validation, compact timestamp parse, _parse_chunk_tickstory, preservation serialization + sidecars, certificate grammar_id + compact sniffing, init cert/config mismatch BLOCK, independent verifier v_parse_chunk_tickstory + preservation ids, evidence + verify_dataset preservation checks; ENGINE_VERSION 1.1.0, PARSER_V1.1 - CLI defect repair: status/resume on run-less dir exit 4 BLOCKED without traceback (P3-DE-003 NEW_ENGINE_DEFECT) + regression tests - qualification: unit, golden G01-G17, SG01-SG15 + e2e, property, adversarial, mutation 8/8, independent verifier dataset+run-complete ACCEPTED, legacy diff 0 unresolved legacy untouched, dataset-builder determinism, CLI E2E; VERDICT QUALIFIED - G-14 unchanged BLOCKED/NOT AUTHORIZED; no real-data ingestion; no workload 46; no chunk 760+; legacy checkpoint 759/18442355762 untouched
2026-09-07 17:34:57 +07:00 | | | parse_compact_datetime,
|
P3-DATA-ENGINE-002: Data Engine v1 implementation + qualification suite (QUALIFIED)
Implements the frozen P3_DATA_ENGINE_V1_SPEC (SHA 84bf0f217ffba51197112a6bbacbcc297058e04b5ca47f0459028fe33e0321e5).
Components: engine/ producer (certify, chunkmap, parse, canonical, worker,
dispatcher, aggregate, storage, journal, checkpoint, lock, evidence, manifest,
run_complete, dataset_builder, cli) + engine/verify independent verifier
(vparse, vaggregate, vinvariants, vcompare); headless CLI sniper-data; golden
corpus G01-G17; unit/property/adversarial/mutation/legacy-diff/CLI suites.
Qualification verdict: QUALIFIED (all 9 mandatory gates pass; independent
verifier accepted). Spec, governance record, and legacy checkpoint untouched.
G-14 NOT AUTHORIZED honored; no real-data processing, no pilot, no workload 46,
no chunk 760 access.
2026-09-07 14:15:25 +07:00 | | | apply_tz_offset,
|
| | | in_ts_valid_window,
|
| | | parse_price_to_micro,
|
| | | parse_volume_token,
|
| | | sha256_bytes,
|
| | | )
|
| | |
|
| | | MALFORMED_EMPTY_LINE = "MALFORMED_EMPTY_LINE"
|
| | | MALFORMED_ENCODING = "MALFORMED_ENCODING"
|
| | | MALFORMED_FIELD_COUNT = "MALFORMED_FIELD_COUNT"
|
| | | MALFORMED_TIMESTAMP_PARSE = "MALFORMED_TIMESTAMP_PARSE"
|
| | | MALFORMED_TIMESTAMP_RANGE = "MALFORMED_TIMESTAMP_RANGE"
|
| | | MALFORMED_PRICE_PARSE = "MALFORMED_PRICE_PARSE"
|
| | | MALFORMED_PRICE_PRECISION = "MALFORMED_PRICE_PRECISION"
|
| | | MALFORMED_PRICE_NONPOSITIVE = "MALFORMED_PRICE_NONPOSITIVE"
|
| | | MALFORMED_BID_ASK_RELATION = "MALFORMED_BID_ASK_RELATION"
|
| | | MALFORMED_VOLUME = "MALFORMED_VOLUME"
|
| | | MALFORMED_DUPLICATE = "MALFORMED_DUPLICATE"
|
| | | MALFORMED_NON_MONOTONIC = "MALFORMED_NON_MONOTONIC"
|
| | | MALFORMED_NON_MONOTONIC_BOUNDARY = "MALFORMED_NON_MONOTONIC_BOUNDARY"
|
| | |
|
| | | ALL_MALFORMED_CLASSES = [
|
| | | MALFORMED_EMPTY_LINE, MALFORMED_ENCODING, MALFORMED_FIELD_COUNT,
|
| | | MALFORMED_TIMESTAMP_PARSE, MALFORMED_TIMESTAMP_RANGE,
|
| | | MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION,
|
| | | MALFORMED_PRICE_NONPOSITIVE, MALFORMED_BID_ASK_RELATION,
|
| | | MALFORMED_VOLUME, MALFORMED_DUPLICATE, MALFORMED_NON_MONOTONIC,
|
| | | MALFORMED_NON_MONOTONIC_BOUNDARY,
|
| | | ]
|
| | |
|
| | | _HEADER_RE_PREFIX = ("datetime", "date", "time")
|
| | |
|
| | |
|
| | | def header_keyword(first_field):
|
| | | """Header detection rule (spec 8.1): first field starts with
|
| | | datetime|date|time followed by a non-digit or end of string, case-insensitive."""
|
| | | low = first_field.lower()
|
| | | for kw in _HEADER_RE_PREFIX:
|
| | | if low.startswith(kw):
|
| | | rest = low[len(kw):]
|
| | | if rest == "" or not rest[0].isdigit():
|
| | | return True
|
| | | return False
|
| | |
|
| | |
|
| | | def split_lines(data):
|
| | | """Deterministic byte-level line splitter.
|
| | |
|
| | | Yields (line_bytes_without_terminator, terminator_len). Terminators are
|
| | | recognized in order: b"\\r\\n" (2), b"\\n" (1), b"\\r" (1). A trailing
|
| | | unterminated line yields terminator_len 0.
|
| | | """
|
| | | start = 0
|
| | | n = len(data)
|
| | | i = 0
|
| | | while i < n:
|
| | | b = data[i]
|
| | | if b == 0x0A: # \n
|
| | | yield data[start:i], 1
|
| | | i += 1
|
| | | start = i
|
| | | elif b == 0x0D: # \r
|
| | | j = i + 1
|
| | | if j < n and data[j] == 0x0A: # \r\n
|
| | | yield data[start:i], 2
|
| | | i = j + 1
|
| | | else:
|
| | | yield data[start:i], 1
|
| | | i = j
|
| | | start = i
|
| | | else:
|
| | | i += 1
|
| | | if start < n:
|
| | | yield data[start:], 0
|
| | |
|
| | |
|
| | | def empty_malformed_counter():
|
| | | return {cls: 0 for cls in ALL_MALFORMED_CLASSES}
|
| | |
|
| | |
|
| | | def parse_chunk(data, *, chunk_index, byte_start, global_line_start, cfg,
|
| | | expect_header, certify_time_ms):
|
| | | """Parse one chunk's byte range into canonical records + malformed sidecars.
|
| | |
|
| | | Returns (records, malformed, counters, flags) where:
|
| | | records: list of (ts_ms, bid_u, ask_u, spread_u, vol, src_line, rec_ord)
|
| | | malformed: list of sidecar dicts per malformed row
|
| | | counters: dict class -> count
|
| | | flags: dict with keys has_header (bool), rows_parsed (int)
|
| | |
|
| | | ``global_line_start`` is the 0-based raw line offset of this chunk's first
|
| | | line; ``byte_start`` is the 0-based file offset. cert_time is the UTC
|
| | | reference used for the timestamp validity window.
|
| | | """
|
 P3-DATA-ENGINE-004: source-grammar correction + re-qualification (QUALIFIED) - spec 1.1.0 controlled amendment (Appendix C): G_TICKSTORY_MT5 six-col YYYYMMDD,HH:MM:SS,bid,ask,last,volume; compact timestamp; mandatory volume; last preserved via source-preservation sidecar (spec 8.6; CTS_V1 unchanged; G-4/G-5 intact); SHA effbaf2624cd46137c22a246fdabff4067052807b6b6224be464366bec4745d9 (machine-verified) - implementation: grammar registry, source_grammar config identity + fail-closed validation, compact timestamp parse, _parse_chunk_tickstory, preservation serialization + sidecars, certificate grammar_id + compact sniffing, init cert/config mismatch BLOCK, independent verifier v_parse_chunk_tickstory + preservation ids, evidence + verify_dataset preservation checks; ENGINE_VERSION 1.1.0, PARSER_V1.1 - CLI defect repair: status/resume on run-less dir exit 4 BLOCKED without traceback (P3-DE-003 NEW_ENGINE_DEFECT) + regression tests - qualification: unit, golden G01-G17, SG01-SG15 + e2e, property, adversarial, mutation 8/8, independent verifier dataset+run-complete ACCEPTED, legacy diff 0 unresolved legacy untouched, dataset-builder determinism, CLI E2E; VERDICT QUALIFIED - G-14 unchanged BLOCKED/NOT AUTHORIZED; no real-data ingestion; no workload 46; no chunk 760+; legacy checkpoint 759/18442355762 untouched
2026-09-07 17:34:57 +07:00 | | | grammar = cfg.get("source_grammar", versions.GRAMMAR_DOTTED)
|
| | | if grammar == versions.GRAMMAR_TICKSTORY_MT5:
|
| | | return _parse_chunk_tickstory(
|
| | | data, chunk_index=chunk_index, byte_start=byte_start,
|
| | | global_line_start=global_line_start, cfg=cfg,
|
| | | expect_header=expect_header, certify_time_ms=certify_time_ms)
|
P3-DATA-ENGINE-002: Data Engine v1 implementation + qualification suite (QUALIFIED)
Implements the frozen P3_DATA_ENGINE_V1_SPEC (SHA 84bf0f217ffba51197112a6bbacbcc297058e04b5ca47f0459028fe33e0321e5).
Components: engine/ producer (certify, chunkmap, parse, canonical, worker,
dispatcher, aggregate, storage, journal, checkpoint, lock, evidence, manifest,
run_complete, dataset_builder, cli) + engine/verify independent verifier
(vparse, vaggregate, vinvariants, vcompare); headless CLI sniper-data; golden
corpus G01-G17; unit/property/adversarial/mutation/legacy-diff/CLI suites.
Qualification verdict: QUALIFIED (all 9 mandatory gates pass; independent
verifier accepted). Spec, governance record, and legacy checkpoint untouched.
G-14 NOT AUTHORIZED honored; no real-data processing, no pilot, no workload 46,
no chunk 760 access.
2026-09-07 14:15:25 +07:00 | | | counters = empty_malformed_counter()
|
| | | malformed = []
|
| | | records = []
|
| | | rec_ord = 0
|
| | | prev_ts = None
|
| | | seen = set()
|
| | | duplicate_cap = versions.DUPLICATE_TRACKER_CAP
|
| | | expect_header = bool(expect_header)
|
| | | has_header = False
|
| | | rows_parsed = 0
|
| | | global_line = global_line_start # 0-based; first raw line -> +1 below
|
| | | expected_fields = 4 if cfg["has_volume"] else 3
|
| | |
|
| | | def reject(cls, reason, raw_bytes):
|
| | | counters[cls] += 1
|
| | | malformed.append({
|
| | | "chunk_index": chunk_index,
|
| | | "byte_start": byte_start,
|
| | | "global_line_no": global_line + 1,
|
| | | "class": cls,
|
| | | "raw_sha256": sha256_bytes(raw_bytes),
|
| | | "reason": reason,
|
| | | })
|
| | |
|
| | | for line_bytes, _term in split_lines(data):
|
| | | global_line += 1
|
| | | # Blank line -> MALFORMED_EMPTY_LINE (expected class), no parse.
|
| | | if not line_bytes:
|
| | | counters[MALFORMED_EMPTY_LINE] += 1
|
| | | continue
|
| | | rows_parsed += 1
|
| | | # UTF-8 decode (BOM was stripped upstream for chunk 0).
|
| | | try:
|
| | | text = line_bytes.decode("utf-8")
|
| | | except UnicodeDecodeError:
|
| | | reject(MALFORMED_ENCODING, "undecodable utf-8 bytes", line_bytes)
|
| | | continue
|
| | | if expect_header and not has_header:
|
| | | first_field = text.split(",", 1)[0]
|
| | | if header_keyword(first_field):
|
| | | has_header = True
|
| | | continue
|
| | | fields = text.split(",")
|
| | | if len(fields) != expected_fields:
|
| | | reject(MALFORMED_FIELD_COUNT,
|
| | | "field count %d expected %d" % (len(fields), expected_fields),
|
| | | line_bytes)
|
| | | continue
|
| | | t_field = fields[0]
|
| | | ts_wall, err = parse_timestamp_dotted(t_field)
|
| | | if err is not None:
|
| | | reject(MALFORMED_TIMESTAMP_PARSE, err, line_bytes)
|
| | | continue
|
| | | ts_ms = apply_tz_offset(ts_wall, cfg["source_tz_offset_minutes"])
|
| | | if not in_ts_valid_window(ts_ms, certify_time_ms):
|
| | | reject(MALFORMED_TIMESTAMP_RANGE, "ts outside validity window", line_bytes)
|
| | | continue
|
| | | bid_u, perr = parse_price_to_micro(fields[1], versions.PRICE_SCALE)
|
| | | if perr in (MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION):
|
| | | reject(perr, "bid token invalid: %r" % fields[1], line_bytes)
|
| | | continue
|
| | | ask_u, aerr = parse_price_to_micro(fields[2], versions.PRICE_SCALE)
|
| | | if aerr in (MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION):
|
| | | reject(aerr, "ask token invalid: %r" % fields[2], line_bytes)
|
| | | continue
|
| | | if bid_u <= 0 or ask_u <= 0:
|
| | | reject(MALFORMED_PRICE_NONPOSITIVE, "bid/ask must be > 0", line_bytes)
|
| | | continue
|
| | | if ask_u < bid_u:
|
| | | reject(MALFORMED_BID_ASK_RELATION, "ask < bid", line_bytes)
|
| | | continue
|
| | | if cfg["has_volume"]:
|
| | | vol, verr = parse_volume_token(fields[3])
|
| | | if verr is not None:
|
| | | reject(MALFORMED_VOLUME, "volume token invalid: %r" % fields[3], line_bytes)
|
| | | continue
|
| | | else:
|
| | | vol = 1
|
| | | spread_u = ask_u - bid_u
|
| | | key = (ts_ms, bid_u, ask_u, vol)
|
| | | if key in seen:
|
| | | reject(MALFORMED_DUPLICATE, "exact duplicate within chunk", line_bytes)
|
| | | continue
|
| | | if len(seen) < duplicate_cap:
|
| | | seen.add(key)
|
| | | if prev_ts is not None and ts_ms < prev_ts:
|
| | | reject(MALFORMED_NON_MONOTONIC, "ts regression within chunk", line_bytes)
|
| | | continue
|
| | | prev_ts = ts_ms
|
| | | records.append((ts_ms, bid_u, ask_u, spread_u, vol, global_line, rec_ord))
|
| | | rec_ord += 1
|
| | |
|
| | | flags = {"has_header": has_header, "rows_parsed": rows_parsed}
|
 P3-DATA-ENGINE-004: source-grammar correction + re-qualification (QUALIFIED) - spec 1.1.0 controlled amendment (Appendix C): G_TICKSTORY_MT5 six-col YYYYMMDD,HH:MM:SS,bid,ask,last,volume; compact timestamp; mandatory volume; last preserved via source-preservation sidecar (spec 8.6; CTS_V1 unchanged; G-4/G-5 intact); SHA effbaf2624cd46137c22a246fdabff4067052807b6b6224be464366bec4745d9 (machine-verified) - implementation: grammar registry, source_grammar config identity + fail-closed validation, compact timestamp parse, _parse_chunk_tickstory, preservation serialization + sidecars, certificate grammar_id + compact sniffing, init cert/config mismatch BLOCK, independent verifier v_parse_chunk_tickstory + preservation ids, evidence + verify_dataset preservation checks; ENGINE_VERSION 1.1.0, PARSER_V1.1 - CLI defect repair: status/resume on run-less dir exit 4 BLOCKED without traceback (P3-DE-003 NEW_ENGINE_DEFECT) + regression tests - qualification: unit, golden G01-G17, SG01-SG15 + e2e, property, adversarial, mutation 8/8, independent verifier dataset+run-complete ACCEPTED, legacy diff 0 unresolved legacy untouched, dataset-builder determinism, CLI E2E; VERDICT QUALIFIED - G-14 unchanged BLOCKED/NOT AUTHORIZED; no real-data ingestion; no workload 46; no chunk 760+; legacy checkpoint 759/18442355762 untouched
2026-09-07 17:34:57 +07:00 | | | return records, malformed, counters, flags
|
| | |
|
| | |
|
| | | def _parse_chunk_tickstory(data, *, chunk_index, byte_start, global_line_start,
|
| | | cfg, expect_header, certify_time_ms):
|
| | | """G_TICKSTORY_MT5 six-column parse (P3-DATA-ENGINE-004 spec 8.1/8.2/8.6).
|
| | |
|
| | | Grammar (derived from the authoritative pilot evidence): exactly six
|
| | | comma-separated fields ``YYYYMMDD,HH:MM:SS,bid,ask,last,volume``; a line
|
| | | with any other field count is MALFORMED_FIELD_COUNT.
|
| | | - date ``YYYYMMDD`` + time ``HH:MM:SS`` (seconds only) -> integer epoch
|
| | | ms UTC via deterministic civil math, then tz-offset applied
|
| | | - bid / ask / last: decimal prices to micro-units (PRICE_SCALE); their
|
| | | token grammar is identical to the dotted preset
|
| | | - bid_u > 0, ask_u > 0 (MALFORMED_PRICE_NONPOSITIVE), ask_u >= bid_u
|
| | | (MALFORMED_BID_ASK_RELATION; mandatory)
|
| | | - volume: non-negative integer token; 0 is VALID (observed in the real
|
| | | source); negative/non-integer -> MALFORMED_VOLUME
|
| | | ``last`` is validated here but is deliberately NOT part of CTS_V1; it is
|
| | | returned in ``flags["last_u"]`` (aligned with records in rec_ord order)
|
| | | for the source-preservation layer (spec 8.6).
|
| | | """
|
| | | counters = empty_malformed_counter()
|
| | | malformed = []
|
| | | records = []
|
| | | last_values = []
|
| | | rec_ord = 0
|
| | | prev_ts = None
|
| | | seen = set()
|
| | | duplicate_cap = versions.DUPLICATE_TRACKER_CAP
|
| | | expect_header = bool(expect_header)
|
| | | has_header = False
|
| | | rows_parsed = 0
|
| | | global_line = global_line_start
|
| | |
|
| | | def reject(cls, reason, raw_bytes):
|
| | | counters[cls] += 1
|
| | | malformed.append({
|
| | | "chunk_index": chunk_index,
|
| | | "byte_start": byte_start,
|
| | | "global_line_no": global_line + 1,
|
| | | "class": cls,
|
| | | "raw_sha256": sha256_bytes(raw_bytes),
|
| | | "reason": reason,
|
| | | })
|
| | |
|
| | | for line_bytes, _term in split_lines(data):
|
| | | global_line += 1
|
| | | if not line_bytes:
|
| | | counters[MALFORMED_EMPTY_LINE] += 1
|
| | | continue
|
| | | rows_parsed += 1
|
| | | try:
|
| | | text = line_bytes.decode("utf-8")
|
| | | except UnicodeDecodeError:
|
| | | reject(MALFORMED_ENCODING, "undecodable utf-8 bytes", line_bytes)
|
| | | continue
|
| | | if expect_header and not has_header:
|
| | | first_field = text.split(",", 1)[0]
|
| | | if header_keyword(first_field):
|
| | | has_header = True
|
| | | continue
|
| | | fields = text.split(",")
|
| | | if len(fields) != 6:
|
| | | reject(MALFORMED_FIELD_COUNT,
|
| | | "field count %d expected 6" % len(fields), line_bytes)
|
| | | continue
|
| | | ts_wall, err = parse_compact_datetime(fields[0], fields[1])
|
| | | if err is not None:
|
| | | reject(MALFORMED_TIMESTAMP_PARSE, err, line_bytes)
|
| | | continue
|
| | | ts_ms = apply_tz_offset(ts_wall, cfg["source_tz_offset_minutes"])
|
| | | if not in_ts_valid_window(ts_ms, certify_time_ms):
|
| | | reject(MALFORMED_TIMESTAMP_RANGE, "ts outside validity window", line_bytes)
|
| | | continue
|
| | | bid_u, perr = parse_price_to_micro(fields[2], versions.PRICE_SCALE)
|
| | | if perr in (MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION):
|
| | | reject(perr, "bid token invalid: %r" % fields[2], line_bytes)
|
| | | continue
|
| | | ask_u, aerr = parse_price_to_micro(fields[3], versions.PRICE_SCALE)
|
| | | if aerr in (MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION):
|
| | | reject(aerr, "ask token invalid: %r" % fields[3], line_bytes)
|
| | | continue
|
| | | last_u, lerr = parse_price_to_micro(fields[4], versions.PRICE_SCALE)
|
| | | if lerr in (MALFORMED_PRICE_PARSE, MALFORMED_PRICE_PRECISION):
|
| | | reject(lerr, "last token invalid: %r" % fields[4], line_bytes)
|
| | | continue
|
| | | if bid_u <= 0 or ask_u <= 0 or last_u <= 0:
|
| | | reject(MALFORMED_PRICE_NONPOSITIVE, "bid/ask/last must be > 0", line_bytes)
|
| | | continue
|
| | | if ask_u < bid_u:
|
| | | reject(MALFORMED_BID_ASK_RELATION, "ask < bid", line_bytes)
|
| | | continue
|
| | | vol, verr = parse_volume_token(fields[5])
|
| | | if verr is not None:
|
| | | reject(MALFORMED_VOLUME, "volume token invalid: %r" % fields[5], line_bytes)
|
| | | continue
|
| | | spread_u = ask_u - bid_u
|
| | | key = (ts_ms, bid_u, ask_u, vol)
|
| | | if key in seen:
|
| | | reject(MALFORMED_DUPLICATE, "exact duplicate within chunk", line_bytes)
|
| | | continue
|
| | | if len(seen) < duplicate_cap:
|
| | | seen.add(key)
|
| | | if prev_ts is not None and ts_ms < prev_ts:
|
| | | reject(MALFORMED_NON_MONOTONIC, "ts regression within chunk", line_bytes)
|
| | | continue
|
| | | prev_ts = ts_ms
|
| | | records.append((ts_ms, bid_u, ask_u, spread_u, vol, global_line, rec_ord))
|
| | | last_values.append(last_u)
|
| | | rec_ord += 1
|
| | |
|
| | | flags = {"has_header": has_header, "rows_parsed": rows_parsed,
|
| | | "last_u": last_values}
|
| | | return records, malformed, counters, flags
|
| | |
|