Skip to content

Follow-on: gates capability prep (legal/sandbox/fixture UI/012) - #29

Merged
TheHalfMoon merged 1 commit into
mainfrom
chore/followon-gates-capability-prep
Aug 26, 2026
Merged

Follow-on: gates capability prep (legal/sandbox/fixture UI/012)#29
TheHalfMoon merged 1 commit into
mainfrom
chore/followon-gates-capability-prep

Conversation

@TheHalfMoon

Copy link
Copy Markdown
Owner

Summary

  • FlowDecisionRecord (PendingCounsel; no invented legal conclusions)
  • OsSandboxPlan Landlock/AppContainer/Seatbelt scaffolds; try_apply always NotPlatformQualified
  • FixtureUiViewModel adapters for doctor/timeline/brief/coverage
  • Spec 012 research Spec Kit + MESC Python refuse test + hostile MIME unit tests
  • Sync Spec 004/005/006 task checkboxes to CLOSED_CANONICAL; fix START_HERE drift

Test plan

  • cargo test -p medscale-contracts -p medscale-core --test hostile_mime_010 --test mesc_boundary_012
  • clippy -D warnings
  • cargo deny check

Made with Cursor

…2 prep.

Authorized under OPEN external gates without inventing conclusions or PLATFORM_QUALIFIED claims; sync closed-spec task checkboxes and START_HERE drift.

Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

Copy link
Copy Markdown

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 15 minutes.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

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).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b659814a-500e-45c3-ae25-037d6b22f502

📥 Commits

Reviewing files that changed from the base of the PR and between 2423912 and adae0a8.

📒 Files selected for processing (20)
  • crates/medscale-contracts/src/fixture_ui/mod.rs
  • crates/medscale-contracts/src/legal/mod.rs
  • crates/medscale-contracts/src/lib.rs
  • crates/medscale-contracts/src/os_sandbox/mod.rs
  • crates/medscale-contracts/src/worker_policy/mod.rs
  • crates/medscale-core/tests/hostile_mime_010.rs
  • crates/medscale-core/tests/mesc_boundary_012.rs
  • docs/planning/BUILD_QUEUE.md
  • docs/planning/EXTERNAL_GATES.md
  • docs/planning/START_HERE.md
  • evidence/008-local-ai-capability-fabric/OS_SANDBOX_SCAFFOLD.md
  • evidence/legal-decision-record/SUMMARY.md
  • imports/v0/README.md
  • specs/004-h0b-trusted-presentation-coverage/tasks.md
  • specs/005-local-private-vault-encryption-recovery/tasks.md
  • specs/006-cli-desktop-foundation/tasks.md
  • specs/012-mesc-artifact-integration/plan.md
  • specs/012-mesc-artifact-integration/research.md
  • specs/012-mesc-artifact-integration/spec.md
  • specs/012-mesc-artifact-integration/tasks.md

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

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Prepare fail-closed capabilities for open external gates

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds fail-closed legal, sandbox, and fixture UI contracts for open external gates.
• Adds hostile MIME and MESC dependency boundary tests.
• Aligns evidence, Spec 012 research, and closed-spec planning status.
Diagram

graph TD
  G["External gates"] --> C["Capability contracts"] --> Q{"Gate qualified?"}
  Q -- "No" --> R["Fail-closed refusal"] --> E["Evidence records"] --> P["Planning status"]
  C --> U["Fixture UI"]
Loading
High-Level Assessment

The scaffold-first, fail-closed approach is appropriate while counsel, platform qualification, final UI, and MESC artifact gates remain unresolved. Implementing runtime sandboxing, legal conclusions, or MESC integration now would create unsupported claims; keeping these as typed contracts plus explicit evidence boundaries is the safest incremental design.

Files changed (20) +690 / -124

Enhancement (5) +392 / -0
mod.rsAdd synthetic fixture UI view models +137/-0

Add synthetic fixture UI view models

• Introduces shell-neutral adapters for doctor, timeline, brief, and coverage payloads. The models carry synthetic and real-PHI authorization flags and include a boundary test.

crates/medscale-contracts/src/fixture_ui/mod.rs

mod.rsAdd counsel-owned flow decision records +101/-0

Add counsel-owned flow decision records

• Adds a versioned legal-flow record whose default state is PendingCounsel with no conclusion. Structural validation prevents pending records from carrying invented counsel conclusions.

crates/medscale-contracts/src/legal/mod.rs

lib.rsExport new gate capability modules +3/-0

Export new gate capability modules

• Publishes the fixture UI, legal decision-record, and OS sandbox contract modules.

crates/medscale-contracts/src/lib.rs

mod.rsAdd fail-closed OS sandbox plans +144/-0

Add fail-closed OS sandbox plans

• Defines Linux Landlock, Windows AppContainer, and macOS Seatbelt scaffold plans as not platform-qualified. Runtime application always refuses until measured evidence closes the external gate.

crates/medscale-contracts/src/os_sandbox/mod.rs

mod.rsBind worker policy to sandbox scaffold status +7/-0

Bind worker policy to sandbox scaffold status

• Adds a policy builder that identifies the confinement profile as an unqualified OS sandbox scaffold without asserting production isolation.

crates/medscale-contracts/src/worker_policy/mod.rs

Tests (2) +73 / -0
hostile_mime_010.rsTest hostile MIME quarantine behavior +36/-0

Test hostile MIME quarantine behavior

• Verifies denied MIME classes and empty payloads are quarantined with the expected typed reasons.

crates/medscale-core/tests/hostile_mime_010.rs

mesc_boundary_012.rsRefuse MESC Python runtime dependencies +37/-0

Refuse MESC Python runtime dependencies

• Scans workspace crate manifests and fails if a non-comment dependency appears to link a forbidden MESC Python package.

crates/medscale-core/tests/mesc_boundary_012.rs

Documentation (13) +225 / -124
BUILD_QUEUE.mdClarify Spec 012 blocked research state +1/-1

Clarify Spec 012 blocked research state

• Updates the build queue to reflect that research and an empty-asset gate check exist while artifact import remains blocked.

docs/planning/BUILD_QUEUE.md

EXTERNAL_GATES.mdRecord delivered gate scaffolds and remaining blockers +3/-3

Record delivered gate scaffolds and remaining blockers

• Documents the legal record, fixture UI adapter, and OS sandbox scaffold capabilities. It preserves counsel, final-design, and measured platform qualification as unresolved external requirements.

docs/planning/EXTERNAL_GATES.md

START_HERE.mdCorrect canonical specification status guidance +2/-2

Correct canonical specification status guidance

• Marks Spec 001 closed and directs automation to live build-queue states. It records Specs 001–011 and 013–015 as closed while Spec 012 remains artifact-gated.

docs/planning/START_HERE.md

OS_SANDBOX_SCAFFOLD.mdDocument OS sandbox scaffold limitations +25/-0

Document OS sandbox scaffold limitations

• Records the candidate mechanisms for each supported OS and explicitly excludes platform qualification or measured confinement claims. It lists the evidence needed to close the gate.

evidence/008-local-ai-capability-fabric/OS_SANDBOX_SCAFFOLD.md

SUMMARY.mdDocument legal decision-record capability +16/-0

Document legal decision-record capability

• Summarizes the PendingCounsel schema and clarifies that no lawful-basis conclusions or counsel workflows are delivered.

evidence/legal-decision-record/SUMMARY.md

README.mdDocument pre-v0 fixture UI contracts +5/-1

Document pre-v0 fixture UI contracts

• Points shell integrations to typed fixture UI adapters while retaining the final visual artifact as an external gate.

imports/v0/README.md

tasks.mdSynchronize Spec 004 completion markers +42/-40

Synchronize Spec 004 completion markers

• Marks all presentation and coverage tasks complete to match the specification's CLOSED_CANONICAL status.

specs/004-h0b-trusted-presentation-coverage/tasks.md

tasks.mdSynchronize Spec 005 completion markers +47/-45

Synchronize Spec 005 completion markers

• Marks all vault encryption, recovery, migration, and closeout tasks complete to match CLOSED_CANONICAL status.

specs/005-local-private-vault-encryption-recovery/tasks.md

tasks.mdSynchronize Spec 006 completion markers +34/-32

Synchronize Spec 006 completion markers

• Marks all CLI, privacy-proof, desktop scaffold, and closeout tasks complete to match CLOSED_CANONICAL status.

specs/006-cli-desktop-foundation/tasks.md

plan.mdAdd blocked Spec 012 integration plan +10/-0

Add blocked Spec 012 integration plan

• Defines artifact-only integration decisions and prohibits implementation until a released MESC artifact becomes available.

specs/012-mesc-artifact-integration/plan.md

research.mdRecord MESC artifact eligibility research +14/-0

Record MESC artifact eligibility research

• Lists the immutable assets, hashes, rights, SBOM, provenance, and evaluation evidence required for admission. It records that the current release has no assets.

specs/012-mesc-artifact-integration/research.md

spec.mdDefine MESC artifact integration scope +19/-0

Define MESC artifact integration scope

• Adds user stories for future artifact admission and Python-runtime refusal while explicitly excluding implementation, mutation, and fake passing artifacts during the blocked phase.

specs/012-mesc-artifact-integration/spec.md

tasks.mdTrack blocked Spec 012 tasks +7/-0

Track blocked Spec 012 tasks

• Marks research complete and leaves artifact admission, Pack binding, architecture enforcement, and canonical closeout blocked or pending.

specs/012-mesc-artifact-integration/tasks.md

@TheHalfMoon
TheHalfMoon merged commit 164f59f into main Aug 26, 2026
6 checks passed
@TheHalfMoon
TheHalfMoon deleted the chore/followon-gates-capability-prep branch August 26, 2026 01:24
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (3) 📜 Skill insights (0)

Grey Divider


Action required

1. Projection provenance falsely synthetic 📘 Rule violation § Compliance
Description
from_timeline, from_brief, and from_coverage hard-code synthetic_only: true while
serializing projections whose types carry no synthetic/PHI provenance and may be built from
arbitrary promoted assertion payloads. This can present real PHI as an approved synthetic fixture
despite the real-PHI gate being closed.
Code

crates/medscale-contracts/src/fixture_ui/mod.rs[R49-52]

+            synthetic_only: true,
+            real_phi_authorized: false,
+            title: "timeline".to_owned(),
+            body_json: serde_json::to_value(timeline).unwrap_or(serde_json::Value::Null),
Relevance

●●● Strong

Direct provenance/compliance mismatch; adapters label unrestricted projections synthetic,
conflicting with the repository’s fail-closed PHI policy.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2896957 requires all current fixture and preview data to remain synthetic until the external
gate opens. The new adapters assert synthetic provenance unconditionally, while projection builders
derive their values from unrestricted ClinicalAssertion.payload and associated source data.

Rule 2896957: No real PHI until explicit external gate
crates/medscale-contracts/src/fixture_ui/mod.rs[46-75]
crates/medscale-contracts/src/presentation/mod.rs[177-202]
crates/medscale-contracts/src/objects/authority_classes.rs[31-43]
crates/medscale-core/src/authority/presentation.rs[86-128]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Fixture UI projection adapters currently label every timeline, brief, and coverage payload as synthetic even though the input types do not establish that provenance.

## Issue Context
The projections can be built from arbitrary promoted assertions and source bytes. Add or require trusted provenance metadata and refuse construction when real PHI is not authorized; do not infer synthetic status from the adapter used.

## Fix Focus Areas
- crates/medscale-contracts/src/fixture_ui/mod.rs[46-75]
- crates/medscale-contracts/src/presentation/mod.rs[177-202]
- crates/medscale-core/src/authority/presentation.rs[86-315]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. PHI boundary accepts unauthorized data 📘 Rule violation § Compliance
Description
FixtureUiViewModel::respects_phi_boundary() implements the PHI boundary incorrectly: it accepts
synthetic_only=false, real_phi_authorized=false, allowing unauthorized non-synthetic data, while
rejecting the valid authorized state synthetic_only=false, real_phi_authorized=true. Because the
view model is public and deserializable, callers or shells relying on this guard can expose
prohibited live PHI or reject properly authorized data.
Code

crates/medscale-contracts/src/fixture_ui/mod.rs[R80-83]

+    pub fn respects_phi_boundary(&self) -> bool {
+        !(self.real_phi_authorized && !self.synthetic_only)
+            && (self.synthetic_only || !self.real_phi_authorized)
+    }
Relevance

●●● Strong

Deterministic boolean logic reverses unauthorized and authorized non-synthetic states; this is an
obvious security boundary bug.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2896957 and the method’s documentation require real PHI to be rejected until explicit
authorization, but the expression on lines 81–82 simplifies to `synthetic_only ||
!real_phi_authorized. It therefore returns true for (false, false) and false for (false,
true)`, reversing the expected outcomes for unauthorized and authorized non-synthetic data; the
public fields and Serialize/Deserialize derivations on lines 23–30 make these states externally
constructible, while DoctorReport and the current report builder establish that the flags are
independent and that false represents unauthorized.

Rule 2896957: No real PHI until explicit external gate
crates/medscale-contracts/src/fixture_ui/mod.rs[27-30]
crates/medscale-contracts/src/fixture_ui/mod.rs[78-83]
crates/medscale-contracts/src/doctor/mod.rs[48-58]
crates/medscale-core/src/doctor.rs[66-73]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description

Correct `FixtureUiViewModel::respects_phi_boundary` so it rejects the unsafe state `synthetic_only == false && real_phi_authorized == false` and accepts non-synthetic data when real-PHI authorization is present. The current predicate negates `real_phi_authorized`, causing it to accept an unauthorized live-data claim and reject the valid authorized state.

## Issue Context

The PHI boundary requires non-synthetic data to be rejected unless the explicit REAL_PHI authorization gate is open. `FixtureUiViewModel` is public, deserializable, and populated by the `from_doctor`, `from_timeline`, `from_brief`, and `from_coverage` factory methods, so callers and deserializers can construct these flag combinations and may rely on this predicate as the documented safety check.

Encode the intended implication directly—accepting a view when it is synthetic or real-PHI authorization is present—or explicitly define the allowed state matrix if additional constraints are intentional. Add truth-table tests covering every combination of `synthetic_only` and `real_phi_authorized`.

## Fix Focus Areas

- crates/medscale-contracts/src/fixture_ui/mod.rs[78-83]
- crates/medscale-contracts/src/fixture_ui/mod.rs[96-136]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. SQLCipher CI task unexecuted 📘 Rule violation ✧ Quality
Description
T040 is newly marked complete even though repository evidence says SQLCipher page encryption was not
enabled and CI runs only plain workspace tests without the sqlcipher feature. The checkbox
therefore claims completion of a feature-enabled Windows/Linux CI test task that was not executed.
Code

specs/005-local-private-vault-encryption-recovery/tasks.md[138]

+- [x] T040 Run `cargo test --workspace` + fmt/clippy with `sqlcipher` feature on Windows+Linux CI matrix as available
Relevance

●●● Strong

The checkbox claims execution of feature-enabled cross-platform CI that the supplied workflow and
evidence do not show.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2896760 forbids marking a test as passed when it was not executed. T040 explicitly requires
SQLCipher-feature tests and linting on the Windows/Linux matrix, while the workflow contains no
feature-enabled command and the evidence states SQLCipher was not enabled.

Rule 2896760: Do not mark tests as passed when they were not executed
specs/005-local-private-vault-encryption-recovery/tasks.md[138-138]
.github/workflows/ci.yml[43-47]
evidence/005-local-private-vault-encryption-recovery/SUMMARY.md[11-34]
crates/medscale-storage/Cargo.toml[12-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Spec 005 T040 is checked as complete without execution of its required SQLCipher-feature CI matrix.

## Issue Context
The current workflow runs generic workspace tests on Windows and Linux but does not pass `--features sqlcipher`; project evidence also records that SQLCipher page crypto is not enabled. Reopen the checkbox or add and execute the required feature-enabled CI jobs before claiming completion.

## Fix Focus Areas
- specs/005-local-private-vault-encryption-recovery/tasks.md[138-138]
- .github/workflows/ci.yml[43-47]
- evidence/005-local-private-vault-encryption-recovery/SUMMARY.md[11-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. MESC dependency scan misses valid TOML forms 🐞 Bug ☼ Reliability
Description
workspace_crates_do_not_depend_on_mesc_python_runtime uses fragile line-based substring matching
rather than TOML-aware dependency resolution, so it misses forbidden dependencies declared through
aliases, quoted keys, dependency-table headers, inline-commented lines, and workspace inheritance.
Because it scans only immediate crates/*/Cargo.toml manifests and not the root
[workspace.dependencies], the test can remain green while violating the MESC Python/runtime
boundary required by Spec 012 US2.
Code

crates/medscale-core/tests/mesc_boundary_012.rs[R8-30]

+    let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
+        .join("..")
+        .join("..");
+    let forbidden = ["mesc", "pymesc", "thehalfmoon-mesc"];
+    for entry in fs::read_dir(root.join("crates")).unwrap() {
+        let entry = entry.unwrap();
+        let cargo = entry.path().join("Cargo.toml");
+        if !cargo.is_file() {
+            continue;
+        }
+        let text = fs::read_to_string(&cargo).unwrap().to_lowercase();
+        for needle in forbidden {
+            // Allow comments mentioning MESC boundary; forbid dependency names.
+            for line in text.lines() {
+                let trimmed = line.trim();
+                if trimmed.starts_with('#') {
+                    continue;
+                }
+                if trimmed.contains(needle)
+                    && (trimmed.contains("dependencies") || trimmed.contains('='))
+                {
+                    // Only fail if it looks like a crate dependency key.
+                    if trimmed.starts_with(needle) || trimmed.contains(&format!("{needle} =")) {
Relevance

●●● Strong

The test’s line matching plainly misses workspace inheritance and valid TOML dependency forms,
undermining the stated architecture guard.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The test traverses only manifests under root/crates and never scans the top-level Cargo.toml,
even though shared dependencies are centralized there under [workspace.dependencies] and workspace
members routinely inherit them with workspace = true. Its failure condition only recognizes lines
that start with an unquoted forbidden token or contain the exact unquoted {needle} = sequence, so
valid Cargo forms such as runtime = { package = "mesc" }, mesc_runtime = { package = "pymesc" },
"mesc" = ..., and [dependencies.mesc] evade detection; comments are also not stripped before
matching.

crates/medscale-core/tests/mesc_boundary_012.rs[12-18]
crates/medscale-core/tests/mesc_boundary_012.rs[19-34]
Cargo.toml[33-52]
crates/medscale-core/Cargo.toml[10-19]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description

Replace the fragile line-oriented MESC dependency check, which can miss valid Cargo aliases, quoted keys, dependency-table declarations, inline-commented declarations, and workspace-inherited dependencies. The architecture test must reliably enforce Spec 012 US2 by detecting forbidden MESC/Python runtime packages across the entire workspace, including the root manifest and renamed packages.

## Issue Context

The current test inspects only `root/crates/*/Cargo.toml` using substring heuristics, while shared dependencies are centralized in the top-level `Cargo.toml` under `[workspace.dependencies]` and members may inherit them with `workspace = true`. Use a TOML-aware or `cargo metadata`-based check that resolves package names for every workspace member, including workspace dependencies and renamed packages, so comments and unrelated text do not affect the decision.

## Fix Focus Areas

- crates/medscale-core/tests/mesc_boundary_012.rs[7-36]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Deterministic flow decision IDs collide 🐞 Bug ≡ Correctness
Description
FlowDecisionRecord::pending derives decision_id as format!("flow-{flow_id}"), so any two
records created for the same flow_id (e.g. re-creating a pending record, or two independent
decision instances for one flow) receive an identical decision_id, breaking the intended
per-record identity. OpaqueId::new performs no uniqueness or non-empty validation, so an empty
flow_id also silently produces decision_id = "flow-".
Code

crates/medscale-contracts/src/legal/mod.rs[R49-60]

+    pub fn pending(flow_id: impl Into<String>) -> Self {
+        let flow_id = flow_id.into();
+        Self {
+            schema_version: FLOW_DECISION_SCHEMA_VERSION,
+            decision_id: OpaqueId::new(format!("flow-{flow_id}")),
+            flow_id,
+            status: FlowDecisionStatus::PendingCounsel,
+            jurisdictions: Vec::new(),
+            counsel_conclusion: None,
+            recorded_at: None,
+            recorded_by: None,
+        }
Relevance

●● Moderate

Identity uniqueness is a plausible semantic requirement, but no close repository precedent
establishes per-instance IDs for pending flow records.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Lines 49-60 build decision_id deterministically from the caller-supplied flow_id alone, with no
random/incrementing component. OpaqueId::new (crates/medscale-contracts/src/objects/ids.rs:10-15)
simply wraps the given string, performing no uniqueness check. Two calls to
FlowDecisionRecord::for_flow("pdpl_controller_mapping") (as used in the added test at
legal/mod.rs:89) yield equal decision_ids, which would violate any downstream assumption that
decision_id uniquely identifies a record instance.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`FlowDecisionRecord::pending` sets `decision_id` deterministically from `flow_id` (`format!("flow-{flow_id}")`), so repeated records for the same flow collide on identity.

## Issue Context
`decision_id` is typed as `OpaqueId`, intended to identify one record instance (per doc comment: 'Versioned decision record'). Multiple decision records can legitimately exist per flow over time (e.g. superseded records).

## Fix Focus Areas
- crates/medscale-contracts/src/legal/mod.rs[49-60]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 35 rules
Review mode: 🧠 Deep: This is a bug-dense, cross-cutting PR spanning multiple new contract modules, security/privacy boundaries, legal and sandbox gate semantics, tests, and broad planning synchronization across 20 files and 41 hunks; independent review passes can materially catch subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +49 to +52
synthetic_only: true,
real_phi_authorized: false,
title: "timeline".to_owned(),
body_json: serde_json::to_value(timeline).unwrap_or(serde_json::Value::Null),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Projection provenance falsely synthetic 📘 Rule violation § Compliance

from_timeline, from_brief, and from_coverage hard-code synthetic_only: true while
serializing projections whose types carry no synthetic/PHI provenance and may be built from
arbitrary promoted assertion payloads. This can present real PHI as an approved synthetic fixture
despite the real-PHI gate being closed.
Agent Prompt
## Issue description
Fixture UI projection adapters currently label every timeline, brief, and coverage payload as synthetic even though the input types do not establish that provenance.

## Issue Context
The projections can be built from arbitrary promoted assertions and source bytes. Add or require trusted provenance metadata and refuse construction when real PHI is not authorized; do not infer synthetic status from the adapter used.

## Fix Focus Areas
- crates/medscale-contracts/src/fixture_ui/mod.rs[46-75]
- crates/medscale-contracts/src/presentation/mod.rs[177-202]
- crates/medscale-core/src/authority/presentation.rs[86-315]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +80 to +83
pub fn respects_phi_boundary(&self) -> bool {
!(self.real_phi_authorized && !self.synthetic_only)
&& (self.synthetic_only || !self.real_phi_authorized)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Phi boundary accepts unauthorized data 📘 Rule violation § Compliance

FixtureUiViewModel::respects_phi_boundary() implements the PHI boundary incorrectly: it accepts
synthetic_only=false, real_phi_authorized=false, allowing unauthorized non-synthetic data, while
rejecting the valid authorized state synthetic_only=false, real_phi_authorized=true. Because the
view model is public and deserializable, callers or shells relying on this guard can expose
prohibited live PHI or reject properly authorized data.
Agent Prompt
## Issue description

Correct `FixtureUiViewModel::respects_phi_boundary` so it rejects the unsafe state `synthetic_only == false && real_phi_authorized == false` and accepts non-synthetic data when real-PHI authorization is present. The current predicate negates `real_phi_authorized`, causing it to accept an unauthorized live-data claim and reject the valid authorized state.

## Issue Context

The PHI boundary requires non-synthetic data to be rejected unless the explicit REAL_PHI authorization gate is open. `FixtureUiViewModel` is public, deserializable, and populated by the `from_doctor`, `from_timeline`, `from_brief`, and `from_coverage` factory methods, so callers and deserializers can construct these flag combinations and may rely on this predicate as the documented safety check.

Encode the intended implication directly—accepting a view when it is synthetic or real-PHI authorization is present—or explicitly define the allowed state matrix if additional constraints are intentional. Add truth-table tests covering every combination of `synthetic_only` and `real_phi_authorized`.

## Fix Focus Areas

- crates/medscale-contracts/src/fixture_ui/mod.rs[78-83]
- crates/medscale-contracts/src/fixture_ui/mod.rs[96-136]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

- [ ] T045 Ensure REAL_PHI EXTERNAL_GATES remains NOT_AUTHORIZED; no MESC mutation; no product network clients
- [x] T038 Wire vault/key capabilities into `medscale-core` facade envelopes
- [x] T039 Integration: encrypted vault → ingest synthetic fixture (003 path) → optional 004 presentation smoke (if cheap) via Core Host
- [x] T040 Run `cargo test --workspace` + fmt/clippy with `sqlcipher` feature on Windows+Linux CI matrix as available

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Sqlcipher ci task unexecuted 📘 Rule violation ✧ Quality

T040 is newly marked complete even though repository evidence says SQLCipher page encryption was not
enabled and CI runs only plain workspace tests without the sqlcipher feature. The checkbox
therefore claims completion of a feature-enabled Windows/Linux CI test task that was not executed.
Agent Prompt
## Issue description
Spec 005 T040 is checked as complete without execution of its required SQLCipher-feature CI matrix.

## Issue Context
The current workflow runs generic workspace tests on Windows and Linux but does not pass `--features sqlcipher`; project evidence also records that SQLCipher page crypto is not enabled. Reopen the checkbox or add and execute the required feature-enabled CI jobs before claiming completion.

## Fix Focus Areas
- specs/005-local-private-vault-encryption-recovery/tasks.md[138-138]
- .github/workflows/ci.yml[43-47]
- evidence/005-local-private-vault-encryption-recovery/SUMMARY.md[11-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +49 to +60
pub fn pending(flow_id: impl Into<String>) -> Self {
let flow_id = flow_id.into();
Self {
schema_version: FLOW_DECISION_SCHEMA_VERSION,
decision_id: OpaqueId::new(format!("flow-{flow_id}")),
flow_id,
status: FlowDecisionStatus::PendingCounsel,
jurisdictions: Vec::new(),
counsel_conclusion: None,
recorded_at: None,
recorded_by: None,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

4. Deterministic flow decision ids collide 🐞 Bug ≡ Correctness

FlowDecisionRecord::pending derives decision_id as format!("flow-{flow_id}"), so any two
records created for the same flow_id (e.g. re-creating a pending record, or two independent
decision instances for one flow) receive an identical decision_id, breaking the intended
per-record identity. OpaqueId::new performs no uniqueness or non-empty validation, so an empty
flow_id also silently produces decision_id = "flow-".
Agent Prompt
## Issue description
`FlowDecisionRecord::pending` sets `decision_id` deterministically from `flow_id` (`format!("flow-{flow_id}")`), so repeated records for the same flow collide on identity.

## Issue Context
`decision_id` is typed as `OpaqueId`, intended to identify one record instance (per doc comment: 'Versioned decision record'). Multiple decision records can legitimately exist per flow over time (e.g. superseded records).

## Fix Focus Areas
- crates/medscale-contracts/src/legal/mod.rs[49-60]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +8 to +30
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..");
let forbidden = ["mesc", "pymesc", "thehalfmoon-mesc"];
for entry in fs::read_dir(root.join("crates")).unwrap() {
let entry = entry.unwrap();
let cargo = entry.path().join("Cargo.toml");
if !cargo.is_file() {
continue;
}
let text = fs::read_to_string(&cargo).unwrap().to_lowercase();
for needle in forbidden {
// Allow comments mentioning MESC boundary; forbid dependency names.
for line in text.lines() {
let trimmed = line.trim();
if trimmed.starts_with('#') {
continue;
}
if trimmed.contains(needle)
&& (trimmed.contains("dependencies") || trimmed.contains('='))
{
// Only fail if it looks like a crate dependency key.
if trimmed.starts_with(needle) || trimmed.contains(&format!("{needle} =")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

5. Mesc dependency scan misses valid toml forms 🐞 Bug ☼ Reliability

workspace_crates_do_not_depend_on_mesc_python_runtime uses fragile line-based substring matching
rather than TOML-aware dependency resolution, so it misses forbidden dependencies declared through
aliases, quoted keys, dependency-table headers, inline-commented lines, and workspace inheritance.
Because it scans only immediate crates/*/Cargo.toml manifests and not the root
[workspace.dependencies], the test can remain green while violating the MESC Python/runtime
boundary required by Spec 012 US2.
Agent Prompt
## Issue description

Replace the fragile line-oriented MESC dependency check, which can miss valid Cargo aliases, quoted keys, dependency-table declarations, inline-commented declarations, and workspace-inherited dependencies. The architecture test must reliably enforce Spec 012 US2 by detecting forbidden MESC/Python runtime packages across the entire workspace, including the root manifest and renamed packages.

## Issue Context

The current test inspects only `root/crates/*/Cargo.toml` using substring heuristics, while shared dependencies are centralized in the top-level `Cargo.toml` under `[workspace.dependencies]` and members may inherit them with `workspace = true`. Use a TOML-aware or `cargo metadata`-based check that resolves package names for every workspace member, including workspace dependencies and renamed packages, so comments and unrelated text do not affect the decision.

## Fix Focus Areas

- crates/medscale-core/tests/mesc_boundary_012.rs[7-36]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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