Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5e9d219
feat: Add _typeFilter support to bulk export operation
johngrimes Feb 19, 2026
8be0a69
feat: Add type filter UI to export form
johngrimes Feb 19, 2026
3ce7713
refactor: Move type filter UI into ExportOptions component
johngrimes Feb 19, 2026
337bac4
refactor: Extract FieldGuidance component for form helper text
johngrimes Feb 19, 2026
cedf94a
fix: Set field guidance text to be display block
johngrimes Feb 19, 2026
9dca0d4
test: Add unit tests to improve server module coverage to 88%
johngrimes Feb 19, 2026
3e6167d
refactor: Extract FieldLabel component for form field labels
johngrimes Feb 19, 2026
938e82b
Merge branch 'code-coverage'
johngrimes Feb 19, 2026
a2715bd
chore: Add CLAUDE.md as mirror of AGENTS.md
johngrimes Feb 19, 2026
002343f
chore: Skip core build when only server or UI files changed
johngrimes Feb 20, 2026
05111a9
chore: Update Sonar project key for server
johngrimes Feb 20, 2026
48007df
chore: Format UI code
johngrimes Feb 20, 2026
501a7f8
chore: Update Prettier version and reformat
johngrimes Feb 20, 2026
16b74f3
chore: Update Sonar project key in sonar-scan.yml
johngrimes Feb 20, 2026
1380a4d
chore: Scope Trivy scans to relevant modules per workflow
johngrimes Feb 20, 2026
e9e309d
chore: Add Trivy scan Claude Code command
johngrimes Feb 20, 2026
5b94669
chore: Split Trivy scanning into per-scope invocations
johngrimes Feb 20, 2026
878a7d6
docs: Add additional skills
johngrimes Feb 20, 2026
90517d8
chore: Update server version to 1.2.0-SNAPSHOT
johngrimes Feb 20, 2026
0abfa72
Merge branch 'main' into release/server/1.2.0
johngrimes Feb 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
plans
171 changes: 171 additions & 0 deletions .claude/commands/trivy-scan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Trivy security scan

Run Trivy vulnerability scans scoped to the modules modified on the current
branch, then analyse the results and provide actionable recommendations.

## Step 1: Determine modified modules

Run `git diff --name-only main...HEAD` to get the list of files changed on the
current branch. Map each changed file to one of the following scopes based on
its top-level directory:

| Changed directory | Scope |
| -------------------------------------------------------------------------------------------------- | ---------------- |
| `server/` | server |
| `ui/` | ui |
| `utilities/`, `encoders/`, `terminology/`, `fhirpath/`, `library-api/`, `library-runtime/`, `lib/` | core-libraries |
| `site/` | site |
| `fhirpath-lab-api/` | fhirpath-lab-api |

Files in other directories (e.g. `.github/`, `openspec/`, `benchmark/`,
`test-data/`, `deployment/`) do not trigger any scan scope.

If no scopes are identified, inform the user that no scannable modules were
modified and stop.

## Step 2: Run Trivy for each scope

Each scope has its own `.trivyignore` file. Run Trivy from within the scope's
directory so that the local `.trivyignore` is picked up automatically.

Common options for all scans:

```
--severity MEDIUM,HIGH,CRITICAL
--exit-code 0
```

### Core libraries scope

Scans from the repository root with `--skip-dirs` to exclude non-core modules.
The root `.trivyignore` contains suppressions for Spark-provided dependencies.

Working directory: repository root.

```bash
trivy repo . \
--severity MEDIUM,HIGH,CRITICAL \
--skip-files "examples/**/*,**/target/**/*,sql-on-fhir/**/*,licenses/**/*" \
--skip-dirs "server,ui,site,fhirpath-lab-api,benchmark,test-data,deployment" \
--exit-code 0
```

### Server scope

Scans the `server` directory. The `server/.trivyignore` contains suppressions
for Spark runtime transitive dependencies and server-specific libraries.

Working directory: `server/`.

```bash
cd server && trivy repo . \
--severity MEDIUM,HIGH,CRITICAL \
--skip-files "**/target/**/*" \
--exit-code 0
```

### UI scope

Scans the `ui` directory. The `ui/.trivyignore` contains suppressions for
client-side JavaScript dependencies.

Working directory: `ui/`.

```bash
cd ui && trivy repo . \
--severity MEDIUM,HIGH,CRITICAL \
--exit-code 0
```

### Site scope

Scans the `site` directory. The `site/.trivyignore` contains any
site-specific suppressions.

Working directory: `site/`.

```bash
cd site && trivy repo . \
--severity MEDIUM,HIGH,CRITICAL \
--skip-files "**/target/**/*" \
--exit-code 0
```

### FHIRPath Lab API scope

Scans the `fhirpath-lab-api` directory. The
`fhirpath-lab-api/.trivyignore` contains any API-specific suppressions.

Working directory: `fhirpath-lab-api/`.

```bash
cd fhirpath-lab-api && trivy repo . \
--severity MEDIUM,HIGH,CRITICAL \
--exit-code 0
```

Run scans for different scopes in parallel where possible. Use a timeout of
5 minutes per scan. If Trivy is not installed, inform the user and suggest
`brew install trivy`.

## Step 3: Analyse results and provide recommendations

For each vulnerability reported by Trivy, perform a contextual impact
assessment before recommending an action. This means reading the relevant parts
of the Pathling codebase to determine whether and how the vulnerable library is
actually used.

### Per-vulnerability analysis

For each vulnerability:

1. **Identify the vulnerability**: Record the CVE/GHSA ID, affected package,
installed version, fixed version (if available), and a brief description of
the attack vector.
2. **Investigate usage in our code**: Search the codebase (within the relevant
scope) to determine how the vulnerable package is used. Look for:
- Direct imports or references to the affected package or its vulnerable
classes/functions.
- Whether the vulnerable code path is reachable given our usage patterns
(e.g. do we call the affected API, use the vulnerable configuration, or
accept untrusted input that reaches the vulnerable code?).
- Whether the package is a direct dependency, a transitive dependency, or a
provided/runtime-only dependency that is not bundled in our distribution.
3. **Assess exploitability**: Based on the usage analysis, classify the
vulnerability as one of:
- **Exploitable**: The vulnerable code path is reachable in our
implementation.
- **Not exploitable**: The vulnerable code path is not reachable, or the
preconditions for exploitation do not apply (e.g. SSR-only vulnerability
in a client-side app, or a configuration we do not use).
- **Not applicable**: The package is a provided dependency not bundled in
our distribution.
4. **Recommend an action**:
- **Exploitable with fix available**: Recommend upgrading to the fixed
version. Identify the specific `pom.xml`, `package.json`, or other
dependency file that needs updating. If it is a transitive dependency,
identify the direct dependency that pulls it in and whether a version
override or exclusion is appropriate.
- **Exploitable with no fix available**: Recommend tracking for future
remediation. Suggest a workaround if one exists.
- **Not exploitable or not applicable**: Recommend adding to the
scope-specific `.trivyignore` with a comment explaining the rationale,
following the existing format in that file (comment line, then CVE/GHSA
ID).

### Output format

For each scope, present:

1. **Vulnerability count** by severity (CRITICAL, HIGH, MEDIUM).
2. **Detailed findings table** with columns: CVE/GHSA ID, package, severity,
exploitability assessment, and recommended action.
3. **`.trivyignore` additions**: For vulnerabilities that should be suppressed,
provide the exact lines to add to the scope's `.trivyignore` file, following
the existing format (comment explaining rationale, then the CVE/GHSA ID).

If no vulnerabilities are found for a scope, report that the scan passed
cleanly.

End with an overall summary and prioritised list of actions, ordered by
exploitability and severity.
Loading
Loading