Skip to content

fix(model): risk gate over every item, TH-001 causes, derived safety-critical count, document inventory queries - #44

Merged
HuiJun merged 3 commits into
developfrom
fix/review-safety-documents
Oct 29, 2026
Merged

HuiJun merged 3 commits into
developfrom
fix/review-safety-documents

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes the review-triage findings 3-2, 3-3, 3-4, 3-5, 5-2, 5-3 and 5-5 (WP-J safety/risk/allocations, WP-K views/documents) and the documentation nits from the integration review. Each finding was reproduced on the pinned OpenSysML (5cd37f288) on develop before the fix; probes below are build/opensysml/sysml … model/*.

Not touched (maintainer decisions still open): 3-6 risk grid vs value table, 5-1 FlightPhases interleaving, 5-4 BudgetView/massBudget.

Findings

# Before (develop 6c387ce) After Fix
3-2 noUnownedRedRisk names earthImpactRisk only; a /tmp copy forcing xenonMarginRisk to catastrophic (rating red, status open) still passed same forced copy: ✗ … noUnownedRedRisk failed — Assertion evaluated to false: forAll(body); committed values passed (on TethysRisk::riskRegister ID: 1) riskRegister gets part items : RiskItem[*], every entry :> items, and the gate is items->forAll { in risk : RiskItem; not (risk.rating == red and risk.status == open) } — a seventh entry is checked without touching the gate. [*] has no fixed count outside an instance, so risk-constraints now -instantiates the register and evaluates the gate on it
3-3 grep -c "connect earthImpactByTarget." = 1 (erroneousFinalTargeting only; TH-001 declares three #causes) 3 connects the two missing #causation connects, as in the closed #32
3-4 safetyCriticalSoftwareFunctions : Natural = 2 while grep -c @SafetyCritical = 3 literal removed; TethysAllocationQueries::SafetyCriticalFunctions root=TethysSafety::safetyCriticalSoftware returns 3 rows (finalTargetingGuidance, captureAbortLogic, highVoltageInhibitLogic) WhereMetadata over Descendants(root) for TethysSafety::SafetyCritical, projecting name and SafetyCritical::rationale (the reason each function is classified; a Devin Review finding caught the first version projecting documentation, which is empty on all three); recorded in allocations-queries
3-5 missionHours … thrusterStringMttfHours : Real missionDuration = 2200.0 [d], thrustDuration = 1100.0 [d], structureMttf = 2.0e6 [h], … : DurationValue; structureMttf / missionDuration = 1250/33, structureReliability = 0.97394…, sepReliability = 0.92267…, missionReliability = 0.74046… (unchanged), reliabilityAllocationMet passed as in the closed #32
5-2 TethysDocuments::TugSubsystems 4 rows (argent's redefinitions) 10 rows (structure … sensors, typed) reads TethysTug::Tug minus InterfaceUsage, as in the closed #34
5-3 Segments 9 rows (5 parts + 4 interfaces), Items 19 rows (7 item defs + 12 interface defs) Segments 5, Items 7 Except(… WhereType(…, "InterfaceUsage")) / Except(… WhereType(…, ("PartDefinition", "InterfaceDefinition"))), as in the closed #34. PortDefinition is not an ItemDefinition, so no port def was in Items
5-5 Risks 0 rows (the Union of four consumer packages never scans TethysRisk) 6 rows (TK-001…TK-006) WhereMetadata(Descendants(Named(("TethysRisk", "TethysSafety"))), "RiskMetadata::Risk") — the packages that own RiskItems, not the consumer list

Absorbed from the closed drafts: 3-3 and 3-5 from #32, 5-2 and 5-3 from #34 — nothing else (not #32's six-name enumeration for 3-2, not = 3 for 3-4, not its envelopeCases rewrite, none of their 3-6 / 5-1 / 5-4 changes).

Documentation

  • docs/coverage/WP-D.md SE-101/SE-103: IcdFlightSegment::dispenser → inspectorDispenser (model 51 redefines inspectorDispenser; there is no dispenser).
  • docs/coverage/WP-D.md SE-278: "satisfied" → "partially satisfied" — ContingencyProcedure::failureMode is a String; no element links a response to a WP-J FMECA FailureMode.
  • docs/coverage/WP-E.md SE-260: ten PhaseCriteria rows cover ten of the twelve flightTimeline phases — integrationAndTest and extendedMission have none (the row claimed "every phase" and misnamed the uncovered pair).
  • docs/coverage/WP-A.md SE-049: the binding exists, but no recorded satisfy reads through tethysSystem.flight.tug; said so.
  • docs/findings/WP-A.md, WP-H.md: KerML 1.1 §8.3.2.5 → §8.3.2.4.5 (both visibleMemberships and validateNamespaceDistinguishability sit under 8.3.2.4 Namespaces).

Model files

model/85-safety.sysml, model/86-risk.sysml, model/87-allocations.sysml, model/87-allocations-tooling.sysml, model/91-documents.sysml, scripts/runs.sh (risk-constraints, allocations-queries).

Runs moved (15 files, make runs from the merged tree)

  • risk-constraints: noUnownedRedRisk passed (on TethysRisk::riskRegister ID: 1) after the new Created instance lines. registerBurningDown / earthImpactBurningDown stay not covered as on develop; only their reason text changes (no value: condition is undetermined: consequence has no value → feature value atPdr.score: calc TethysRisk::Score … no value for feature consequence) because the register instance now exists in the same process.
  • allocations-queries: + SafetyCriticalFunctions 3 rows.
  • document-queries: Risks 0 → 6 rows; Segments 9 → 5; Items 19 → 7; TugSubsystems 4 → 10.
  • render-documents-md/html, documents/*, documents-html/* (InterfaceControlDocuments: Items table loses the 12 interface definitions, which the "Interface definitions" section already lists; RiskRegister: 6 rows instead of empty; SystemDescription: 5 segments, 10 tug subsystems), render-all and views/TethysRisk.riskRegisterView~…md, risk-register-view: one new items row.
  • house-rules: 80537 → 80560 elements, 703451 → 703618 checks, 0 violations, 0 unevaluated.

Behaviour changes

No recorded verdict flips. noUnownedRedRisk now fails on any red+open entry (it passed on the forced-red probe before). Element/check counts in house-rules grew with items, the two connects and the query.

Gates

make check (validate, pilot-mission, pilot-all, house-rules, runs-check) exit 0 and make software-check exit 0 (11 passed) on OpenSysML 5cd37f288 / go1.25.11 (runs/tool-version.txt unchanged). house-rules: 80560 elements, 703618 checks, 0 violations, 0 unevaluated. The pilot tiers were built with OpenJDK 21.

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/74adb29eca264b2c915329a4bd614477
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/74adb29eca264b2c915329a4bd614477?variant=devin
Requested by: @HuiJun

CI Status

0 passed, 0 failed, 5 pending (use git with action=pr_checks for full details)
Pending: software-check, software-flight-check, check, software-ground-check, software-conformance-check

Conversation

4 comment(s)
--- Begin PR Conversation ---
[Commit] fix(model): risk gate over every item, TH-001 causes, derived safety-critical count, document inventory queries by devin-ai-integration[bot] (3123ac4)
[Comment 1 / 4] by devin-ai-integration[bot] | 2026-10-29T02:42:37+00:00 (comment id: 6486423724)

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

[Resolved] [Comment 2 / 4] by devin-ai-integration[bot] on model/87-allocations-tooling.sysml:66 | 2026-10-29T03:21:22+00:00 (comment id: 4408371198)
Note: This comment was made in the context of the file's PR diff. It is suggested that you view the diff with git diff --merge-base develop fix/review-safety-documents -- model/87-allocations-tooling.sysml
PR review thread id: PRRT_kwDOVS_dXc6xZ1z5 (pass as resolve_thread_id to git_comment_on_pr to resolve this thread; not valid for in_reply_to)
Citing:
```diff
@@ -55,6 +55,17 @@ package TethysAllocationQueries {
relationshipKind = "allocation", direction = "outgoing", exists = false)
}

                +    calc def SafetyCriticalFunctions :> Query {
                +        doc /* The functions under root annotated @SafetyCritical, with the rationale each
                +             * carries. Expected over TethysSafety::safetyCriticalSoftware: the three functions
                +             * of the hazard analysis; the row count is the safety-critical software count. */
                +        in root : Element;
                +        Project(
                +            source = WhereMetadata(source = Descendants(source = root),
                +                                   'metadata' = "TethysSafety::SafetyCritical"),
comment added > +            properties = ("name", "documentation"))
```
<!-- devin-review-comment {"id": "BUG_pr-review-job-8543b2ef305a472da8eb362f5db06ed9_0001", "file_path": "model/87-allocations-tooling.sysml", "start_line": 66, "end_line": 66, "side": "RIGHT", "based_on_repo_rules": false, "kind": "bug"} -->

🟡 **Safety-critical rationales disappear from inventory**

For all three annotated functions, `SafetyCriticalFunctions` reports `documentation = (none)` instead of their safety rationales. `SafetyCritical::rationale` holds those reasons, so the inventory loses the basis for each classification.

<details>
<summary>Learn more</summary>

Each marked element carries its reason in `@SafetyCritical { rationale = ... }` under [safetyCriticalSoftware](https://github.com/open-mbee/tethys/blob/3123ac490bbfc3dcc40f743ea723d965a37e0f04/model/85-safety.sysml#L573-L585 "model/85-safety.sysml:573-585"). The new query projects ordinary documentation instead. The pinned [query result](https://github.com/open-mbee/tethys/blob/3123ac490bbfc3dcc40f743ea723d965a37e0f04/runs/allocations-queries.txt#L82-L92 "runs/allocations-queries.txt:82-92") confirms that all three documentation cells are empty. The count is correct, but a reader cannot inspect why each item was classified.

**Example:** `finalTargetingGuidance` has a TH-001 rationale, yet its inventory row displays `documentation = (none)`.

**Recommended fix:** Project `SafetyCritical::rationale` rather than `documentation` and regenerate the pinned query output; verify the metadata property path renders the three recorded reasons.

</details>

```suggestion
            properties = ("name", "SafetyCritical::rationale"))
```

<!-- devin-review-badge-begin -->
<a href="https://nasa-jpl-demo.devinenterprise.com/review/open-mbee/tethys/pull/44" target="_blank"><picture><source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-devin-review-dark.svg?v=4"><img src="https://static.devin.ai/assets/gh-devin-review-light.svg?v=4" alt="Devin Review"></picture></a>
<!-- dev... (truncated)

[Resolved] [Reply] [Comment 3 / 4] by devin-ai-integration[bot] on model/87-allocations-tooling.sysml:66 | 2026-10-29T03:49:11+00:00 (comment id: 4408498702)
Reproduced on the pinned tool: all three rows reported documentation = (none) — the reason lives in the @SafetyCritical { rationale = ... } annotation, not in a doc comment. Fixed in 392d066: the query now projects ("name", "SafetyCritical::rationale"), as the Verification::* projections elsewhere do, and runs/allocations-queries.txt is re-recorded with the three rationales (TH-001, TH-002, TH-006). make check exit 0.
[Review 4 / 4] by devin-ai-integration[bot] | 2026-10-29T03:21:23+00:00
State: COMMENTED
Devin Review found 1 potential issue.

Devin Review

[Commit] fix(model): project SafetyCritical::rationale in SafetyCriticalFunctions by devin-ai-integration[bot] (392d066)

…critical count, document inventory queries

Review triage findings 3-2, 3-3, 3-4, 3-5, 5-2, 5-3, 5-5 and the integration-review documentation nits.

- 3-2 TethysRisk::riskRegister::noUnownedRedRisk quantifies over the new items : RiskItem[*] collection every register entry subsets, instead of naming earthImpactRisk; risk-constraints instantiates the register so the gate evaluates on it.
- 3-3 TH-001's returnTrajectoryInsideCorridor and lossOfThrustOnFinalArc causes are connected to earthImpact like the other hazards.
- 3-4 safetyCriticalSoftwareFunctions = 2 is replaced by the query TethysAllocationQueries::SafetyCriticalFunctions over @safetycritical.
- 3-5 Reliability durations are DurationValues in [d] and [h].
- 5-2 TugSubsystems reads TethysTug::Tug (10 rows, was 4).
- 5-3 Segments and Items exclude InterfaceUsage / InterfaceDefinition.
- 5-5 Risks scans TethysRisk and TethysSafety (6 rows, was 0).
- docs: IcdFlightSegment::inspectorDispenser, SE-049/SE-260/SE-278 rows say what the model shows, KerML citation §8.3.2.4.5.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 29, 2026 03:19
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits October 29, 2026 03:22
The inventory of @safetycritical functions showed documentation = (none) for all three rows; the reason for each classification lives in SafetyCritical::rationale, so the query projects that instead. Re-recorded allocations-queries.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…documents

Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	runs/house-rules.txt
@HuiJun
HuiJun merged commit 5b0d541 into develop Oct 29, 2026
5 checks passed
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