Skip to content

Bound JSONL growth with lossless process rotation; release 0.2.25 - #11

Merged
ifuri-validator-agent[bot] merged 1 commit into
mainfrom
ticket/005-jsonl-byte-bound
Nov 5, 2026
Merged

ifuri-validator-agent[bot] merged 1 commit into
mainfrom
ticket/005-jsonl-byte-bound

Conversation

@tom-sapletta-com

Copy link
Copy Markdown
Contributor

JSONSink currently appends without a size bound, so a retained 50 MB log immediately grows beyond the target when a producer resumes. This adds opt-in max_bytes / NFO_JSONL_MAX_BYTES and bumps the package to 0.2.25. The default remains unbounded.

Cooperating POSIX writers acquire a persistent per-path lock before opening the active inode. Whole files move atomically into unique private raw-segment directories; oversized events are preserved in separate segments. Partial oversized writes remain explicitly incomplete, and no archives are pruned. Every writer to a configured path must cooperate; external readers may briefly observe a missing active path during rollover and should retry.

Validation: 54 targeted tests passed across new rotation, existing JSONSink and configure behavior. They include four spawned writers, process death immediately after rename, short/failed writes, fsync failures, UTF-8 byte limits, linked paths, opaque tails, lock identity and delegation. On frozen pre-change source, 20 regression cases fail with no setup errors. Pinned Docs completion passed. Required protected Python 3.11/3.12/3.13 checks and independent Validator approval remain mandatory; local results do not replace them.

Planfile PLF-005, project ticket-005; closes #10. Producer dependency of maskservice/c2004#738, which remains open for runtime activation, persistent-bound observation and actual 24-hour acceptance. No service activation or unrelated dirty primary changes are included.

@ifuri-validator-agent ifuri-validator-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validator approval after policy checks for exact head 4dbfd5d1ba489938f32084fbc88a44fbad550d06.

Ticket: ticket-005
Correlation ID: local-semcod-nfo-pr-11-ticket-005
Model: openai/cursor-auto
Reviewed diff chunks: 3
Advisory LLM verdict: APPROVE
Advisory summary: Reviewed all 3 diff chunk(s). The visible chunk correctly introduces the documented opt-in POSIX bounded JSONL rotation foundation, including stable advisory locking, directory-relative no-follow operations, regular single-link file validation, short-write handling, fsync durability steps, inode identity checks, atomic archival rename, partial-tail rollover, and byte-based bounds. No unresolved code or security defect is evident in this chunk. | The visible chunk correctly adds opt-in bounded JSONL writing while preserving the legacy unbounded default, validates explicit and environment-provided limits, routes bounded writes through the cooperative writer, preserves delegation behavior, and includes substantial coverage for concurrency, oversized UTF-8 records, opaque existing data, invalid configuration, special-file rejection, rollover failure, and process recovery. No unresolved code or security defect is evident in this chunk. | The visible chunk adds focused regression and security-hardening coverage for hard links, symlinked parents and archive directories, incomplete and short writes, UTF-8 byte accounting, persistent private locks and segments, crash recovery, and fsync failure behavior. No code, security, or test defect is evident in this chunk.
Advisory findings: none
The LLM output above is advisory and was not used as the approval trust root.
Semantic review prerequisite: not_required; policy 676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7.

Actual PR impact radar

Exact range: 2d74ad212ef279aef19b7a3aa9a6a507b2ead5af...4dbfd5d1ba489938f32084fbc88a44fbad550d06
Change digest: 1a7671691ec2f8623c17088786d3505508703bf9dc5a0c550f45bab8e06e3fb4
Score: 76/100 (L), estimated 113 min, split recommended: true
Affected services/components: repository-wide/unclassified

Machine-readable radar JSONL and SVG
{"actual_change":{"additions":582,"base_sha":"2d74ad212ef279aef19b7a3aa9a6a507b2ead5af","binary_files":0,"categories":{"code":3,"configuration":2,"docs":3,"tests":1},"change_digest":"1a7671691ec2f8623c17088786d3505508703bf9dc5a0c550f45bab8e06e3fb4","comparison":"2d74ad212ef279aef19b7a3aa9a6a507b2ead5af...4dbfd5d1ba489938f32084fbc88a44fbad550d06","deletions":5,"file_count":9,"files":["docs/README.md","docs/information/jsonl-rotation.md","nfo/__init__.py","nfo/json_rotation.py","nfo/json_sink.py","project/ticket-005/README.md","project/ticket-005/intent.json","pyproject.toml","tests/test_json_sink_rotation.py"],"head_sha":"4dbfd5d1ba489938f32084fbc88a44fbad550d06","service_count":0,"services":[]},"assessment_mode":"observed-pr","axes":{"coupling":5,"delivery":4,"scope":5,"uncertainty":3,"validation":2},"complexity":"L","confidence":0.9,"diagnostics":["RADAR-ACCEPTANCE-MISSING","RADAR-BUDGET-EXCEEDED"],"estimate":{"budget_minutes":30,"minutes":113,"within_budget":false},"impact":{"components":["3.11","docs","maskservice","nfo","project","repository-root","short","tests"],"files":["3.11/3.12/3.13","docs/README.md","docs/information/jsonl-rotation.md","maskservice/c2004","nfo/__init__.py","nfo/json_rotation.py","nfo/json_sink.py","project/ticket-005/README.md","project/ticket-005/intent.json","pyproject.toml","short/failed","tests/test_json_sink_rotation.py"],"public_interfaces":[],"runtime_dependencies":1},"schema":"subactor.ticket-radar/v1","score":76,"split":{"parts":[{"estimated_minutes":13,"name":"Implement 3.11","scope":["3.11"]},{"estimated_minutes":13,"name":"Implement docs","scope":["docs"]},{"estimated_minutes":13,"name":"Implement maskservice","scope":["maskservice"]},{"estimated_minutes":13,"name":"Implement nfo","scope":["nfo"]},{"estimated_minutes":13,"name":"Implement project","scope":["project"]},{"estimated_minutes":15,"name":"Validate and project to trackers","scope":["tests","planfile","github/gitlab/jira projections"]}],"reason":"estimated_minutes_exceed_budget","recommended":true},"standards":[{"id":"wellmanifest/dsl","revision":"6c60fc4e0dd1f1bb74f46a7745e28019908d1203","version":"0.1.0-dev"},{"id":"wellmanifest/ticket-lifecycle","revision":"5bf581907a87b46a13a73e6c033d3abe4d9a306f","version":"0.1.0-dev"},{"id":"wellmanifest/git-lifecycle","revision":"7d77d4b7af57e69bc75c3a0290b3a4805c5c4438","version":"0.2.0-dev"},{"id":"wellmanifest/logs","revision":"48c284ef7a069055c0bcb6b900147ce5e65f8b43","version":"0.3.0"}],"ticket_ref":"ticket-005"}
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img"><title>ticket-005: Bound JSONL growth with lossless process rotation; release 0.2.25</title><rect width="128" height="128" rx="12" fill="#f8fafc"/><g stroke-width="1"><polygon points="64,55 72,61 69,71 59,71 56,61" fill="none" stroke="#d7dde5"/><polygon points="64,47 80,59 74,78 54,78 48,59" fill="none" stroke="#d7dde5"/><polygon points="64,38 89,56 79,85 49,85 39,56" fill="none" stroke="#d7dde5"/><polygon points="64,30 97,53 84,92 44,92 31,53" fill="none" stroke="#d7dde5"/><polygon points="64,21 105,51 89,99 39,99 23,51" fill="none" stroke="#d7dde5"/><line x1="64" y1="64" x2="64" y2="21" stroke="#aab4c0"/><line x1="64" y1="64" x2="105" y2="51" stroke="#aab4c0"/><line x1="64" y1="64" x2="89" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="39" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="23" y2="51" stroke="#aab4c0"/></g><polygon points="64,21 105,51 79,85 54,78 31,53" fill="#fb923c" fill-opacity="0.45" stroke="#c2410c" stroke-width="2"/><circle cx="64" cy="64" r="3" fill="#c2410c"/><g font-family="sans-serif" font-size="7" fill="#334155"><text x="64" y="11" text-anchor="middle">SCO</text><text x="114" y="48" text-anchor="middle">COU</text><text x="95" y="107" text-anchor="middle">UNC</text><text x="33" y="107" text-anchor="middle">VAL</text><text x="14" y="48" text-anchor="middle">DEL</text></g><text x="64" y="124" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#0f172a">L · 113m</text></svg>
Merge will be attempted after this approval when explicitly authorized. ## Decision record (recomputable)
DECISION D-005-2055
TICKET ticket-005
HEAD_SHA 4dbfd5d1ba489938f32084fbc88a44fbad550d06
CORRELATION_ID local-semcod-nfo-pr-11-ticket-005
ACTOR agent:ifuri-validator-agent[bot]
APPLIED_RULE P-CORE-015
INPUT author_login = "tom-sapletta-com"
INPUT observed_checks = ["test (3.12)=PASS","test (3.11)=PASS","test (3.13)=PASS"]
INPUT required_checks = ["test (3.11)","test (3.12)","test (3.13)"]
INPUT required_checks_source = "protected registry (env/request)"
INPUT reviewer_login = "ifuri-validator-agent[bot]"
INPUT semantic_review_assessment = {"schema":"subactor.validator/semantic-review-assessment/v1","subject":{"repository":"semcod/nfo","pull_request":11,"head_sha":"4dbfd5d1ba489938f32084fbc88a44fbad550d06","base_sha":"2d74ad212ef279aef19b7a3aa9a6a507b2ead5af","diff_sha256":"81499e34da73433cb5b26758602a3df61d76641b137f7cef98154eda078a9372"},"policy":{"policy_schema":"subactor.validator/semantic-review-policy/v1","policy_version":1,"policy_sha256":"676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7","required":false,"critical_paths":[],"observed_paths":["docs/README.md","docs/information/jsonl-rotation.md","nfo/__init__.py","nfo/json_rotation.py","nfo/json_sink.py","project/ticket-005/README.md","project/ticket-005/intent.json","pyproject.toml","tests/test_json_sink_rotation.py"]},"grounding":"full-diff-not-per-finding-proof","execution_authority":false,"status":"not_required","reason":null,"review_sha256":null,"unresolved":[]}
INPUT superseded_checks = []
INPUT ticket_radar_receipt = {"schema":"subactor.ticket-radar/v1","base_sha":"2d74ad212ef279aef19b7a3aa9a6a507b2ead5af","head_sha":"4dbfd5d1ba489938f32084fbc88a44fbad550d06","change_digest":"1a7671691ec2f8623c17088786d3505508703bf9dc5a0c550f45bab8e06e3fb4","score":76,"complexity":"L","estimated_minutes":113,"split_recommended":true,"services":[],"authority":"ADVISORY","promotion":"FORBIDDEN"}
VERDICT APPROVE AUTHORITY DETERMINISTIC
REJECTED REQUEST_CHANGES BECAUSE NO_UNSAFE_CHANGE_REASON_FOUND
ADVISORY llm_verdict = "APPROVE" MODEL "openai/cursor-auto"
ASSERT VERDICT_AUTHORITY != "ADVISORY"

@ifuri-validator-agent
ifuri-validator-agent Bot merged commit 61eae16 into main Nov 5, 2026
3 checks passed
@ifuri-validator-agent
ifuri-validator-agent Bot deleted the ticket/005-jsonl-byte-bound branch November 5, 2026 20:08
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.

Bound JSONL growth with lossless coordinated process rotation (PLF-005)

1 participant