
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
@agentbadge/database
Advanced tools
Shared database layer for AgentBadge — Prisma ORM 8 client, repositories, store abstraction
Shared database layer for AgentBadge — Prisma ORM 8 contract-based client,
repository abstraction, and in-memory fallback. Consumers call
createDatabase() — never touch Prisma directly.
cd packages/database
bun install
bun run db:up # Postgres 17 in Docker, host port 5335
cp .env.example .env # DATABASE_URL + DIRECT_URL → localhost:5335
bun run contract:emit # regenerate contract.json/.d.ts (committed)
bun run db:init # bootstrap schema + sign marker
bun run db:seed # 3 sample events (idempotent)
bunx vitest run # unit tests (PG-backed when DATABASE_URL set)
Stop / inspect / wipe:
bun run db:down # stop container (named volume keeps data)
bun run db:logs # follow Postgres logs
docker compose down -v # wipe data completely
import { createDatabase } from "@agentbadge/database";
const database = createDatabase({
enabled: config.database?.enabled ?? false, // DATABASE_ENABLED gate
url: config.database?.url, // DATABASE_URL (pooled)
});
// database.db — Prisma client facade, null when disabled
// database.events — Store (EventRepository on PG, InMemoryStore otherwise)
// database.scanResults — ScanResultStore (ScanResultRepository │ InMemoryScanResultStore)
// database.chatSubscriptions — ChatSubscriptionStore (ChatSubscriptionRepository │ InMemoryChatSubscriptionStore)
// database.health()— SELECT 1 probe → boolean
// database.close() — call ONCE at shutdown, never per-request
enabled:false or missing url → in-memory store, db=null,
health()→false, never throws. Server wiring lives in
hackathon/server/src/server/lib/database.ts (lazy getDatabase()
singleton); env section in src/config/env/database.ts.
Env topology: the package never reads env at runtime — the caller passes
url. Server runtime uses hackathon/server/.env locally and Fly secrets
in prod (DATABASE_ENABLED + DATABASE_URL only). This package's .env is
for CLI/migrations/tests inside the package dir only and is never published
(files: ["dist"]). DIRECT_URL (unpooled, migrations) stays local in
.env.deployer — see RUNBOOK.md.
Event as a generic persisted-event tableEvent is intentionally generic — new persisted event streams do NOT need
their own model. Convention (EPIC-145):
type — the stream kind, e.g. "audit" (keeperhub audit events)source — the producing subsystem, e.g. "keeperhub"payload — the event JSONStore.list({ type }) filters by stream kind (added in SLICE-145-4)Dedicated models exist only where the shape is truly relational:
ScanResult (latest-scan-per-domain lookups) and ChatSubscription
(telegram chat ↔ username bindings, unique constraints + upsert).
src/prisma/contract.prismabun run contract:emit — regenerate committed artifactsbun run db:plan --name add_<entity> — writes migrations/app/<ts>_add_<entity>/bun run db:migrate — apply (single tx + advisory lock on PG)bun run db:verify — marker + schema match contractsrc/repositories/<entity>-repository.ts copying
EventRepository (extends Repository<T,TCreate,TUpdate>, implements
the entity's Store interface)Store contract + InMemoryStore if the entity needs an
in-memory fallback; wire into createDatabase()tests/store.test.ts| Script | Purpose |
|---|---|
bun run build | tsc → dist/ |
bun run typecheck | tsc --noEmit over src + scripts + tests |
bun test / bunx vitest run | unit tests (PG suites skip without DATABASE_URL) |
bun run db:up / db:down / db:logs | dev Postgres lifecycle |
bun run contract:emit | regenerate contract.json + contract.d.ts |
bun run db:init | bootstrap DB schema + sign marker (fresh DB) |
bun run db:update | dev-loop schema sync (destructive needs --confirm <db>) |
bun run db:plan --name <slug> | write a reviewable migration package |
bun run db:migrate | replay committed migrations (--advance-ref db) |
bun run db:verify | check DB marker + live schema match contract |
bun run db:seed | upsert 3 sample events (idempotent) |
No prisma generate, no generated/ client folder. The contract is the
source of truth; contract.json + contract.d.ts are committed to git
(D16). Migrations are on-disk packages under migrations/app/ — replayed by
db migrate, never invented at apply time. See RUNBOOK.md for prod.
Pinned RC versions (API breaks between RCs — do not upgrade casually):
prisma@8.0.0-rc.15, @prisma/orm-postgres@8.0.0-rc.11,
@prisma/cli-engine@0.4.0.
db.close() in handlers — the pool is shared; close once at
shutdown (server does this in the SIGTERM/SIGINT handler).db is not exported from the package index — src/prisma/db.ts reads
process.env.DATABASE_URL at module load; only scripts/seed.ts imports
it directly. Consumers: createDatabase().CONTRACT.MARKER_READ_FAILED / CONFIG.DB_CONNECTION_REQUIRED —
DATABASE_URL/DIRECT_URL not set in the package's .env (CLI context).db update refuses without --confirm <database>
(--yes does NOT grant consent). db migrate has no flag — review
destructive ops in the plan output before applying.migration.ts after db:plan, or keep-then-drop in two
migrations.upsert conflictOn — pass the unique field as an object:
conflictOn: { id }, not "id".SELECT 1 AS health (bare
SELECT 1 yields ?column?, which fails the row spec).# local dev (monorepo) — already wired in hackathon/server:
# "@agentbadge/database": "file:../../packages/database"
# after npm publish:
bun add @agentbadge/database
import { createDatabase } from "@agentbadge/database";
const database = createDatabase({
enabled: process.env.DATABASE_ENABLED === "true",
url: process.env.DATABASE_URL, // pooled postgres:// URL
});
await database.events.create({ type: "scan.completed", payload: { s: 92 } });
const up = await database.health(); // SELECT 1 probe
await database.close(); // once, at shutdown — never per-request
The package ships dist/ only (files: ["dist"]) — contract artifacts are
compiled in, no prisma generate needed at install. It never reads env at
runtime; the caller passes url explicitly.
# from repo root — "database" is in the PACKAGES list:
./scripts/publish-packages.sh patch --dry-run # verify tarball contents
./scripts/publish-packages.sh patch # real publish (needs npm login + OTP)
# then switch the consumer from file: to the published version:
# hackathon/server/package.json:
# "@agentbadge/database": "file:../../packages/database" → "^0.1.0"
cd hackathon/server && bun install
bunx vitest run tests/e2e/database.test.ts --config vitest.e2e.config.ts
Version bumps follow semver: patch = fixes, minor = new entity/store,
major = CacheProvider/Store/Database interface breaks.
hackathon/server (Hono) Fly.io machine
└─ createDatabase({enabled, url}) ──► Prisma Postgres
├─ events: Store (EventRepository │ InMemoryStore)
├─ scanResults: ScanResultStore (ScanResultRepository │ InMemoryScanResultStore)
├─ chatSubscriptions: ChatSubscriptionStore (ChatSubscriptionRepository │ InMemoryChatSubscriptionStore)
├─ health() → SELECT 1 (pooled DATABASE_URL)
└─ close() on SIGTERM/SIGINT
packages/database (this repo) local dev
└─ docker compose: postgres:5335 + valkey:6336
└─ migrations: contract.prisma → emit → plan → migrate
(DIRECT_URL, local shell only — never on Fly)
src/ — package source (published via dist/)src/prisma/ — contract artifacts (contract.json, contract.d.ts,
db.ts dev client) — committed (D16)src/repositories/ — EventRepository (canonical template), ScanResultRepository, ChatSubscriptionRepositorymigrations/ — committed migration packages + snapshot store + db reftests/ — vitest suites (PG legs skip without DATABASE_URL)scripts/seed.ts — idempotent seeddocker-compose.yml — local dev Postgres only; prod = managed Prisma
Postgres (see RUNBOOK.md)FAQs
Shared database layer for AgentBadge — Prisma ORM 8 client, repositories, store abstraction
The npm package @agentbadge/database receives a total of 637 weekly downloads. As such, @agentbadge/database popularity was classified as not popular.
We found that @agentbadge/database demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.