Skip to content

Close Hospital and Repowise trust boundaries - #8

Merged
2233admin merged 4 commits into
mainfrom
codex/code-intel-trust-boundary
Jul 24, 2026
Merged

Close Hospital and Repowise trust boundaries#8
2233admin merged 4 commits into
mainfrom
codex/code-intel-trust-boundary

Conversation

@2233admin

Copy link
Copy Markdown
Owner

Summary

  • make Hospital decisions and scores fail closed on missing or unreadable evidence
  • make scoped Repowise default to HEAD-only inputs with a schema v2 frozen egress manifest
  • select local Git/LM Wiki control planes before optional hosted trackers
  • enforce the new trust contracts in CI

Verification

  • Hospital trust contract: 16/16
  • PowerShell regression suite: 29/29
  • Repowise validator: 11/11
  • scoped Repowise security/worktree: pass
  • Rust tests: 24/24
  • pipeline smoke: pass
  • independent Standards + Spec review: no remaining P0/P1

No real remote provider was invoked during tests.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@2233admin, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9890555-f01f-44e7-87f3-99bef315a8b9

📥 Commits

Reviewing files that changed from the base of the PR and between 142ecf2 and 42ee3b6.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • install-code-intel-pipeline.ps1
  • overlays/repowise/README.md
  • test-regression-fixes.ps1
  • tools/sentrux-shim/sentrux-shim.ps1
📝 Walkthrough

Walkthrough

The PR adds scoped Repowise egress manifests and payload freezing, strengthens hospital evidence gating and scoring, resolves repository configuration by physical path, updates control-plane and artifact contracts, and adds PowerShell/Python regression coverage wired into CI.

Changes

Scoped Repowise egress

Layer / File(s) Summary
Scoped worktree preparation and manifest generation
Invoke-ScopedRepowise.ps1
Adds working-tree inclusion, path and reparse-point validation, normalized sparse-checkout inputs, scoped copying, and schema v2 egress manifest creation.
Manifest validation and provider payload freezing
Run-ScopedRepowiseDocs.py, Invoke-ScopedRepowise.ps1
Validates manifest identity, scope, hashes, and policy; freezes exact provider bytes before provider construction.
Scoped egress regression coverage and CI execution
.github/workflows/ci.yml, test-scoped-repowise-*
Adds security, worktree, manifest, TOCTOU, payload, and long-path tests to CI.

Hospital fail-closed contract

Layer / File(s) Summary
Evidence, scoring, and modality state
run-code-intel.ps1
Loads expanded artifacts, derives pollution and scope states, defaults unknown evidence to zero, and exposes modality statuses.
Fail-closed decisions and state transitions
run-code-intel.ps1
Adds structural evidence, provider quota, Sentrux, and surgery-target requirements to hospital routing and discharge decisions.
Hospital contract tests and supporting documentation
test-hospital-trust-contract.ps1, docs/artifact-data-contract.md, docs/hospital-mode.md
Verifies fail-closed behavior, evidence states, quota routing, target resolution, modality scoring, and report wiring.

Repository configuration resolution

Layer / File(s) Summary
Resolved repository configuration lookup
check-code-intel-tools.ps1, run-code-intel.ps1
Selects repository configuration by normalized resolved filesystem path when RepoPath is provided.
Configuration resolution regression tests
test-doctor-repo-config-resolution.ps1, test-repo-config-resolution.ps1
Tests physical-path selection, alias lookup, Sentrux scope resolution, and Repowise settings.

Local-first control-plane documentation

Layer / File(s) Summary
Control-plane authority and boundaries
docs/adr/0008-*, docs/agents/issue-tracker.md, docs/project-management-support.md, pipeline.config.json
Defines single-writer task authority, optional hosted projections, authorization boundaries, local Work-OS rules, and the updated project path.
Artifact and hospital contract documentation
docs/artifact-data-contract.md
Documents fail-closed hospital evidence and scoped Repowise manifest and payload-freezing contracts.

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

Possibly related PRs

Poem

A rabbit hops through scopes so tight,
Hashes guard the files just right.
Hospital gates say, “Prove, don’t guess,”
Frozen bytes bring trustfulness.
CI drums its code-review beat—
Safe little burrows, clean and neat!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.13% 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
Title check ✅ Passed The title accurately summarizes the main change: tightening Hospital and Repowise trust boundaries.
Description check ✅ Passed The description is clearly related to the changeset and matches the stated goals and verification results.
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.

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a fail-closed egress and trust contract for scoped Repowise document generation and hospital-mode state tracking. Key changes include the addition of egress manifest validation, path-traversal and reparse-point security checks, and updated state-machine guards to handle provider quota exhaustion and incomplete structural evidence. Review feedback highlights several critical runtime issues: PowerShell scripts should use the fully qualified [System.StringComparer] type to prevent TypeNotFound exceptions, the hospital state machine should route to the 'govern' protocol upon Sentrux gate failures, and the Python boundary requires path normalization for Windows compatibility and verification of the get_repo_structure signature to avoid a potential TypeError.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread Invoke-ScopedRepowise.ps1
[string]$WorkingTreePolicy
)

$inventoryByPath = [System.Collections.Generic.Dictionary[string, object]]::new([StringComparer]::Ordinal)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

In PowerShell, [StringComparer] is not a default type accelerator. Using it without the full namespace will throw a TypeNotFound exception at runtime. Use [System.StringComparer] instead.

    $inventoryByPath = [System.Collections.Generic.Dictionary[string, object]]::new([System.StringComparer]::Ordinal)

Comment thread Invoke-ScopedRepowise.ps1
}

$orderedPaths = [string[]]@($inventoryByPath.Keys)
[Array]::Sort($orderedPaths, [StringComparer]::Ordinal)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

In PowerShell, [StringComparer] is not a default type accelerator. Use [System.StringComparer] instead to avoid a runtime TypeNotFound exception.

    [Array]::Sort($orderedPaths, [System.StringComparer]::Ordinal)

Comment thread run-code-intel.ps1
if ($providerQuotaCount -gt 0) { return "triage" }
if ($null -ne $GitHubResearch -and [bool]$GitHubResearch.required) { return "github_solution_research" }
if ($FailureCounts.graphMissing -gt 0) { return "diagnose" }
if (-not $RulesExists) { return "govern" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

If a Sentrux check or gate fails ($FailureCounts.sentruxFail -gt 0), the next protocol should be "govern" to address the architectural violation. Currently, the function falls through to "surgery_plan" or "post_op", which bypasses the governance phase. Update the guard to route to "govern" when rules are missing or when there is an active gate failure.

    if (-not $RulesExists -or $FailureCounts.sentruxFail -gt 0) { return "govern" }

Comment thread Run-ScopedRepowiseDocs.py
Comment on lines +105 to +108
relative = entry.get("path")
expected_hash = entry.get("sha256")
if not isinstance(relative, str) or not isinstance(expected_hash, str):
raise RuntimeError(f"egress manifest {label} entry is incomplete")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To ensure robust cross-platform path handling, normalize any backslashes in relative to forward slashes. On Windows, paths in the manifest might contain backslashes, which PurePosixPath does not treat as directory separators, leading to single-segment paths containing literal backslashes.

        relative = entry.get("path")
        expected_hash = entry.get("sha256")
        if not isinstance(relative, str) or not isinstance(expected_hash, str):
            raise RuntimeError(f"egress manifest {label} entry is incomplete")
        relative = relative.replace("\\", "/")

Comment thread Run-ScopedRepowiseDocs.py
file_infos = list(traverser.traverse())
repo_structure = traverser.get_repo_structure()
source_map = freeze_provider_payload(repo_path, egress_manifest, file_infos, manifest)
repo_structure = traverser.get_repo_structure(file_infos)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

If the underlying repowise library's get_repo_structure method does not accept any arguments (as in standard versions), passing file_infos here will raise a TypeError at runtime. Since the test suite only mocks this method or skips calling it on the real class, this signature mismatch would not be caught during verification.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (3)
test-repo-config-resolution.ps1 (1)

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

Align the repo-config helpers across scripts

Find-RepoConfigByPath and the repo resolver have different contracts in run-code-intel.ps1 and check-code-intel-tools.ps1 (Resolve-Repo vs Resolve-RepoPath, and repos-only vs full-config input). Rename or normalize them so the shared names don’t imply interchangeable behavior.

🤖 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 `@test-repo-config-resolution.ps1` around lines 13 - 18, Normalize the
extracted helper contracts across run-code-intel.ps1 and
check-code-intel-tools.ps1: align the resolver naming (Resolve-Repo versus
Resolve-RepoPath) and make Find-RepoConfigByPath consistently accept the same
repos-only or full-config input in both scripts. Update all corresponding
callers and the functionNames extraction list in test-repo-config-resolution.ps1
so the shared names accurately represent interchangeable behavior.
run-code-intel.ps1 (1)

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

Guard reads for localToolError/graphMissing/sentruxFail are not as defensive as providerQuota.

providerQuota is read via an explicit IDictionary.Contains/PSObject.Properties guard (1899-1904), but toolsOk/graphOk/sentruxOk still use direct member access (e.g. [int]$FailureCounts.localToolError). If a caller ever supplies a FailureCounts object missing one of those keys, [int]$null collapses to 0, i.e. the guard silently passes (fail-open) for the one area this contract most wants fail-closed. All current callers populate every key, so this is defensive-only, but routing it through Get-FailureCount would keep the seam uniformly 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 `@run-code-intel.ps1` around lines 1896 - 1919, The guard logic around the
state-machine checks should read localToolError, graphMissing, and sentruxFail
defensively like providerQuota, failing closed when keys are absent. Reuse the
existing Get-FailureCount helper for these three values, then base toolsOk,
graphOk, and sentruxOk on its results while preserving the current zero-count
behavior for present keys.
Run-ScopedRepowiseDocs.py (1)

306-326: 🚀 Performance & Scalability | 🔵 Trivial

Per-file HEAD-blob validation runs twice and spawns 2 git processes per file.

For the head-tracked-only policy, _validate_file_entries shells out to git rev-parse HEAD:<path> and git hash-object for every inventory entry, and this full validation runs once here (Line 316) and again inside freeze_provider_payload (Line 292). For small scoped worktrees this is negligible, but if a scope ever spans many files the process-spawn count grows to roughly 4 * N. If that becomes a hot path, consider batching with a single git ls-tree -r HEAD plus git hash-object --stdin-paths (or git status --porcelain) to compare blobs in one pass.

🤖 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 `@Run-ScopedRepowiseDocs.py` around lines 306 - 326, Remove the redundant
egress-manifest validation from generate_docs after freeze_provider_payload
already validates it, while preserving the manifest value needed by the
function. Ensure head-tracked-only file validation occurs only once rather than
being repeated by generate_docs and freeze_provider_payload.
🤖 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.

Nitpick comments:
In `@run-code-intel.ps1`:
- Around line 1896-1919: The guard logic around the state-machine checks should
read localToolError, graphMissing, and sentruxFail defensively like
providerQuota, failing closed when keys are absent. Reuse the existing
Get-FailureCount helper for these three values, then base toolsOk, graphOk, and
sentruxOk on its results while preserving the current zero-count behavior for
present keys.

In `@Run-ScopedRepowiseDocs.py`:
- Around line 306-326: Remove the redundant egress-manifest validation from
generate_docs after freeze_provider_payload already validates it, while
preserving the manifest value needed by the function. Ensure head-tracked-only
file validation occurs only once rather than being repeated by generate_docs and
freeze_provider_payload.

In `@test-repo-config-resolution.ps1`:
- Around line 13-18: Normalize the extracted helper contracts across
run-code-intel.ps1 and check-code-intel-tools.ps1: align the resolver naming
(Resolve-Repo versus Resolve-RepoPath) and make Find-RepoConfigByPath
consistently accept the same repos-only or full-config input in both scripts.
Update all corresponding callers and the functionNames extraction list in
test-repo-config-resolution.ps1 so the shared names accurately represent
interchangeable behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4654f86e-7daf-4092-90c4-90c6c020025d

📥 Commits

Reviewing files that changed from the base of the PR and between ba676f6 and 142ecf2.

📒 Files selected for processing (17)
  • .github/workflows/ci.yml
  • Invoke-ScopedRepowise.ps1
  • Run-ScopedRepowiseDocs.py
  • check-code-intel-tools.ps1
  • docs/adr/0008-local-first-project-control-plane.md
  • docs/agents/issue-tracker.md
  • docs/artifact-data-contract.md
  • docs/hospital-mode.md
  • docs/project-management-support.md
  • pipeline.config.json
  • run-code-intel.ps1
  • test-doctor-repo-config-resolution.ps1
  • test-hospital-trust-contract.ps1
  • test-repo-config-resolution.ps1
  • test-scoped-repowise-security.ps1
  • test-scoped-repowise-validator.py
  • test-scoped-repowise-worktree.ps1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant