Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
ac13e08
feat(observability-map): package scaffold and route scanner
1stvamp Jul 31, 2026
4fd2020
fix(observability-map): find every route entry point and scope body a…
1stvamp Jul 31, 2026
fa01e3e
feat(observability-map): remix route adapter
1stvamp Jul 31, 2026
944f4cb
feat(observability-map): import and callee based sensitivity classifi…
1stvamp Jul 31, 2026
68e0988
fix(observability-map): resolve one-hop helpers and narrow the scanne…
1stvamp Jul 31, 2026
6ab9118
feat(observability-map): triviality rule and suppression comments
1stvamp Jul 31, 2026
75eaaa8
feat(observability-map): the four coverage checks
1stvamp Jul 31, 2026
6a07d6d
feat(observability-map): record catch clause and callee evidence on e…
1stvamp Jul 31, 2026
751ea1b
feat(observability-map): rework two checks on the enriched scanner
1stvamp Jul 31, 2026
3b19436
feat(observability-map): flag entry points whose catches guard one op…
1stvamp Jul 31, 2026
3cb31cc
fix(observability-map): stop request-context excusing routes that log…
1stvamp Jul 31, 2026
ed52e17
feat(observability-map): add scoring and aggregation with an audit ga…
1stvamp Jul 31, 2026
f3b582f
feat(observability-map): terminal and json reports
1stvamp Jul 31, 2026
7183976
fix(observability-map): stop auth-boundary accusing routes it cannot …
1stvamp Jul 31, 2026
a8413e1
feat(observability-map): record catch evidence per clause
1stvamp Jul 31, 2026
093d447
fix(observability-map): judge catch clauses one at a time
1stvamp Jul 31, 2026
1dbb49a
feat(observability-map): cli, single entry inspection and integration…
1stvamp Jul 31, 2026
ca8b916
fix(observability-map): stop guardsParse and branches firing on looka…
1stvamp Jul 31, 2026
e4eaa7c
chore(observability-map): declare vitest and scope the build
1stvamp Jul 31, 2026
8232d11
fix(observability-map): stop paying routes for having no error handling
1stvamp Jul 31, 2026
bacda64
fix(observability-map): stop a suppression buying a better score
1stvamp Jul 31, 2026
8631151
fix(observability-map): break the circularity in sensitivity
1stvamp Jul 31, 2026
fe62964
fix(observability-map): make the report and the CLI say what they mean
1stvamp Jul 31, 2026
2f4823a
test(observability-map): cover the comment-only suppression rule
1stvamp Jul 31, 2026
ec5922a
fix(observability-map): report the request-context gap as a figure, n…
1stvamp Jul 31, 2026
99e14ca
docs(observability-map): explain what the number means
1stvamp Jul 31, 2026
3c74869
fix(observability-map): make the package typecheck and build again
1stvamp Jul 31, 2026
655b3ca
fix(observability-map): stop paying for a catch that only rethrows
1stvamp Jul 31, 2026
7754cac
fix(observability-map): name the suppression directive honestly, and …
1stvamp Jul 31, 2026
2cb36aa
chore(observability-map): remove dead scanner surface
1stvamp Jul 31, 2026
751af3f
fix(observability-map): stop crediting an if or switch that never loo…
1stvamp Jul 31, 2026
11c5908
docs(observability-map): explain triviality's exclusion and the gamin…
1stvamp Jul 31, 2026
b897141
docs(observability-map): refresh the collapse figures and say audit-t…
1stvamp Jul 31, 2026
dd3c2f6
fix(observability-map): remove the last dead scanner field and pin th…
1stvamp Jul 31, 2026
1df57d4
feat(observability-map): add --routes flag and a PR-comment renderer …
1stvamp Aug 1, 2026
902c013
ci(observability-map): scan head vs merge base and upsert a sticky PR…
1stvamp Aug 1, 2026
df0333e
fix(observability-map): stop audit-trail leaking into the PR-comment …
1stvamp Aug 1, 2026
960a568
fix(observability-map): make the CONTEXT line true in both renderers
1stvamp Aug 1, 2026
08f6be5
fix(observability-map): derive measured from pre-suppression applicab…
1stvamp Aug 1, 2026
e88f04d
fix(observability-map): read suppression comments from real comment r…
1stvamp Aug 1, 2026
b3200c1
fix(observability-map): require a genuine read of the catch binding
1stvamp Aug 1, 2026
46c5ad0
fix(observability-map): stop a dead throw counting as a rethrow
1stvamp Aug 1, 2026
433ebec
fix(observability-map): require request-context to name a tenant, at …
1stvamp Aug 1, 2026
2061d99
fix(observability-map): compare a parse guard against its own body, n…
1stvamp Aug 1, 2026
9e3b21a
fix(observability-map): stop attributing an inline callback's catch t…
1stvamp Aug 1, 2026
4704228
fix(observability-map): root the callback-boundary rule for catch att…
1stvamp Aug 1, 2026
255accb
fix(observability-map): read suppression comments off the parsed sour…
1stvamp Aug 1, 2026
fc73a2e
fix(observability-map): make every published figure pre-suppression
1stvamp Aug 1, 2026
9e30033
fix(observability-map): shadow-check a binding from any enclosing sco…
1stvamp Aug 1, 2026
e2e9ab3
fix(observability-map): drop the parse-guard ratio for an absolute, u…
1stvamp Aug 1, 2026
4e4dd81
fix(observability-map): tighten the minors (level set, bare env, a de…
1stvamp Aug 1, 2026
28c034d
fix(observability-map): read a directive off a comment, not off JSX text
1stvamp Aug 1, 2026
68b8380
fix(observability-map): judge a catch on its own path, and stop excus…
1stvamp Aug 1, 2026
fb8ca4d
test(observability-map): make the score-cannot-rise property a corpus
1stvamp Aug 1, 2026
eaafa3d
test(observability-map): check that a docstring names a test that exists
1stvamp Aug 1, 2026
3a95d7e
test(observability-map): test the JSX suppression fix, and name a tes…
1stvamp Aug 1, 2026
07dc007
fix(observability-map): refuse three ways of adding error handling th…
1stvamp Aug 1, 2026
d919ee2
test(observability-map): add the additive half of the corpus
1stvamp Aug 1, 2026
a11b661
fix(observability-map): cut a dead error test at the right moment
1stvamp Aug 1, 2026
3e1ee43
docs(observability-map): say what the unreachable-catch rule actually…
1stvamp Aug 1, 2026
b2e030b
fix(observability-map): read parse diagnostics through public typescr…
1stvamp Aug 1, 2026
d0d50f8
fix(observability-map): report a suppression that names no check inst…
1stvamp Aug 1, 2026
e0860dd
test(observability-map): cover the unknown-suppression line, and guar…
1stvamp Aug 1, 2026
3241352
fix(observability-map): render measured state in the pr comment, and …
1stvamp Aug 1, 2026
5ed9544
ci(observability-map): stop the head scan reddening a pull request, a…
1stvamp Aug 1, 2026
4d39fb4
feat(observability-map): add --out, honour --json for one route, and …
1stvamp Aug 1, 2026
6c54ec7
test(observability-map): give the cli tests their own routes tree, an…
1stvamp Aug 1, 2026
7273d12
fix(observability-map): mark a suppression-caused row, and post when …
1stvamp Aug 1, 2026
b0d6dc0
ci(observability-map): make a failed comment lookup mean one thing, a…
1stvamp Aug 1, 2026
bccaf9f
ci: revert the observability-map widening of the internal filter
1stvamp Aug 1, 2026
12f661d
ci(observability-map): gate the package tests through pr_checks, not …
1stvamp Aug 1, 2026
0645447
fix(observability-map): look at the access-control surface, and stop …
1stvamp Aug 1, 2026
cd02789
test(observability-map): add the two guard-laundering shapes to the c…
1stvamp Aug 1, 2026
e755639
docs(observability-map): rewrite the README from the numbers the tool…
1stvamp Aug 1, 2026
d441ca9
fix(observability-map): make auth-scope ask for the tenant floor, and…
1stvamp Aug 2, 2026
a65ff6b
test(observability-map): budget the real-tree scan instead of leaving…
1stvamp Aug 2, 2026
e250040
test(observability-map): colocate tests with their sources
1stvamp Aug 2, 2026
9b26552
fix(observability-map): repoint imports and guards to the colocated t…
1stvamp Aug 2, 2026
a7e6a17
fix(observability-map): point the corpus job at the moved file and ow…
1stvamp Aug 2, 2026
3635f2f
fix(observability-map): make audit-trail true, and stop one dead stat…
1stvamp Aug 2, 2026
7b207e2
docs(observability-map): disclose the free point auth-scope carries, …
1stvamp Aug 2, 2026
87b7382
fix(observability-map): trim trailing underscores without a backtrack…
1stvamp Aug 2, 2026
77179f1
fix(observability-map): make the corpus harness cover what it claims
1stvamp Aug 2, 2026
db8e1bd
fix(observability-map): print the unknown-suppression warning once
1stvamp Aug 2, 2026
cff46a7
docs(observability-map): correct a mutation's what text and tag a REA…
1stvamp Aug 2, 2026
951d430
fix(observability-map): credit a thrown ternary that classifies the e…
1stvamp Aug 2, 2026
023bc03
test(observability-map): stop the directive-prologue test passing on …
1stvamp Aug 2, 2026
87e0822
fix(observability-map): stop a switch's break cutting the statements …
1stvamp Aug 2, 2026
c53cbfd
docs(observability-map): note that auth-scope reads only the builder-…
1stvamp Aug 2, 2026
467a7fd
fix(observability-map): stop a dead statement blinding the catch walk
1stvamp Aug 2, 2026
2cb4233
fix(observability-map): enter the walk exactly where execution is gua…
1stvamp Aug 2, 2026
78e6ad5
fix(observability-map): judge refused callback catches on their evidence
1stvamp Aug 2, 2026
184f441
test(observability-map): assert the mirror direction of the corpus pr…
1stvamp Aug 2, 2026
fac948a
fix(observability-map): refuse catch evidence from a try a finally ca…
1stvamp Aug 2, 2026
ea6d6ff
fix(observability-map): block the refused-swallow accusation on any o…
1stvamp Aug 2, 2026
61fe11d
fix(observability-map): refuse a log call as evidence of caller scoping
1stvamp Aug 3, 2026
32c301d
ci(observability-map): stop the nightly corpus depending on the paths…
1stvamp Aug 3, 2026
f06e723
chore(observability-map): declare the ES2020 lib the tests already need
1stvamp Aug 3, 2026
5ad6026
fix(observability-map): keep the test task out of the turbo cache
1stvamp Aug 3, 2026
00b78cb
ci(observability-map): write scan reports with --out instead of captu…
1stvamp Aug 3, 2026
26c4059
ci(observability-map): widen the obsmap filter to what the suite reads
1stvamp Aug 3, 2026
4ea20b0
test(observability-map): size the real-tree timeouts for shard conten…
1stvamp Aug 3, 2026
30fdb02
fix(observability-map): attribute auth-boundary guards per export
1stvamp Aug 3, 2026
4f80d58
fix(observability-map): widen the corpus helper to every export form
1stvamp Aug 3, 2026
2de22e4
refactor(observability-map): share or pin the rest of the duplicated …
1stvamp Aug 3, 2026
4b0b243
fix(observability-map): read a branch arm's exit through the liveness…
1stvamp Aug 3, 2026
042c9c3
fix(observability-map): reconcile a comment the paths no longer reach
1stvamp Aug 3, 2026
420d2db
docs(observability-map): move the inline design record into the README
1stvamp Aug 3, 2026
272c3df
refactor(observability-map): apply the comment rule to the source files
1stvamp Aug 3, 2026
70a6bf8
test(observability-map): apply the comment rule to the tests
1stvamp Aug 3, 2026
be72dd5
docs(observability-map): split the README and cut its history
1stvamp Aug 3, 2026
0313884
fix(observability-map): stop preserving mutations deleting suppressio…
1stvamp Aug 3, 2026
eb01d0a
fix(observability-map): enumerate route modules in name order
1stvamp Aug 3, 2026
ace5342
fix(observability-map): name the base score when the head is the unme…
1stvamp Aug 3, 2026
82bb097
fix(observability-map): survive a null comment body in the report lookup
1stvamp Aug 3, 2026
b7cc564
fix(observability-map): let the renderer write its own comment file
1stvamp Aug 3, 2026
902379b
test(observability-map): pin why hasDelta needs no sensitivity term
1stvamp Aug 3, 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
375 changes: 375 additions & 0 deletions .github/workflows/observability-map.yml

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions .github/workflows/pr_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
webapp: ${{ steps.filter.outputs.webapp }}
packages: ${{ steps.filter.outputs.packages }}
internal: ${{ steps.filter.outputs.internal }}
obsmap: ${{ steps.filter.outputs.obsmap }}
cli: ${{ steps.filter.outputs.cli }}
sdk: ${{ steps.filter.outputs.sdk }}
steps:
Expand Down Expand Up @@ -81,6 +82,36 @@ jobs:
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'turbo.json'
# The whole webapp app tree, not just its routes, and that is the whole reason this
# filter exists. Two tests in @internal/observability-map read it: integration.test.ts
# scans the live route tree, and webappSymbols.test.ts walks all of apps/webapp/app and
# fails when a guard, sensitive or audit symbol stops resolving. Routes-only was this
# filter's own bug: renaming e.g. requireUserId in app/services/session.server.ts
# matched `webapp` and nothing else, so no job ran the suite and the break landed on
# main, or on the next unrelated internal-packages PR.
#
# The cost of the wider set, measured over the last 400 commits on main: 31% touch
# routes, 52% touch apps/webapp/app, so the job goes from firing on roughly a third of
# PRs to roughly a half. It is the cheap one -- a single 4x runner, no containers, no
# database, no prisma generate -- which is what makes that affordable.
#
# observability-map.yml is here because integration.test.ts asserts on its text and no
# other filter watches it, so editing the report workflow alone ran nothing at all.
#
# Deliberately NOT here: this package's own paths, and packages/plugins/src and
# internal-packages/rbac/src, the other two trees webappSymbols.test.ts reads.
# `internal` above already matches `internal-packages/**` and `packages/**`, and
# `unit-tests-internal.yml` runs `turbo run test --filter "@internal/*"`, which picks up
# @internal/observability-map and runs the same vitest suite. Listing them here as well
# ran the suite twice on every PR touching them, which was this filter's own doing.
obsmap:
- 'apps/webapp/app/**'
- '.github/workflows/pr_checks.yml'
- '.github/workflows/unit-tests-observability-map.yml'
- '.github/workflows/observability-map.yml'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
Comment thread
1stvamp marked this conversation as resolved.
Comment thread
1stvamp marked this conversation as resolved.
cli:
- 'packages/cli-v3/**'
- 'packages/build/**'
Expand Down Expand Up @@ -149,6 +180,11 @@ jobs:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}

obsmap:
needs: changes
if: needs.changes.outputs.obsmap == 'true'
uses: ./.github/workflows/unit-tests-observability-map.yml
Comment thread
1stvamp marked this conversation as resolved.

e2e:
needs: changes
if: needs.changes.outputs.cli == 'true'
Expand All @@ -172,6 +208,7 @@ jobs:
- e2e-webapp
- packages
- internal
- obsmap
- e2e
- sdk-compat
if: always()
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/unit-tests-observability-map.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: "🧪 Unit Tests: Observability Map"

permissions:
contents: read

# Its own workflow rather than a job inside observability-map.yml, because that workflow is not
# reachable from pr_checks.yml's all-checks aggregate and so gates nothing. Called from there
# instead, behind a paths filter, which is how every other test suite in this repo is gated.
on:
workflow_call:

jobs:
unitTests:
name: "🧪 Unit Tests: Observability Map"
# No containers and no database: the package is a static analyser over source text, so the
# suite is CPU bound on parsing the route tree and needs nothing the runner does not have.
runs-on: warp-ubuntu-latest-x64-4x
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false

- name: ⎔ Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
version: 10.33.2

- name: ⎔ Setup node
uses: WarpBuilds/setup-node@bc639b444d583175926b588962199c247d23e8d3 # v6
with:
node-version: 24.18.0
cache: "pnpm"

- name: 📥 Download deps
run: pnpm install --frozen-lockfile

# This suite reads apps/webapp/app (the route tree for the scan, the whole app tree for the
# symbol check) and the report workflow's text, which is why the filter that gates this
# workflow watches all of those and not only the routes folder.
- name: 🧪 Run tests
run: pnpm --filter @internal/observability-map run test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,6 @@ ailogger-output.log

# local planning/design docs, not committed
**/docs/superpowers/

# observability-map CLI output artifact, not committed
observability-map.json
Loading
Loading