Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3c4d198
feat: reconcile DSH compatibility continuously
MicroMilo Aug 21, 2026
15a3370
fix: require complete DSH profile graph evidence
MicroMilo Aug 21, 2026
f7d740b
feat: expose unresolved DSH profile edges
MicroMilo Aug 21, 2026
6575ac6
feat: reconcile DSH host dependency boundaries
MicroMilo Aug 21, 2026
fa89a3a
fix: retain runtime graph collector failures
MicroMilo Aug 21, 2026
3117974
fix: discover the exact DSH runtime dependency plane
MicroMilo Aug 21, 2026
291101e
fix: include pnpm virtual-store host dependencies
MicroMilo Aug 21, 2026
a257c03
fix: resolve pnpm DSH virtual-store dependencies
MicroMilo Aug 21, 2026
874740d
feat: verify DSH peer contracts at runtime
MicroMilo Aug 21, 2026
70d99d5
fix: boot DSH bundles during compatibility observation
MicroMilo Aug 21, 2026
7452058
feat: import DSH plugins from their profile anchor
MicroMilo Aug 21, 2026
d43d3b4
feat: resolve DSH plugin peers from the profile runtime
MicroMilo Aug 21, 2026
4c2765f
feat: materialize DSH compatibility relations
MicroMilo Aug 21, 2026
70b49e2
feat: classify static peer use in compatibility evidence
MicroMilo Aug 21, 2026
2818d56
fix: keep type-only peers out of runtime import evidence
MicroMilo Aug 21, 2026
fe9392f
fix: run maintained OpenPencil cell on Node 24
MicroMilo Aug 21, 2026
3607890
docs: show a real DSH contract-drift case
MicroMilo Aug 21, 2026
940faca
fix: discover the full pnpm DSH host plane
MicroMilo Aug 21, 2026
fd2b975
fix: resolve DSH peers through pnpm runtime links
MicroMilo Aug 21, 2026
67c4696
test: keep DSH host showcase within trusted boundary
MicroMilo Aug 21, 2026
fa227dd
test: parse executable showcase scripts in CI
MicroMilo Aug 21, 2026
53dde8a
docs: record verified DSH host-plane evidence
MicroMilo Aug 21, 2026
8ac4df2
Merge remote-tracking branch 'origin/main' into feat/compatibility-le…
MicroMilo Aug 23, 2026
bf9d32b
feat: close the DSH compatibility incident loop
MicroMilo Aug 23, 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
2 changes: 1 addition & 1 deletion .github/workflows/action-consumer-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: MicroMilo/upstream-radar@v0.40.0
- uses: MicroMilo/upstream-radar@v0.41.0
with:
config: examples/github-actions/consumer/upstream-radar.config.json
fail-on: high
56 changes: 50 additions & 6 deletions .github/workflows/observe-dsh-plugin-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
required: false
default: ''
type: string
node_major:
description: Node.js major version inside the isolated observer image
required: false
default: '22'
type: string
workflow_call:
inputs:
plugin:
Expand All @@ -47,6 +52,10 @@ on:
required: false
default: ''
type: string
node_major:
required: false
default: '22'
type: string

# The target package executes arbitrary lifecycle and load code. This workflow
# deliberately has no write permission and declares no secrets.
Expand All @@ -72,6 +81,7 @@ jobs:
RADAR_CASE_ID: ${{ inputs.case_id }}
RADAR_TIMEOUT_SECONDS: ${{ inputs.timeout_seconds }}
RADAR_ALLOW_BUILDS: ${{ inputs.allow_builds }}
RADAR_NODE_MAJOR: ${{ inputs.node_major }}
run: |
set -euo pipefail
exact_package='^(@[^/@[:space:]]+/[^@/[:space:]]+|[^@/[:space:]]+)@[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'
Expand All @@ -89,6 +99,10 @@ jobs:
echo 'case_id must be a short lowercase label' >&2
exit 1
fi
if [[ ! "$RADAR_NODE_MAJOR" =~ ^(1[6-9]|2[0-9]|3[0-9]|40)$ ]]; then
echo 'node_major must be a supported Node.js major version between 16 and 40' >&2
exit 1
fi
if [[ ! "$RADAR_TIMEOUT_SECONDS" =~ ^[0-9]+$ ]] || (( RADAR_TIMEOUT_SECONDS < 30 || RADAR_TIMEOUT_SECONDS > 600 )); then
echo 'timeout_seconds must be an integer between 30 and 600' >&2
exit 1
Expand All @@ -111,9 +125,11 @@ jobs:
done
fi

- name: Build the pinned observer image
- name: Build the selected observer runtime image
shell: bash
run: docker build --file docker/dsh-install-observer.Dockerfile --tag upstream-radar-install-observer:${{ github.run_id }} .
env:
RADAR_NODE_MAJOR: ${{ inputs.node_major }}
run: docker build --build-arg NODE_MAJOR="$RADAR_NODE_MAJOR" --file docker/dsh-install-observer.Dockerfile --tag upstream-radar-install-observer:${{ github.run_id }} .

- name: Install and load inside the restricted container
id: observe
Expand All @@ -122,6 +138,7 @@ jobs:
env:
RADAR_PLUGIN: ${{ inputs.plugin }}
RADAR_DSH_VERSION: ${{ inputs.dsh_version }}
RADAR_CASE_ID: ${{ inputs.case_id }}
RADAR_TIMEOUT_SECONDS: ${{ inputs.timeout_seconds }}
RADAR_IMAGE: upstream-radar-install-observer:${{ github.run_id }}
RADAR_REPORT_DIRECTORY: ${{ runner.temp }}/upstream-radar-install-observation
Expand Down Expand Up @@ -163,6 +180,7 @@ jobs:
"$RADAR_IMAGE" \
"$RADAR_PLUGIN" \
--dsh-version "$RADAR_DSH_VERSION" \
--case-id "$RADAR_CASE_ID" \
--isolation-provider github-actions-hosted-runner \
--timeout "$RADAR_TIMEOUT_SECONDS" \
--execute \
Expand All @@ -180,6 +198,7 @@ jobs:
env:
RADAR_PLUGIN: ${{ inputs.plugin }}
RADAR_DSH_VERSION: ${{ inputs.dsh_version }}
RADAR_NODE_MAJOR: ${{ inputs.node_major }}
RADAR_OBSERVER_EXIT: ${{ steps.observe.outputs.exit }}
RADAR_REPORT: ${{ runner.temp }}/upstream-radar-install-observation/report.json
run: |
Expand All @@ -192,6 +211,7 @@ jobs:
'',
`- Plugin: \`${inline(process.env.RADAR_PLUGIN)}\``,
`- DSH: \`${inline(process.env.RADAR_DSH_VERSION)}\``,
`- Requested Node major: \`${inline(process.env.RADAR_NODE_MAJOR)}\``,
`- Observer exit: \`${inline(process.env.RADAR_OBSERVER_EXIT)}\``,
]
if (!existsSync(process.env.RADAR_REPORT)) {
Expand All @@ -203,10 +223,15 @@ jobs:
lines.push('- Result: `unknown` — report JSON was invalid.')
} else {
lines.push(
`- Profile graph coverage: ${inline(report.resolution?.profileLockfile?.nodes ?? 'unknown')} node(s), ${inline(report.resolution?.profileLockfile?.edges ?? 'unknown')} edge(s), ${inline(report.resolution?.profileLockfile?.unresolved ?? 'unknown')} unresolved edge(s)`,
`- Effective runtime graph: \`${inline(report.resolution?.runtimeGraph?.digest ?? 'not established')}\`; ${inline(report.resolution?.runtimeGraph?.nodes ?? 'unknown')} node(s), ${inline(report.resolution?.runtimeGraph?.edges ?? 'unknown')} edge(s), ${inline(report.resolution?.runtimeGraph?.unresolved ?? 'unknown')} required unresolved edge(s), ${inline(report.resolution?.runtimeGraph?.optionalUnavailable ?? 0)} optional package(s) unavailable on this runtime`,
`- Plugin peer contracts: ${inline(report.resolution?.runtimeGraph?.pluginPeerContracts?.satisfied ?? 'unknown')}/${inline(report.resolution?.runtimeGraph?.pluginPeerContracts?.declared ?? 'unknown')} satisfied; ${inline(report.resolution?.runtimeGraph?.pluginPeerContracts?.mismatched ?? 'unknown')} mismatched, ${inline(report.resolution?.runtimeGraph?.pluginPeerContracts?.missing ?? 'unknown')} missing, ${inline(report.resolution?.runtimeGraph?.pluginPeerContracts?.indeterminate ?? 'unknown')} indeterminate`,
`- Effective runtime graph collector: ${inline(report.resolution?.runtimeGraphError ?? 'captured')}`,
`- Result: \`${inline(report.result)}\` — ${inline(report.reason)}`,
`- Exact artifact: \`sha256:${inline(report.artifact?.sha256)}\``,
`- Runtime: Node \`${inline(report.runtime?.nodeVersion)}\` on \`${inline(`${report.runtime?.platform}/${report.runtime?.architecture}`)}\`; pnpm \`${inline(report.runtime?.packageManager?.version)}\``,
`- Plugin Node requirement: \`${inline(report.artifact?.nodeEngine ?? 'not declared')}\``,
`- Resolved profile graph: \`${inline(report.resolution?.profileLockfile?.graphDigest ?? 'not established')}\``,
`- Approved dependency builds: \`${inline(report.boundary?.approvedDependencyBuilds?.join(', ') || 'none')}\``,
`- Declared lifecycle scripts: \`${inline(report.artifact?.lifecycleScripts?.join(', ') || 'none')}\``,
`- Install behavior: ${count(report.observations?.install?.processes)} process exec(s), ${count(report.observations?.install?.network)} network attempt(s), ${count(report.observations?.install?.fileWrites)} file-write syscall(s)`,
Expand All @@ -215,10 +240,22 @@ jobs:
`- Isolation: \`${inline(report.boundary?.isolationProviderClaim)}\`; no repository secrets were passed into the container.`,
)
const endpoints = (report.observations?.install?.network ?? []).slice(0, 5)
const graphGaps = (report.resolution?.runtimeGraph?.unresolvedDependencies
?? report.resolution?.profileLockfile?.unresolvedDependencies
?? []).slice(0, 8)
const peerIssues = (report.resolution?.runtimeGraph?.pluginPeerContracts?.issues ?? []).slice(0, 8)
if (endpoints.length > 0) {
lines.push('- First observed install destinations:')
for (const event of endpoints) lines.push(` - \`${inline(`${event.address}${event.port === undefined ? '' : `:${event.port}`}`)}\` (${inline(event.operation)}, count ${inline(event.count)})`)
}
if (graphGaps.length > 0) {
lines.push('- First unresolved required graph edges:')
for (const gap of graphGaps) lines.push(` - \`${inline(gap.from)}\` → \`${inline(gap.name)}\` (${inline(gap.kind)}: \`${inline(gap.spec)}\`)`)
}
if (peerIssues.length > 0) {
lines.push('- Direct plugin peer-contract findings:')
for (const issue of peerIssues) lines.push(` - \`${inline(issue.name)}\`: ${inline(issue.status)}; requires \`${inline(issue.required)}\`${issue.resolvedVersion === undefined ? '' : `, resolved \`${inline(issue.resolvedVersion)}\``}; static use: \`${inline(issue.staticUsage ?? 'unknown')}\``)
}
}
}
lines.push('', 'This is bounded behavior evidence from a disposable VM plus restricted container. It is not a proof that adversarial code is safe.', '')
Expand All @@ -234,7 +271,7 @@ jobs:
if-no-files-found: warn
retention-days: 30

- name: Fail the check unless the exact pair installed and loaded
- name: Validate that a trustworthy compatibility result survived
if: always()
shell: bash
env:
Expand All @@ -251,9 +288,16 @@ jobs:
console.error('The machine-readable install observation is invalid JSON.')
process.exit(1)
}
if (report.result !== 'compatible') {
console.error(`DSH install observation: ${report.result ?? 'unknown'} — ${report.reason ?? 'no reason recorded'}`)
const trustworthyResults = new Set([
'compatible',
'runtime-incompatible',
'peer-contract-incompatible',
'install-failed',
'load-failed',
])
if (!trustworthyResults.has(report.result)) {
console.error(`DSH install observer did not establish a trustworthy result: ${report.result ?? 'unknown'} — ${report.reason ?? 'no reason recorded'}`)
process.exit(1)
}
console.log(`Compatible: ${report.artifact?.spec} with DSH ${report.dshVersion}`)
console.log(`Observed: ${report.artifact?.spec} with DSH ${report.dshVersion} on Node ${report.runtime?.nodeVersion} -> ${report.result}`)
NODE
2 changes: 1 addition & 1 deletion .github/workflows/review-dsh-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Inspect and load-test the exact plugin
id: radar
continue-on-error: true
uses: MicroMilo/upstream-radar@v0.40.0
uses: MicroMilo/upstream-radar@v0.41.0
with:
inspect-package: ${{ inputs.plugin }}
inspect-fail-on: never
Expand Down
127 changes: 122 additions & 5 deletions .github/workflows/upstream-observer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ jobs:
echo "exit=$observer_exit" >> "$GITHUB_OUTPUT"
exit "$observer_exit"

- name: Plan isolated install observations only for changed coordinates
- name: Reconcile the current DSH compatibility matrix
id: install-plan
env:
OBSERVER_JSON: ${{ runner.temp }}/upstream-radar-observer.json
run: |
node scripts/write-dsh-install-plan.mjs \
examples/dsh/install-observer/targets.json \
observations.json \
"$OBSERVER_JSON"
"$OBSERVER_JSON" \
compatibility-ledger.json

# The state is written even when an upstream source or the optional
# Agent fails. Pending tasks and the last trustworthy observations must
Expand All @@ -124,16 +125,18 @@ jobs:
fi
git config user.name 'upstream-radar[bot]'
git config user.email 'upstream-radar[bot]@users.noreply.github.com'
git add observations.json
git add -- observations.json
if git diff --cached --quiet; then
echo 'No observation point changed; no commit created.'
exit 0
fi
git commit -m 'chore: update upstream observation point [skip ci]'
git push

# Every matrix entry gets a fresh GitHub-hosted VM. The reusable workflow
# adds a restricted container and never receives the observer's model key.
# Every selected matrix entry gets a fresh GitHub-hosted VM. The reusable
# workflow adds a restricted container and never receives the model key.
# Selection is reconciliation-driven: missing, stale, or invalidated cells
# run even when neither package published a new version.
install-observation:
needs: observe
if: needs.observe.outputs.run_install_observation == 'true'
Expand All @@ -147,5 +150,119 @@ jobs:
plugin: ${{ matrix.plugin }}
dsh_version: ${{ needs.observe.outputs.install_dsh_version }}
case_id: ${{ matrix.id }}
node_major: ${{ matrix.nodeMajor }}
timeout_seconds: '180'
allow_builds: ${{ matrix.allowedBuilds }}

# Dynamic reports are useful only if they become durable, comparable
# evidence. This job accepts reports only when their exact case, plugin,
# DSH version, runtime major, and build-approval policy match the static
# matrix that scheduled them. Missing reports remain unsatisfied and will be
# selected again on the next daily reconciliation.
reconcile-install-observations:
needs: [observe, install-observation]
if: always() && needs.observe.result == 'success' && needs.observe.outputs.run_install_observation == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
issues: write
steps:
- name: Check out the latest durable observation state
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.repository.default_branch }}
fetch-depth: 1

- name: Set up pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with:
version: 11.3.0
run_install: false

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: pnpm

- name: Build the checked-out Radar
run: |
pnpm install --frozen-lockfile
pnpm build

- name: Materialize the exact scheduled matrix
env:
INSTALL_MATRIX: ${{ needs.observe.outputs.install_matrix }}
INSTALL_MATRIX_PATH: ${{ runner.temp }}/upstream-radar-install-matrix.json
run: |
node --input-type=module <<'NODE'
import { writeFile } from 'node:fs/promises'
const matrix = JSON.parse(process.env.INSTALL_MATRIX ?? '')
await writeFile(process.env.INSTALL_MATRIX_PATH, `${JSON.stringify(matrix, null, 2)}\n`, 'utf8')
NODE

- name: Download isolated observation reports
id: download-reports
continue-on-error: true
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: upstream-radar-install-*-${{ github.run_id }}
path: ${{ runner.temp }}/upstream-radar-install-reports

- name: Reconcile dynamic evidence into the compatibility ledger
id: ledger
env:
INSTALL_MATRIX_PATH: ${{ runner.temp }}/upstream-radar-install-matrix.json
INSTALL_REPORTS_PATH: ${{ runner.temp }}/upstream-radar-install-reports
LEDGER_REPORT: ${{ runner.temp }}/upstream-radar-compatibility-ledger.md
COMPATIBILITY_IR: compatibility-ir.json
COMPATIBILITY_REVERSE_INDEX: compatibility-reverse-index.json
run: |
node scripts/merge-dsh-compatibility-ledger.mjs \
compatibility-ledger.json \
"$INSTALL_MATRIX_PATH" \
"$INSTALL_REPORTS_PATH" \
"$LEDGER_REPORT" \
"$COMPATIBILITY_IR" \
"$COMPATIBILITY_REVERSE_INDEX"
cat "$LEDGER_REPORT" >> "$GITHUB_STEP_SUMMARY"

- name: Keep compatibility evidence artifacts
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: upstream-radar-compatibility-ledger-${{ github.run_id }}
path: |
${{ runner.temp }}/upstream-radar-compatibility-ledger.md
compatibility-ledger.json
compatibility-ir.json
compatibility-reverse-index.json
if-no-files-found: warn
retention-days: 30

# The consumer is part of the transaction: a ledger that cannot create,
# update or close its managed incident is not persisted as delivered.
# The next scheduled run will therefore reproduce and retry the cell.
- name: Create, update or close compatibility incidents
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/sync-dsh-compatibility-issues.mjs compatibility-ledger.json

- name: Persist compatibility evidence
shell: bash
run: |
set -euo pipefail
if [[ ! -f compatibility-ledger.json || ! -f compatibility-ir.json || ! -f compatibility-reverse-index.json ]]; then
echo 'complete compatibility evidence was not produced; nothing to persist.'
exit 0
fi
git config user.name 'upstream-radar[bot]'
git config user.email 'upstream-radar[bot]@users.noreply.github.com'
git add -- compatibility-ledger.json compatibility-ir.json compatibility-reverse-index.json
if git diff --cached --quiet; then
echo 'No compatibility evidence changed; no commit created.'
exit 0
fi
git commit -m 'chore: update DSH compatibility evidence [skip ci]'
git push
Loading