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
3 changes: 1 addition & 2 deletions .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
"singleQuote": false,
"trailingComma": "es5",
"printWidth": 100,
"tabWidth": 2,
"plugins": ["prettier-plugin-tailwindcss"]
"tabWidth": 2
}
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,19 @@ Owner: founder + marketing + engineering.
- **RLS runtime role**: `DATABASE_URL` must connect as a role with `rolsuper = false` and `rolbypassrls = false`. `FORCE ROW LEVEL SECURITY` (applied to all 21 workspace-scoped tables since `20260721033000_strict_workspace_rls`, and to the 9 child tables since `20260803000001_child_table_rls` — though those nine were only genuinely protected once `20260803000002_child_table_rls_enable` added the missing `ENABLE ROW LEVEL SECURITY`; **`FORCE` without `ENABLE` is a no-op and leaves every policy on the table inert**, which is exactly what shipped between those two migrations) binds the table _owner_ to policies but does nothing to a superuser or any `BYPASSRLS` role — a superuser connection makes every RLS policy inert regardless of `FORCE`, which is easy to inherit by accident from a managed Postgres provider's default user. Verify with `SELECT rolsuper, rolbypassrls FROM pg_roles WHERE rolname = current_user;` — both must be `false`. See `docs/deployment/PRODUCTION_DEPLOYMENT.md` "Known production blockers" §2 for the role-creation SQL. `packages/db/src/rls-fail-closed.test.ts` enforces this in CI by refusing to run its assertions (rather than passing vacuously) against a role that can bypass RLS. **Current state (2026-08-07):** all 30 tables are RLS-protected — the 21 workspace-scoped tables plus the 9 child tables (`ScanEvent`, `Evidence`, `ScanResultManifest`, `ScanCoverageReceipt`, `FixProposal`, `PullRequest`, `Ticket`, `ScorecardShare`, `ScorecardEvent`), which were re-enabled by `20260807000003_child_table_rls_re_enable` after the `42501` outage was root-caused to a single write path (`account-deletion.ts` updating `ScorecardShare` outside `withWorkspaceRLS`). Application-layer enforcement (`withWorkspaceRLS` at 43 call sites + service-layer parent-ownership verification in `addScanEvent` et al.) remains in place as defence in depth. The child-table fail-closed tests are un-skipped, and the `rls-child-write-repro` CI job runs them against real Postgres under a restricted role on every push. **Lesson worth keeping:** the original gap survived CI because the tests only asserted cross-workspace reads return zero rows — a policy that always evaluates false also returns zero rows. Any new RLS policy needs a same-workspace **write** assertion to be meaningfully covered.
- **Email verification and shared rate limiting are enforced at different times, deliberately.** `LYRASHIELD_REQUIRE_EMAIL_VERIFICATION` (default `"1"`, currently pinned to `"0"` in production — see the blockers doc) is validated at **boot** in `packages/config/src/env.ts`, because it is about not claiming to verify addresses the app cannot mail. `UPSTASH_REDIS_REST_URL`/`UPSTASH_REDIS_REST_TOKEN` are validated at **deploy** in `deploy-azure.yml`, not at boot — boot validation fires in every production-mode process including the Playwright E2E server, and would fail a _running_ app on restart, trading a rate-limiting weakness for an availability outage. Do not move either check to the other's enforcement point without re-deriving why it lives where it does.

## Repository boundaries and generated artifacts

- `lyrashield-engine` (sibling repo) owns the Python scanner/runtime implementation; product code in this repo only invokes it through the worker.
- `lyrashield-marketplace` (sibling repo) owns published public install artifacts; generation source lives here in `packages/agent-plugin` and `docs/marketplace`, but the committed releases belong in the marketplace repo.
- `lyrashieldai` (this repo) is the authoritative source for product, auth, API, dashboard, MCP, installer source, and generation/conformance checks.
- `@lyrashield/cli` is deprecated; the canonical published CLI is the unscoped `lyrashield` package.

Build artifacts and generated media are **not kept in this repo**.

- `apps/web/.next/`, `apps/marketing/dist/`, `packages/*/dist/`, `.turbo/`, `apps/marketing-motion/renders/`, and `apps/marketing/public/media-local/` are generated and `.gitignore`d.
- Heavy media masters/renders are archived to remote storage (R2) or regenerated by the `apps/marketing-motion` workflow.
- Run `pnpm install` and `pnpm build` as needed; do not commit `node_modules` or build output.

## Documentation ownership

- `PRD.md` — strategy, authoritative backlog, accepted/rejected work
Expand Down
2 changes: 0 additions & 2 deletions apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@
"@cloudflare/workers-types": "^5.20260724.1",
"@tailwindcss/typography": "^0.5.20",
"@types/node": "^24.0.0",
"lighthouse": "^13.4.1",
"puppeteer": "^25.3.0",
"tsx": "^4.23.1",
"typescript": "^6.0.0",
"wrangler": "^4.116.0"
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"eslint-config-next": "^16.2.11",
"eslint-plugin-security": "^3.0.1",
"prettier": "^3.9.6",
"prettier-plugin-tailwindcss": "^0.8.1",
"turbo": "^2.10.6",
"vitest": "^4.1.9"
},
Expand Down
Loading
Loading