Skip to content

WordPress: protect reports and require trusted request closure - #25

Merged
CompleteDotTech merged 14 commits into
mainfrom
fix/wordpress-v8-report-lifecycle-17
Nov 14, 2026
Merged

CompleteDotTech merged 14 commits into
mainfrom
fix/wordpress-v8-report-lifecycle-17

Conversation

@CompleteDotTech

@CompleteDotTech CompleteDotTech commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Implements issue#24 WordPress lifecycle requirements: canonical signer/client/scope binding, generic report notifications with protected single-use retrieval, trusted closure provenance, conservative findings/evidence retention, and fresh manual-marker enqueue serialization.

Final candidate 9ec9567, base 91299cf. Both separately spawned fresh-context reviewers independently returned No Issues on the complete15-file candidate; completed automated reviews are posted above. All6 exact-head Actions jobs passed in run43569851377, including actual WordPress/MariaDB and controlled worker/package fixtures.

Strict target-control chronology now rejects pre-acceptance/future proof across notification/retrieval while permitting valid historical prepared-report delivery. SQL retention and tombstone guards preserve malformed, missing, contradictory and held evidence. Metabox controls use the WordPress parent form correctly.

This source publication runs only the repository's read-only test workflow. Site installation/activation and schema-v8 data application remain separately reviewed and unperformed; customer scans and report delivery require actual authorization and technical prerequisites. Rollback uses a reviewed Git revert plus separately protected installation/data recovery where applicable. Related site requirements remain open.

@CompleteDotTech CompleteDotTech left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context review A, submitted by the program coordinator on behalf of its separately spawned reviewer. This is not a human approval. Verdict: changes required.

Independent final review A — upstream PR 25 / issue 24

Reviewed identity and verdict

  • Repository: CompleteTech-Security/php2shell-check
  • Worktree: /home/complete/ct-worktrees/h17-upstream-v8-20261113
  • Base: 91299cf90e20c6b29ed0c6df0b21ebe4ce376623
  • Head: b96360162457d39427f706d5f119ab151030fbb5
  • Verdict: Changes required — two unresolved findings (one medium, one low).

I independently fetched issue 24, read the applicable repository instructions, README, CONTRIBUTING, SECURITY and all of docs/WORDPRESS.md, and inspected the complete 14-file base-to-head diff and relevant surrounding implementation/tests. There were no nested AGENTS.md files in the changed directories. The base is the merge base of the supplied commits. The worktree was clean before and after review. No implementation files were changed, and no other review reports, PR comments or verdicts were consulted.

Findings

A1 — Medium / P2: the destructive findings SQL accepts event records that the trusted-event validator rejects

Location: integrations/wordpress/ct-scan.php:1633 through the event predicates at lines 1641–1642; compare ct_scan_closure_metadata_trusted() at lines 1095–1132.

The new purge directly clears result_json and manual_remainder_notes using a weaker definition of a trusted event than the PHP validator. Lower-bound date comparisons do not establish a valid calendar date. For example, with a 2023 creation/acceptance, closed_at = report_delivered_at = report_access_used_at = '2024-02-00 00:00:00', source report_delivery, actor 0, reason report_delivered, terminal status and no hold, the timestamp comparisons pass once the cutoff is later than that value. MariaDB can retain partial-zero DATETIME values when NO_ZERO_IN_DATE is absent. The PHP validator correctly rejects this event, but the UPDATE can still erase its findings.

There is also an exactness mismatch on ordinary case-insensitive WordPress table collations: closure_source = 'REPORT_DELIVERY' matches the SQL literal report_delivery, while PHP's strict source comparison rejects it. The same issue applies to status/reason comparisons. A restored or damaged record can therefore be displayed and treated elsewhere as untrusted while its findings are irreversibly cleared. This violates issue 24's fail-closed requirement for malformed event evidence.

Executed evidence and reproduction: I executed the current PHP validator with both the partial-zero event and an otherwise valid event whose source was REPORT_DELIVERY; both returned false. After the coordinator supplied a verified local runtime account, I executed the table-independent MariaDB SELECT in the appendix with an explicit supported _ci collation and a canonical control row. MariaDB returned findings_purge_matches = 1 for all three rows, including both malformed events. This confirms the predicate mismatch without reading any database tables or executing an UPDATE. The behavior also follows the documented MariaDB date rules and collation semantics.

Required change: Make the destructive purge require the same strict event/date validation as ct_scan_closure_metadata_trusted(). A bounded per-row validation plus a compare-and-set that preserves the hold/race checks is one option. If SQL validation is retained, it must cover real calendar dates and exact event/status/reason semantics, not just textual lower bounds. Add actual database regression cases demonstrating that malformed dates and noncanonical event fields retain both findings columns, while a valid due event still clears them.

A2 — Low / P3: the edit-screen metabox falsely rejects every successfully recorded closure

Location: integrations/wordpress/ct-scan.php:3930, with the resulting branch at lines 3942–3947.

The final-close metabox selects neither created_at nor terms_accepted_at, but immediately passes its projected row to ct_scan_closure_metadata_trusted(), which requires both properties. Consequently the trusted branch is unreachable. After a valid administrator final close or report redemption, the edit screen says, “Closure metadata is present but does not pass validation; leave the request pending for review.” The private queue, which selects the full row, recognizes the same event as trusted. This gives the administrator contradictory lifecycle evidence after a successful action.

Executed reproduction: Using the existing standalone report fixture, I supplied a fake database that returns exactly the columns named by the metabox SELECT, finalized a failed request as authenticated administrator 41, and rendered the metabox. The output was:

Close succeeded: true
Full stored row trusted: true
Metabox output: Report transport: not_sent. Report delivered: not confirmed.Closure metadata is present but does not pass validation; leave the request pending for review.

Required change: Include all properties required by the validator in that SELECT (at least the two missing dates), and test the actual metabox projection/rendering after both an admin close and a redeemed report. Verify that malformed records still show the warning.

Acceptance and security checks

Issue 24 criterion Review result
Canonical client/signer identity and exact Target Summary Strict evidence checks bind the saved legal name, signer name, role and typed signature to their digests and contract header; the canonical summary includes the client/signer fields and code-defined limits. Duplicate, partial and mismatched evidence is refused. The frozen summary digest detects later identity/scope changes.
Generic notification; harmless GET; one-time POST Mail contains a generic subject/body and opaque capability link, with only its SHA-256 hash stored. GET renders a form without serving findings or recording retrieval. POST rereads the row and accepted request under the queue lock, checks recipient, target/scope, terms, confirmation, target-control window and capability, and serves escaped findings only after a successful compare-and-set. Failed writes, replay, revocation and mismatches disclose no report.
Explicit trusted closure Terminal execution timestamps are no longer promoted to new closure events. Report POST records access, retrieval and closure in one database update. Independent no-report closure requires an authenticated positive administrator, manage_options, the exact terminal reason, unambiguous no-report state and sane clocks. The metabox display has finding A2.
366-day findings retention; malformed evidence kept The PHP policy uses the trusted retrieval/no-report close and a separate 366-day deadline. New-version evidence requires trusted closure; legacy acceptance-based evidence periods remain. The destructive SQL has finding A1.
Optional manual-close/enqueue serialization The manual readiness helper proves current-connection queue-lock ownership, current schema and a successful absent-job query. Enqueue reads the exact raw marker directly from postmeta under that same lock. Missing verifier, malformed/duplicate values and read failures block enqueue; cached absence is not trusted.
Defaults, target safety and regression coverage Disabled configuration, explicit terms policy, egress prerequisite, passive profile, confirmation/control gates, authenticated worker protocol and no-rescan behavior remain. No active scanning profile or activation was added. Local and hosted tests cover meaningful success, refusal, race, legacy and database paths, but omit the two failing scenarios above.

The reviewed report path intentionally separates expired scan traffic authorization from delivery of an already prepared report to its unchanged confirmed recipient. Its capability has its own seven-day expiry. This does not admit new target traffic. Report access headers deny storage, referrers, indexing, framing and external resources; output escaping prevents report text from executing as markup. Mail transport acceptance remains separate from server-observed report retrieval, which is not proof of human reading.

Verification and evidence limits

Executed locally on the reviewed worktree:

  • python -m unittest -v: 197 tests; 193 passed, four skipped, exit 0. A ResourceWarning was emitted by an existing synthetic socket test; it did not fail the suite.
  • python wordpress_check.py --help: passed.
  • git diff --check BASE HEAD: passed.
  • All four standalone PHP suites with the provided PHP 8.3 runtime: report access (72 checks), manual lifecycle (30 guards), retention and tombstones passed. The tombstone suite intentionally logged its synthetic failed-read case.
  • PHP syntax checks: 18 integration/standalone/deployment-fixture files, zero failures.
  • The extra metabox projection reproduction confirmed A2; extra PHP validator probes rejected both malformed events described in A1.
  • Authorized MariaDB constant/derived-row SELECT: both malformed events and the canonical control matched the purge predicate. No database was selected, no existing table was read, and no database mutation occurred.

Hosted evidence was checked independently through GitHub read APIs and compared with the specified h17-tests/upstream-ci-b963601-jobs.json manifest. Run 43545235956, associated with the exact reviewed head, completed successfully in all six jobs: Python 3.10/3.14 on Linux/Windows, standalone PHP lifecycle tests, and WordPress queue/authorization. The WordPress job log checks out the PR merge of the reviewed head into the reviewed base and reports passing queue/receipt, admission, bound acceptance, HTTP worker, retention, target-control and packaging/isolation checks. Since the supplied base is an ancestor of head, the reviewed source changes are the candidate changes exercised by that merge.

I did not rerun a real WordPress/MariaDB application fixture locally: PHP was initially absent from PATH and the Docker socket was inaccessible. The provided staged PHP binary allowed all standalone checks. An initial authorized MariaDB attempt as root was refused before execution; after the coordinator provided the verified local account, the pure constant/derived-row SELECT succeeded. The already successful hosted disposable WordPress/MariaDB job is actual application/database evidence; local mocks or the limited SQL predicate check are not substituted for it. No production endpoints, customers, real target scans, worker activation or real report delivery were involved.

Outstanding pre-merge work: Resolve A1 and A2, add their focused regressions, run the required checks/hosted database job on the revised exact head, and independently review that final diff/head. The successful current CI does not resolve these findings.

Post-merge site application criteria — not completed by this review

Merging the upstream source does not apply schema 8 to production, deploy the site or activate a worker. Before any production application:

  1. Obtain matching independent review of the integrated site PR against its current main, including the recorder/theme/archive implementation. Verify exact upstream/site release identities and matching managed plugin bytes; the packet's claimed site source binding is not an independent site review performed here.
  2. Verify a protected pre-migration backup and a demonstrated isolated restore. Keep backups/configuration HTTP-denied, access restricted and secrets out of logs.
  3. Apply the reviewed schema/code only with the queue disabled and the exact worker identity/build/configuration reconciled. Verify the report route, headers, capability replay/refusal and closure behavior using isolated synthetic requests; do not use customer scans as a deployment test.
  4. Define rollback as the matching prior code and protected pre-migration database, preserving/reconciling evidence and pending receipts. Do not reinterpret legacy report email or maintenance timestamps as trusted retrieval. Restoring only old code over a migrated database is not the demonstrated rollback criterion.
  5. Keep production disabled until actual customer/exact-target authorization and the existing worker, egress, cancellation and delivery prerequisites are separately satisfied. No activation authorization follows from this upstream PR or this review.

Appendix — bounded literal/derived-row MariaDB predicate check

This successfully executed query uses no selected database, tables, DDL or mutations. The partial-zero row is meaningful on MariaDB configurations that permit such values. The uppercase row independently demonstrates the collation issue using valid dates. A canonical control is included. Observed SQL result: findings_purge_matches = 1 for all three rows. The executed PHP trust probes returned false for the first two.

partial-zero event  2024-02-00 00:00:00  report_delivery  1
upper-case event    2024-02-01 00:00:00  REPORT_DELIVERY  1
canonical control   2024-02-01 00:00:00  report_delivery  1
SELECT case_name, closed_at, closure_source,
  (status IN ('completed','failed','failed_unknown','cancelled','expired','blocked')
   AND created_at >= '2020-01-01 00:00:00'
   AND terms_accepted_at >= '2020-01-01 00:00:00'
   AND closed_at >= '2020-01-01 00:00:00'
   AND closed_at >= created_at AND closed_at >= terms_accepted_at
   AND closed_at <= '2026-11-14 00:00:00'
   AND closed_at < '2025-11-13 00:00:00'
   AND ((closure_source = 'report_delivery' AND closed_by = 0
         AND closure_reason = 'report_delivered'
         AND report_delivered_at = closed_at
         AND report_access_used_at = report_delivered_at)
        OR (closure_source = 'admin_final_close' AND closed_by > 0
            AND closure_reason = status
            AND report_delivered_at IS NULL
            AND report_access_used_at IS NULL))) AS findings_purge_matches
FROM (
 SELECT 'partial-zero event' AS case_name,
    CONVERT('completed' USING utf8mb4)
      COLLATE utf8mb4_unicode_520_ci AS status,
    CAST('2023-01-01 00:00:00' AS DATETIME) AS created_at,
    CAST('2023-01-01 00:00:00' AS DATETIME) AS terms_accepted_at,
    CAST('2024-02-00 00:00:00' AS DATETIME) AS closed_at,
    CONVERT('report_delivery' USING utf8mb4)
      COLLATE utf8mb4_unicode_520_ci AS closure_source,
    0 AS closed_by,
    CONVERT('report_delivered' USING utf8mb4)
      COLLATE utf8mb4_unicode_520_ci AS closure_reason,
    CAST('2024-02-00 00:00:00' AS DATETIME) AS report_delivered_at,
    CAST('2024-02-00 00:00:00' AS DATETIME) AS report_access_used_at
 UNION ALL SELECT 'upper-case event', 'completed',
    CAST('2023-01-01 00:00:00' AS DATETIME),
    CAST('2023-01-01 00:00:00' AS DATETIME),
    CAST('2024-02-01 00:00:00' AS DATETIME), 'REPORT_DELIVERY',
    0, 'report_delivered',
    CAST('2024-02-01 00:00:00' AS DATETIME),
    CAST('2024-02-01 00:00:00' AS DATETIME)
 UNION ALL SELECT 'canonical control', 'completed',
    CAST('2023-01-01 00:00:00' AS DATETIME),
    CAST('2023-01-01 00:00:00' AS DATETIME),
    CAST('2024-02-01 00:00:00' AS DATETIME), 'report_delivery',
    0, 'report_delivered',
    CAST('2024-02-01 00:00:00' AS DATETIME),
    CAST('2024-02-01 00:00:00' AS DATETIME)
) AS synthetic_events;

@CompleteDotTech CompleteDotTech left a comment •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context review B, submitted by the program coordinator on behalf of its separately spawned reviewer. This is not a human approval. Verdict: changes requested.

Independent final review B — upstream PR 25

Scope and verdict

  • Repository: CompleteTech-Security/php2shell-check, local checkout /home/complete/ct-worktrees/h17-upstream-v8-20261113.
  • Issue independently retrieved: #24, “WordPress: protect report retrieval and record trusted request closure.”
  • Exact reviewed base: 91299cf90e20c6b29ed0c6df0b21ebe4ce376623.
  • Exact reviewed head: b96360162457d39427f706d5f119ab151030fbb5.
  • Verdict: Changes requested. Three new defects and one remaining acceptance gap are unresolved below. No source fixes were made.

I read AGENTS.md, README.md, CONTRIBUTING.md, SECURITY.md, docs/WORDPRESS.md, the factual review packet and exact CI manifest. There were no nested AGENTS.md files in the repository. I inspected the complete 14-file base-to-head diff and surrounding acceptance, queue, retention, report and admin code, including all four new standalone suites. I did not participate in implementation or consult other reviewers, review reports, PR review comments or verdicts.

Findings

B1 — P2: The edit-screen final-close form is nested inside WordPress’s post form

Location: integrations/wordpress/ct-scan.php:3957; the emitted helper is at line 3912.

ct_scan_admin_render_final_close_metabox() is a side metabox on the request edit screen, but calls ct_scan_admin_form(), which emits a complete <form>. WordPress already wraps these metaboxes in its <form id="post" action="post.php">. Browsers discard the nested form opening tag: the closure button submits the outer edit form, with competing action and _wpnonce controls, to post.php instead of admin-post.php. The nested closing tag also ends the outer form prematurely, which can detach later edit controls. The queue-page form is a separate working route; that does not make this new edit-screen control functional.

Reproduction executed: Rendered the actual candidate metabox with the standalone fixture’s synthetic pending terminal job, placed that output inside the documented WordPress edit-form wrapper, and parsed it in headless Chromium using a local data: document. No HTTP submission occurred. The DOM reported:

{"forms":1,"closeFormId":"post","closeFormAction":"https://complete.tech/wp-admin/post.php","submittedActions":["editpost","ct_scan_admin_action"],"nonceCount":2,"updateHasForm":false}

The official WordPress edit-form source confirms that do_meta_boxes( $post_type, 'side', $post ) occurs inside the post form.

Required change: Use an edit-screen-safe control, such as a link to the private queue, or a separate form outside the post editor with explicit form ownership. Preserve the authenticated, nonce-protected POST handler. Add a DOM/browser regression covering the edit screen and ordinary post saving.

B2 — P2: Revoking an unused v8 report link destroys the evidence needed for no-report final close

Location: integrations/wordpress/ct-scan.php:3375, interacting with lines 3655–3663 and 3721.

Revocation clears report_access_token_hash and report_access_expires_at while leaving the notification status accepted or unknown. Those capability fields are also the only durable discriminator used by ct_scan_no_report_close_eligible() to distinguish a v8 link notification from ambiguous pre-v8 mail containing findings. Consequently, a normal “issue link, revoke before retrieval, explicitly finalize without a report” sequence becomes permanently ambiguous. An authenticated administrator cannot close it, the findings have no trusted 366-day anchor, and current-version signed evidence has no trusted closure anchor. The queue UI also hides its close controls for revoked jobs.

Reproduction executed: Reused standalone-tests/report-access.php without modifying it: send_fixture_link(true), then ct_scan_admin_revoke($job_id), then set synthetic authenticated administrator 71 with manage_options and call ct_scan_admin_close($job_id, 'failed'). Result:

{"eligible_before_revoke":true,"revoked":true,"eligible_after_revoke":false,"notification_status":"accepted","close_result":"close_report_ambiguous","closure_source":null}

Required change: Retain durable non-secret proof that this was a v8 link-only notification while invalidating redemption, or record an explicit link cancellation state sufficient for the no-report close validator. Keep revoked links unusable and keep ambiguous pre-v8 full-report mail pending. Add the full issued-link → revoke → authenticated no-report close regression.

B3 — P3: The edit-screen metabox always labels valid closure metadata untrusted

Location: integrations/wordpress/ct-scan.php:3930, used at line 3942.

The metabox’s SELECT omits created_at and terms_accepted_at. ct_scan_closure_metadata_trusted() explicitly requires both properties, so it always returns false for this projected object. Every valid report-retrieval or administrator closure therefore renders “Closure metadata is present but does not pass validation; leave the request pending for review” instead of its actual final-closure state.

Reproduction executed: Extended the standalone fake database to apply the actual SQL projection, created a pending terminal fixture, and successfully closed it as synthetic administrator 72. The complete stored row passed ct_scan_closure_metadata_trusted(), while rendering the metabox returned:

{"close_result":true,"full_row_trusted":true,"metabox_markup":"<p>Report transport: not_sent. Report delivered: not confirmed.</p><p>Closure metadata is present but does not pass validation; leave the request pending for review.</p>"}

Required change: Select all fields required by the validator and test the metabox with both trusted closure sources and genuinely malformed metadata.

B4 — P2 acceptance gap: The modified tombstone guard still bypasses legacy closure-date invariants

Location: integrations/wordpress/ct-scan.php:1320 and line 1337; deletion is reached at line 1759.

For an evidence-only r2-or-earlier row, ct_scan_required_retain_until() derives its deadline solely from acceptance and creation. The modified tombstone helper never checks whether closed_at is present, valid, or no earlier than creation. A matching tombstone can therefore delete a legacy row that ct_scan_deletion_decision() correctly keeps for a missing, invalid or backwards closure. This contradicts issue #24’s invalid/backwards-date acceptance criterion and the new standalone test’s explicit legacy invariant. This is a remaining gap in the changed retention scope, not a newly introduced base-to-head regression.

Reproduction executed: Used the new retention suite’s legacy_due fixture (terms_version=2026-10-21-r2, accepted/created 2021-01-01 00:00:00, deadline 2024-01-01 00:00:00, terminal, no hold and no findings), and evaluated it at 2026-01-16 00:00:00. For each closed_at value below, normal retention returned ['keep', null] but the candidate tombstone helper returned true:

null
invalid
2020-12-31 23:59:59

I also passed the closed_at=null row and a matching scope MAC/identity tombstone through the actual ct_scan_apply_tombstones() using the standalone synthetic database. It performed one tombstone insert, one personal-field scrub and one job deletion despite normal retention’s keep decision. This reproduction used only in-memory synthetic records; no database was accessed.

Required change: Apply the legacy date prerequisites consistently to tombstone deletion, including valid/non-backwards closure and valid stored deadlines, without replacing the three-year acceptance-based period with the newer six-year policy. Add matched-tombstone regressions for evidence-only legacy rows with missing, zero/invalid and backwards closure dates. The existing tests exercise these dates only through normal retention.

Acceptance and security checks

The reviewed implementation does bind strict acceptance to canonical legal name, signer name, stated role, exact typed signature and Target Summary, with duplicate/missing evidence rejection. It retains a distinct legacy summary function. Report mail is generic; the random 256-bit capability is hashed at rest; GET produces a form without findings or consumption; POST revalidates the saved request, confirmed recipient, target-control fields, accepted tuple, result and pending closure under the queue lock. Its compare-and-set records retrieval, delivery and closure together before serving escaped findings. Responses disable caching, indexing, referrers, framing and external resources. The bearer capability supplies the authorization for the explicit POST; no report content is placed in notification mail.

Terminal scanner state is no longer promoted automatically to trusted closure. New-version retention requires explicit source/actor/reason metadata, findings use the separate 366-day anchor, and matching tombstones no longer override an underivable current-version deadline. B4 identifies the remaining legacy inconsistency. Manual no-queue readiness verifies current connection lock ownership, schema 8 and a successful absent-job read. Enqueue reads the raw lifecycle marker directly under the same lock, rejects duplicate/malformed/unverifiable markers, and passes the exact raw value to the optional archive verifier. This addresses the stale whole-post-metadata-cache enqueue race.

No scanner profile, worker network adapter, target budget or egress enforcement was broadened. Defaults remain disabled, with explicit terms policy and external egress prerequisites. No production changes, customer scans, target contacts or real report deliveries were performed during this review.

Validation and evidence

Executed locally on the frozen candidate

  • python3 -m unittest -v: 197 tests, 193 passed, 4 skipped, 26.609 seconds. The skipped privileged execution cases are covered by the hosted privileged-worker job.
  • CLI --help: passed.
  • Exact base-to-head git diff --check: passed.
  • PHP 8.3.35, zend.assertions=1, assert.exception=1: all four standalone suites passed: report access (72 checks), manual lifecycle (30 guards), retention and tombstones.
  • PHP lint: all 17 integration/source/standalone PHP files plus changed deployment/test-http-fixture.php passed (18 files).
  • Additional targeted PHP reproductions and local Chromium DOM reproduction above. These expose cases absent from the passing suites.
  • Repository working tree remained clean; source head remained frozen.

The host has no system PHP and the current user cannot access the Docker socket; noninteractive sudo also requires a password. I used the existing supplied PHP 8.3.35 CLI at /home/complete/Documents/projects/ct/complete-tech-program-20261112/private/archived-local-runtime/php83-build/sapi/cli/php with my isolated TMPDIR. I did not rerun a local WordPress/MariaDB instance or inspect another database.

Hosted evidence independently checked

I read h17-tests/upstream-ci-b963601-jobs.json, independently fetched the workflow runs associated with the exact head and all six live job results, and inspected the actual WordPress/MariaDB job log. Actions run 43545235956 completed successfully:

  1. Python 3.10 on Ubuntu.
  2. Python 3.14 on Ubuntu.
  3. Python 3.10 on Windows.
  4. Python 3.14 on Windows.
  5. WordPress lifecycle unit checks.
  6. WordPress queue and authorization, including actual disposable WordPress/MariaDB integration, admission/cancellation, bound evidence, synthetic HTTP worker/control, retention, privileged worker execution and packaged isolation.

The log explicitly shows the generated PR merge commit 65d55e4ea402aa29bf39aac6171030603a443c26, merging the requested head into the requested base. Local git merge-base BASE HEAD equals the exact base, so this is the candidate’s source content with a generated merge identity, rather than a literal checkout of head b963601. The actual log records “WordPress integration checks passed,” “Evidence binding checks passed,” “Retention checks passed,” successful synthetic HTTP boundaries and scanner secret isolation. Thus actual database evidence is present; local mocks are not being substituted for it.

Missing pre-merge coverage

The generic required local and hosted checks are available and green. Regression coverage is missing for B1–B4, and these findings must be fixed and reverified on the resulting exact head before this review can approve it. A full running WordPress edit-screen browser test was not performed locally; B1 is confirmed by the actual candidate markup parsed in Chromium and the official WordPress form structure. No production backup or restore outcome is claimed by this source review.

Post-merge site application and rollback criteria

Merging upstream PR 25 alone must not deploy CompleteTech, enable the queue, activate workers or scan customers. Any resulting upstream revision requires matching independent review of the site PR/current main after integration, and exact source binding between the released upstream plugin bytes, site-managed plugin and configured/built worker identity. The separate site theme/recorder and archive-plugin implementation were not reviewed here.

Before schema 8 is applied to production, verify a protected, HTTP-denied pre-migration database/code backup and demonstrate an isolated restore. Keep the queue disabled and workers stopped or reconciled through application, verify the actual schema and public/admin route behavior, and preserve existing acceptance and receipt evidence. Installation can migrate schema on init even while queue execution is disabled; backup/restore gates must precede installing the code.

Rollback must restore the reviewed prior code together with its protected pre-migration database, with a plan to preserve/reconcile any intervening live evidence. Restoring only old code is insufficient. Ambiguous legacy report mail must not be relabeled trusted retrieval. No backup, restore, live migration, source-binding verification or rollback was performed by this reviewer.

The owner has already approved program implementation, merges and necessary production changes; the root coordinator is the sole executor, and no new owner go-live decision is required. Root-coordinated application and execution must still meet the protected backup/isolated restore requirements, customer-specific and exact-target authorization, matching accepted signer/summary evidence, confirmed recipient and target control, matching reviewed source/worker identity, protected credentials/receipts, independently enforced egress, and retention, cancellation and delivery verification. This candidate neither expands active scanning nor satisfies those operational prerequisites by itself.

@CompleteDotTech CompleteDotTech left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context round 2 review A, submitted by the program coordinator on behalf of a separately spawned reviewer. This is not a human approval. Verdict: changes required.

Independent final review A — upstream PR #25 / issue #24

  • Verdict: Changes required. One unresolved medium-severity finding; this candidate does not qualify for No Issues.
  • Repository: CompleteTech-Security/php2shell-check.
  • Reviewed base: 91299cf90e20c6b29ed0c6df0b21ebe4ce376623.
  • Reviewed head: 8d3243b3ec65040b8f93d98254eca5d334fc022b.
  • Worktree: /home/complete/ct-worktrees/h17-upstream-v8-review-fixes-20261114; clean before and after review. Base is the merge base. No source changes made.
  • Completed: 2026-11-14 UTC. Fresh independent review; no implementation participation, reviewer contact, previous review reports, or PR comments/reviews used.

Scope and requirements

Read repository AGENTS.md, README, CONTRIBUTING, SECURITY, and all of docs/WORDPRESS.md; the instruction search found no nested AGENTS.md. Independently fetched the issue #24 body, checked current PR base/head metadata and hosted jobs, and inspected the full 15-file base-to-head diff plus surrounding authorization, queue, report, retention, hold, admin, and test code. The supplied factual packet and CI manifest supplemented that inspection.

The issue requires canonical client/signer and exact Target Summary binding; a generic notification with harmless GET and single-use protected POST retrieval; a fresh authorization check and atomic retrieval event; explicit trusted closure rather than scanner timestamps; 366-day findings retention with conservative handling of doubtful evidence; shared locking for optional manual closure and enqueue; and preservation of disabled defaults and target/egress controls.

Finding R1 — Medium / P2: PHP truthiness bypasses findings retention for the valid string 0

Locations: ct-scan.php:1296, ordinary evidence deletion; ct-scan.php:1351, matched-tombstone deletion. The same logical defect occurs in both places.

Both predicates use ! empty( $row->result_json ) || ! empty( $row->manual_remainder_notes ) to decide whether the independent findings deadline must be enforced. PHP regards the nonempty string '0' as empty. This is an accepted manual-notes value: ct_scan_admin_save_manual_remainder() rejects only an empty string or more than 12,000 bytes (line 3476), and the report builder likewise treats '0' as present.

Once a legacy acceptance's three-year signed-evidence deadline is due, a failed job with result_json = NULL and manual_remainder_notes = '0' can therefore be deleted immediately after an explicit final close, despite its 366-day findings deadline still being almost a year away. A matching tombstone allows the same early deletion. If trusted event metadata is absent, the same false “no findings” classification also bypasses the intended keep-on-unknown findings rule. This defeats the issue's findings-retention acceptance criterion; the strict findings-purge helper does not prevent the subsequent whole-record deletion.

Reproduction, all synthetic and offline:

  1. Confirm the supported save API accepts '0'. The independent fixture returned {"notes_save_succeeded":true,"stored_notes":"0"}.
  2. Construct an otherwise valid terminal legacy row: acceptance/creation 2021-01-01 00:00:00, existing evidence deadline 2024-01-01 00:00:00, trusted administrator close 2026-11-13 00:00:00, actor 42, matching reason failed, both report timestamps SQL NULL, valid opaque identity, and no hold. Set result SQL NULL and notes '0'. Evaluate at 2026-11-14 00:00:00.
  3. ct_scan_closure_metadata_trusted() returns true and ct_scan_findings_retain_until() correctly returns 2027-11-14 00:00:00, but ct_scan_deletion_decision() returns ['delete', null], ct_scan_tombstone_deadline_passed() returns true, and ct_scan_delete_if_due() reaches the mocked destructive path (deleted, one job deletion).
  4. Change only notes to 'no external findings': the ordinary decision becomes keep, the tombstone predicate becomes false, and no job deletion occurs.

Runnable harnesses and captured results:

Required change: Determine findings presence from explicit SQL NULL state, with missing/ambiguous columns kept conservatively, consistently with ct_scan_purge_findings_if_due(). Cover both ordinary and tombstone deletion with a stored '0' value and recent/missing trusted event evidence. Keep the positive evidence-only NULL/NULL controls. No fix was made during this review.

Acceptance assessment

Criterion Assessment
Canonical signer/client identity and exact Target Summary Satisfied in the reviewed paths: canonical fields, signature equality, authority/evidence digests, duplicate rejection, exact summary bytes, and frozen summary digest. Actual database strict-acceptance checks passed.
Generic notification and protected single-use retrieval Satisfied in reviewed paths: random 256-bit token hashed at rest, generic email, no findings or event write on GET, fresh validation under queue lock on POST, guarded single-use write, and escaped report response.
Current saved recipient, acceptance, revocation and target authority Satisfied in reviewed paths: private request/job linkage and accepted tuple are reread; recipient confirmation and original exact-target verification are required. Traffic expiry is deliberately distinct from prepared-report delivery expiry.
Explicit closure and trustworthy event evidence Satisfied in reviewed paths: authenticated positive administrator actor plus exact terminal reason, or one successful retrieval event with equal access/delivery/closure timestamps; terminal status alone no longer closes requests. Old ambiguous mail state remains pending.
366-day findings lifetime and legacy/evidence deletion Not fully satisfied: R1. Ordinary values pass the new conservative logic, but PHP-empty non-NULL findings can skip that gate during whole-record deletion.
Dates, holds, races, tombstones, restored rows and failures Reviewed protections and existing regressions pass, including strict PHP date/case validation, binary findings CAS, committed hold race, raised periods, failed queries, lease preservation, restored snapshots and pagination. R1 affects both ordinary and tombstone findings-presence checks.
Optional manual-close/enqueue serialization Satisfied in reviewed paths: connection-owned queue lock, current schema and successful empty-queue read; direct raw marker query under the same enqueue lock; exactly one raw marker passed to its owning verifier; ambiguous/missing-verifier state blocks enqueue.
Edit screen and ordinary post save Satisfied: the actual metabox projection contains validator fields; the metabox links to the private queue without nesting a form. Independent Chromium DOM/save verification passed.
Privacy, passive scope, compatibility and defaults No additional finding. No scanner/Python or worker profile expansion; disabled/egress/terms-policy gates and confirmation/admission/cancellation restrictions remain. Legacy acceptance-based retention and uncertain migrated state remain conservative except R1.
Deployment/rollback documentation Source guidance clearly separates upstream merge from installation/activation, identifies schema-8 migration while disabled, and requires protected backup/restore and deployment verification. Actual production proof remains a site gate.

Test evidence

Independent local checks on the frozen head:

  • PHP 8.3.35, zend.assertions=1, assert.exception=1: standalone report access 84 checks, retention, tombstones, and manual lifecycle 30 guards all passed. Local logs.
  • Python unittest: 197 total, 193 passed, 4 skipped, exit 0; the skips are privilege/environment-dependent worker checks. CLI help and exact-range git diff --check passed. Python log.
  • All 18 PHP files in the integration/fixture scope linted successfully. Lint log.
  • Generated HTML from the actual committed PHP report fixture and independently drove installed Chromium via CDP inside bwrap --unshare-net: one original editor form, editpost action, original nonce and update-button form ownership, working private queue link, intercepted ordinary post save, zero page network requests. DOM receipt. This was an independent browser harness; the committed Playwright script itself was inspected, not rerun.
  • R1 independently reproduced with a nonzero-string control; current suites do not cover this accepted zero-string deletion case.

Local HOME and TMPDIR were unique private directories under private/up25-r2-a-runtime/review-54p90rnk, mode 0700. Chromium used a short namespace mount of that same private TMPDIR to fit its Unix-socket path limit; host /tmp storage was not used. No existing WordPress database, customer endpoint, production endpoint, target scan, or notification service was accessed or mutated.

Independently checked hosted evidence: Actions run 43552397396 is successful with all six jobs: Python 3.10/3.14 on Ubuntu/Windows, standalone PHP lifecycle, and real disposable WordPress/MariaDB integration. The job logs identify PR merge ref 512dc60…, merging the exact reviewed head into the exact reviewed base; the base is already an ancestor of this head.

The WordPress job log records successful integration, admission, bound acceptance, HTTP synthetic worker/receipt retry, retention, target-control, privileged-worker and packaged-secret-isolation checks. The standalone job records all four lifecycle suites passing. Source inspection confirms the actual database regressions retain malformed dates/case, assert the invalid values survive storage, exercise the before-CAS hold mutation, and include valid restored-row/lease/paging controls. I did not connect to or rerun any existing database locally.

Existing required pre-merge evidence is present, but successful CI does not cover or resolve R1. A corrected candidate needs regression verification and review before a No Issues verdict.

Post-merge site criteria

These remain installation/activation prerequisites, not authorization supplied by an upstream merge:

  1. Review the separate site source candidate and its actual private WordPress/CLI/archive and visual rehearsals; matching scanner bytes alone do not review its form, recorder, archive or theme changes.
  2. Before installation can run the init-time schema migration, verify an HTTP-denied protected backup and demonstrate an isolated restore. Reconcile exact released integration/worker identity and validate schema/routes and private capability access in the site environment while execution remains disabled.
  3. Verify real customer consent, signer authority and exact-target authorization before any target traffic. Maintain existing recipient confirmation, cancellation, worker credential isolation and independently enforced egress requirements; conduct no production scan as a deployment test.
  4. Verify actual report/accepted-copy delivery prerequisites and distinguish mail-transport acceptance, server-observed retrieval and human reading. Synthetic fixtures establish none of those real-world outcomes.
  5. Rehearse rollback with previous code and protected database restoration, preserving intervening real leads, immutable acceptance evidence, queue state and receipts. A code downgrade alone cannot convert old full-report email state into trusted v8 closure evidence.

Root remains the sole merger and production operator. No new owner-approval loop or production change was requested or performed by this review.

@CompleteDotTech CompleteDotTech left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context round 2 review B, submitted by the program coordinator on behalf of a separately spawned reviewer. This is not a human approval. Verdict: changes required.

Independent final review B — changes required. Two medium-severity findings and one low-severity finding remain. This candidate does not meet the requested zero-unresolved-findings standard.

Review identity Value
Repository / PR CompleteTech-Security/php2shell-check, PR 25
Requirements Issue 24 body, independently fetched through GitHub; no comments or reviews read
Exact base 91299cf90e20c6b29ed0c6df0b21ebe4ce376623
Exact head 8d3243b3ec65040b8f93d98254eca5d334fc022b
Worktree /home/complete/ct-worktrees/h17-upstream-v8-review-fixes-20261114
Integration SHA-256 cf045f91727e7238c30e327d717fa11a6e3d93b7c0f3e960a5a5720d8a150eeb

I inspected all 15 changed files across the complete base-to-head diff, relevant surrounding acceptance, queue, authorization, retention, result validation, report and administrator code, and the tests. I read AGENTS.md, README.md, CONTRIBUTING.md, SECURITY.md and docs/WORDPRESS.md; no nested AGENTS.md was found. I had no implementation role, did not read previous reports, ledgers, implementation conversations or another reviewer's output, and did not spawn or contact another reviewer. The worktree remained clean and unchanged.

Actionable findings

  1. Medium / P2 — malformed confirmation timestamps authorize the new report path. Location: integrations/wordpress/ct-scan.php:3530, ct_scan_validate_report_job().

    Recipient confirmation is checked only with empty($row->confirmed_at). Both the zero datetime 0000-00-00 00:00:00 and partial-zero datetime 2024-02-00 00:00:00 are nonempty, so they pass as confirmation evidence. The new send and redemption paths then issue a link and serve findings even though the saved confirmation time cannot be verified. This concerns damaged/restored retained records; I did not establish a public input path that creates these values. The mailbox capability still applies, so this is not a claim that an arbitrary unauthenticated visitor can retrieve reports.

    Reproduction: adversarial-report.php loads only the existing in-memory standalone report fixture, replaces confirmed_at with each value, captures synthetic mail, and explicitly redeems its captured capability. For both values, actual output was sent:true, post_status:200, findings_disclosed:true. See receipt.

    Required correction: validate confirmation as a real canonical datetime with appropriate acceptance/creation/authorization chronology before sending or redeeming. Add zero/partial-zero and backwards/future confirmation cases that assert no notification or report is served, alongside a valid confirmation control. The currently supplied report tests cover a missing confirmation, not these malformed values.

  2. Medium / P2 — a damaged hold with a missing purpose is treated as no hold. Location: integrations/wordpress/ct-scan.php:1221, ct_scan_job_on_hold(), used by the new findings purge at line 1603 and by evidence/tombstone deletion.

    The helper immediately returns false when hold_reason is SQL NULL, without checking whether hold_until or other hold metadata remains present. A restored/damaged hold with a future expiry and retained setter information therefore permits destructive cleanup. The fresh-read lock and binary compare-and-set do not help: the row itself is accepted as unheld, and those predicates faithfully match its damaged values. This leaves the fail-closed handling of malformed holds incomplete.

    Reproduction: adversarial-retention.php supplies a valid due trusted event with hold_reason=NULL, hold_until='2027-01-01 00:00:00', setter 42, a saved set time, and no release. At synthetic now='2026-01-16 00:00:00', actual output was on_hold:false, purge:"cleared", result_retained:false. A due legacy evidence row with the same orphaned expiry returned evidence_decision:["delete",null]. See receipt. The destructive helper uses the existing in-memory database double; no real database was accessed.

    Required correction: recognize the absence of a hold only when the relevant hold tuple consistently represents absence. Preserve contradictory/orphaned hold metadata until repaired, including a non-null expiry with a missing purpose. Cover findings, ordinary evidence deletion and matched tombstones, plus a genuinely absent hold and a valid expired hold after grace. Existing tests cover a purpose with a missing/zero expiry, but not this inverse case.

  3. Low / P3 — legacy deletion does not reject closure before acceptance. Locations: integrations/wordpress/ct-scan.php:1282 and ct-scan.php:1337, ordinary and matched-tombstone legacy date guards.

    Both paths reject closed_at < created_at, but the legacy branch only validates the shape/calendar validity of terms_accepted_at. It does not reject closed_at < terms_accepted_at. The stronger new-version event validator does reject that ordering. Consequently a legacy record can pass deletion with contradictory acceptance/closure chronology, contrary to issue 24's invalid/backwards-date refusal criterion. This does not demonstrate deletion before the three-year acceptance-based deadline; the concern is deleting a record whose lifecycle dates are untrustworthy.

    Reproduction: the same retention edge fixture uses legacy r2, valid identity, no findings or hold, created_at='2021-01-01 00:00:00', terms_accepted_at='2021-01-01 00:04:00', closed_at='2021-01-01 00:02:00', and due retain_until='2024-01-01 00:04:00'. Actual output at 2026-01-16 00:00:00 was normal:["delete",null], tombstone:true.

    Required correction: apply the acceptance/closure ordering guard to both ordinary legacy deletion and the tombstone deadline helper while retaining the legacy three-year acceptance anchor. Add this case with a separate valid due legacy control. Existing backwards-date cases set creation and acceptance together, so they exercise only closure-before-creation.

Acceptance assessment

Criterion Assessment
Strict canonical client/signer identity and exact Target Summary Satisfied in inspected code and positive/negative hosted evidence. Required fields, typed signature/contact equality, signer and acceptance digests, duplicate evidence refusal, canonical summary and frozen summary digest are enforced.
Generic protected report notification; harmless GET; single-use protected POST; current recipient/authority Core flow is present and tested: hashed 256-bit capability, generic mail, no GET consumption/findings, locked current saved acceptance/control checks, successful-write-before-disclosure, escaped output and restrictive response headers. Finding 1 prevents full acceptance.
Explicit trusted new-version closure Satisfied for inspected normal paths. Terminal execution does not invent closure; administrator closure requires an authenticated positive actor, exact status reason, trustworthy server time and atomic write. Retrieval writes equal access/delivery/closure timestamps. Ambiguous pre-v8 mail remains pending.
366-day findings retention; missing/malformed event evidence; holds and races Event validation, bounded fresh reads and binary CAS are sound for tested cases, including the real database hold race. Finding 2 leaves malformed-hold refusal incomplete.
Legacy evidence retention; backwards dates; tombstones/restores/failures Three-year acceptance policy, creation floor, non-shortening deadlines, identity protections, bounded paging, read-failure handling and restored lease safeguards are covered. Finding 3 leaves one backwards-date ordering unchecked.
Editor metabox and ordinary saving Passed actual candidate-rendered DOM check: one original editor form, original action and nonce, associated Update button, private queue link, intercepted normal save and zero network requests.
Optional manual closure / enqueue serialization Satisfied in inspected code/tests: actual connection ownership of the queue advisory lock, schema check, successful empty-job read, fresh direct raw marker query, duplicate/malformed/missing-verifier refusal, exact raw marker passed to the verifier, and explicit false required to reopen.
Privacy, passive limits, disabled defaults and scope No new scan profile, customer traffic, historical sweep or activation was introduced. Existing target-control, cancellation/admission, HMAC, recipient and egress prerequisites remain. The Python CLI remains unchanged.

Independent verification and evidence limits

Local execution used PHP 8.3.35 with zend.assertions=1 and assert.exception=1. Unique HOME/TMPDIR storage is inside /home/complete/Documents/projects/ct/complete-tech-program-20261112/private/up25-r2-b-runtime.b3r8vW, mode 0700. Executions used bwrap --unshare-net, a read-only source/filesystem view and a writable mount of that private runtime. No existing WordPress database/tables, production endpoint, customer site, real customer email or worker activation was accessed or mutated.

Independently executed check Result
Python python3 -m unittest -v 197 tests, 193 passed, 4 skipped; 33.276 seconds
Standalone report access 84 checks passed
Standalone retention / tombstones Both passed
Standalone manual lifecycle 30 guards passed
PHP syntax 17 WordPress integration PHP files plus changed deployment HTTP fixture passed
CLI help / full base-to-head git diff --check Passed
Actual rendered metabox / headless Chromium save interception Passed; receipt records one form/action/nonce, correct button ownership, queue link and zero requests
Independent supplemental malformed-state checks Reproduced findings 1–3; receipts linked above

The first browser launch failed before page execution because the long private TMPDIR exceeded Chromium's Unix-socket path limit. The successful rerun mounted the same private runtime at /mnt inside the isolated namespace; source/fixture bytes were unchanged.

I independently queried GitHub's PR metadata, commit-associated workflow run and all six jobs, and checked the supplied exact-head manifest. Base/head match the identities above. Actions 43552397396 succeeded in all six jobs: Python 3.10/3.14 on Ubuntu/Windows, standalone PHP lifecycle checks, and actual disposable WordPress/MariaDB integration. I also fetched the WordPress job log; checkout identifies the expected head merged into the expected base, and logs show integration, admission, bound acceptance, HTTP worker, retention, target-control, privileged-worker and packaged isolation success. The real database retention suite explicitly verifies malformed values survive storage, exercises invalid-event preservation and valid clearing, injects the before-CAS hold race, and covers complete restored snapshots, paging, leases and malformed legacy tombstones. These are meaningful tests, but they omit the three reproduced cases above. I did not rerun WordPress/MariaDB locally or infer production behavior from the standalone doubles.

Required disposition and post-merge site criteria

Resolve findings 1–3 and add the stated regressions before treating a replacement exact head as “No Issues.” Run appropriate local checks and the hosted matrix on that replacement, followed by independent review. No further owner-approval loop is requested by this review; root remains the sole merger and production actor.

The following remain separate site gates after maintained-source merge, not substitutes for fixing the source findings:

  • Review and reconcile the separate site candidate's recorder, theme and archive changes; identical scanner bytes alone do not review PR 287 or prove its private WordPress/CLI/archive rehearsal and visual matrix.
  • Before installation/init can migrate schema 8, capture scoped backups in an HTTP-denied protected location and demonstrate actual isolated restore. Record the exact released integration/worker identity and verify disabled configuration, schema, routes and private access behavior.
  • Rehearse rollback with previous code and appropriate pre-migration database state while preserving intervening real leads, queue receipts and immutable accepted evidence. A code-only downgrade or indiscriminate stale database restore is insufficient. Stop/disable and reconcile the worker and its receipt spool; never turn an uncertain prior run into an automatic rescan.
  • Keep execution disabled until actual customer/exact-target authorization, accepted terms, recipient confirmation, worker identity/authentication, independent egress enforcement, cancellation/admission and delivery prerequisites are verified. Test the actual site's harmless GET/protected POST, editor saving, access headers and closure/hold/retention behavior through authorized controlled fixtures.
  • Customer consent, legal sufficiency, protected delivery configuration and production activation remain real site prerequisites. This review authorizes no production scan or customer contact, and a recorded successful retrieval is not proof of human reading.

@CompleteDotTech CompleteDotTech left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context final review A, posted by the program coordinator from the completed structured report.

Verdict: No Issues. Zero unresolved findings or missing upstream premerge evidence.
Base: 91299cf
Head: 9ec9567
WordPress integration SHA256: 00b05b07e2ba82a4d9ca5089b08ba15b5eb2ccc5133b67161a45bd82c51bdd04.

The newly spawned reviewer independently inspected the complete15-file diff, surrounding queue/authorization/report/retention code, issue24 and project instructions; no implementation, fix discussions, other reports or PR discussion was consulted. Exact-head Actions43569851377 passed all6jobs: Linux/Windows Python3.10/3.14, PHP lifecycle and actual WordPress/MariaDB queue/acceptance/HTTPworker/retention/control/privilege/package fixtures. Local checks and canonical chronology negative/positive controls were independently verified.

Acceptance checked: exact signer/client/Target Summary binding; generic notification; harmless GET and single-use POST with current evidence under lock; historical confirmation/control proof within creation/acceptance/deadline chronology; authenticated trusted no-report closure; strict SQL/PHP retention parity, holds and restored/tombstone invariants; enqueue/manual-marker serialization; no nested WordPress metabox forms.

This verdict covers the upstream source merge. Site installation, actual schema migration and public/worker outcomes require their separate reviewed backup/rehearsal/rollout gates. Customer-target authorization and controlled worker/egress/report-delivery prerequisites remain enforced. Source merge does not activate live scanning. Rollback is a reviewed source revert; preserve pre-migration backups before any later installation.

@CompleteDotTech CompleteDotTech left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated independent fresh-context final review B, posted by the program coordinator from the completed structured report.

Verdict: No Issues. Zero unresolved findings or missing upstream premerge evidence.
Base: 91299cf
Head: 9ec9567
WordPress integration SHA256: 00b05b07e2ba82a4d9ca5089b08ba15b5eb2ccc5133b67161a45bd82c51bdd04.

The newly spawned reviewer independently inspected the complete15-file diff, surrounding queue/authorization/report/retention code, issue24 and project instructions; no implementation, fix discussions, other reports or PR discussion was consulted. Exact-head Actions43569851377 passed all6jobs: Linux/Windows Python3.10/3.14, PHP lifecycle and actual WordPress/MariaDB queue/acceptance/HTTPworker/retention/control/privilege/package fixtures. Local checks and canonical chronology negative/positive controls were independently verified.

Acceptance checked: exact signer/client/Target Summary binding; generic notification; harmless GET and single-use POST with current evidence under lock; historical confirmation/control proof within creation/acceptance/deadline chronology; authenticated trusted no-report closure; strict SQL/PHP retention parity, holds and restored/tombstone invariants; enqueue/manual-marker serialization; no nested WordPress metabox forms.

This verdict covers the upstream source merge. Site installation, actual schema migration and public/worker outcomes require their separate reviewed backup/rehearsal/rollout gates. Customer-target authorization and controlled worker/egress/report-delivery prerequisites remain enforced. Source merge does not activate live scanning. Rollback is a reviewed source revert; preserve pre-migration backups before any later installation.

@CompleteDotTech
CompleteDotTech marked this pull request as ready for review November 14, 2026 07:49
@CompleteDotTech
CompleteDotTech merged commit 5d42d23 into main Nov 14, 2026
12 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-11-14T07:51:29.297827Z 9ec9567 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

1 participant