Skip to content

Quality pass + PR #6 review fixes#7

Open
bioless wants to merge 2 commits into
mainfrom
quality-and-review-fixes
Open

Quality pass + PR #6 review fixes#7
bioless wants to merge 2 commits into
mainfrom
quality-and-review-fixes

Conversation

@bioless

@bioless bioless commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Follow-up to #6. High-reasoning quality pass plus resolution of the Copilot and Codex review comments on the real EVTX parser. 48 passed, 1 skipped. See docs/QUALITY_REVIEW.md for the per-comment responses.

bioless added 2 commits June 15, 2026 00:51
…ted to execution-log schema, reject path-like identifiers earlier, verifier now content-checks prefetch/registry/evtx artifacts; QUALITY_REVIEW.md
…_output_bytes, configurable timeout_seconds, drop unpopulated record_offset (use record_number), pinned/readable parser resolution, hash handling, portable test shebangs; verifier content-checks + schema/identifier hardening
Copilot AI review requested due to automatic review settings June 15, 2026 00:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b6cd86714

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/sift_crs/tools.py
Comment on lines +734 to +736
with stdout_path.open("wb") as stdout_handle, stderr_path.open(
"wb"
) as stderr_handle:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Refuse symlinked parser-output files

When a caller reuses a tool-run ID whose output directory contains evtx_dump_stdout.xml or evtx_dump_stderr.txt as a symlink, opening these paths directly with "wb" follows the symlink and truncates its target. In particular, a symlink to registered evidence silently modifies that evidence after the hash check, bypassing ToolContext.write_json and ensure_not_registered_evidence_path; validate the resolved destinations or create the files without following symlinks before writing.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/findings.py
Comment on lines +465 to +468
program_names = {
str(program.get("program_name", "")).lower()
for program in artifact.get("programs", [])
if program.get("program_name")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject malformed artifact records instead of crashing

Because artifact payloads are not schema-validated, a successful plugin tool can produce a Prefetch artifact such as {"artifact_type":"prefetch","programs":["bad"]}. The verifier then calls .get() on the string here and raises AttributeError instead of deterministically rejecting the unsupported artifact; validate collection and record types before dereferencing them. The Registry Run key and EVTX branches have the same malformed-record risk.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/findings.py
Comment on lines +305 to +308
if not content_supported:
notes.append(support_note)
notes.append(content_note)
return self._decision(candidate, "rejected", "rejected", notes)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve self-correction for content-mismatch rejections

When this new content check rejects a supported artifact type because an executable or event ID is absent, SelfCorrectionLoop cannot correct it: detect_missing_support only calls artifact_support_decision, sees that the artifact type supports the claim type, returns trigger none, and selects no follow-up action. For example, a notepad.exe claim sourced from an rclone.exe Prefetch artifact now stops immediately instead of rerunning the targeted Prefetch tool for notepad.exe; expose a content-mismatch trigger to the correction loop.

Useful? React with 👍 / 👎.

Comment thread src/sift_crs/tools.py
Comment on lines +744 to +745
returncode = process.poll()
if stdout_path.exists() and stdout_path.stat().st_size > max_output_bytes:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply the parser-output cap to stderr

When evtx_dump emits large diagnostics to stderr, only the stdout file size is checked against max_output_bytes, while stderr is continuously written to an uncapped file until the potentially hour-long timeout. A malformed EVTX or failing parser that logs rapidly can therefore exhaust the analysis filesystem despite the configured output cap; monitor and cap stderr as well.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Follow-up quality pass on PR #6’s real EVTX typed tool and surrounding workflow: strengthens identifier validation, tightens evtx_dump resolution/execution guardrails, and adds deterministic verifier content checks with accompanying schema + test updates.

Changes:

  • Add identifier validation for case_id, evidence_id, and tool_run_id, and extend schemas/tests to cover path-like identifiers.
  • Harden parse_evtx_real execution (rehash check, trusted parser resolution, streamed stdout with output/timeout limits) and update docs/tests accordingly.
  • Add deterministic verifier “content-consistency” checks (Prefetch/RunKey/EVTX) and validate execution-log events against schema in reporting/audit-package tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_typed_tools.py Adds regression test ensuring tool_run_id rejects path-like values.
tests/test_reporting.py Validates every execution-log event against the execution-log schema.
tests/test_parse_evtx_real.py Updates EVTX tests for new parser resolution + output/timeout/hash-mismatch behaviors.
tests/test_findings_verifier.py Adds a regression test rejecting Prefetch claims for executables absent from artifact content.
tests/test_evidence_registration.py Adds tests that case_id / evidence_id reject path-like identifiers.
src/sift_crs/tools.py Refactors EVTX parser discovery/execution and adds streaming + limits + hash recheck + tool_run_id validation.
src/sift_crs/findings.py Adds claim/artifact content-consistency checks and helper extractors.
src/sift_crs/evidence.py Adds shared identifier validation and enforces it for case_id and evidence_id.
schemas/tool-run.schema.json Tightens tool_run_id schema with an identifier pattern.
schemas/parse_evtx_real.input.schema.json Adds typed inputs for timeout_seconds and max_output_bytes.
schemas/execution-log.schema.json Adds missing report_generated / audit_package_exported event types.
README.md Updates EVTX parser documentation to reflect new guardrails/limits and record fields.
docs/QUALITY_REVIEW.md Adds per-issue quality review notes and responses.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/sift_crs/evidence.py
Comment on lines +208 to +212
def validate_identifier(value: str, field_name: str) -> None:
if not isinstance(value, str) or not value or IDENTIFIER_RE.fullmatch(value) is None:
raise ValueError(
f"{field_name} must match ^[A-Za-z0-9._:-]+$ and must not be empty"
)
Comment thread src/sift_crs/findings.py
Comment on lines +547 to +548
def _extract_executable_names(text: str) -> set[str]:
return {match.lower() for match in re.findall(r"\b[A-Za-z0-9_.-]+\.exe\b", text)}
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.

2 participants