Rectify incomplete merge preflight evidence - #335
Conversation
Carry forward the reviewed implementation from PR #321. The original PR preserves its review and authorship record. Assemble synthetic grouped-number probes without embedding complete identifier-shaped literals in source.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99623f78d4
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae12d1b92b
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2023ab4b46
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5222cdde8
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 91404d7f2f
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fda1e2e9e
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2c73c64e1f
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f958f22c3
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7a29762e4f
ℹ️ 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".
| test("^scripts/bank_statement_import\\.py$"; "i") or | ||
| test("^scripts/prune-package-compiler-cache\\.mjs$"; "i") or | ||
| test("^\\.github/workflows/(ci\\.yml|release-mcpb-preview\\.yml|deploy-install-page\\.yml)$"; "i") or | ||
| test("^src-tauri/Cargo\\.toml$|^src-tauri/src/lib\\.rs$|^src/(AxalScreen|DocumentsScreen)\\.tsx$|^src-tauri/src/axal\\.rs$|^src-tauri/src/db/encrypted\\.rs$|^src-tauri/src/documents\\.rs$|^src-tauri/src/commands\\.rs$"; "i"))) |
There was a problem hiding this comment.
Review the shared credential-session owner
Fresh evidence beyond the explicitly listed credential screens is that src/main.tsx owns axalSession.id at lines 486-489 and passes it into the DSC, Documents, and AXAL views, but a PR changing only that module matches none of these focused-review alternatives. Such a change can alter credential-session retention or exposure while the gate still emits MAY MERGE without a security-focused reviewer comment; include this module and its rename history in the classifier.
AGENTS.md reference: AGENTS.md:L194-L194
Useful? React with 👍 / 👎.
| landline_status=0 | ||
| landline_matches=$(grep -Eo '(^|[^[:alnum:]])0[1-9][0-9][ ._-][0-9]{4}[ ._-][0-9]{4}([^[:alnum:]]|$)' <<<"$normalized_whitespace") || landline_status=$? | ||
| standard_landline_status=0 | ||
| standard_landline_matches=$(grep -Eo '(^|[^[:alnum:]])0[1-9][0-9][ -][0-9]{8}([^[:alnum:]]|$)' <<<"$normalized_whitespace") || standard_landline_status=$? |
There was a problem hiding this comment.
Recognize variable-length landline area codes
Fresh evidence beyond the covered 0XX formats is a customer landline such as 0120-2345678: this expression requires exactly three area-code digits followed by eight subscriber digits, while the other scans see only separated four- and seven-digit chunks. I exercised that added payload against the gate and it returned MAY MERGE, so normalize bounded four-digit-area-code/seven-digit-subscriber forms before counting identifier shapes.
AGENTS.md reference: AGENTS.md:L192-L193
Useful? React with 👍 / 👎.
| bad "privacy scan found $home_path_count developer-home path shape(s)" | ||
| fi | ||
| pem_certificate_status=0 | ||
| pem_certificate_count=$(grep -Eic -- '-----BEGIN[[:space:]]+(X509[[:space:]]+)?CERTIFICATE-----' <<<"$scan_input") || pem_certificate_status=$? |
There was a problem hiding this comment.
Block trusted-certificate PEM envelopes
Fresh evidence beyond the covered BEGIN CERTIFICATE envelope is -----BEGIN TRUSTED CERTIFICATE-----, which this expression misses because its only permitted prefix is X509. A trusted-certificate PEM whose base64 body has no incidental identifier shape therefore passes the privacy scan and can reach MAY MERGE; recognize the trusted-certificate envelope as raw certificate output too.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| bad "privacy scan found $pem_certificate_count PEM certificate envelope(s)" | ||
| fi | ||
| redaction_status=0 | ||
| redacted=$(sed -E 's/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/<uuid>/g; s/[0-9a-fA-F]{32,}/<digest>/g' <<<"$scan_input") || redaction_status=$? |
There was a problem hiding this comment.
Block UUID-shaped credential session IDs
When added content contains a live AXAL credential-session ID, it has the UUID shape generated by src-tauri/src/axal.rs:162, but this blanket substitution removes it before the blocking identifier scan and the subsequent branch emits only a note. I exercised such an added session ID and the gate returned MAY MERGE; UUID-shaped credentials and hex access tokens must be held or distinguished from proven synthetic hashes rather than exempted wholesale.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| fi | ||
|
|
||
| echo "MAY MERGE — bind the merge to the reviewed head and validated base:" | ||
| printf ' [ "$(gh pr view %s --repo %s --json baseRefName -q .baseRefName)" = "%s" ] \\\n && gh pr merge %s --repo %s --squash --match-head-commit %s\n' \ |
There was a problem hiding this comment.
Bind the merge command to the validated base tip
If master advances after preflight, this guard still passes because it checks only baseRefName, while the merge command binds only the PR head. I checked gh pr merge --help: --match-head-commit is “Commit SHA that the pull request head must match,” and the same help explains that merge-queue targets may be queued or have auto-merge enabled when requirements are pending; the command can therefore merge this reviewed head against a different, unreviewed base tip. Recheck the exact base SHA immediately before merging and refuse instead of enqueueing when it differs.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f5fd22e8f
ℹ️ 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".
| all_bad=$(jq '[.[] | select(.bucket == "fail" or .bucket == "cancel" or .bucket == "pending")] | length' <<<"$buckets") | ||
| skipped=$(jq '[.[] | select(.bucket == "skipping")] | length' <<<"$buckets") | ||
| [ "$all_bad" -eq 0 ] || bad "$all_bad reported check(s) are failing, cancelled, or pending" | ||
| [ "$skipped" -eq 0 ] || say "note" "$skipped optional check(s) are skipped; required skipped contexts remain blocking" | ||
| [ "$context_report_valid" = true ] && [ "$check_bad" -eq 0 ] && [ "$all_bad" -eq 0 ] && say "ok" "all reported checks concluded successfully" |
There was a problem hiding this comment.
Verify skipped jobs against an explicit allowlist
When a PR changes ci.yml to add if: false to an unprotected job such as tally-portable, the required-checks job at .github/workflows/ci.yml:584-613 still succeeds because it rejects only failed or cancelled dependencies. This code then treats the skipped Tally job as optional, while the protected aggregate reports success, so the gate can emit MAY MERGE without running the portable core tests; validate skipped job names and their legitimate path conditions instead of inferring optionality solely from protected-context membership.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78a3931270
ℹ️ 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".
| test("^scripts/bank_statement_import\\.py$"; "i") or | ||
| test("^scripts/prune-package-compiler-cache\\.mjs$"; "i") or | ||
| test("^\\.github/workflows/(ci\\.yml|release-mcpb-preview\\.yml|deploy-install-page\\.yml)$"; "i") or | ||
| test("^src-tauri/Cargo\\.toml$|^src-tauri/src/lib\\.rs$|^src/(AxalScreen|DocumentsScreen)\\.tsx$|^src-tauri/src/axal\\.rs$|^src-tauri/src/db/encrypted\\.rs$|^src-tauri/src/documents\\.rs$|^src-tauri/src/commands\\.rs$"; "i"))) |
There was a problem hiding this comment.
Review credential dependency lockfile changes
Fresh evidence beyond the previously flagged Cargo.toml backend case is that src-tauri/Cargo.lock pins the shipped keyring, cryptoki, secret-service, and security-framework implementations, but this predicate does not match that lockfile. A PR can therefore update a credential backend entirely through the lockfile—for example, with cargo update -p keyring—and reach MAY MERGE without the mandatory focused security review; include the lockfile and its rename history, or classify changes to those package entries.
AGENTS.md reference: AGENTS.md:L194-L194
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c033dd40ec
ℹ️ 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".
| (test("(^|[/_.-])(dsc|credential[s]?|certificate[s]?|keystore|secret[s]?)(?=[/_.-]|$|[A-Z])"; "i") or | ||
| test("^scripts/bank_statement_import\\.py$"; "i") or | ||
| test("^scripts/prune-package-compiler-cache\\.mjs$"; "i") or | ||
| test("^\\.github/workflows/(ci\\.yml|release-mcpb-preview\\.yml|deploy-install-page\\.yml)$"; "i") or | ||
| test("^src-tauri/Cargo\\.(toml|lock)$|^src-tauri/src/lib\\.rs$|^src/(AxalScreen|DocumentsScreen)\\.tsx$|^src-tauri/src/axal\\.rs$|^src-tauri/src/db/encrypted\\.rs$|^src-tauri/src/documents\\.rs$|^src-tauri/src/commands\\.rs$"; "i"))) |
There was a problem hiding this comment.
Require security review for privacy-gate changes
For a PR changing only scripts/merge_gate_privacy.py, this predicate remains false because none of the alternatives include the privacy/data-leak gate itself or its rename history. Such a change can weaken credential, certificate, or personal-data detection and still reach MAY MERGE without the security-focused reviewer that owns data-leak prevention checks; classify this module and the shell privacy coordinator as security-sensitive boundaries.
AGENTS.md reference: AGENTS.md:L8-L8
Useful? React with 👍 / 👎.
| elif CREDENTIAL_CONTEXT_RE.search(line): | ||
| credential += 1 | ||
| pieces.append("<blocked-uuid>") |
There was a problem hiding this comment.
Block non-UUID credential tokens
When added content contains a live non-UUID bearer or API token, credential context is never consulted because this branch runs only for values already matched by UUID_RE; an alphanumeric token without a long digit run therefore produces no blocker and the gate can reach MAY MERGE. Fresh evidence in the extracted classifier is that token context was added exclusively inside UUID tokenization, so extend credential-context handling to non-UUID secret values rather than declaring those payloads identifier-free.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| IDENTIFIER_RE = re.compile( | ||
| r"\d{2}[A-Z]{5}\d{4}[A-Z][0-9A-Z]{3}|[A-Z]{5}[ -]\d{4}[ -][A-Z]|" | ||
| r"[A-Z]{5}\d{4}[A-Z]|[6-9]\d{9}", | ||
| re.I, | ||
| ) |
There was a problem hiding this comment.
Detect customer email addresses in added payloads
When a source or document adds a customer email address whose local and domain components contain no covered numeric shape, these identifier patterns and the later long-digit check both return zero, so the classifier reports that the payload carries no identifier shapes and the gate can reach MAY MERGE. Scan email-shaped values in added payload and destination inputs separately from the standard commit-author identities that are intentionally admitted.
AGENTS.md reference: AGENTS.md:L192-L193
Useful? React with 👍 / 👎.
| def focused: (.body | type == "string") and | ||
| (visible_body | test("(?im)^#{0,6} *security review: *" + $head + " *$")) and | ||
| (visible_body | test("(?im)^result: *accepted *$")) and | ||
| (visible_body | has_substantive_line("reviewed +(dsc|credential|certificate|keystore|secret)([ ]+[A-Za-z][A-Za-z-]*)?")) and | ||
| (visible_body | has_substantive_line("security rationale|security reasoning")); |
There was a problem hiding this comment.
Ignore fenced examples in security-review records
When an authorized collaborator rejects a credential-sensitive change while quoting the expected accepted-review template inside a Markdown fence, these regexes still match the fenced SHA, accepted result, scope, and rationale lines, causing security_review to become true despite the surrounding rejection. Strip fenced example regions before evaluating the focused-review fields so quoted templates cannot satisfy the mandatory security review.
AGENTS.md reference: AGENTS.md:L194-L194
Useful? React with 👍 / 👎.
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
Avoid static secret-like literals in the regression fixture so external secret scanning can evaluate the final PR range without suppressing the privacy-gate coverage.
60fc50c to
57799cb
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 57799cb020
ℹ️ 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".
| r"(?i)(?P<prefix>(?<![A-Za-z0-9_-])" + CREDENTIAL_KEY_RE + | ||
| r"(?![A-Za-z0-9_-])\s*(?:=|:)\s*)(?P<value>.*)$" |
There was a problem hiding this comment.
Recognize quoted credential keys
When added JSON or JSONL contains a credential such as {"api_key": "customerproductioncredential"}, this pattern expects : immediately after the key text, so the closing quote prevents any match and the classifier reports no blockers. Fresh evidence after the earlier non-UUID-token finding is that the new tokenizer handles unquoted assignments but still misses the standard quoted-key representation used by API captures and configuration files, allowing a hardcoded credential to pass the privacy gate; permit a balanced optional quote around recognized keys.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| r"(?:process\.env\.[A-Za-z_][A-Za-z0-9_]*|os\.environ(?:\.get)?\([^\n]+\)|env\([^\n]+\)))$", | ||
| re.I, | ||
| ) | ||
| TYPE_REFERENCE_RE = re.compile(r"^(?:str|string|bytes|secret(?:str)?|token|optional\[[A-Za-z]+\]|[A-Z][A-Za-z0-9_]*(?:Token|Secret))$", re.I) |
There was a problem hiding this comment.
Stop exempting credential values that resemble type names
When an explicit assignment has a live value ending in Token or Secret, such as access_token: productionToken or client_secret: supersecret, this case-insensitive type-reference expression classifies the value as a placeholder and the scan returns no blocker. Fresh evidence after the earlier non-UUID-token finding is that the newly added literal scanner now reaches these assignments but exempts ordinary credential strings because re.I makes the leading-capital type-name constraint ineffective; restrict this exemption to an unambiguous type-syntax context or preserve the intended case requirement.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f41d6341a2
ℹ️ 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".
| ) | ||
| EMAIL_RE = re.compile(r"(?<![A-Za-z0-9._%+-])[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@([A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+)(?![A-Za-z0-9._%+-])") | ||
| EXAMPLE_EMAIL_DOMAINS = {"example.com", "example.org", "example.net", "example.invalid"} | ||
| CREDENTIAL_KEY_RE = r"(?:api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|credential|session[_-]?token)" |
There was a problem hiding this comment.
Scan password assignments as credential literals
When added configuration contains a hardcoded value such as {"password":"customerproductionpassword"}, this key whitelist does not recognize the assignment, and the remaining email/UUID/identifier scans also miss the alphabetic secret. The classifier consequently returns no blockers and the preflight can reach MAY MERGE; include password, passphrase, and private-key credential keys in the literal scan.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| malformed = 0 | ||
| retained = [] | ||
| for line in text.splitlines(True): | ||
| match = AUTHORIZATION_BEARER_RE.search(line) or CREDENTIAL_ASSIGNMENT_RE.search(line) |
There was a problem hiding this comment.
Inspect every credential assignment on a line
When minified configuration contains multiple credential fields on one line, this single search examines only the first. For example, {"api_key":"example_api_key","client_secret":"customerproductionsecret"} classifies the first value as an allowed placeholder, retains the entire line, and never examines the live second value, so the privacy classifier reports no blocker and the gate can permit a secret-bearing PR. Iterate over all assignments rather than stopping after the first match.
AGENTS.md reference: AGENTS.md:L191-L191
Useful? React with 👍 / 👎.
| final_failed_runs=$(jq --rawfile contexts "$tmpdir/required-contexts" ' | ||
| ($contexts | split("\n")) as $required | | ||
| [.[] | .check_runs[] | . as $run | | ||
| select((.conclusion != "success" and .conclusion != "neutral" and .conclusion != "skipped") or | ||
| (.conclusion != "success" and ($required | index($run.name)) != null))] | length |
There was a problem hiding this comment.
Revalidate required contexts in the final check snapshot
When a required context passes the initial gh pr checks read but is deleted or disappears before the final fence, the refreshed check-run and status responses can be internally complete while omitting that context. This expression counts only non-successful runs that are present and never reconstructs required-context coverage, while an empty final legacy-status response is explicitly accepted, so the gate can emit MAY MERGE using the stale initial success. Reconcile every required context against the union of the final check-run and commit-status snapshots.
AGENTS.md reference: AGENTS.md:L145-L147
Useful? React with 👍 / 👎.
| # and base. A head/base move after it invalidates the entire preflight. | ||
| : >"$errfile" | ||
| late_meta_status=0 | ||
| late_meta=$(gh pr view "$PR" --repo "$REPO" --json headRefOid,baseRefOid,baseRefName 2>"$errfile") || late_meta_status=$? |
There was a problem hiding this comment.
Include mutable PR fields in the last identity fence
When the PR author edits the title or description after the full metadata read at line 1358 but while the final check/status requests are running, this last fence fetches only the head and base fields. Those values remain unchanged, so the gate can still emit MAY MERGE even though the description may now omit required evidence or contain newly published customer data that was never privacy-scanned. Re-fetch and compare every mutable reviewed field, including the raw body, title, draft/state, and mergeability, in the last fence.
AGENTS.md reference: AGENTS.md:L192-L193
Useful? React with 👍 / 👎.
Closes #328. Addresses #317's incomplete merge-evidence failure mode. Replaces #321; that PR preserves the original review discussion and authorship record. Its older commit messages contain synthetic identifier examples that the final privacy gate intentionally rejects. This branch preserves that reviewed implementation on current master and incorporates its five subsequent findings. The privacy rule still rejects the historical examples; synthetic test values are assembled without full identifier literals in the source.
Functional summary
Add a read-only preflight that binds its result to the full current PR head and master tip. It requires the exact protected-context set, a completed current provider review, independent acceptance, complete review/file/commit inventories, description evidence and compatibility manifests. Known failures return MUST NOT MERGE; missing or malformed evidence returns INDETERMINATE. The command never changes GitHub state.
Check and combined-status pagination validate complete, unique, current-head records. Large context and review payloads travel through files, avoiding Linux argument limits; failed diagnostic computation cannot become success. Required skipped checks remain blocking, while deliberate optional skips are allowed. A summary-only provider receipt needs an explicit independent-review attestation naming the complete head.
The diff parser preserves payload using Git's LF delimiter, including Unicode separators and CRLF content. Independently quoted paths, textual destinations and rename metadata reconcile with REST file records. Added payload, paths, PR text, commit messages and standard Git identity fields enter the bounded privacy heuristic. Horizontal Unicode spaces and tabs normalize without joining distinct lines. Coverage and metadata-only diagnostics redact private path shapes and bound every example. Null linked GitHub identities remain valid; ordinary names and email addresses are not automatically classified as private data. Binary additions and changes require two explicit manual attestations,
--binary-review-sha FULL_SHAand--independent-review-sha FULL_SHA, both naming the complete current head. The binary attestation covers every current binary byte plus ownership, licensing and NOTICE obligations; it cannot be inferred from the PR body or bypass privacy, coverage, review, thread or final-head checks. Gitlinks remain indeterminate pending provenance, license and NOTICE review.The description must link an actual checklist item at the complete candidate SHA and provide a concrete validation command. Populated canonical template fields and concrete Node validation commands are accepted. Fence delimiters (including tilde fences with information strings), thematic breaks, empty labels, hidden HTML comments (including unclosed comments), bare placeholders and unrelated sibling fields are insufficient. Raw body bytes remain available to privacy scanning and final drift detection. Checklist anchors require a real delimiter after the line number. Security impact accepts explicit None/N/A/no impact responses while rejecting pending or TODO. Implementation additions, including shell, PowerShell and SQL code, require all three P4 answers. Native and platform-sensitive paths require affected-host evidence or a justified unaffected-host statement; workflow and database migration paths require rollback notes. Renames retain their prior path for conditional checks. DSC/credential changes additionally need a fetched independent security-focused reviewer record naming the full head.
The final batch modularizes the privacy classifier and fake provider while preserving the shell coordinator as the sole ordered GitHub-evidence transaction. UUIDs are classified before generic digest masking: nil UUIDs remain an explicit placeholder, credential/session/token/bearer contexts block, and unexplained non-nil UUIDs are indeterminate. Trusted certificate envelopes and bounded three- and four-digit Indian landline forms block without echoing matched values. CI skipped jobs are allowed only when their names and changed-path conditions match the workflow; the gate enforces this at both the initial and final head-bound check-run fences. The credential-focused security-review classifier also covers direct and renamed
src-tauri/Cargo.lockchanges while excluding unrelated Cargo lockfiles. It also recognizes CamelCase DSC and credential path names; treats the known Axal frontend/native credential modules, encrypted key-store module, credential command facade, and bank-statement import password consumer as security-sensitive; strips terminated and unterminated hidden HTML before evaluating visible security sign-off and requires reviewed-scope text; scans root-account developer-home paths; rejects punctuated template placeholders; recognizes tilde-fenced validation commands; and requires actual host evidence. Rollback parsing stops at sibling template fields, initial review-thread pagination omits its cursor, and the final mutable fence refetches current-head checks and statuses. Mixed grouped identifier separators normalize for detection while compact dates remain excluded, redaction errors are indeterminate, and dependency-manifest additions require substantive justification. Inline platform fields require an unambiguously affirmative outcome, and the dedicated Windows native setup action and preview release workflow are platform-sensitive through direct and renamed paths. Bare host labels, empty fences, placeholders, negated outcomes, and any same-level sibling list field cannot supply Windows or macOS validation evidence; indented continuations, concrete affirmative outcomes, justified unaffected statements, and fenced commands with an explicit affirmative host outcome remain supported.The current owner-authorized stopping rule defers additional P2 hardenings to #344, #345, #346, #347, #356, #357, #358, #359, #360, #361, and #362, #363, #364, and #365, #366, #367, #368, #369, #370, #371, and #372, #373, #374, and #375, and #376, and #377, and #380. This PR does not claim those behaviors as fixed.
Scope, reuse, and impact
Test or reproduction command
Candidate:
92d151cf605bccaa30be6fd924cc8ecc184d1f53, based on masterba1742cf0ec8f17c3f10d537a5bfa845739b946f.python3 scripts/merge-gate.test.py: all 148 controls passed in 944.730 seconds on the exact committed candidate. The final shell coordinator, privacy classifier, fake provider, parser, tests, workflow and compatibility files were fingerprinted before and after the retained full run. The earlier failed run is retained: its stale positive fixture supplied only a bare fenced command, which the strengthened affirmative-outcome policy correctly rejects. Synthetic grouped-number fixtures now construct their runtime values from fragments so the privacy scan continues to test the payload rather than blocking static test-source examples. The prior PR's 118-control result remains historical evidence and is not substituted for this changed implementation.bash -n scripts/merge-gate.sh, Python compilation,node scripts/check-ci-workflow-consistency.mjsandgit diff --checkpassed.python3 scripts/merge-gate.test.pypassed all 131 controls locally on macOS in 681.365 seconds. Linux qualification runs the complete suite in Workflow consistency; its bounded timeout is now 20 minutes to allow suite and setup headroom on slower runners.Migration compatibility
No application schema, persisted data, Tally transport or credential change. The preflight supplements branch protection and required native/live evidence. Its field checks and privacy heuristic do not replace human assessment of test results, source completeness, licensing or private-data exposure. Independent acceptance also verifies whether production-regression policy applies, that the branch is dedicated to its fix, and that the required rectification label is present. AGENTS.md defines no branch-name prefix or authoritative metadata classifier; the gate documents this semantic responsibility instead of inventing one. This PR is dedicated to the merge-gate defect and carries
type:rectify.Rollback notes
Revert this PR to remove the advisory preflight and its Workflow consistency invocation. Branch protection remains in place. Run a fresh preflight immediately before a head-bound merge after relevant state changes.
Security impact
The P1 repair makes sensitive-diff review cover the coordinator, privacy classifier, and diff parser across direct, deleted, and renamed bytes. It rejects literal credential values before masking, confines the Git identity-email exception to validated identity fields, and ignores fenced review examples when evaluating security-review evidence. Independent secret scanning remains required.
Read-only GitHub queries, numeric PR selection and fixed repository validation. Privacy diagnostics report counts instead of matched values. Bank-statement password handling, the compiler-cache pruner token path, the known token-bearing workflow paths, and the document credential-session boundary (including renames) are classified as credential-sensitive for the existing focused independent-review gate. Security review records require visible substantive scope and rationale. The privacy scan recognizes bounded fixed-line patterns and Unicode developer-home usernames alongside its existing identifier shapes; no secret or contact value is read or logged by this change.