forked from retoor/devplacepy
Refuse to touch the production database without stated confirmation
data/devplace.db is the live database and make dev, make prod and the Docker stack all share it, so an agent-initiated command that reaches it is a production incident waiting for a typo. The hazard is invisible in the command text: the script that prompted this named no path at all, it imported devplacepy and therefore resolved config.DATA_DIR to the real file. A path-pattern rule would have sailed straight past it. The PreToolUse hook reads the script and judges it on content, so one that points DEVPLACE_DATABASE_URL at a scratch file passes and an unguarded one does not. It also refuses commands naming the database or a production data directory, the management CLI, and python -m devplacepy. The suite, the server targets and the mandated import gate stay free. permissions.deny additionally refuses Write and Edit anywhere under data, which the Bash hook cannot see. The escape hatch is two-factor and cannot be self-served: without confirmation the command is denied outright rather than prompted, and the token that downgrades it to a prompt may only be added after the user has confirmed in their own words. Verified against thirty-five commands, and the heuristic is narrower than it looks because the repository path itself contains the package name, so it matches an import statement rather than the bare word. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -266,6 +266,16 @@ Devii is also reachable over **Telegram** (one supervised long-poller subprocess
|
||||
|
||||
`devplacepy/seo.py` generates JSON-LD schemas (WebSite, BreadcrumbList, DiscussionForumPosting, ProfilePage, SoftwareApplication). Every router builds context via `base_seo_context(request, ...)`. Auth/messages/notifications are `noindex,nofollow`; profiles with fewer than 2 posts are `noindex,follow`. `/robots.txt` and `/sitemap.xml` are served by `routers/seo.py`. Full implementation map (template layer, heading hierarchy, slugs, related posts, performance, default OG image, SEO tests) is in `devplacepy/routers/CLAUDE.md`.
|
||||
|
||||
## The production database is never touched without explicit confirmation (hard rule)
|
||||
|
||||
`data/devplace.db` is the live production database, and `make dev`, `make prod` and the Docker stack all share it (see "Production deployment"). No agent-initiated command may read or write it, or anything else under `data/`, without the user's explicit, stated confirmation - not a one-click approval, a confirmation they wrote themselves after being told exactly what the command would do.
|
||||
|
||||
This is enforced, not remembered. `.claude/hooks/guard_production_db.py` runs as a `PreToolUse` hook on every Bash call and **denies** the command outright when it reaches production, naming the reason. The interesting case is the one that motivated the rule: a script that never mentions a path at all but imports `devplacepy` and therefore resolves `config.DATA_DIR` to the real database. The hook reads the script and decides on its content, so a scratch-database script passes and an unguarded one does not.
|
||||
|
||||
What the guard blocks: any command naming `data/devplace.db` or a production data directory, the `devplace` management CLI, `python -m devplacepy...`, and any inline `-c` or script file that imports `devplacepy` without a `DEVPLACE_DATABASE_URL` override. What stays free: `make test` and `pytest` (the suite runs on its own temp database), `make dev`/`make prod`/`make docker-*`, the mandated import gate `python -c "from devplacepy.main import app"`, and anything that sets `DEVPLACE_DATABASE_URL` to a scratch file. `permissions.deny` in `.claude/settings.json` additionally refuses `Write`/`Edit` anywhere under `data/`, which the Bash hook cannot see.
|
||||
|
||||
The escape hatch is deliberately two-factor and must never be self-served: after the user has confirmed in their own words, the command may carry the literal token `I-HAVE-CONFIRMED-PRODUCTION-DB-ACCESS`, which downgrades the denial to a permission prompt the user still has to approve. **Never add that token on your own initiative.** Write disposable scripts against a temp database via `DEVPLACE_DATABASE_URL`/`DEVPLACE_DATA_DIR` instead, exactly as "Rigorous correctness verification" already requires.
|
||||
|
||||
## Conventions (project-specific)
|
||||
|
||||
- **No comments, no docstrings in source.** Code is self-documenting.
|
||||
|
||||
Reference in New Issue
Block a user