Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 5 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
# Minutia Agent Notes

## Repo Boundaries
## Scope

- Core product code and generic self-host support live in this repo.
- OSS self-host is a single-workspace model: one organization per instance, with workspace invitations for additional users.
- Hosted VPS deployment automation lives in the private sibling repo `minutia-ops`.
- Private hosted billing and control-plane work lives in the private sibling repo `minutia-cloud`.
- Cloud multi-tenant provisioning and super-admin organization creation live in `minutia-cloud`, not this OSS repo.
- Do not add VPS-specific deployment overlays, private runtime topology, domains, hostnames, SSH details, provider details, or incident runbooks to this OSS repo.
- Do not add tenant provisioning, organization switching, cloud super-admin UI, or hosted lifecycle code to this OSS repo.
- Keep generic self-host files public and provider-neutral unless explicitly asked otherwise.
- This repository is the open-source, self-hostable Minutia app: an Outstanding Issues Log (OIL) for recurring meetings.
- Single-workspace model: one organization per instance, with workspace invitations for additional users.
- Keep self-host files provider-neutral. Do not add deployment topology, domains, hostnames, secrets, SSH details, or provider-specific runtime details to this repository.

## Guardrails

- Preserve core app behavior and generic self-host behavior when removing hosted/VPS surfaces.
- Prefer small, test-backed changes.
- Do not put test stubs in production code. Production route handlers, services, and app code must never branch on test-only env vars or fake provider responses. Keep stubs, fixtures, and provider fakes in tests, local harnesses, or pure contract verifiers only.
- Run targeted scans before committing OSS changes.
- Run targeted secret and topology scans over changed files before committing.

<!-- gitnexus:start -->
# GitNexus - Code Intelligence
Expand Down
70 changes: 8 additions & 62 deletions scripts/verify-oss-boundaries.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { existsSync, readFileSync } from "node:fs";
import assert from "node:assert/strict";

// Self-host integrity check.
// Verifies the generic, provider-neutral self-host surface stays intact:
// required files are present and key self-host wiring is wired up.
// This check only asserts what SHOULD exist; it intentionally does not
// enumerate or describe anything outside this repository.

const mustExist = [
"docker-compose.yml",
".env.example",
Expand All @@ -13,61 +19,12 @@ const mustExist = [
"supabase/migrations/20260603021000_google_calendar_watch_channels.sql"
];

const mustNotExist = [
"deploy/minutia/Caddyfile",
"deploy/minutia/docker-compose.vps.yml",
"deploy/minutia/env.vps.example",
"docs/DEPLOY_SELF_HOST_VPS.md",
"src/app/api/admin/organizations/route.ts",
"src/app/org/[slug]/page.tsx",
"scripts/deploy-minutia-vps.sh",
"supabase/migrations/20260527000000_hosted_control_plane_gate.sql"
];

const bannedTextByFile = {
".env.example": [
"MINUTIA_HOSTED_CONTROL_PLANE",
"hosted_control_plane"
],
"src/app/(app)/settings/page.tsx": [
"/api/admin/organizations",
"Hosted organizations",
"HostedOrgData"
],
"src/components/minutia/app-sidebar.tsx": [
"organizations.length > 1",
"window.location.href = `/org/"
],
"src/lib/supabase/admin-auth.ts": [
"MINUTIA_HOSTED_CONTROL_PLANE",
"hosted_control_plane",
"isHostedControlPlaneEnabled"
],
"playwright.config.ts": [
"MINUTIA_HOSTED_CONTROL_PLANE"
],
"e2e/regression/organization-rbac.spec.ts": [
"/api/admin/organizations",
"Hosted organizations",
"hosted_control_plane",
"/org/${slug}",
"selectOption(orgId)"
],
"supabase/migrations/20260526061638_multi_tenant_orgs.sql": [
"hosted_mode"
]
};

for (const path of mustExist) {
assert.equal(existsSync(path), true, `${path} must remain for generic self-host`);
}

for (const path of mustNotExist) {
assert.equal(existsSync(path), false, `${path} belongs in minutia-ops`);
}

const packageJson = JSON.parse(readFileSync("package.json", "utf8"));
assert.equal(packageJson.scripts["deploy:vps"], undefined, "deploy:vps belongs in minutia-ops");
assert.equal(typeof packageJson.scripts.build, "string", "package.json must define a build script");

const envExample = readFileSync(".env.example", "utf8");
const generatedEnvScript = readFileSync("scripts/generate-self-host-env.mjs", "utf8");
Expand All @@ -88,16 +45,5 @@ assert.match(dockerCompose, /NEXT_PUBLIC_SUPABASE_URL=\$\{NEXT_PUBLIC_SUPABASE_U
assert.match(dockerCompose, /GOOGLE_CALENDAR_WEBHOOK_URL=\$\{GOOGLE_CALENDAR_WEBHOOK_URL/, "docker compose must pass the calendar webhook URL to the web app");
assert.match(dockerCompose, /\.\/supabase\/migrations:\/migrations:ro/, "docker compose must mount Supabase migrations");
assert.match(calendarWatchMigration, /CREATE TABLE IF NOT EXISTS public\.google_calendar_watch_channels/, "calendar watch channel table migration must remain");
assert.doesNotMatch(envExample, /STRIPE_/, "Stripe configuration belongs in minutia-cloud, not OSS setup docs");
assert.doesNotMatch(generatedEnvScript, /STRIPE_/, "Stripe configuration belongs in minutia-cloud, not OSS env generation");

for (const [path, bannedTerms] of Object.entries(bannedTextByFile)) {
const content = readFileSync(path, "utf8");
for (const term of bannedTerms) {
assert.equal(
content.includes(term),
false,
`${term} belongs in private hosted org/control-plane code, not OSS ${path}`
);
}
}
console.log("OSS self-host integrity verified");
Loading