From cb4ec9343d5b9b5a7797084204e926d0affa984a Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:32:23 -0400 Subject: [PATCH 1/8] Guard generated lockfiles from silent text merges --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..078b4ca5f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# Lockfiles are generated files. Git's line-level merge can splice concurrent +# edits into syntactically invalid content without reporting a conflict. +# Treat them as binary so concurrent edits require explicit regeneration. +package-lock.json merge=binary +bun.lock merge=binary From 859b3c98cdb6c5a4f99a8ba62383deb9ec7a4cec Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:32:48 -0400 Subject: [PATCH 2/8] Fail fast on malformed package manifests and lockfiles --- .github/workflows/baseline.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/baseline.yml b/.github/workflows/baseline.yml index 9c1eb9d75..2dd5fb3e8 100644 --- a/.github/workflows/baseline.yml +++ b/.github/workflows/baseline.yml @@ -35,6 +35,8 @@ jobs: uses: actions/checkout@v7 - name: Set up pinned Node.js and npm uses: ./.github/actions/setup-ross-node + - name: Validate backend package manifests + run: node -e "const fs=require('fs'); for (const f of ['backend/package.json','backend/package-lock.json']) JSON.parse(fs.readFileSync(f, 'utf8'))" - name: Install backend dependencies run: npm ci --prefix backend - name: Run backend tests @@ -51,6 +53,8 @@ jobs: uses: actions/checkout@v7 - name: Set up pinned Node.js and npm uses: ./.github/actions/setup-ross-node + - name: Validate frontend package manifests + run: node -e "const fs=require('fs'); for (const f of ['frontend/package.json','frontend/package-lock.json']) JSON.parse(fs.readFileSync(f, 'utf8'))" - name: Install frontend dependencies run: npm ci --prefix frontend - name: Build frontend @@ -65,6 +69,8 @@ jobs: uses: actions/checkout@v7 - name: Set up pinned Node.js and npm uses: ./.github/actions/setup-ross-node + - name: Validate website package manifests + run: node -e "const fs=require('fs'); for (const f of ['website/package.json','website/package-lock.json']) JSON.parse(fs.readFileSync(f, 'utf8'))" - name: Install website dependencies run: npm ci --prefix website - name: Build website @@ -83,6 +89,8 @@ jobs: uses: actions/checkout@v7 - name: Set up pinned Node.js and npm uses: ./.github/actions/setup-ross-node + - name: Validate all package manifests + run: node -e "const fs=require('fs'); for (const d of ['.','backend','frontend','website']) for (const f of ['package.json','package-lock.json']) JSON.parse(fs.readFileSync(d === '.' ? f : `${d}/${f}`, 'utf8'))" - name: Install locked dependencies run: npm run install:all - name: Regenerate release manifest for verification From 6d98d4c2aa622ee6920aa7544a393a6d3df0b56e Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:33:18 -0400 Subject: [PATCH 3/8] Avoid shell interpolation in manifest validation --- .github/workflows/baseline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/baseline.yml b/.github/workflows/baseline.yml index 2dd5fb3e8..722b1ccea 100644 --- a/.github/workflows/baseline.yml +++ b/.github/workflows/baseline.yml @@ -90,7 +90,7 @@ jobs: - name: Set up pinned Node.js and npm uses: ./.github/actions/setup-ross-node - name: Validate all package manifests - run: node -e "const fs=require('fs'); for (const d of ['.','backend','frontend','website']) for (const f of ['package.json','package-lock.json']) JSON.parse(fs.readFileSync(d === '.' ? f : `${d}/${f}`, 'utf8'))" + run: node -e "const fs=require('fs'); for (const d of ['.','backend','frontend','website']) for (const f of ['package.json','package-lock.json']) JSON.parse(fs.readFileSync(d === '.' ? f : d + '/' + f, 'utf8'))" - name: Install locked dependencies run: npm run install:all - name: Regenerate release manifest for verification From bc188b60543fe617c7e178a081e6cbe37a69bb59 Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:39:58 -0400 Subject: [PATCH 4/8] Ignore generated local Supabase scaffold --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 0a704f17c..567f81b45 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ next-env.d.ts .DS_Store .vercel coverage + +# Generated local Supabase CLI scaffold. CI and production build their own +# database state from the governed schema and migrations. +backend/supabase/ From dcea41f23e22bf36312cba2c22dc30be23ee5346 Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:40:12 -0400 Subject: [PATCH 5/8] Add ROSS pull request verification template --- .github/PULL_REQUEST_TEMPLATE.md | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..6ccc68fc5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,33 @@ +## Summary + + + +## Why + + + +## Changes + + + +## Tradeoffs and risk + + + +## How verified + + + +## Upstream provenance + + + +## Checklist + +- [ ] Ran the relevant focused tests and the applicable Baseline commands. +- [ ] Reviewed the final diff and removed unrelated changes. +- [ ] Preserved ROSS data-boundary, authentication, privacy, and release controls. +- [ ] Updated documentation and environment examples when behaviour or setup changed. +- [ ] No secrets, API keys, real client documents, privileged material, or `.env` files are committed. From 93efb3f88d7ce66ea98b609bb9168e27f54bfa57 Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:40:39 -0400 Subject: [PATCH 6/8] Adapt upstream contributor verification guidance --- CONTRIBUTING.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8a3b522f9..06182a5e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,26 @@ Mike functionality recorded in the baseline contract. - changes - why - testing + - tradeoffs and risk + - upstream provenance, when applicable + +## Testing Expectations + +- Add a regression test at the lowest practical layer for each feature or bug + fix. Prefer a focused unit test, then a route or integration test, and use an + end-to-end test only when a browser or deployed service is necessary to prove + the behaviour. +- Do not weaken, skip, broadly disable, or delete an existing test merely to + make a change pass. Correct stale expectations only when the implementation + and governing contract demonstrate that the expectation is obsolete. +- Record the exact commands run in the PR description. Baseline verification is + required on the final PR head; a successful run on an earlier commit is not + sufficient. +- Tests requiring live Supabase, provider keys, or deployed URLs must be + explicitly environment-gated and must not expose secrets or real client data. +- Changes to authentication, authorization, privacy, data boundaries, + migrations, deployment, or release mechanics require focused verification in + addition to the normal Baseline. ## System Workflows From 280e1140cc5d098818f0f2a42ae364ea9e2ce474 Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:40:53 -0400 Subject: [PATCH 7/8] Remove unused Supabase request auth helper --- backend/src/lib/supabase.ts | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/backend/src/lib/supabase.ts b/backend/src/lib/supabase.ts index da821862d..51ad41ed3 100644 --- a/backend/src/lib/supabase.ts +++ b/backend/src/lib/supabase.ts @@ -12,33 +12,3 @@ export function createServerSupabase() { } return createClient(url, key, { auth: { persistSession: false } }); } - -/** - * Extract and verify the Supabase JWT from the Authorization header. - * Returns the user's UUID string, or throws a Response with 401. - */ -export async function getUserIdFromRequest(req: Request): Promise { - const auth = req.headers.get("authorization") ?? ""; - if (!auth.startsWith("Bearer ")) { - throw new Response("Missing or invalid Authorization header", { - status: 401, - }); - } - const token = auth.slice(7).trim(); - - const supabaseUrl = process.env.SUPABASE_URL || ""; - const serviceKey = process.env.SUPABASE_SECRET_KEY || ""; - - if (!supabaseUrl || !serviceKey) { - throw new Response("Server auth is not configured", { status: 500 }); - } - - const admin = createClient(supabaseUrl, serviceKey, { - auth: { persistSession: false }, - }); - const { data } = await admin.auth.getUser(token); - if (!data.user) { - throw new Response("Invalid or expired token", { status: 401 }); - } - return data.user.id; -} From cab93fa11cddfc7c7ff125e1940a012e5fdd7944 Mon Sep 17 00:00:00 2001 From: ranade-oss Date: Tue, 28 Jul 2026 19:41:40 -0400 Subject: [PATCH 8/8] Record completed low-risk upstream integration inventory --- docs/upstream-integration-plan.md | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/upstream-integration-plan.md diff --git a/docs/upstream-integration-plan.md b/docs/upstream-integration-plan.md new file mode 100644 index 000000000..4ebf766ea --- /dev/null +++ b/docs/upstream-integration-plan.md @@ -0,0 +1,65 @@ +# Upstream integration plan + +## Objective + +Integrate useful changes from `Open-Legal-Products/mike` incrementally while +preserving ROSS-specific security, privacy, legal-source, data-boundary, and +release controls. + +## Required method + +Every upstream change is classified before implementation: + +- **Adopt** — incorporate substantially as written. +- **Adapt** — port the useful behaviour around ROSS architecture and controls. +- **Skip** — irrelevant, already implemented, superseded, or incompatible. +- **Investigate** — potentially useful, but requires focused security, + migration, dependency, deployment, licensing, or product analysis. + +Do not bulk-merge upstream. Each implementation batch must be independently +reviewable, reversible, and verified by Baseline on its exact final head. + +## ROSS safeguards that upstream work must not weaken + +- governed release train, immutable digest promotion, rollback, and manifests; +- authentication, authorization, MFA, and encrypted provider-key handling; +- data-boundary and upload/document scanning controls; +- Ontario legal-source integrations and health checks; +- privacy, public-beta evidence, and operational policy controls; +- trusted-agent final-head verification and bounded automatic repair. + +## Completed low-risk inventory + +| Upstream change | Classification | ROSS disposition | +| --- | --- | --- | +| `cb2306c5` — unify full-screen loading markup | **Adapt** | Ported in ROSS PR #32 while preserving `DataBoundaryGate`, auth redirects, and MFA behaviour. | +| PR #240 — prevent silently merge-corrupted lockfiles | **Adapt** | Extended across ROSS backend, frontend, website, and governance Baseline partitions in ROSS PR #33. | +| PR #234 — contributor testing policy and PR template | **Adapt** | Added ROSS-specific final-head, privacy, data-boundary, release, and upstream-provenance requirements in ROSS PR #33. | +| `fb3ec2d6` — ignore generated local Supabase scaffold | **Adopt** | Added `backend/supabase/` to `.gitignore` in ROSS PR #33. | +| PR #186 — remove unused `getUserIdFromRequest` helper | **Adopt** | Removed after confirming no repository references in ROSS PR #33. Active Express authentication middleware is unchanged. | +| `4728fd19` — pin Turbopack workspace root | **Skip: already implemented** | ROSS already sets `turbopack.root` to its resolved repository root. | +| PR #270 — discover workflow packs through `pack.yaml` | **Skip: architecture differs** | ROSS discovers governed workflows directly from `mike-workflows/system/*/SKILL.md`; it does not use upstream pack-directory discovery. | +| PR #258 — synchronize Bun lockfile | **Skip: not applicable** | ROSS uses npm lockfiles for its governed workspaces. | +| PR #236 — Anthropic-specific E2E key instructions | **Skip: superseded** | ROSS uses provider-neutral encrypted user keys and a separate dedicated `OPENAI_API_KEY` only for bounded CI repair. | +| PR #232 / reference CI workflow | **Skip: superseded** | ROSS has a partitioned Baseline, final aggregation gate, event-driven merge, manifest refresh, and bounded repair. | +| Reference Vitest/evals harnesses | **Skip: superseded for the low-risk batch** | ROSS already has governed backend, frontend build, website, evaluation, security, operational, and release checks. Broader new test dependencies require a separate dependency-reviewed batch. | + +## Remaining work — not low risk + +The remaining useful upstream areas require dedicated focused batches and are +not part of routine maintenance integration: + +- ownership and authorization fixes for tabular reviews, projects, folders, and + shared resources; +- RLS, schema, migration, Supabase, and tenant-isolation changes; +- prompt-injection, SSRF, download-token, connector-secret, CORS, and other + security hardening; +- broad route-level, browser E2E, or new test-runner dependency additions; +- workflow-pack format changes with external repository dependencies; +- provider, local inference, storage, DMS, telemetry, queue, RAG, organization, + service-layer, deployment, Docker, and air-gap architecture; +- changes affecting release, staging, rollback, production configuration, or + public operational evidence. + +For these categories, implementation begins only after architecture and threat +analysis identifies the ROSS-specific adaptation and validation requirements.