Skip to main content

project-journal-compatibility

Mandatory compatibility rules when changing journal file readers, writers, fixtures, conformance tests, interoperability tests, or journalctl rewrites.

معلومات المصدر

المستودع
netdata/systemd-journal-sdk
آخر نشاط في المصدر
٢٦ أكتوبر ٢٠٢٦ في ١٠:٣٠
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٠
التفرعات
١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
project-journal-compatibility
description
Mandatory compatibility rules when changing journal file readers, writers, fixtures, conformance tests, interoperability tests, or journalctl rewrites.
# Project Journal Compatibility ## Purpose Keep all implementations aligned with the systemd journal file format, Netdata Rust reader/writer sources, and the project scope decisions. ## Scope Use this skill when: - importing or adapting Rust journal code; - implementing journal readers or writers in Rust or Go; - porting systemd tests or fixtures; - building shared interoperability tests; - implementing journalctl rewrites. Do not use this skill for: - pure repository bootstrap work; - generic SOW maintenance unrelated to journal behavior. ## Mandatory Knowledge - SDK journal-format compatibility targets `systemd/systemd` tag `v260.1`. - The portable file-backed journalctl contract targets tag `v262` (8cc40e0c5e9234bf45084751ac53b1fbfe70b492). Run the pinned full-feature oracle; host versions and feature-limited builds cannot certify this target. Query-matrix qualification requires `--journalctl PATH`; every helper must use that selected oracle, including version reporting and empty-result cases. - Native PCRE2-8 >=10.42 is CLI-private. Enable CGO only for Go CLI builds and tests; retain CGO-disabled SDK checks. Declare the C compiler, pkg-config and PCRE2 development prerequisites in command-inclusive coverage/CI. - File-backed CLIs preserve native Unix path bytes through selection, facade opening and discovery. File patterns use platform globbing with a temporary thread-local environment locale; literal paths bypass expansion. Windows uses Unicode paths and brace/wildcard selection. Keep these native calls in CLI modules and retain pure SDK checks. Test replacement-named decoys and locale-sensitive patterns against the pinned oracle, with portable Unicode controls in native OS CI. - Color parity includes policy/environment selection, priority and audit styles, PCRE2 first-match offsets, multiline preparation, verbose fields, JSON primitives, separators and table headers. Compare ANSI bytes as well as visible content; normalize JSON key order without discarding its styles. Retain buffered match offsets without a second regex evaluation and keep color-only work off the plain-output path. - Parser recognition is insufficient. Compare encounter order and terminal actions, raw required values, empty-versus-absent options, final-action scope, timestamps/DST/TZif state, binary MESSAGE behavior, status and complete output. Check calendar rendering independently from bound parsing: POSIX TZ, custom TZDIR, leap records, transition-free footers and malformed-rule fallback must agree in entry output, headers and tables. Omitted DST dates must exercise the configured posixrules file, absent-file defaults and transition flags; provider defaults alone do not establish native parity. Preserve raw epoch widths and lazily resolve rendering zones once, without per-row file reads or zone allocation. Do not let intentional follow termination hide a child failure or a blocked stdout pipe. Retain native exit status and drain large backlogs to files. - Use native OS jobs for commands with native dependencies. A CGO-disabled cross-build of the SDK does not establish native CLI portability. - Audit complete CLI selector components after a verified mismatch. Unit show groups and invocation-discovery groups differ; test naming/glob boundaries, raw field bytes, current-user conversion, ID precedence, global bounds, directional limits, secondary-ID offsets and frozen follow selection. Compare supplied oracle binaries explicitly, including live command builders. Exercise platform fallback matchers on the primary test host. FreeBSD unit brackets need the shared CLI compatibility matcher: native fnmatch lacks named classes and collating elements. Validate malformed brackets as well as positive matches, multibyte-to-byte retry, and native OS execution. Keep ordinary patterns on native fnmatch without compatibility allocations. Use indexed eligibility and metadata getters; do not expand unrelated message payloads. - The test scope is SDK conformance plus file-backed journalctl behavior. - Do not implement daemon-only journalctl commands such as daemon sync, flush, rotate, or relinquish-var operations. - journalctl already treats repeated matches for the same field as OR alternatives and different fields as AND. - The `+` separator is a systemd journalctl disjunction feature to replicate for file-backed journalctl behavior; it is not a new extension. - Each product language must provide two API layers: idiomatic SDK API plus a libsystemd-compatible reader facade. The facade is required unless a SOW records concrete evidence that it would require native bindings, violate the pure-language policy, or create an unsafe/unrepresentable API in that language. - Each product-language writer must expose two compatible append shapes: a systemd-compatible raw full-field `KEY=value` byte payload layer and a structured binary-safe `{name, value}` SDK layer. Structured is the SDK hot path for already-structured producers; raw full payloads are the systemd-compatible low-level layer. - Each product-language writer must expose the same three field-name policy layers: `RAW`, `JOURNALD`, and `JOURNAL-APP`. `JOURNALD` is the default and preserves trusted protected fields such as `_HOSTNAME`; `JOURNAL-APP` emulates untrusted application-facing journald restrictions and drops invalid caller fields; `RAW` allows every field name the DATA structure can represent directly, currently non-empty and no `=` in the field name. - The SDK must not perform producer-specific field-name remapping. Do not add or keep SDK behavior that emits project-specific mapping marker fields or project-specific mapped field prefixes. Consumers that need naming transformations must perform them before calling the SDK. - Core journal readers and writers are file-format implementations only. They must not execute external programs, discover host identity, read host identity sources, or enforce cooperating-writer locks by default. They must operate on explicit caller-provided paths, bytes, timestamps, machine IDs, boot IDs, seqnum IDs, and options. - Systemd/journald compatibility is a policy/API layer above the file-format core. It may require caller-provided machine and boot identity, but it must not silently probe host identity. Callers that want automatic identity discovery must explicitly call the optional identity helper and pass the result in. - Cooperating-writer locking is an optional helper/wrapper, independent from systemd compatibility. The journal format has a one-writer operational contract, but the lock protocol is not part of the systemd journal file format and must not be described as systemd compatibility. Core writer constructors must not expose lock-enable options; callers acquire and release the optional lock helper separately around writer use. - Host-observation mechanisms such as `/proc`, `/host/proc`, `/etc/machine-id`, platform registries, `sysctl`, `system_profiler`, `ps`, shell commands, and subprocess APIs are forbidden in core reader/writer runtime paths. They are allowed only in explicitly named optional helper code and tests for that helper. - Low-level writers must sort ENTRY DATA references by on-disk DATA object offset and remove duplicate DATA references by default, matching systemd. A trusted unique-payload option may skip only duplicate elimination when the caller guarantees no duplicate full payloads in one entry; it must not skip offset sorting unless a later SOW records measured evidence, compatibility validation, and a user decision for a non-byte-identity mode. - Jenkins lookup3 hashing must match systemd `jenkins_hashlittle2()`, including the empty payload value `0xdeadbeefdeadbeef`. - The final writer target includes compression and Forward Secure Sealing, but implementation may be phased. - Live concurrency compatibility is mandatory for every writer and reader. A writer is not production-compatible unless stock `journalctl --file` and stock libsystemd readers can safely read the file while that writer is appending. A reader is not production-compatible unless it can safely read files while they are being appended by each repository writer and, where testable without violating repository-boundary rules, stock systemd writers. - The live concurrency contract is one writer plus multiple readers on the same journal file. Tests must cover online state, append publication windows, tail metadata changes, entry-array growth, reader follow/tail behavior, clean close verification, and interruption/reopen scenarios for the claimed feature slice. - Distinguish live mapping/access bounds from stable-file integrity checks. A writer may publish rounded arena capacity before physical allocation reaches it. Ordinary readers must still read committed entries safely; excluded-writer snapshots, strict verification and append-open retain declared-arena checks. Exercise the actual DATA-preparation window and physical growth boundary, not only completed appends. `tests/interoperability/run_live_growth.py` supplies deterministic regular/compact SDK writer-reader coverage; it supplements the stock/live feature matrix rather than replacing it. - Writers expose a cross-language `live_publish_every_entries` publication cadence. The default `1` is the stock live-reader compatibility mode. `0` disables explicit SDK live publication, and `N > 1` publishes after every `N` appended entries for latency-tolerant consumers. Non-default modes must not be described as stock `journalctl --follow` compatible unless their exact mode is covered by live matrix evidence; they still must pass clean-close verify and final reads. - The reusable live-concurrency harness is under `tests/conformance/live/`. Writer tests should use the configured monotonically increasing sequence field, default `LIVE_SEQ`, so stock readers prove complete ordered visibility. - Stock reader harness adapters may retry transient active-writer `ENODATA` open/read failures or partial snapshots only while the writer is active. After the writer exits, final ordered reads and `journalctl --verify --file` must pass. - High-level directory writers must apply configured retention once when an active writer is opened or created. Existing-active reopen and eager open enforce during construction; lazy archived-only construction remains side-effect-free until the first append opens the active file, then retention runs before the first entry is written. Active/current files must remain protected and normal retention deletion lifecycle events must be reused. - Apply the **Go/Rust Feature Parity** development rule in `AGENTS.md`; consumer language alone does not justify a feature gap. - Go's explicit `LogConfig.RootRetention` and Rust's `Config::with_root_retention(true)` are exceptions to the default machine-local lifecycle rules above: archived-only startup also maintains the owned root, file lengths and tail times govern deletion, and live files may be finalized for idle expiry or allocation-policy changes. Recovered active files require caller verification/exclusion. Use header-native `InspectRootRetention` before open and `Log.InspectRootRetention` for live query/status inventory (Rust exposes equivalent snake_case APIs); do not substitute Reader entry-vector expansion. Live inventory must reject missing/replaced active files instead of reporting false-empty success, and maintenance must validate it before mutation. Root close, disposal and rotation MUST share live-path/header ownership preflight before mutation or ownership detachment. Archive and lazy-creation destinations MUST be absent. Reject safely, preserve bytes and permit healthy rotation/creation retry after path restoration; rejected close releases only. Test changes completed between SDK calls, with caller exclusion during calls, and cover empty actives after policy setters as well as lazy successors. Preserve separate safe-maintenance errors and fatal archive-mutation errors: failed retired-file open/validation before mutation must not poison a healthy current writer. Detach outgoing ownership before archive mutations so even a post-rename failure leaves evidence inspectable. New root files, successors and allocation checks must share configured options rather than inheriting stale recovered layout. Exercise regular/compact transitions through both append APIs, pre/post-mutation failures, and archive-before-delete events. Fixed-header inventory MUST validate every header-addressed object extent against the declared arena and allocated object tail, including ENTRY-array and tail-entry hints. Reuse stable-header validation with append recovery and excluded-writer snapshots; corruption in array contents remains outside the header-only inventory contract. Exercise malformed header offsets in both languages and require failed preflight to preserve journal bytes. Stable validation MUST also enforce fixed-header object/category population bounds and cached offset/count agreement, using complete on-disk field gates for historical headers. The aggregate of present disjoint object categories MUST fit within the total, including one object for each declared DATA/FIELD hash table; those two object types have no dedicated count fields. Use checked addition or a remaining-object budget. Test exact and insufficient budgets with zero, one and two table declarations, including historical headers. A present ENTRY_ARRAY counter MUST cover the distinct nonzero first/tail array locations declared by complete header fields. Equal pointers count once; additional arrays are permitted. Test historical counters before cached-tail fields exist and preserve bytes on inventory/startup rejection. Test small in-bounds contradictions, not only overflowing offsets. Do not impose stable counter consistency on live mapping validation. - For deterministic regular uncompressed writer output, the layout target is byte-for-byte identity with the systemd v260.1 reference ingester for the accepted corpus. Writers must match systemd object order, alignment, initial allocation envelope, v260 header fields, entry-array growth, tail metadata, and hash-chain header behavior for that slice. - Deterministic byte-identity validation must cover systemd final-state variants: online/plain close, offline close, and archived close. - Header readers must use the on-disk `header_size` when validating object and hash-table locations. Do not compare historical file offsets against the current in-memory v260 `JournalHeader` struct size, and do not expose bytes beyond the on-disk header as newer header fields. - Readers must not require `HEADER_INCOMPATIBLE_KEYED_HASH` for opening existing historical files. If that flag is absent, readers must use the unkeyed Jenkins lookup3 hash path and still support applicable compression flags such as LZ4. Writers may remain conservative when appending and reject unkeyed historical files unless a SOW explicitly proves safe mutation of that historical format. - Writer append-open rejection for historical unkeyed files must be controlled and must occur before entry mutation. Do not leave assertion panics or partial state changes as the user-facing failure mode. - High-level directory writers own reliable active replacement. If a low-level append-open rejects an existing active file as unsupported, the directory writer must follow systemd's reliable-open shape: use readable header metadata to continue sequence identity where possible, move the old active file out of the normal `.journal` set with a collision-safe `*.journal~` disposed name, and create a fresh active file. Do not archive unsupported active files into normal readable history. - Journal-native API performance is part of compatibility. If the format provides a hash table, FIELD/DATA chain, DATA entry array, ENTRY array, offset, or mmap-backed path for an operation, implementations must use that path instead of scanning and expanding all entries unless a SOW records measured evidence and an explicit accepted reason. - Field-name enumeration should use FIELD hash-table traversal on valid indexed files. A compatibility fallback to entry scanning is acceptable only when a historical or damaged FIELD table cannot be traversed safely, and that fallback must be documented in the active SOW. - Unfiltered unique value enumeration must match systemd's algorithmic shape: find the FIELD object and walk its DATA chain, then de-duplicate across files. It must not scan every entry or expand unrelated fields. - Changes to `journal-engine` index semantics, `FileIndexKey`, serialized index contents, cache schema, or consumer-visible cache partitioning must explicitly decide whether `CACHE_VERSION` changes. If bumped, record the one-time reindex/invalidation impact in the active SOW, product scope, and release notes. If not bumped, record why old cache entries remain semantically safe. - Avoid unnecessary DATA decompression, repeated `FIELD=value` parsing, allocation, sorting, hashing, or syscalls in reader/writer hot paths. Treat these as regressions unless tests and benchmark evidence prove they are required. - Relocated baseline/candidate source copies must include the tests' referenced fixture and helper files at their original relative paths. Check those dependencies before running the suite and verify copied bytes. Select Cargo packages from their manifest names, not directory names or dependency aliases. - Explorer column catalogs must be built from FIELD indexes. The Rust `ExplorerQuery::debug_collect_column_fields_by_row_traversal` switch is a debug-only discrepancy tool; production reports, benchmarks, or compatibility claims with that switch enabled are invalid and must be treated as an explorer defect. - Indexed aggregation changes must force temporary DATA reuse during nested posting and ENTRY reads. From `go/`, run `go test -count=1 ./journal -run '^TestExplorerIndexedWindow'` for both layouts, all DATA compression modes, mmap/auto eviction and ReadAt scratch reuse. Keep possible mmap faults in child processes. Compare full results and indexed counters, including empty/binary values, singleton DATA, unset/repeated values, time filters, bucket integer boundaries and partial read-error counters. A small fixture or a successful zero-row query does not establish the default-window lifetime. Benchmark matching and unmatched low/high-cardinality queries with `BenchmarkExplorerIndexedValueOwnership`; record allocations separately from elapsed time. Use `BenchmarkExplorerIndexedCompressedValueOwnership` with an explicit `JOURNAL_SDK_EXPLORER_COMPRESSED_CORPUS` for prebuilt codec controls; check indexed/traversal outputs, actual decompression and update totals before timing. Freeze the same complete test helper for baseline and candidate, and exclude fixture construction and reader teardown from timing. An incorrect or crashing baseline cannot certify a speedup. - Inspect CLI-helper timer boundaries before interpreting profiles or batching. The Go reader helper opens/closes a fresh reader and checksums/sorts results on every `--loops` iteration; its final ExplorerStats describe the last loop. Pilot one iteration before selecting a batch count for each workload. Keep CPU-profile post-timer activity and heap-profile forced GC separate from query-cost claims; sampled cumulative allocation is not peak live memory. - For Go ENTRY-slot header acquisition, run `TestEntrySlotHeader` controls on both backends, default/tiny/non-power-of-two windows, boundary headers, partial errors, closed readers, row pins, eviction and live array growth. Measure `BenchmarkReaderOpen`, `BenchmarkReaderEntryHeader` and `BenchmarkReaderAllocation` with the same complete header benchmark helper in both builds. Record actual allocation classes with `TestReaderAllocationShape`; raw sizeof does not establish heap cost, and 64-bit layout preservation does not establish 32-bit layout preservation. Exclude candidate-only direct-helper correctness tests from both timing binaries, document that exclusion and run those tests separately. Preserve the baseline validator's policy when isolating acquisition changes from other paused work, and verify matching pure-build flags and source hashes. For uncertain small-open timings, compare the same immutable five-entry corpus using `JOURNAL_SDK_READER_OPEN_SMALL_CORPUS` and retain a generated-file control with those same binaries. Preserve earlier results: a changed helper can alter test linking even when production source is byte-identical. - For Go native-file opener changes, run `TestNativeReaderFile` uncached on amd64 and 386. Verify read-only/blocking/close-on-exec flags, typed path errors, symlink identity, descriptor closure and sparse reads above 2 GiB. Preserve interrupted-open retry, native malformed-file cleanup and existing `.zst` source/staging behavior; build non-Linux delegation targets. The direct Linux opener bypasses Go's internal test-cache input hook, so use `-count=1` for fixture-dependent tests and retain explicit immutable fixture hashes. Exclude candidate-only opener contract tests from both timing builds, as for direct header tests. Primitive syscall savings do not establish full-reader performance; repeat small, large and higher-level reader/query controls. - For cached constructor statistics, run `TestReaderAccessorInitial` for empty/nonempty files and initial mmap failure. Verify explicit counters, selected/requested modes and fallback reason against a fresh statistics query. Windows zero-byte raw files fail explicit mmap construction and Auto falls back to ReadAt; preserve that platform behavior in test expectations. Exclude candidate-only statistics tests from both timing builds. - Smoke tests are not sufficient evidence for production compatibility. SOW validation must record exact stock systemd version, commands/helpers, stress duration, entry counts, reader counts, and failure criteria. - Common compression-library dependencies are allowed after dependency review. Journal parsing/writing must not depend on systemd/libjournal; CGO and linking to system journal libraries remain disallowed unless the user explicitly changes those separate constraints. - Every external-agent prompt must include the canonical repository-boundary block verbatim from `AGENTS.md` or `.agents/skills/project-agent-orchestration/SKILL.md`. - Compatibility probing must not use the workstation's live journal. Do not run `systemd-cat`, `logger`, live `journalctl`, or write under `/var/log/journal` or `/run/log/journal`; stock-reader validation must use `journalctl --file` or repository-local `--directory` fixtures only. ## Best Practices - Treat systemd source and tests as the compatibility authority when documentation and implementation disagree. - Keep shared tests language-neutral and run them against both product SDKs. - Add shared live-concurrency tests before accepting a writer or reader as production-compatible. - Prove cross-language interoperability with files written by each implementation and read by every implementation. - Prove stock-reader interoperability while repository writers are actively appending, not only after close. - For live writer/reader compatibility changes, run `tests/interoperability/run_live_matrix.py` and require the feature matrix to cover regular, zstd/xz/lz4 DATA compression, compact, compact plus DATA compression, and sealed/FSS files. The matrix must include stock `journalctl --file`, stock libsystemd, all repository readers, final `journalctl --verify --file`, and `--verify-key` for sealed files. - For compressed-DATA writer changes, run `tests/interoperability/run_compression_matrix.py` and require the structural oracle to validate object order, offsets, flags, counters, hash-chain consistency, tail metadata, references, and compression flags plus stock journalctl, stock libsystemd, and all repository reader checks. - For compact writer changes, run `tests/interoperability/run_compact_matrix.py` and require the structural oracle to validate compact object layout, 32-bit compact offset constraints, optional compression flags, stock journalctl, stock libsystemd, and all repository reader checks. - For deterministic writer layout changes, run `tests/interoperability/run_byte_identity.py --final-state all` and require `all_equal: true` for the accepted uncompressed corpus unless the active SOW records exact byte deltas and a user decision changes the pass condition. The accepted corpus must keep deliberate DATA hash-bucket collisions, and the byte-identity runner must fail if `data_hash_chain_depth` does not match the systemd reference value for every language and final state. - For writer lock changes, run `tests/interoperability/run_lock_matrix.py` and require all SDK writer pairs to reject a second active writer before the contender publishes a ready file, plus stale-lock cleanup after crashed writers. This matrix applies to optional lock helpers/wrappers, not to the core writer constructors after SOW-0071. - For directory reader or file-backed `journalctl --directory` changes, run `tests/interoperability/run_directory_matrix.py` and require stock journalctl plus Rust and Go rewrites to agree on traversal, ordering, filtering, boot listing, corrupt-file skipping, empty directories, and repository `.journal.zst` directory discovery. - For mixed directory feature changes, run `tests/interoperability/run_mixed_directory_matrix.py` and require stock journalctl plus Rust and Go rewrites to agree on mixed regular/compact files, uncompressed and zstd/xz/lz4 DATA-compressed files, sealed/unsealed reads, directory verification with and without keys, and the repository whole-file `.journal.zst` directory extension. - For file-backed journalctl query or follow changes, run `tests/interoperability/run_journalctl_query_matrix.py` and require stock journalctl plus Rust and Go rewrites to agree on `--since`/`--until` realtime ranges, `--boot` descriptors, and live `--follow` reads from actively appended file and directory inputs, including no-tail, default-tail, and boot-plus-since cases. - For journalctl parser or option-surface changes, run `tests/parser-parity/check_v260_manifest.py` and `tests/parser-parity/run_parser_parity.py`. Parser parity must cover option names, short aliases, output modes, parser-required conflicts, recognized options interspersed after show-action match arguments, stock short-option attached values and clusters such as `-n2`, `-ball`, and `-rn2`, and optional-argument edge cases where bare and explicit-empty forms differ, such as `--boot` versus `--boot=`, bare `--lines` versus `--lines=`, and bare `--case-sensitive` versus `--case-sensitive=`. - CLI integer controls must exercise native base prefixes/octal, leading and trailing whitespace, signed 32-bit descriptor limits and explicit ID-offset signs. Preserve raw Unix match operands separately from raw grep patterns. - Short-output controls must include multiline and distinct-suffix messages, width/line/byte thresholds and repeated MESSAGE values; grep/cat select the first value while short output selects the last. Prove bounded reads stop before further matching, boot observation precedes grep, and follow-tail selection/resume state includes nonmatching native rows. - Check short MESSAGE preparation before printability/truncation: tabs, completed and malformed CSI/OSC sequences, CR boundaries and show-all raw controls. JSON duplicate controls must include a binary first occurrence; a byte array must not become the repeated-values collection. - Cursor controls must compare final native position as well as selected output: grep misses, bound crossings, zero counts and after-terminal seeks. Verify follow cursor-file contents after a skipped suffix or no matches, rather than accepting file existence alone. Size parsing needs compound suffix, fraction, unit-order/case and overflow controls, including terminal help encounter order. Preserve raw source-option presence on Unix. - For verifier changes, run `tests/interoperability/run_verify_matrix.py` and require stock `journalctl --verify --file` plus Rust and Go verification paths to agree on positive regular, zstd/xz/lz4 DATA-compressed, compact, compact plus DATA-compressed, and sealed files, and on negative object type, object size, payload hash, hash-chain, entry-array, header-counter, seqnum, monotonic, and TAG/FSS corruption classes. - For ordinary traversal or compressed-reader changes, build both conformance adapters and run `tests/interoperability/run_reader_hardening.py` against an explicitly selected file-backed stock oracle. Use a new `.local/` output directory. The paired corpus covers cycles, missing required posting links, acyclic compatibility controls, facade/directory callers, complete Zstandard streams and whole-file staging. `--only chains --only streams` does not validate public crash recovery. Strict verification is a separate gate; ordinary stock corruption handling can differ from the SDK's completeness errors, so record the actual expected contract for each fixture. - For recovery changes, test fresh exact queries as well as queries after a full unfiltered drain. Earlier traversal can hide a missing-pointer bug by activating recovery first. Include sparse postings, same-size unpublished tails, partial arrays, forward/reverse/time positioning, directory refresh, and strict capture/append rejection. Release DATA guards before cold recovery reads. Do not replay controlled Explorer callbacks or sampling state to retry a failed indexed operation. - Reader recovery must not mutate source journals. Separate static damaged-file extraction, actual writer publication, and synthetic fault injection in test evidence. Restoring previously committed bytes is not evidence of journald publication or a required repair lifecycle. Before adding state or repeated scans for a restore/retry scenario, establish its supported upstream trigger. - Recovery EOF controls must separate repeated same-direction/count polls from reversal, explicit seeks and actual append count changes. Check bounded read work on an unchanged damaged file and verify source bytes remain unchanged. Cover raw as well as filtered readers; Go explicit Refresh is a separate path. - Count-bounded ENTRY-array traversal must reject the first required revisit; a lazy unbounded-cycle guard alone can miss it before the count completes. Cover short cycles, descending-prefix/ascending revisits, public Rust Node iteration and writer tail selection before mutation. Preserve acyclic backward links and ignore reader links beyond the declared population. Prefix checks may inspect only already visited arrays, not future headers. - Requalification must use one stable observed recovery view across every Boolean branch. Test a failure after an earlier branch was clipped; do not install a partially qualified expression. Synthetic ENTRY/DATA restoration can exercise rollback but does not establish a production repair contract. Pending builders and installed expressions must retain retry state and known DATA identities, including empty lists. A failed backward preparation must retain captured populations rather than reread DATA counts after a later append. Check public expression composition where exposed. Clearing matches must rewind file/directory/facade readers without an explicit seek; test this after multiple sparse matches. - Filter position controls must cover installing at a resolved row, reversal after EOF and early AND/OR exhaustion, duplicate realtime bounds, and failed selected ENTRY loads followed by getters and transient I/O retry. Test both SDK and facade APIs, regular/compact layouts and Go access backends. Directory controls must include sequential file transitions, partial merge prefetch, initial unset errors and pending realtime seeks; preserve candidate order through complete retry/EOF traversal. Explicit filtered realtime search checks visited posting slots; separately prove ordinary traversal still encounters damaged skipped slots. Use probe counts plus isolated release comparisons to establish search work and elapsed cost respectively. Test recovery first discovered while sequential traversal crosses files, followed by a later merge-probe error. Internal merge restarts must reuse the inner routine; one public movement owns rollback of its selected child without discarding other prefetched candidates. Install and replace filters at a committed directory row, including group operators. Preserve pending seeks after an initial failed load. Prove native sequential discovery with an unvisited later-file error: nearer rows must remain readable before that file is reached. Raw/filtered mode changes must reuse proven sequential positions as well as filter replacements. Audit strict index consumers for suppressed new traversal errors and cached partial results. Exercise requested facet/source posting chains, positive counts with missing pointers and actual cache omission with a healthy sibling; retain documented value tolerance and propagate required traversal failures. - Exercise recovery through public default constructors, not only a private enablement switch. Cover file/directory/facade and whole-file compressed input, normal EOF plus observed status, unchanged source bytes and declared counters, and strict verification/capture/append rejection. Test live publication with actual writers separately from synthetic restoration. A zero status is not a full-index integrity result. Preserve errors for unknown secondary posting tails and malformed compressed streams. Run `TestRecoveryEqualCountFacetWithoutPostings` and measure `BenchmarkRecoveryUnmatchedFacet` when changing Go facet shortcuts: incomplete unused array capacity can leave visible and declared counts equal while suppressing postings. Keep the large orphan value out of unmatched key copies; record allocation evidence rather than inferring it from correct results. - Before reader performance acceptance, freeze matching helper sources against baseline and candidate SDKs. Keep immutable fixtures and complete semantic counters. `tests/benchmarks/run_reader_regression_comparison.py` alternates order and retains per-process output, measured runs and comparisons even when a later case fails. An unsuccessful baseline is not a valid timing reference. - Select representative performance controls from the actual changed work. Careful code review and high-level tests can suffice for unchanged hot work or cold-only checks. Use targeted timing/profiling for credible added costs and observed regressions; do not mechanically expand every API, layout and backend combination or build a large framework for small changes. Retain adverse evidence, and distinguish uncertainty from established equality. - Separate reader support for existing historical files from writer feature milestones. - Record excluded upstream tests with a reason and extract file-level behavior where practical. ## Bad Practices - Do not implement daemon/service behavior just to satisfy journalctl daemon-control options. - Do not rely on one language's tests as sufficient for all languages.
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub