|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | # End-to-end demo of RSScript's capability-aware review pipeline. |
3 | 3 | # |
4 | | -# Phase 1 rss pkg review — list a package's powers, ranked by risk |
5 | | -# Phase 3 rss pkg diff — what powers did a change introduce? |
6 | | -# Phase 2 rss pkg lock — a provider swap changes the review hash |
7 | | -# Phase 0 rss check — effect-annotated closures parse; bad category flagged |
| 4 | +# rss pkg review — list a package's powers, ranked by risk |
| 5 | +# rss pkg diff — what powers did a change introduce? |
| 6 | +# rss pkg lock — a provider swap changes the review hash |
| 7 | +# rss check — effect-annotated closures parse; bad category flagged |
| 8 | +# reir report-pr — reconcile required vs granted with a policy, emit SARIF |
| 9 | +# rss pkg review --markdown — PR-facing review render |
| 10 | +# rss native audit — native adapter risk facts |
| 11 | +# rss pkg metadata — fail closed: invalid source yields no evidence |
| 12 | +# rss check --explain --json— machine-readable diagnostic for agents |
8 | 13 | # |
9 | | -# Run from anywhere; it locates the repo root and builds `rss` if needed. |
| 14 | +# Run from anywhere; it locates the repo root and builds `rss`/`reir` if needed. |
10 | 15 | set -euo pipefail |
11 | 16 |
|
12 | 17 | here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
|
25 | 30 | RSS="$root/target/debug/rss" |
26 | 31 | fi |
27 | 32 |
|
| 33 | +if [[ -x "$root/target/debug/reir" ]]; then |
| 34 | + REIR="$root/target/debug/reir" |
| 35 | +elif [[ -x "$root/target/release/reir" ]]; then |
| 36 | + REIR="$root/target/release/reir" |
| 37 | +else |
| 38 | + echo "building reir ..." >&2 |
| 39 | + (cd "$root" && cargo build --quiet --bin reir -p reir) |
| 40 | + REIR="$root/target/debug/reir" |
| 41 | +fi |
| 42 | + |
28 | 43 | rule() { printf '\n=== %s ===\n\n' "$1"; } |
29 | 44 |
|
30 | 45 | rule "PHASE 1 — capability-aware review (powers ranked by risk)" |
@@ -73,4 +88,59 @@ sed -i.bak 's/category = "database.read"/category = "databse.raed"/' "$bogus/rss |
73 | 88 | echo "\$ rss pkg review <package with a typo'd category 'databse.raed'>" |
74 | 89 | "$RSS" pkg review "$bogus" | sed -n '/capabilities (by risk)/,/^exports:/p' | grep -v '^exports:' || true |
75 | 90 |
|
| 91 | +rule "GATE — reconcile required vs granted (policy + SARIF)" |
| 92 | +work="$(mktemp -d)" |
| 93 | +"$RSS" pkg review --json "$after" > "$work/after-review.json" 2>/dev/null || true |
| 94 | +"$REIR" collect --producer rsscript --package-review "$work/after-review.json" \ |
| 95 | + --out "$work/required.reir.json" >/dev/null |
| 96 | +# The deployment grants the package's powers EXCEPT the new outbound network the |
| 97 | +# PR introduced (infra wasn't updated) — derived from the real required facts. |
| 98 | +python3 - "$work/required.reir.json" "$work/granted.reir.json" <<'PY' |
| 99 | +import json, sys |
| 100 | +req = json.load(open(sys.argv[1])) |
| 101 | +facts = [] |
| 102 | +for fact in req.get("facts", []): |
| 103 | + cap = fact.get("capability") or {} |
| 104 | + if cap.get("category") == "network.client": |
| 105 | + continue # infra did not grant the new power |
| 106 | + if fact.get("role") == "required": |
| 107 | + fact = dict(fact, role="granted") |
| 108 | + facts.append(fact) |
| 109 | +json.dump({**req, "facts": facts}, open(sys.argv[2], "w")) |
| 110 | +PY |
| 111 | +echo "\$ reir report-pr --policy examples/rss-policy.toml --target prod --sarif" |
| 112 | +set +e |
| 113 | +"$REIR" report-pr --required "$work/required.reir.json" --granted "$work/granted.reir.json" \ |
| 114 | + --policy "$root/examples/rss-policy.toml" --target prod --sarif 2>/dev/null \ |
| 115 | + | python3 -c "import sys,json; d=json.load(sys.stdin); [print(' ', r['level'], r['ruleId'], '-', r['message']['text']) for r in d['runs'][0]['results']]" |
| 116 | +"$REIR" report-pr --required "$work/required.reir.json" --granted "$work/granted.reir.json" \ |
| 117 | + --policy "$root/examples/rss-policy.toml" --target prod >/dev/null 2>&1 |
| 118 | +echo " gate exit code: $? (non-zero = blocked)" |
| 119 | +set -e |
| 120 | + |
| 121 | +rule "RENDER — markdown review for a PR" |
| 122 | +echo "\$ rss pkg review --markdown after" |
| 123 | +"$RSS" pkg review --markdown "$after" | sed -n '1,14p' |
| 124 | + |
| 125 | +rule "NATIVE AUDIT — adapter risk facts" |
| 126 | +echo "\$ rss native audit after" |
| 127 | +"$RSS" native audit "$after" 2>/dev/null || true |
| 128 | + |
| 129 | +rule "FAIL CLOSED — invalid source yields no authoritative evidence" |
| 130 | +broken="$(mktemp -d)/broken" |
| 131 | +cp -r "$after" "$broken" |
| 132 | +printf '\nnative fn Broken.x(a: read String -> String\n' >> "$broken/interface/lib.rssi" |
| 133 | +echo "\$ rss pkg metadata <package with a parse error>" |
| 134 | +set +e |
| 135 | +"$RSS" pkg metadata "$broken" >/dev/null 2>&1 |
| 136 | +echo " metadata exit code: $? (non-zero = refused)" |
| 137 | +set -e |
| 138 | +test -f "$broken/review/reir/rsscript.json" \ |
| 139 | + && echo " REIR written (unexpected)" \ |
| 140 | + || echo " REIR bundle NOT written — evidence withheld for invalid source" |
| 141 | + |
| 142 | +rule "AGENT — machine-readable diagnostic explanation" |
| 143 | +echo "\$ rss check --explain RS0015 --json" |
| 144 | +"$RSS" check --explain RS0015 --json 2>/dev/null || true |
| 145 | + |
76 | 146 | printf '\nDone.\n' |
0 commit comments