Skip to content

feat(deploy): harden canonical Linux test deployment - #484

Merged
monkey1sai merged 20 commits into
mainfrom
chore/deploy-linux-test-skill
Aug 11, 2026
Merged

monkey1sai merged 20 commits into
mainfrom
chore/deploy-linux-test-skill

Conversation

@monkey1sai

@monkey1sai monkey1sai commented Aug 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add a repo-local deploy-linux-test-environment Codex skill for the owner-inventory canonical Linux workflow
  • make deployment verification target-aware, private-bind redacted, redirect/proxy safe, and strict about service identity
  • pin the NVIDIA CAD entrypoint by exact package, size, and SHA-256; reject link escapes and atomically replace the Linux world-writable leaf with a 0400 inode
  • give the host-native Kit Manager an exact child-only runtime identity and verify its typed health values

Change Classification

Item Result
Change lane G
Behavior contract changed yes
Requirement source existing contract

Deploy Path Verification

Item Result
Affects runtime / docker / Kit / viewer / ports / env? yes — canonical Linux deploy, conversion authority, Kit Manager identity, and health verification
Canonical deploy path updated? yes — scripts/deploy.ps1, host-native launcher, verifier, and repo-local operator skill
Deploy dry-run command not used: canonical test rebuild contract forbids DryRun; executed scripts/dev/rebuild-test-deploy.ps1 -Build -InventoryPath <owner-private inventory> from fresh origin/main
Verify command remote pwsh -NoProfile -NonInteractive -File scripts/verify-all.ps1 -Profile Deployment; branch bootstrap adapter harden/reverify was separately labeled self-referential

AI Coding Governance

Item Result
Linked issue owner-directed canonical Linux deployment hardening in the current session; no separate issue
Requirement source existing contract
CODEOWNERS / owner review required before merge; this PR stops at review-ready
GitNexus evidence UNKNOWN — linked-worktree CLI discovery and the global registry could not produce a trustworthy exact diff; owner explicitly accepted source, executable tests, and independent reviewer evidence
Browser E2E evidence not a frontend product change; browser/full-system E2E is not claimed
Agent workflow changed? yes — adds one repo-local Codex deployment skill
Required checks expected PR metadata contract, changed-path CI jobs, self-referential debt gate, and local PR preflight

Windows On-Demand Verification

Item Result
Windows verification tier kit_gpu
Windows verification evidence exact head 6cf4fb8; local Windows host-native conversion suite: 101 passed, 6 skipped; kit-manager-api: 14 passed; test-remote-deploy-transport, test-host-native-launcher, test-verify-all, test-deploy-governance-static, test-self-referential-bootstrap, test-rebuild-test-deploy and test-agent-governance-check PASS; skill integrity/sync Check valid (31 skills); git diff --check clean; exact-head CI run: https://github.com/monkey1sai/AI-BIM-governance/actions/runs/31462624695 (in progress at body update; local exact-head gates passed)

Self-Referential Bootstrap

Item Result
Self-referential bootstrap yes
Bootstrap ledger entry linux-test-deploy-verifier-hardening
Bootstrap reason The canonical transport deploys only freshly fetched origin/main, so a branch that changes deploy and verification mechanisms cannot produce post-change canonical evidence before merge; branch evidence is explicitly bootstrap-only and requires a merge-time fixpoint rerun.

Verification

  • python -m pytest bim-streaming-server/tests/test_host_native_conversion_service.py -q: 101 passed, 6 skipped on Windows at exact head 6cf4fb8ba57f27a63e0a0a444fefc3b7eb927feb
  • WSL Linux atomic hardener smoke: passed; inode changed and final mode was 0400
  • scripts/tests/test-host-native-launcher.ps1: passed, including exact child env and parent restoration
  • python -m pytest services/kit-manager-api/tests -q: 14 passed, including the hostile-proxy direct-socket regression and the new redirect-rejection regression
  • scripts/tests/test-verify-all.ps1: passed
  • scripts/tests/test-deploy-governance-static.ps1: passed
  • scripts/tests/test-deploy-target-registry.ps1: passed
  • scripts/tests/test-rebuild-test-deploy.ps1: passed on the final staged revision
  • agent governance, PowerShell static, skill integrity/sync, skill-creator validation, secret scan, and git diff --check: passed
  • all 15 reviewer threads on this PR are resolved; each fix is recorded on its thread or in the commit message
  • independent contract reviewer: accept; independent security reviewer: accept

Deployment evidence and limits

  • canonical target: canonical-linux / linux_host_native / canonical_test_deploy / SSH
  • fresh baseline deployed with the regular no-selector canonical form: source a93c5a34cfef7bb6f3fdd5d20c287d9c83c89ea1; build/restart exited 0 and created deploy tag deploy-20260811-639220225263578177-002
  • owner-private env staging was created and removed; the pre-reset remote checkout had 2,205 changes and was reset/cleaned by the canonical helper
  • branch bootstrap hardening and strict adapter reverify both exited 0; tracked Linux digest matched and the entrypoint finished mode 0400
  • the currently running origin/main conversion process remains degraded because its old resolver cannot traverse the top-level cache link; this PR does not mislabel branch bootstrap as canonical post-change success
  • .bim-deploy root ACL restoration was verified after the final private-input use: protected DACL with exactly owner, SYSTEM, and Administrators
  • Full-system E2E claimed: no

Known follow-up

  • add the CAD resolver/atomic-hardener security suite to required Windows and Linux CI so future trust-boundary regressions cannot pass on the existing stage-only streaming gate
  • after merge, rebuild from fresh origin/main, rerun the same strict deployment verification, and close the bootstrap ledger fixpoint in a separate PR

Summary by CodeRabbit

New Features

  • Added a governed workflow for rebuilding and independently verifying the canonical Linux test environment.
  • Added trusted CAD extension validation and permission hardening.
  • Added target- and inventory-aware deployment verification with service and JSON identity checks.
  • Improved host-native service startup configuration and environment isolation.

Bug Fixes

  • Deployments now fail safely on invalid artifacts, identities, permissions, targets, or health checks.
  • Runtime control requests bypass inherited proxies and remain blocked when unconfigured.

Tests

  • Expanded coverage for deployment governance, CAD trust validation, environment handling, and target verification.

Copilot AI balanced review requested due to automatic review settings August 10, 2026 06:52
@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds canonical Linux deployment skills, trusted CAD entrypoint validation, host-native Kit Manager control handling, target-aware deployment verification, proxy-free runtime requests, and self-referential bootstrap evidence.

Changes

Linux deployment security and verification

Layer / File(s) Summary
Canonical deployment workflow
.codex/skills/..., .claude/skills/..., agent-skills-manifest.json, .gitattributes, .gitignore
Defines gated rebuilds, secure staging, independent verification, structured reporting, and agent metadata.
Trusted CAD entrypoint validation
bim-streaming-server/config/..., bim-streaming-server/scripts/..., bim-streaming-server/source/extensions/..., bim-streaming-server/tests/...
Pins CAD packages and validates hashes, sizes, ownership, permissions, trusted roots, file identity, and atomic replacement.
Deployment and host-native launch wiring
scripts/deploy.ps1, scripts/lib/..., scripts/tests/...
Runs cache hardening during Linux conversion deployment and passes validated Kit control URLs with isolated environment restoration.
Target-aware deployment verification
scripts/verify-all.ps1, scripts/verify-all.sh, scripts/tests/test-verify-all.ps1, services/kit-manager-api/...
Adds inventory-based target resolution, local bind checks, proxy-free runtime requests, service identity validation, and runtime-signature checks.
Bootstrap evidence and command verification
docs/evidence/..., scripts/self-referential-bootstrap-ledger.json, scripts/tests/test-self-referential-bootstrap.ps1
Adds deployment evidence, an open bootstrap ledger entry, and validated command specifications for rebuild and verification paths.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant Deployment as scripts/deploy.ps1
  participant Hardener as harden-cad-extension-cache.py
  participant Adapter as Conversion adapter
  participant Verifier as scripts/verify-all.ps1
  participant KitGateway as KitRuntimeGateway
  Operator->>Deployment: Start canonical Linux deployment
  Deployment->>Hardener: Harden CAD extension cache
  Hardener->>Adapter: Validate and harden HOOPS entrypoint
  Adapter-->>Deployment: Return hardening status
  Deployment->>Verifier: Run target-aware verification
  Verifier->>KitGateway: Check runtime control status
  KitGateway-->>Verifier: Return proxy-free runtime result
  Verifier-->>Operator: Report deployment and health results
Loading

Possibly related issues

  • monkey1sai/AI-BIM-governance#400: Covers canonical rebuild and deployment-verification gaps addressed by the deployment scripts and tests.

Possibly related PRs

Suggested reviewers: monkey1sai-blip

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: hardening the canonical Linux test deployment workflow.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/deploy-linux-test-skill

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the canonical Linux test-deployment path for the AI-BIM-governance workspace. It strengthens the trust boundary around NVIDIA's CAD converter entrypoint (hoops_main.py), makes deployment health verification target-aware and privacy-redacted with strict service-identity checks, pins the host-native Kit Manager's runtime identity, and adds a Codex operator skill for the owner-inventory SSH deployment workflow.

Changes:

  • Adds pinned CAD entrypoint validation (exact package/size/SHA-256, symlink-escape rejection, owner-private permission checks) plus an atomic 0400-inode hardener, invoked from deploy.ps1 on the Linux conversion path and independently re-validated at runtime preflight/execution.
  • Makes verify-all.ps1 deployment health checks resolve targets via the registry, redact private host-native bind addresses, and assert typed JSON service identities; gives the host-native Kit Manager an explicit child-only environment restored in finally.
  • Adds the deploy-linux-test-environment Codex skill (manifest/gitignore/gitattributes entries) and broad test coverage.

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ifc2usdc_powershell_adapter.py Pinned CAD entrypoint discovery/validation, atomic permission hardening, and post-preflight identity re-checks
bim-streaming-server/scripts/harden-cad-extension-cache.py New CLI wrapper that hardens the entrypoint and emits a redacted result schema
bim-streaming-server/config/trusted-cad-entrypoints.json New per-platform trusted package/digest manifest
bim-streaming-server/source/apps/ezplus.bim_ifc_usd_converter.kit Trailing-newline-only change
scripts/deploy.ps1 Runs the CAD hardener on the Linux conversion path after Kit build
scripts/verify-all.ps1 Target-aware, redacted, redirect/proxy-safe health checks with typed service identity
scripts/lib/host-native-launcher.ps1 Explicit Kit Manager child env with parent restoration
bim-streaming-server/tests/test_host_native_conversion_service.py Tests for pinning, escapes, ambiguity, swap-after-preflight, and atomic hardening
scripts/tests/test-verify-all.ps1, test-host-native-launcher.ps1, test-deploy-governance-static.ps1 Verifier/launcher/static assertions for the new behavior
agent-skills-manifest.json, .gitignore, .gitattributes, .codex/skills/deploy-linux-test-environment/* New Codex deployment skill and its registration

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (4)
bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py (1)

538-548: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Bound the read by the expected size before loading the file into memory.

source_stat is already available at Line 532. The loop reads the whole file into trusted_bytes and only then compares the length to expected_size. If the inode holds a much larger file, the process allocates all of it before rejecting it. Check source_stat.st_size against expected_size first, and cap the read.

♻️ Proposed refactor
+            if source_stat.st_size != expected_size:
+                raise ConversionAuthorityError(
+                    "converter_unavailable",
+                    "Pinned CAD extension entrypoint size does not match the tracked manifest.",
+                )
             trusted_bytes = bytearray()
             while True:
                 chunk = os.read(source_descriptor, 1024 * 1024)
                 if not chunk:
                     break
                 trusted_bytes.extend(chunk)
+                if len(trusted_bytes) > expected_size:
+                    break
             if len(trusted_bytes) != expected_size or hashlib.sha256(trusted_bytes).hexdigest() != expected_sha256:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`
around lines 538 - 548, Update the trusted-byte loading logic near source_stat
and the os.read loop: reject the source when source_stat.st_size differs from
expected_size before allocating or reading its contents, then cap each read so
the total trusted_bytes cannot exceed expected_size. Preserve the existing
SHA-256 validation and ConversionAuthorityError behavior for invalid content.
scripts/verify-all.ps1 (1)

109-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename $matches to avoid the automatic variable.

$Matches is a PowerShell automatic variable that the -match and -notmatch operators overwrite. The current loop body does not run -match between the assignment on Line 109 and the read on Line 115, so the code works today. A later edit that adds a regex comparison inside the loop would silently corrupt the result. Use a local name.

♻️ Proposed change
-                $matches = if ($expectedValue -is [bool]) {
+                $propertyMatches = if ($expectedValue -is [bool]) {
                     $actualValue -is [bool] -and $actualValue -eq $expectedValue
                 }
                 else {
                     [string]$actualValue -ceq [string]$expectedValue
                 }
-                if (-not $matches) {
+                if (-not $propertyMatches) {
                     throw "response identity property '$propertyName' did not match the expected value"
                 }

Note: scripts/tests/test-verify-all.ps1 Line 171 asserts the boolean comparison text only, so this rename does not break that assertion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/verify-all.ps1` around lines 109 - 118, Rename the local `$matches`
variable in the response identity comparison block to a non-reserved local name,
and update its subsequent negated check accordingly. Keep the boolean and string
comparison logic unchanged.
bim-streaming-server/tests/test_host_native_conversion_service.py (1)

682-686: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Align the path comparison with the discovery return contract.

Line 485 compares resolved_hoops_main.resolve() with hoops_main.resolve(). Line 684 compares the unresolved return value with hoops_main.resolve(). harden_default_hoops_main_permissions returns the value of _default_hoops_main(), and the fixture reaches the leaf through a directory symlink in release_root. If discovery returns the symlinked path, this assertion fails. Use the same normalization in both tests.

♻️ Proposed change
-    assert hardened == hoops_main.resolve()
-    assert (hardened.stat().st_dev, hardened.stat().st_ino) != original_identity
+    assert hardened.resolve() == hoops_main.resolve()
+    assert (hardened.stat().st_dev, hardened.stat().st_ino) != original_identity
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bim-streaming-server/tests/test_host_native_conversion_service.py` around
lines 682 - 686, Update the assertion for harden_default_hoops_main_permissions
to compare hardened.resolve() with hoops_main.resolve(), matching the
normalization used by the other discovery test while preserving the identity and
permission assertions.
scripts/tests/test-verify-all.ps1 (1)

159-159: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Anchor the private-address leak assertion.

192\.0\.2\.1 also matches inside 192.0.2.10, which is the fixture public_host on Line 117. The current plan output does not print public_host, so the assertion passes. A future change that prints the public host would fail this assertion for the wrong reason. Add a boundary.

♻️ Proposed change
-    Assert-True ($deploymentPlan.Output -notmatch '192\.0\.2\.1') 'deployment profile never publishes the private host-native bind address'
+    Assert-True ($deploymentPlan.Output -notmatch '192\.0\.2\.1(?!\d)') 'deployment profile never publishes the private host-native bind address'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test-verify-all.ps1` at line 159, Update the private-address
assertion in the deployment-plan test to match 192.0.2.1 only as a complete host
value, using an appropriate boundary so it cannot match the public_host fixture
192.0.2.10.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bim-streaming-server/scripts/harden-cad-extension-cache.py`:
- Around line 30-50: Ensure every execution path in the script emits the
`cad-extension-cache-hardening/v1` JSON contract, including import,
initialization, and unexpected failures. Add a shared status-emission helper and
place the import and `Ifc2UsdcPowershellConverterAdapter` setup within broad
exception handling, using a distinct `reason_kind` for unexpected errors while
preserving `ConversionAuthorityError.code`. Use the same helper for the success
branch so both success and failure output remain consistently structured.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`:
- Around line 197-215: Update _group_is_private_to_process to cache each
group_id result at instance or module scope, and return the cached value on
repeated checks. Treat an empty pwd.getpwall() result as not private before
evaluating group membership, while preserving the existing Windows and
lookup-error behavior.

In `@scripts/deploy.ps1`:
- Around line 1225-1236: Validate that the path returned by
Resolve-PlatformVenvPython exists and is executable before invoking the hardener
in the Phase 2 flow. If validation fails, log the failure and enter the existing
CAD hardening failure path with a nonzero exit result, preventing the success
tag from being emitted; only invoke the command and read $LASTEXITCODE after
validation succeeds.

In `@scripts/tests/test-host-native-launcher.ps1`:
- Around line 255-268: Update the Test 21 stubs around Resolve-HostNativePython
and Start-HostNativeKitManager so the test no longer depends on a real python
executable or installed fastapi/uvicorn packages. Route resolution through the
existing platform adapter or mock/extract the import probe, while preserving the
test’s focus on captured environment wiring.

In `@scripts/tests/test-verify-all.ps1`:
- Around line 104-107: Guard the default Deployment plan assertions in the test
block around Invoke-VerificationPlan with a Windows-only condition, so they run
only when the current platform resolves the Windows target; alternatively,
invoke the plan with an explicit loopback fixture target. Ensure Linux runs do
not fail or skip the subsequent Linux fixture assertions.

---

Nitpick comments:
In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`:
- Around line 538-548: Update the trusted-byte loading logic near source_stat
and the os.read loop: reject the source when source_stat.st_size differs from
expected_size before allocating or reading its contents, then cap each read so
the total trusted_bytes cannot exceed expected_size. Preserve the existing
SHA-256 validation and ConversionAuthorityError behavior for invalid content.

In `@bim-streaming-server/tests/test_host_native_conversion_service.py`:
- Around line 682-686: Update the assertion for
harden_default_hoops_main_permissions to compare hardened.resolve() with
hoops_main.resolve(), matching the normalization used by the other discovery
test while preserving the identity and permission assertions.

In `@scripts/tests/test-verify-all.ps1`:
- Line 159: Update the private-address assertion in the deployment-plan test to
match 192.0.2.1 only as a complete host value, using an appropriate boundary so
it cannot match the public_host fixture 192.0.2.10.

In `@scripts/verify-all.ps1`:
- Around line 109-118: Rename the local `$matches` variable in the response
identity comparison block to a non-reserved local name, and update its
subsequent negated check accordingly. Keep the boolean and string comparison
logic unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1db1ab5a-4556-44dc-a2f8-5348a140c119

📥 Commits

Reviewing files that changed from the base of the PR and between 89ff9c8 and 36ed788.

📒 Files selected for processing (16)
  • .codex/skills/deploy-linux-test-environment/SKILL.md
  • .codex/skills/deploy-linux-test-environment/agents/openai.yaml
  • .gitattributes
  • .gitignore
  • agent-skills-manifest.json
  • bim-streaming-server/config/trusted-cad-entrypoints.json
  • bim-streaming-server/scripts/harden-cad-extension-cache.py
  • bim-streaming-server/source/apps/ezplus.bim_ifc_usd_converter.kit
  • bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py
  • bim-streaming-server/tests/test_host_native_conversion_service.py
  • scripts/deploy.ps1
  • scripts/lib/host-native-launcher.ps1
  • scripts/tests/test-deploy-governance-static.ps1
  • scripts/tests/test-host-native-launcher.ps1
  • scripts/tests/test-verify-all.ps1
  • scripts/verify-all.ps1

Comment thread bim-streaming-server/scripts/harden-cad-extension-cache.py Outdated
Comment thread scripts/deploy.ps1
Comment thread scripts/tests/test-host-native-launcher.ps1 Outdated
Comment thread scripts/tests/test-verify-all.ps1 Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36ed788e77

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread .codex/skills/deploy-linux-test-environment/SKILL.md

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c6c96392f

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread scripts/lib/host-native-launcher.ps1 Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9225480416

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread bim-streaming-server/scripts/harden-cad-extension-cache.py Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aeb02d8828

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread scripts/lib/host-native-launcher.ps1 Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/skills/deploy-linux-test-environment/agents/openai.yaml:
- Around line 2-4: Update the default_prompt in the deploy skill metadata to be
action-neutral and invoke $deploy-linux-test-environment for read-only preflight
or status inspection by default. Do not instruct rebuilding, cleanup, service
restarts, verification after mutation, or tag creation unless the user
explicitly requests a rebuild.

In @.claude/skills/deploy-linux-test-environment/SKILL.md:
- Around line 16-25: Update the deployment workflow instructions to require a
pre-deploy verification gate before any remote checkout reset, rebuild, or other
mutation: run affected type checks, lint, and unit/integration checks first,
fail closed on any failure, and explicitly report each skipped or unrun check
with its reason. Anchor this requirement to the “Load current truth” workflow
and preserve the existing verification-source ordering.
- Around line 29-31: Update the deployment reconstruction flow to create a fresh
sibling worktree from the captured, freshly fetched origin/main SHA, then verify
that worktree’s HEAD matches the SHA and its status is clean before invoking
rebuild-test-deploy.ps1. Run the wrapper from this isolated worktree instead of
the current branch worktree, while preserving the existing handle and
input-integrity checks.
- Line 82: Update the final report guidance in the deployment skill to redact
private paths: show a command template with placeholders instead of expanded
inventoryPath, identityFile, or deploy_root values, and report snapshot/log
artifacts using repository-relative paths. Keep raw commands and absolute paths
only in protected local evidence, while preserving the requirement to include
the rebuild command and artifact locations.

In
`@docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/README.md`:
- Line 1: Add explicit document metadata to the README heading, declaring
“Document nature: working note,” and add equivalent machine-readable metadata at
the start of verification.txt without disrupting its existing evidence format.
Ensure both documents clearly remain evidence rather than authoritative runtime
or API specifications. Apply changes to
docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/README.md
(lines 1-1) and verification.txt (lines 1-1).
- Around line 14-16: Update README.md lines 14-16 to document git fetch origin
--prune, sibling worktree creation from origin/main, matching git rev-parse HEAD
and origin/main values, an empty git status --porcelain before rebuild, the
rebuild-test-deploy.ps1 -Build command, and the owner-controlled private
canonical-linux inventory; do not present reset/clean of a dirty checkout as
isolated-baseline evidence. Update verification.txt line 18 to include the exact
canonical rebuild command, target, inventory source, and source commit, or
explicitly mark canonical-linux-rebuild as bootstrap evidence pending fixpoint.

In
`@docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt`:
- Around line 5-17: Update the self-referential bootstrap verification report to
explain the single skipped test and explicitly record whether the affected
Python and PowerShell type-check and lint checks ran. For every check that did
not run, include its reason; otherwise record its result, preserving the
existing check results.

In `@scripts/self-referential-bootstrap-ledger.json`:
- Around line 109-131: Update the ledger entry’s verification_mechanism_paths to
include every changed runtime and test implementation file underlying the listed
command_ids, including harden-cad-extension-cache.py and
test_host_native_conversion_service.py. If any paths belong to a separate scope,
move them to a distinct ledger entry with its own fixpoint obligation.

In `@scripts/tests/test-self-referential-bootstrap.ps1`:
- Around line 400-401: Update commandPathById and the self-referential bootstrap
assertion to preserve canonical deployment invocation details, not just source
paths. Ensure the command runner generates the rebuild command with -Build and
inventory/target metadata, and invokes scripts/verify-all.ps1 with the
Deployment profile plus TargetId and InventoryPath; alternatively store this
invocation metadata alongside each mapped command and assert it.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c719d7f4-c921-475d-845d-e5e7b12f0269

📥 Commits

Reviewing files that changed from the base of the PR and between 36ed788 and aeb02d8.

📒 Files selected for processing (9)
  • .claude/skills/deploy-linux-test-environment/SKILL.md
  • .claude/skills/deploy-linux-test-environment/agents/openai.yaml
  • .gitattributes
  • .gitignore
  • agent-skills-manifest.json
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/README.md
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt
  • scripts/self-referential-bootstrap-ledger.json
  • scripts/tests/test-self-referential-bootstrap.ps1
🚧 Files skipped from review as they are similar to previous changes (2)
  • .gitattributes
  • agent-skills-manifest.json

Comment thread .claude/skills/deploy-linux-test-environment/agents/openai.yaml Outdated
Comment thread .claude/skills/deploy-linux-test-environment/SKILL.md
Comment thread .claude/skills/deploy-linux-test-environment/SKILL.md Outdated
Comment thread .claude/skills/deploy-linux-test-environment/SKILL.md
Comment thread scripts/self-referential-bootstrap-ledger.json
Comment thread scripts/tests/test-self-referential-bootstrap.ps1 Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce30c055af

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread .codex/skills/deploy-linux-test-environment/SKILL.md Outdated
Comment thread .codex/skills/deploy-linux-test-environment/SKILL.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
.claude/skills/deploy-linux-test-environment/SKILL.md (4)

117-117: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Require explicit approval for the ACL mutation.

Creating the destination with a protected ACL changes ACL state. The approval described here covers file creation and removal, but it does not explicitly cover the ACL change. Require approval that names creation, ACL assignment, and cleanup. Otherwise, mark the workflow HELD.

As per coding guidelines, ACL changes require explicit approval and the workflow must not automatically alter ACLs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy-linux-test-environment/SKILL.md at line 117, Update
the destination-creation workflow guidance to require explicit approval covering
file creation, protected ACL assignment, and temporary-copy cleanup before
proceeding. If approval does not explicitly include the ACL mutation, mark the
workflow HELD and do not automatically alter ACLs.

Source: Coding guidelines


162-162: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Require the operability gate before claiming full-system E2E.

The requirement lists semantic E2E, first frame, USD stage, DataChannel acknowledgement, and design-fidelity evidence. It does not require the operability gate. HTTP 200 checks do not prove Review Room or Edge Console operation.

Require both design-fidelity and operability evidence. If scope or either gate is unknown, report Full-system E2E claimed: no.

As per coding guidelines, user-facing completion requires both the design-fidelity gate and the operability gate, and unknown scope must fail closed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy-linux-test-environment/SKILL.md at line 162, Update
the full-system E2E claim requirement in the deployment guidance to require both
design-fidelity evidence and the operability gate, including proof that Review
Room and Edge Console operate beyond HTTP 200 checks. If the scope or either
gate is unknown, require reporting “Full-system E2E claimed: no.”

Source: Coding guidelines


150-156: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Synchronize the conversion-health instruction with the verifier.

.claude/skills/deploy-linux-test-environment/SKILL.md says the deployment profile keeps conversion checks on loopback at line 21, then line 27 requires conversion health through the public route. scripts/verify-all.ps1 uses conversionHealthHost from bim-streaming-conversion-service.params.json and asserts it is local, so the documented public-route expectation conflicts with the verifier’s intended loopback binding. State one route explicitly, or add a second requirement if both loopback and public checks are required.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy-linux-test-environment/SKILL.md around lines 150 -
156, Update the conversion health verification instruction near the coordinator
and viewer checks to match the verifier’s loopback behavior: require HTTP 200
from conversion at :49101 through the local/loopback route, not the public
route. Keep the existing coordinator and viewer role/port/result requirements
unchanged.

Source: Coding guidelines


100-100: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Request READ_CONTROL for the security descriptor query.

GetFileSecurityFromHandle from this same handle requires the handle to have access to the security descriptor, which FILE_READ_ATTRIBUTES does not provide. Request READ_CONTROL | FILE_READ_ATTRIBUTES, or query owner/DACL from a separate security-descriptor handle or path.

Proposed access-mask correction
-CreateFileW(FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)
+CreateFileW(READ_CONTROL | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy-linux-test-environment/SKILL.md at line 100, Update
the selected private-root handle opened by the validation procedure to request
READ_CONTROL together with FILE_READ_ATTRIBUTES, preserving the existing
sharing, creation, and flag settings so GetFileSecurityFromHandle can query the
owner and DACL from that handle.
bim-streaming-server/tests/test_host_native_conversion_service.py (1)

791-794: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add a POSIX-only marker to the atomic hardening test.

Line 794 hardcodes the linux-x86_64 release directory. On Windows, _default_release_root returns windows-x86_64, so _discover_default_hoops_main finds no candidate and harden_default_hoops_main_permissions raises converter_unavailable. Line 804 also relies on POSIX mode bits.

The neighbouring hardener test at line 816 carries @pytest.mark.skipif(os.name == "nt", ...). Apply the same marker here.

💚 Proposed fix
+@pytest.mark.skipif(os.name == "nt", reason="POSIX descriptor hardening contract")
 def test_hardener_atomically_replaces_pinned_entrypoint_with_private_inode(
     tmp_path: Path, monkeypatch
 ):
     release_root = tmp_path / "_build" / "linux-x86_64" / "release"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bim-streaming-server/tests/test_host_native_conversion_service.py` around
lines 791 - 794, Add the same `@pytest.mark.skipif`(os.name == "nt", ...)
decorator used by the neighbouring hardener test to
test_hardener_atomically_replaces_pinned_entrypoint_with_private_inode,
preserving the test’s POSIX-only behavior and existing implementation.
bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py (1)

709-717: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

An explicitly configured hoops_main_path bypasses the pinned-package trust boundary.

When self.hoops_main_path is set, line 717 assigns it directly to effective_hoops. The code then only resolves the path and records its identity at lines 727-733. It never calls _trusted_cad_entrypoint or _verify_cad_entrypoint_digest for that path. The pinned package name, size, and SHA-256 are not checked.

The docstring at lines 510-511 states that runtime discovery never accepts an unpinned digest. That guarantee holds only for the discovery path.

scripts/deploy.ps1 lines 1301-1306 reject STREAMING_CONVERSION_HOOPS_MAIN on the canonical Linux path, so the deployed configuration is covered. Any other construction of the adapter with hoops_main_path still runs an unverified entrypoint.

Apply the same digest verification to the configured path, or document that the configured path is an unpinned developer-only escape hatch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`
around lines 709 - 717, Update the configured-path branch in the adapter
initialization flow so `self.hoops_main_path` is validated through the same
pinned-package trust checks as `_default_hoops_main`, including
`_trusted_cad_entrypoint` and `_verify_cad_entrypoint_digest`; retain the
existing `ConversionAuthorityError` handling and failure state, and only assign
a configured path to `effective_hoops` after verification succeeds.
🧹 Nitpick comments (3)
bim-streaming-server/scripts/harden-cad-extension-cache.py (1)

60-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Mark the intentional broad exception handler for Ruff.

Line 60 is required to convert unexpected failures into the JSON status contract. Ruff reports BLE001 here. Add a scoped # noqa: BLE001 with a rationale, or configure this handler explicitly. Do not narrow the handler without preserving the fallback contract.

Proposed fix
-    except Exception as exc:
+    # Preserve the machine-readable failure contract for unexpected errors.
+    except Exception as exc:  # noqa: BLE001
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bim-streaming-server/scripts/harden-cad-extension-cache.py` at line 60, Add a
scoped Ruff suppression for BLE001 on the broad exception handler `except
Exception as exc`, including a brief rationale that it preserves the JSON status
fallback contract; keep the broad handler and its existing fallback behavior
unchanged.

Source: Linters/SAST tools

scripts/lib/host-native-launcher.ps1 (1)

543-546: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Apply the same import-probe fix to Start-HostNativeGovernance.

Lines 543-546 replace the stale $LASTEXITCODE check with an injectable process probe that reads a real ExitCode. Start-HostNativeGovernance at lines 470-474 still uses & $pythonExe -c "..." *> $null followed by $LASTEXITCODE.

deploy.ps1 sets $ErrorActionPreference = 'Continue'. If the interpreter cannot be launched there, $LASTEXITCODE keeps its previous value. A prior successful native command then makes the governance import check pass, and the service dies at import instead. The failure surfaces 30 seconds later as a Phase 4a health timeout.

Reuse the new ImportProbeFn pattern for governance so both launchers share one probe contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/lib/host-native-launcher.ps1` around lines 543 - 546, Update
Start-HostNativeGovernance to use the injectable ImportProbeFn and its returned
real ExitCode, replacing the direct python invocation and $LASTEXITCODE check.
Preserve the existing governance import validation and failure behavior,
matching the probe contract already used by the surrounding launcher.
scripts/deploy.ps1 (1)

566-591: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Preserve the hardener failure reason and reconsider the stderr rule.

Two points about this result-interpretation block:

  1. Lines 566-570 discard the caught exception. The caller at line 1331 then logs only CAD extension cache permission hardening failed. On a remote canonical deploy the operator loses the actual cause. Capture $_.Exception.Message and return it so the failure tag can include it.
  2. Line 578 requires [string]::IsNullOrWhiteSpace($stderr). Any benign warning that Python writes to stderr, for example a DeprecationWarning from an imported module, invalidates a successful hardening and aborts the deploy with exit 2. Decide whether stderr silence is a required part of the contract, or gate only on the exit code and the single JSON status line.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/deploy.ps1` around lines 566 - 591, Update the hardener
result-interpretation block to preserve the caught exception message from the
catch handler and return or propagate it so the caller’s failure log includes
the actual cause. Reconsider the [string]::IsNullOrWhiteSpace($stderr)
requirement in the $exitCode/$lines validation, retaining it only if stderr
silence is an explicit contract; otherwise validate successful execution using
the zero exit code and single valid JSON status line while tolerating benign
warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/skills/deploy-linux-test-environment/SKILL.md:
- Around line 39-55: Update the deployment setup block to capture the caller’s
exact cwd, current branch, and porcelain worktree status before git fetch or
Set-Location, alongside the existing sourceRepoRoot. Validate each provenance
command and mark deployment HELD on failure, then retain these captured values
for inclusion in the final report rather than reporting only the isolated
worktree state.
- Around line 52-54: Update the isolated deployment worktree validation around
the git rev-parse and git status commands to run them separately and capture
each command’s output and exit status. Check $LASTEXITCODE after both commands,
and throw the existing deployment-held error if either command fails; only
compare the resolved HEAD and clean-status output after both checks succeed.

In `@scripts/deploy.ps1`:
- Around line 556-573: Bound child-process waits in both helpers: in
scripts/deploy.ps1 lines 556-573, update Invoke-CadExtensionCacheHardener to
accept a timeout, use the timeout-based WaitForExit call, and kill the process
tree when it expires; in scripts/lib/host-native-launcher.ps1 lines 512-520,
apply the same bounded wait to the default ImportProbeFn’s $importProcess and
return a non-zero exit code on timeout.
- Around line 1310-1317: Update the hardener interpreter readiness check around
$hardenerPythonReady to verify that [System.IO.File]::GetUnixFileMode is
available before invoking it, preserving the existing executable-bit check when
supported and avoiding a false “missing or not executable” failure on older
PowerShell/.NET runtimes.

In `@scripts/tests/test-rebuild-test-deploy.ps1`:
- Around line 271-273: Update the Start-HostNativeKitManager test double and its
host-native launch scenario to retain the received KitControlUrl and assert it
matches the expected canonical control URL, ensuring empty or incorrect caller
values fail the test.

In `@services/kit-manager-api/app/kit_gateway.py`:
- Line 12: Update the opener initialization in the gateway class to install a
no-op HTTP redirect handler alongside ProxyHandler({}), preventing redirects
from the Kit control authority from being followed. Extend the existing redirect
test to verify the gateway rejects or does not follow a redirect and therefore
never contacts the redirected authority.

---

Outside diff comments:
In @.claude/skills/deploy-linux-test-environment/SKILL.md:
- Line 117: Update the destination-creation workflow guidance to require
explicit approval covering file creation, protected ACL assignment, and
temporary-copy cleanup before proceeding. If approval does not explicitly
include the ACL mutation, mark the workflow HELD and do not automatically alter
ACLs.
- Line 162: Update the full-system E2E claim requirement in the deployment
guidance to require both design-fidelity evidence and the operability gate,
including proof that Review Room and Edge Console operate beyond HTTP 200
checks. If the scope or either gate is unknown, require reporting “Full-system
E2E claimed: no.”
- Around line 150-156: Update the conversion health verification instruction
near the coordinator and viewer checks to match the verifier’s loopback
behavior: require HTTP 200 from conversion at :49101 through the local/loopback
route, not the public route. Keep the existing coordinator and viewer
role/port/result requirements unchanged.
- Line 100: Update the selected private-root handle opened by the validation
procedure to request READ_CONTROL together with FILE_READ_ATTRIBUTES, preserving
the existing sharing, creation, and flag settings so GetFileSecurityFromHandle
can query the owner and DACL from that handle.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`:
- Around line 709-717: Update the configured-path branch in the adapter
initialization flow so `self.hoops_main_path` is validated through the same
pinned-package trust checks as `_default_hoops_main`, including
`_trusted_cad_entrypoint` and `_verify_cad_entrypoint_digest`; retain the
existing `ConversionAuthorityError` handling and failure state, and only assign
a configured path to `effective_hoops` after verification succeeds.

In `@bim-streaming-server/tests/test_host_native_conversion_service.py`:
- Around line 791-794: Add the same `@pytest.mark.skipif`(os.name == "nt", ...)
decorator used by the neighbouring hardener test to
test_hardener_atomically_replaces_pinned_entrypoint_with_private_inode,
preserving the test’s POSIX-only behavior and existing implementation.

---

Nitpick comments:
In `@bim-streaming-server/scripts/harden-cad-extension-cache.py`:
- Line 60: Add a scoped Ruff suppression for BLE001 on the broad exception
handler `except Exception as exc`, including a brief rationale that it preserves
the JSON status fallback contract; keep the broad handler and its existing
fallback behavior unchanged.

In `@scripts/deploy.ps1`:
- Around line 566-591: Update the hardener result-interpretation block to
preserve the caught exception message from the catch handler and return or
propagate it so the caller’s failure log includes the actual cause. Reconsider
the [string]::IsNullOrWhiteSpace($stderr) requirement in the $exitCode/$lines
validation, retaining it only if stderr silence is an explicit contract;
otherwise validate successful execution using the zero exit code and single
valid JSON status line while tolerating benign warnings.

In `@scripts/lib/host-native-launcher.ps1`:
- Around line 543-546: Update Start-HostNativeGovernance to use the injectable
ImportProbeFn and its returned real ExitCode, replacing the direct python
invocation and $LASTEXITCODE check. Preserve the existing governance import
validation and failure behavior, matching the probe contract already used by the
surrounding launcher.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7767b3a-c368-49ba-9d68-9b024dcf9233

📥 Commits

Reviewing files that changed from the base of the PR and between aeb02d8 and f04f1b5.

📒 Files selected for processing (21)
  • .claude/skills/deploy-linux-test-environment/SKILL.md
  • .claude/skills/deploy-linux-test-environment/agents/openai.yaml
  • .codex/skills/deploy-linux-test-environment/SKILL.md
  • .codex/skills/deploy-linux-test-environment/agents/openai.yaml
  • agent-skills-manifest.json
  • bim-streaming-server/scripts/harden-cad-extension-cache.py
  • bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py
  • bim-streaming-server/tests/test_host_native_conversion_service.py
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/README.md
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt
  • scripts/deploy.ps1
  • scripts/lib/host-native-launcher.ps1
  • scripts/self-referential-bootstrap-ledger.json
  • scripts/tests/test-deploy-governance-static.ps1
  • scripts/tests/test-host-native-launcher.ps1
  • scripts/tests/test-rebuild-test-deploy.ps1
  • scripts/tests/test-self-referential-bootstrap.ps1
  • scripts/tests/test-verify-all.ps1
  • scripts/verify-all.ps1
  • services/kit-manager-api/app/kit_gateway.py
  • services/kit-manager-api/tests/test_kit_service_runtime_status.py
🚧 Files skipped from review as they are similar to previous changes (6)
  • agent-skills-manifest.json
  • scripts/self-referential-bootstrap-ledger.json
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/README.md
  • .codex/skills/deploy-linux-test-environment/agents/openai.yaml
  • scripts/verify-all.ps1

Comment thread .claude/skills/deploy-linux-test-environment/SKILL.md
Comment thread .claude/skills/deploy-linux-test-environment/SKILL.md Outdated
Comment thread scripts/deploy.ps1
Comment thread scripts/deploy.ps1 Outdated
Comment thread scripts/tests/test-rebuild-test-deploy.ps1
Comment thread services/kit-manager-api/app/kit_gateway.py Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9df4b9f768

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread scripts/verify-all.ps1

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a40fabe69f

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread scripts/deploy.ps1 Outdated
Comment thread scripts/verify-all.ps1

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py (1)

716-733: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Validate configured HOOPS paths against the same trust policy.

Line 717 accepts self.hoops_main_path without package, trusted-root, owner, permission, size, or SHA-256 validation. Lines 727-733 only record the identity of that untrusted file. A writable configured file can therefore pass preflight and reach -HoopsMainPath at Line 1017.

Apply the manifest and owner-private validation to configured paths before calculating the execution identity. Add a test that an existing arbitrary configured file fails before PowerShell starts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`
around lines 716 - 733, Update the configured-path branch around effective_hoops
validation to apply the same manifest, trusted-root, owner-private permissions,
size, and SHA-256 checks used for packaged HOOPS files before calling
_hoops_file_identity or assigning validated_hoops_main. Ensure an existing
arbitrary self.hoops_main_path is rejected during preflight and cannot reach the
-HoopsMainPath execution path, and add a test verifying PowerShell is not
started.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`:
- Around line 716-733: Update the configured-path branch around effective_hoops
validation to apply the same manifest, trusted-root, owner-private permissions,
size, and SHA-256 checks used for packaged HOOPS files before calling
_hoops_file_identity or assigning validated_hoops_main. Ensure an existing
arbitrary self.hoops_main_path is rejected during preflight and cannot reach the
-HoopsMainPath execution path, and add a test verifying PowerShell is not
started.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4905932f-f44e-4cdf-b3f8-2779acfc5efb

📥 Commits

Reviewing files that changed from the base of the PR and between f04f1b5 and 939232e.

📒 Files selected for processing (5)
  • bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py
  • scripts/tests/test-deploy-governance-static.ps1
  • scripts/tests/test-host-native-launcher.ps1
  • scripts/tests/test-self-referential-bootstrap.ps1
  • scripts/tests/test-verify-all.ps1
🚧 Files skipped from review as they are similar to previous changes (3)
  • scripts/tests/test-self-referential-bootstrap.ps1
  • scripts/tests/test-verify-all.ps1
  • scripts/tests/test-deploy-governance-static.ps1

Closes the outstanding PR #484 review threads:

- validate Windows owner/DACL per path component before trusting the CAD
  extension cache instead of returning unconditional success on nt
- keep the pinned entrypoint inode when it is already 0400, so an idempotent
  redeploy cannot interrupt an in-flight conversion
- detect NTFS junctions through the reparse attribute on Python 3.11, where
  Path.is_junction does not exist
- reject redirects from the Kit control authority in KitRuntimeGateway
- bound the CAD hardener and Kit Manager import-probe child waits, killing the
  process tree and failing closed on timeout
- drop the GetUnixFileMode probe, which is .NET 7+/PowerShell 7.3+ only and
  aborted every conversion-enabled deploy on PowerShell 7.0-7.2
- require a revision in each deployment runtime signature and reject a runtime
  from another checkout
- mirror --target-id and --inventory-path in scripts/verify-all.sh
- assert the forwarded canonical Kit control URL in the rebuild harness
- give the deploy-linux-test-environment skill caller provenance capture,
  exit-code-checked git probes, a finally-based worktree/branch closeout, a
  report template that mirrors the actual invocation, and an isolated-worktree
  canonical env destination

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/tests/test-verify-all.ps1 (1)

333-360: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

On Windows the execution matrix ignores the canonical-Linux fixture it just validated.

Lines 340-355 build and validate $executionInventoryPath for canonical-linux. Lines 357-360 then attach -InventoryPath only when -not $IsWindows. On a Windows runner, Invoke-VerificationExecution runs with no target arguments and resolves the current-platform target instead. The runtime-signature rejection matrix at Lines 434-441 therefore exercises the local-windows path, and the validated canonical-Linux fixture is never used.

The canonical operator workstation is Windows, so this is the path that runs in practice. Either pass -TargetId canonical-linux -InventoryPath $executionInventoryPath on both platforms, or state in a comment why the Windows run must use the platform default and assert which target the execution resolved.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test-verify-all.ps1` around lines 333 - 360, The execution
matrix validates the canonical-linux fixture but omits it on Windows, causing
verification to use the platform-default target. Update the
`$executionArguments` construction and its `Invoke-VerificationExecution` caller
to pass `-TargetId 'canonical-linux' -InventoryPath $executionInventoryPath` on
both platforms, preserving any required non-Windows arguments.
🧹 Nitpick comments (4)
.codex/skills/deploy-linux-test-environment/SKILL.md (1)

182-232: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the git branch -d precondition for the cleanup step.

Line 218 uses git branch -d. Git refuses this delete when the branch is not merged into the current HEAD or its upstream. The isolated branch points at origin/main. If the caller worktree is checked out at a revision that does not contain origin/main, the delete fails and the closeout reports HELD even though nothing changed. The fail-closed outcome is correct, but the operator needs to know this cause. Add one sentence that names this condition, so the operator does not treat it as tampering evidence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.codex/skills/deploy-linux-test-environment/SKILL.md around lines 182 - 232,
Add a sentence in the “Close the isolated worktree” cleanup documentation
explaining that `git branch -d` can fail when the caller’s current HEAD or
upstream does not contain the isolated branch’s `origin/main` commit; identify
this as a non-tampering cause of the resulting HELD status.
services/kit-manager-api/app/kit_gateway.py (1)

40-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The failed_http_{status} branch is unreachable through the opener.

OpenerDirector.open installs HTTPDefaultErrorHandler, which raises HTTPError for any status at or above 400. HTTPError is a subclass of URLError, so control reaches Line 44 and the gateway returns blocked_runtime_control_unavailable. Lines 41-42 never run. A Kit control that answers with 403 or 500 is therefore reported as unreachable rather than as an explicit rejection.

The behavior matches the previous urlopen call, so this is not a regression. Consider catching HTTPError before URLError to keep the distinct status, or remove the dead branch.

♻️ Proposed change
         try:
             with self._opener.open(request, timeout=self.timeout_seconds) as response:
-                if response.status >= 400:
-                    return f"failed_http_{response.status}"
                 return "sent"
+        except HTTPError as exc:
+            return f"failed_http_{exc.code}"
         except URLError:
             return "blocked_runtime_control_unavailable"

Import HTTPError from urllib.error alongside URLError. Note that the redirect rejection surfaces as HTTPError with code 302, so update the redirect test expectation if you apply this change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/kit-manager-api/app/kit_gateway.py` around lines 40 - 43, Update the
request handling around KitGateway’s opener call to catch urllib.error.HTTPError
before URLError and return failed_http_{status} using the error’s status code,
preserving distinct handling for HTTP 4xx/5xx responses. Also account for
redirect rejections surfaced as HTTPError code 302 by updating the corresponding
redirect test expectation.
bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py (1)

1022-1038: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Chain the fallback anchor error to its cause.

Line 1035 raises a new ConversionAuthorityError inside an except ConversionAuthorityError block without from. The original anchor failure is then hidden in the traceback. Ruff reports this as B904. Bind the caught error and chain it.

♻️ Proposed change
         try:
             anchor = self._trusted_directory_anchor(candidate)
-        except ConversionAuthorityError:
+        except ConversionAuthorityError as anchor_error:
             if self.hoops_main_path is None:
                 raise
             try:
                 anchor = candidate.parent.resolve(strict=True)
             except OSError as exc:
                 raise ConversionAuthorityError(
                     "converter_unavailable",
                     "Configured HOOPS entrypoint parent could not be resolved safely.",
                 ) from exc
             if not self._path_components_are_owner_private(anchor, anchor):
                 raise ConversionAuthorityError(
                     "converter_unavailable",
                     "Configured HOOPS entrypoint parent is not owner-private.",
-                )
+                ) from anchor_error
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`
around lines 1022 - 1038, Update the inner fallback handler in the anchor
resolution flow to bind the outer ConversionAuthorityError and chain the new
ConversionAuthorityError raised for an unsafe HOOPS parent to that caught cause
using explicit exception chaining, satisfying B904 while preserving existing
behavior.

Source: Linters/SAST tools

services/kit-manager-api/tests/test_kit_service_runtime_status.py (1)

139-184: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Start both servers inside the try block, and silence the Ruff A002 hit.

Two small points:

  1. Lines 153-155 start the destination server before the try at Line 171. If ThreadingHTTPServer(...) at Line 168 raises, the destination server and its thread are never closed. Move the destination server setup inside the try, or manage both servers with contextlib.ExitStack.
  2. Ruff reports A002 at Lines 150 and 165 because format shadows a builtin. The name comes from the BaseHTTPRequestHandler.log_message signature, so keep it and add # noqa: A002.

The redirect assertions themselves are correct. The rejected redirect surfaces as HTTPError, which URLError handling maps to blocked_runtime_control_unavailable, and the destination counter proves the second authority was never contacted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/kit-manager-api/tests/test_kit_service_runtime_status.py` around
lines 139 - 184, Update
test_configured_gateway_rejects_redirects_without_contacting_the_destination to
create both HTTP servers and their threads inside the try block, ensuring
cleanup runs if either setup fails; retain the existing finally cleanup for
successfully initialized resources. Keep the required
BaseHTTPRequestHandler.log_message parameter name format and add the targeted
noqa A002 suppression to both handler methods.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/verify-all.sh`:
- Around line 104-109: Add scripts/verify-all.sh to the
linux-test-deploy-verifier-hardening entry in
scripts/self-referential-bootstrap-ledger.json, alongside
scripts/verify-all.ps1. Rerun the governance check to confirm the bootstrap
ledger covers this POSIX adapter.

---

Outside diff comments:
In `@scripts/tests/test-verify-all.ps1`:
- Around line 333-360: The execution matrix validates the canonical-linux
fixture but omits it on Windows, causing verification to use the
platform-default target. Update the `$executionArguments` construction and its
`Invoke-VerificationExecution` caller to pass `-TargetId 'canonical-linux'
-InventoryPath $executionInventoryPath` on both platforms, preserving any
required non-Windows arguments.

---

Nitpick comments:
In @.codex/skills/deploy-linux-test-environment/SKILL.md:
- Around line 182-232: Add a sentence in the “Close the isolated worktree”
cleanup documentation explaining that `git branch -d` can fail when the caller’s
current HEAD or upstream does not contain the isolated branch’s `origin/main`
commit; identify this as a non-tampering cause of the resulting HELD status.

In
`@bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py`:
- Around line 1022-1038: Update the inner fallback handler in the anchor
resolution flow to bind the outer ConversionAuthorityError and chain the new
ConversionAuthorityError raised for an unsafe HOOPS parent to that caught cause
using explicit exception chaining, satisfying B904 while preserving existing
behavior.

In `@services/kit-manager-api/app/kit_gateway.py`:
- Around line 40-43: Update the request handling around KitGateway’s opener call
to catch urllib.error.HTTPError before URLError and return failed_http_{status}
using the error’s status code, preserving distinct handling for HTTP 4xx/5xx
responses. Also account for redirect rejections surfaced as HTTPError code 302
by updating the corresponding redirect test expectation.

In `@services/kit-manager-api/tests/test_kit_service_runtime_status.py`:
- Around line 139-184: Update
test_configured_gateway_rejects_redirects_without_contacting_the_destination to
create both HTTP servers and their threads inside the try block, ensuring
cleanup runs if either setup fails; retain the existing finally cleanup for
successfully initialized resources. Keep the required
BaseHTTPRequestHandler.log_message parameter name format and add the targeted
noqa A002 suppression to both handler methods.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 066586b3-926a-4835-a869-5f221b30f74d

📥 Commits

Reviewing files that changed from the base of the PR and between 939232e and 1b8b18c.

📒 Files selected for processing (16)
  • .claude/skills/deploy-linux-test-environment/SKILL.md
  • .codex/skills/deploy-linux-test-environment/SKILL.md
  • agent-skills-manifest.json
  • bim-streaming-server/source/extensions/ezplus.bim_review_stream.messaging/ezplus/bim_review_stream/messaging/ifc2usdc_powershell_adapter.py
  • bim-streaming-server/tests/test_host_native_conversion_service.py
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt
  • scripts/deploy.ps1
  • scripts/lib/host-native-launcher.ps1
  • scripts/tests/test-deploy-governance-static.ps1
  • scripts/tests/test-host-native-launcher.ps1
  • scripts/tests/test-rebuild-test-deploy.ps1
  • scripts/tests/test-verify-all.ps1
  • scripts/verify-all.ps1
  • scripts/verify-all.sh
  • services/kit-manager-api/app/kit_gateway.py
  • services/kit-manager-api/tests/test_kit_service_runtime_status.py
🚧 Files skipped from review as they are similar to previous changes (9)
  • agent-skills-manifest.json
  • scripts/tests/test-host-native-launcher.ps1
  • docs/evidence/linux-test-deploy-verifier-hardening/self-referential-bootstrap/verification.txt
  • scripts/deploy.ps1
  • scripts/tests/test-deploy-governance-static.ps1
  • .claude/skills/deploy-linux-test-environment/SKILL.md
  • scripts/lib/host-native-launcher.ps1
  • scripts/verify-all.ps1
  • bim-streaming-server/tests/test_host_native_conversion_service.py

Comment thread scripts/verify-all.sh

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8da4c4284e

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread scripts/tests/test-self-referential-bootstrap.ps1 Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85d518b5a6

ℹ️ 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".

@monkey1sai

Copy link
Copy Markdown
Owner Author

Scheduled overnight run — evidence and hand-off (not a human review)

This comment is machine-generated by the ai-bim-geo scheduled task. It records evidence only; it is not an approving review.

Codex tri-adversarial ship gate

Run on head 1b8b18c (base main @ a93c5a3, 26 files, -MaxDiffChars 400000).
Engine: L0 gpt-5.6-terra triage -> L1 lens fanout routed terra/luna/gpt-5.5 (security floor gpt-5.5) -> L2 refute-by-default gpt-5.5 with top-tier findings refuted cross-model by gpt-5.6-sol -> L3 apex gpt-5.6-sol/max. 14/14 agent calls ok, engine wall clock 1009.5s.

Verdict: SHIP — 0 critical, 0 high. L1 raw 13 / deduped 13, L2 confirmed 6 / refuted 2 / unverified 0, L3 final 6.

Surviving findings, all medium (non-blocking):

id lens file finding
L1-COR-001 correctness scripts/deploy.ps1 timed-out CAD hardener could keep running after deploy reports failure (Kill($true) failure discarded, HasExited unchecked)
L1-SEC-003 security scripts/deploy.ps1 hardener subprocess inherits PYTHONPATH/PYTHONHOME; launch with -I and a cleaned child environment
TG-001 test-gap harden-cad-extension-cache.py the checked-in CLI success path is never executed end to end
TG-002 test-gap scripts/verify-all.sh new option forwarding is only regex-asserted, never executed
TG-003 test-gap scripts/lib/host-native-launcher.ps1 the default import probe implementation is never run against a blocking child
TG-004 test-gap ifc2usdc_powershell_adapter.py no adversarial Windows integration test installs a hostile DACL or races the pinned execution handle

Refuted and dropped at L2/L3: L1-SEC-001 (control URL is validated twice on the canonical path) and L1-SEC-002 (Remove-Item Env:PYTHONNOUSERSITE is unchanged context, not introduced here).

L1-COR-001 is already closed by e41ef7e (Stop-HostNativeProcessTreeAndWait now throws when termination cannot be proven).

Reviewer threads

All 15 previously unresolved threads are resolved, each with the specific fix recorded on the thread.

Local validation at head 8da4c42 (Windows)

test-deploy-governance-static PASS - test-host-native-launcher PASS - test-verify-all PASS - test-rebuild-test-deploy PASS - test-self-referential-bootstrap PASS - test-agent-governance-check 45/45 - sync-agent-skills -Mode Check valid - pytest bim-streaming-server/tests/test_host_native_conversion_service.py 94 passed / 6 skipped - pytest services/kit-manager-api/tests 14 passed - git diff --check clean. test-verify-all re-run PASS at 85d518b.

Why this run did not merge

A second autonomous agent session is editing this branch concurrently. Its mid-flight edits were swept into e41ef7e and left test-deploy-governance-static broken (a call to Stop-HostNativeProcessTreeAndWait that the AST sandbox never loads); fe10d76 repairs that. The branch head moved again to 85d518b and new untracked work is in progress. Merging now would truncate that work, invalidate the gate evidence above, and ship code this run did not validate, so the merge, the monkey1sai-blip approving review, and the governance-base-audit re-run are deliberately left to the owner or to the session that finishes the branch.

Also still open before merge: the PR body Windows verification evidence row pins head 8da4c42 and must be re-pointed at the final head with an exact-head Actions run URL, otherwise pr-metadata-contract-diagnostic stays red.

monkey1sai and others added 5 commits August 11, 2026 13:11
…port-test target id

Two review follow-ups on this branch:

- capture_output piped the converter's stdout/stderr into PowerShell and
  its Kit grandchild; on timeout, run() kills only the direct child and
  its cleanup communicate() waits forever on the pipe the grandchild
  still holds. The adapter now redirects into temp files (nothing to
  wait on after the kill), decodes them for the existing CONV_META
  parsing, and gives the outer timeout a 30s buffer so the ps1's own
  -TimeoutSeconds cleans the Kit tree first. Pinned by a
  no-pipes contract test and a converter_timeout mapping test.
- The transport unit tests no longer invoke helpers with the
  canonical-linux target id: the canonical rebuild's regular form takes
  no -TargetId at all (the wrapper defaults to the registry canonical
  target), so unit fixtures use a neutral id and the canonical id
  appears only where the registry declares it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpF P6
…he canonical Linux host

deploy-main-to-linux-test rides on deploy-linux-test-environment (the
single source of truth for every deployment guardrail) and records the
2026-08-11 live-verified shortest path: isolated origin/main worktree,
canonical env staging, the regular no-TargetId invocation, tag/health
verification, and the pitfall table (pwsh 7 vs 5.1 native-stderr,
missing staging HELD, worktree-add stderr, no explicit canonical id).
Claude side is canonical; the Codex mirror, gitignore whitelists, and
manifest digest are synced via sync-agent-skills (Check valid, 31
skills).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6
…or form

The canonical rebuild's regular form takes no -TargetId: the wrapper
resolves the registry canonical_target, and the explicit selector exists
only for on-demand targets. The bootstrap test's command specs and the
recorded baseline evidence previously smuggled '-TargetId canonical-linux'
into what claimed to be the canonical form.

- test-self-referential-bootstrap: command specs use the regular form and
  a new assertion pins canonical-linux-rebuild to stay selector-free.
- evidence: baseline rerun with the branch wrapper (head 1b764e2) in the
  regular form; deployed source a93c5a3, tag
  deploy-20260811-639220225263578177-002, deploy_exit=0.
- conversion suite count updated (96 passed) for the pipe-hang fix cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6
…ation root

The owner-private walk only covered the validation root downward. On
Linux an ancestor of the release root or extension cache root that
another account can write would let that account rename the validated
tree and substitute its own content before PowerShell reopens the
entrypoint by pathname. Walk from each validation root up to the
filesystem root and require every ancestor to be a directory owned by
root or the service account, not other-writable and not group-writable
to a shared group, with the sticky bit exempting shared directories
where foreign entries cannot be renamed.

Five platform-independent unit cases pin the contract (root-owned
chain, other-writable ancestor, sticky world-writable ancestor,
foreign-owned ancestor, group-writable ancestor without a private
group).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6
Every mirrored skill tree carries a text eol=lf attribute so the
agent-skill-tree digest is byte-stable across platforms; the new skill
was missing its pair. On the windows-latest governance runners git's
default autocrlf checkout turned SKILL.md into CRLF, so the source-side
digest no longer matched the manifest and the sync preflight failed
closed (integrity mismatch in non-remediable location [claude]).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6

@monkey1sai-blip monkey1sai-blip left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved by monkey1sai-blip (the reviewer account pinned by the repo's merge governance).

Submitted through scripts/blip_review.py — a scripted approval carrying the operator's authority, pinned to head 6cf4fb8ba57f27a63e0a0a444fefc3b7eb927feb. This is the mechanism the GitHub App cannot satisfy: an App's approving review does not count toward required_approving_review_count.

@monkey1sai
monkey1sai merged commit 5a7fea9 into main Aug 11, 2026
51 of 54 checks passed
@monkey1sai
monkey1sai deleted the chore/deploy-linux-test-skill branch August 11, 2026 06:07
monkey1sai added a commit that referenced this pull request Aug 11, 2026
…mmand (#487)

* fix(deploy): stop Start-Process from shredding the Linux Kit build command

The bash launch path passed the whole build command as one -c string
with embedded quotes. Start-Process joins its ArgumentList into a single
Arguments string and re-tokenizes it, so bash actually received only the
repo.sh path as the command: repo.sh printed its usage with no arguments
and exited 0, the build argument and the log redirect were silently
dropped, and deploy.ps1 took the fake exit 0 as a successful build until
the artifact recheck failed with a far less diagnosable message. This
was latent since the Linux migration (#467) — every earlier rebuild
found the deployment checkout unchanged and skipped the build phase —
and first fired on the post-#484 fixpoint rebuild, which reset the
checkout and cleaned _build.

Write the launch command into a wrapper script instead, so the command
line carries exactly one plain path argument that no platform's argument
re-quoting can damage. Also fail closed when the build process exits 0
without ever creating its log file: that combination means the launch
line was shredded and nothing ran.

Verified on the canonical Linux host (isolated probe): repo.sh received
exactly 'build', the redirect created the log, exit 0. The full canonical
rebuild through this path lands with the ledger fixpoint after merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6

* fix(deploy): feed the build wrapper via stdin and scope the log to this launch

Review round: feed the wrapper script to bash on stdin so the command
line carries no argument at all — a deploy_root with spaces has nothing
left to shred. Remove any stale kit-repo-build.log before launching so
the exit-0-must-have-a-log guard proves this build created it, not an
earlier one. Mark the test fixture repo.sh executable on POSIX hosts
where exec would otherwise fail with EACCES, and run the dynamic bash
test inside a directory with spaces.

Verified again on the canonical Linux host: exit 0, args seen=[build],
log created, from a 'deploy root with spaces' directory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6

* fix(deploy): escape shell metacharacters in the wrapper's embedded paths

The registry accepts deploy_root values containing $ and backtick; embedding
those raw inside the wrapper's double-quoted sh strings lets the shell perform
parameter/command substitution on the path, so exec or the log redirect targets
a different location. Escape the four double-quote-special characters when
composing the wrapper, and run Test 15c from a directory carrying spaces, $,
and a backtick (fails with exit 127 without the escaping).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Gn3PJQ96Krb3adAErpXGu

* test(deploy): make launcher regressions portable on Windows

* fix(deploy): fail closed on stale build logs

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
monkey1sai added a commit that referenced this pull request Aug 12, 2026
…e timeout path (#502)

Closes #493 (TG-02, gate #484 finding). Every existing dynamic
Start-HostNativeKitManager case injected a succeeding fake -ImportProbeFn, so
the DEFAULT probe's WaitForExit/Stop-HostNativeProcessTreeAndWait/-1
propagation was only proven by source-regex assertions, never actually
driven.

Add a dynamic case to Test 21 that puts a fastapi.py shim on PYTHONPATH which
spawns a child and sleeps, forcing the hardcoded `-c 'import fastapi, uvicorn'`
probe to hang. Calls Start-HostNativeKitManager with no -ImportProbeFn
override and a 1s -ImportProbeTimeoutSec, asserting: the documented
"...cannot import fastapi and uvicorn" throw, a bounded (<10s) elapsed time,
that Start-HostNativeService is never reached, and that both the shim's
parent and child PIDs have exited.

Verified the assertions actually bite: temporarily raising
-ImportProbeTimeoutSec past the 10s bound fails the elapsed-time assertion,
and temporarily stubbing out Stop-HostNativeProcessTreeAndWait fails the
surviving-PID assertion. Both reverted before commit.

Test-only change; scripts/lib/host-native-launcher.ps1 is untouched.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
monkey1sai added a commit that referenced this pull request Aug 12, 2026
…with its rebuild-backed fixpoint (#499)

* fix(governance): close the linux-test-deploy-verifier-hardening debt with its rebuild-backed fixpoint

Rerun the entry's ordered 14-command verification contract after #487 merged:
local suites 1-11 all exit 0, canonical Linux rebuild exit 0 with the repaired
stdin-fed build launch proven on the canonical host (deploy tag
deploy-20260811-639220482065640754-003), the CAD hardener idempotently exit 0,
and the remote Deployment-profile verify all green. Two group-writable
directory drifts the #484 trust-root ancestry validation correctly refused are
recorded in the summary with their in-run chmod remediation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Gn3PJQ96Krb3adAErpXGu

* docs(evidence): attest the strict contract-order fixpoint sweep

Rerun the full 14-command contract in the opening contract's exact order
(1-11 local at the deployed source commit c88dca6, then harden 12, rebuild 13
with deploy tag deploy-20260811-639220494716638402-004, verify 14) after review
flagged the first sweep's 13-before-12 chronology; every command exit 0 in a
single pass. The first sweep and the in-run permission findings remain recorded
as context.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Gn3PJQ96Krb3adAErpXGu

* docs(evidence): declare an allowed document nature and add run timestamps

working note replaces the non-vocabulary 'evidence' nature per docs/AGENTS.md,
and the attested-run section now carries UTC time anchors proving the
12-before-13 execution order.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Gn3PJQ96Krb3adAErpXGu

* docs(evidence): rerun command 14 with the pinned -InventoryPath invocation

The immutable command map pins canonical-linux-deployment-verify as
verify-all.ps1 -Profile Deployment -InventoryPath <owner-private-inventory>;
the sweep had substituted the environment-variable inventory form. Rerun the
pinned invocation against the same unchanged -004 deployment (exit 0, all six
checks Passed, 2026-08-12T02:00:16Z) and make it the attested record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Gn3PJQ96Krb3adAErpXGu

* fix(governance): attest the fixpoint with a pinned-form 12-14 remediation rerun

Review P1 on this PR proved command 13's recorded invocation carried an
extra -IdentityFile beyond the immutable command map's pinned form. The
owner moved the deploy key into default ssh resolution (batch-mode
preflight DEFAULT_IDENTITY_OK), then commands 12-14 were rerun in contract
order, all pinned form, single pass:

- 12 harden-cad on the remote deploy_root: exact schema line, exit 0
- 13 rebuild from fresh origin/main (970dc34, isolated worktree), NO
  -IdentityFile / -TargetId: deploy exit 0, tag
  deploy-20260812-639221007059362180-001 pushed
- 14 verify-all -Profile Deployment -InventoryPath on the NEW deployment:
  six checks Passed, none Failed, exit 0

summary.md keeps the 2026-08-11 invocation as a historical record and
marks the 2026-08-12 rerun as the attested one; ledger fixpoint
reverified_at rebound to 2026-08-12T03:07:00Z.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

3 participants