Add deep-dive documentation#5
Conversation
Add a multi-stage Dockerfile (Next.js standalone output), .dockerignore, and docker-compose.yml. Enables output: standalone in next.config.mjs for a lean runtime image. Secrets are injected at runtime via .env.local, never baked into the image. Verified: image builds and the container serves HTTP 200.
Alpine's busybox wget lacks --spider/--no-verbose, and the standalone server binds to IPv4 0.0.0.0, so the probe must hit 127.0.0.1 not localhost (::1). Also add the nginx reverse-proxy vhost used to serve the app behind the shared nginx as a name-based virtual host.
Adds a 'New Report' button in the header that clears the project brief, evidence artifacts, manual notes, and generated draft, returning the studio to the setup step. Confirms before discarding in-progress work, resets the file input, and clears any auto-saved draft from localStorage.
Three detailed documents plus an index covering the product vision and competitive positioning, the full A-to-Z architecture and engine pipeline, and a catalog of innovations with their real-world rationale and moat analysis.
|
Looking for one thing? Review this PR in Change Stack to search files, summaries, diffs, and code without losing your place. 📝 WalkthroughWalkthroughThis PR establishes production deployment infrastructure for Verric, comprehensive product and technical documentation, and adds a UI feature to reset the report studio. The changes configure Next.js for standalone output, define a multi-stage Docker build with Alpine runtime, compose the service with environment variables and health checks, set up Nginx reverse proxy with TLS and security headers, document the product vision and competitive positioning, provide a technical architecture reference, and introduce a reset button to start fresh reports. ChangesProduction Deployment and Containerization
Product and Technical Documentation
Studio Reset Feature
🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docker-compose.yml`:
- Around line 14-18: The environment block currently uses shell-style
substitutions (OPENAI_MODEL: ${OPENAI_MODEL:-gpt-4o-mini}, USE_MOCK_REPORT:
${USE_MOCK_REPORT:-false}) which override values from env_file; remove those
substitutions from the docker-compose service's environment section so it relies
solely on env_file values (i.e., stop setting OPENAI_MODEL and USE_MOCK_REPORT
with ${...:-} in the compose file), and instead add or update a
.env.local.example documenting defaults (OPENAI_MODEL=gpt-4o-mini,
USE_MOCK_REPORT=false, OPENAI_API_KEY=...) so users know the expected variables
and defaults.
In `@docs/01-VISION-AND-PRODUCT.md`:
- Around line 115-126: The fenced code block containing the numbered artifact
list is missing a language identifier; update that opening fence from ``` to
```text so the block becomes a text code fence (i.e., add the language tag to
the triple-backtick that precedes the list) to satisfy markdownlint MD040 while
leaving the list contents unchanged.
In `@docs/02-ARCHITECTURE-AND-ENGINE.md`:
- Around line 25-46: Several fenced code blocks in the ARCHITECTURE doc are
missing language specifiers (MD040); update each fenced block that contains
ASCII diagrams, directory trees or plain text to use ```text and the deploy
command block to use ```bash. Locate the blocks that include the src/ tree, the
RAW EVIDENCE → ... flow, the grounded/unsupported ASCII diagram, the cd ~/verric
&& git pull && sudo docker compose up -d --build snippet, and the Studio
(page.tsx, client) box and add the appropriate language labels (`text` for
diagrams/trees and `bash` for the deploy command) so linting passes.
In `@src/app/page.tsx`:
- Around line 380-382: The confirmation guard builds hasWork but omits edited
project setup state, so add the project-dirty check to the same boolean used
before calling window.confirm. Update the hasWork computation (the const hasWork
that currently references artifacts, manualNotes, and hasReviewed) to also
include the project edit flag or comparison (e.g., projectDirty or projectEdited
or a diff between currentProject and initialProject) so that the if (hasWork &&
!window.confirm(...)) branch prevents starting a new report when project fields
have unsaved edits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d2e4e89f-42b5-4933-be34-7d6d192352ed
📒 Files selected for processing (10)
.dockerignoreDockerfiledeploy/verric.cyberkunju.com.confdocker-compose.ymldocs/01-VISION-AND-PRODUCT.mddocs/02-ARCHITECTURE-AND-ENGINE.mddocs/03-INNOVATIONS-AND-COMPETITIVE-EDGE.mddocs/README.mdnext.config.mjssrc/app/page.tsx
| environment: | ||
| NODE_ENV: production | ||
| # Sensible fallbacks if a value is absent from .env.local. | ||
| OPENAI_MODEL: ${OPENAI_MODEL:-gpt-4o-mini} | ||
| USE_MOCK_REPORT: ${USE_MOCK_REPORT:-false} |
There was a problem hiding this comment.
Environment section overrides env_file values.
The environment section takes precedence over env_file, and ${VAR:-default} substitutes from the host shell environment (not from .env.local). If a user sets OPENAI_MODEL=gpt-4o in .env.local but doesn't export it in their host shell, the container will receive gpt-4o-mini (the default), ignoring the .env.local value.
This contradicts the comment on line 11 ("Reuses your existing .env.local") and line 16 ("fallbacks if a value is absent from .env.local").
⚙️ Recommended fix: rely on env_file only
env_file:
- .env.local
environment:
NODE_ENV: production
- # Sensible fallbacks if a value is absent from .env.local.
- OPENAI_MODEL: ${OPENAI_MODEL:-gpt-4o-mini}
- USE_MOCK_REPORT: ${USE_MOCK_REPORT:-false}Then document the expected .env.local format with defaults in a comment or .env.local.example:
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-mini
USE_MOCK_REPORT=false
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| environment: | |
| NODE_ENV: production | |
| # Sensible fallbacks if a value is absent from .env.local. | |
| OPENAI_MODEL: ${OPENAI_MODEL:-gpt-4o-mini} | |
| USE_MOCK_REPORT: ${USE_MOCK_REPORT:-false} | |
| environment: | |
| NODE_ENV: production |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docker-compose.yml` around lines 14 - 18, The environment block currently
uses shell-style substitutions (OPENAI_MODEL: ${OPENAI_MODEL:-gpt-4o-mini},
USE_MOCK_REPORT: ${USE_MOCK_REPORT:-false}) which override values from env_file;
remove those substitutions from the docker-compose service's environment section
so it relies solely on env_file values (i.e., stop setting OPENAI_MODEL and
USE_MOCK_REPORT with ${...:-} in the compose file), and instead add or update a
.env.local.example documenting defaults (OPENAI_MODEL=gpt-4o-mini,
USE_MOCK_REPORT=false, OPENAI_API_KEY=...) so users know the expected variables
and defaults.
| ``` | ||
| 01-nmap-external-scan.txt # service enumeration | ||
| 02-burp-admin-unauthenticated-poc.http # /admin returns 200 without auth | ||
| 03-burp-idor-user-export-poc.http # IDOR on a user-export endpoint | ||
| 04-sqlmap-login-confirmed.txt # confirmed SQLi from sqlmap | ||
| 05-login-sqli-request-response.http # manual true/false request/response proof | ||
| 06-tester-notes.md # rough hypotheses and context | ||
| 07-admin-panel-screenshot.png # visual PoC | ||
| 08-idor-response-screenshot.png # visual PoC | ||
| 09-sqlmap-confirmed-screenshot.png # visual PoC | ||
| 10-api-export-response.json # raw API response | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced block to satisfy markdownlint (MD040).
The code fence starting at Line 115 is missing a language identifier. Add text to keep docs lint-clean.
Suggested patch
-```
+```text
01-nmap-external-scan.txt # service enumeration
02-burp-admin-unauthenticated-poc.http # /admin returns 200 without auth
...
10-api-export-response.json # raw API response
-```
+```📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ``` | |
| 01-nmap-external-scan.txt # service enumeration | |
| 02-burp-admin-unauthenticated-poc.http # /admin returns 200 without auth | |
| 03-burp-idor-user-export-poc.http # IDOR on a user-export endpoint | |
| 04-sqlmap-login-confirmed.txt # confirmed SQLi from sqlmap | |
| 05-login-sqli-request-response.http # manual true/false request/response proof | |
| 06-tester-notes.md # rough hypotheses and context | |
| 07-admin-panel-screenshot.png # visual PoC | |
| 08-idor-response-screenshot.png # visual PoC | |
| 09-sqlmap-confirmed-screenshot.png # visual PoC | |
| 10-api-export-response.json # raw API response | |
| ``` |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 115-115: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/01-VISION-AND-PRODUCT.md` around lines 115 - 126, The fenced code block
containing the numbered artifact list is missing a language identifier; update
that opening fence from ``` to ```text so the block becomes a text code fence
(i.e., add the language tag to the triple-backtick that precedes the list) to
satisfy markdownlint MD040 while leaving the list contents unchanged.
Source: Linters/SAST tools
| ``` | ||
| src/ | ||
| ├── app/ | ||
| │ ├── page.tsx # The 5-step studio (client component, all UI state) | ||
| │ ├── layout.tsx # Root layout, fonts (Cormorant Garamond, IBM Plex Sans/Mono) | ||
| │ ├── globals.css # Theme tokens | ||
| │ └── api/ | ||
| │ ├── generate-report/route.ts # LLM draft + validateReport + verifyGrounding (2nd pass) | ||
| │ ├── export-pdf/route.tsx # Multi-page React-PDF renderer | ||
| │ ├── export-docx/route.ts # docx renderer | ||
| │ └── export-txt/route.ts # Plain-text renderer | ||
| └── lib/ | ||
| └── report.ts # Types, CVSS engine, nmap parser, chunker, | ||
| # validateReport, deterministic mock report, | ||
| # renderPlainTextReport | ||
| demo-evidence-pack/ # Minimal demo artifacts | ||
| demo-complete-evidence-pack/ # 10 artifacts for the full demo flow | ||
| deploy/ | ||
| └── verric.cyberkunju.com.conf # nginx reverse-proxy vhost (production) | ||
| Dockerfile # Multi-stage, Next.js standalone output | ||
| docker-compose.yml # One-command deploy, runtime secrets, healthcheck | ||
| ``` |
There was a problem hiding this comment.
Fence language specifiers are missing on multiple blocks (MD040).
Several fenced blocks are missing language labels. Please add explicit identifiers (text for diagrams/maps, bash for the deploy command).
Suggested patch
-```
+```text
src/
...
docker-compose.yml # One-command deploy, runtime secrets, healthcheck
-```
+```
-```
+```text
RAW EVIDENCE → 1. INGEST → 2. CHUNK → 3. DRAFT (LLM) → 4. VALIDATE → 5. GROUND (LLM `#2`) → 6. SCORE → OUTPUT
-```
+```
-```
+```text
┌───────────────────────────── grounded (in polished body)
...
unsupported → flagged (⚠ "unsupported", pulled from body)
-```
+```
-```bash
+```bash
cd ~/verric && git pull && sudo docker compose up -d --build- +text
┌── Studio (page.tsx, client) ───────────────────────────────────────────────┐
...
└──────────────────────────────────────────────────────────────────────────────┘
- +
</details>
Also applies to: 144-146, 248-257, 340-342, 350-366
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>
[warning] 25-25: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @docs/02-ARCHITECTURE-AND-ENGINE.md around lines 25 - 46, Several fenced code
blocks in the ARCHITECTURE doc are missing language specifiers (MD040); update
each fenced block that contains ASCII diagrams, directory trees or plain text to
use text and the deploy command block to use bash. Locate the blocks that
include the src/ tree, the RAW EVIDENCE → ... flow, the grounded/unsupported
ASCII diagram, the cd ~/verric && git pull && sudo docker compose up -d --build
snippet, and the Studio (page.tsx, client) box and add the appropriate language
labels (text for diagrams/trees and bash for the deploy command) so linting
passes.
</details>
<!-- fingerprinting:phantom:triton:hawk -->
<!-- cr-comment:v1:7e91b2ca9eb960337949cf1e -->
_Source: Linters/SAST tools_
<!-- This is an auto-generated comment by CodeRabbit -->
| const hasWork = artifacts.length > 0 || manualNotes.trim().length > 0 || hasReviewed; | ||
| if (hasWork && !window.confirm("Start a new report? This clears the current brief, evidence, and draft.")) { | ||
| return; |
There was a problem hiding this comment.
Confirmation guard misses edited project brief state
Line 380 only checks artifacts/manual notes/review status. If the user edits project fields in setup, no confirmation is shown and Line 385 clears that work immediately. Include project-dirty state in hasWork so “New Report” consistently protects in-progress brief edits.
Suggested fix
function resetStudio() {
- const hasWork = artifacts.length > 0 || manualNotes.trim().length > 0 || hasReviewed;
+ const hasProjectChanges = JSON.stringify(project) !== JSON.stringify(emptyProjectDetails);
+ const hasWork = hasProjectChanges || artifacts.length > 0 || manualNotes.trim().length > 0 || hasReviewed;
if (hasWork && !window.confirm("Start a new report? This clears the current brief, evidence, and draft.")) {
return;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const hasWork = artifacts.length > 0 || manualNotes.trim().length > 0 || hasReviewed; | |
| if (hasWork && !window.confirm("Start a new report? This clears the current brief, evidence, and draft.")) { | |
| return; | |
| const hasProjectChanges = JSON.stringify(project) !== JSON.stringify(emptyProjectDetails); | |
| const hasWork = hasProjectChanges || artifacts.length > 0 || manualNotes.trim().length > 0 || hasReviewed; | |
| if (hasWork && !window.confirm("Start a new report? This clears the current brief, evidence, and draft.")) { | |
| return; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/app/page.tsx` around lines 380 - 382, The confirmation guard builds
hasWork but omits edited project setup state, so add the project-dirty check to
the same boolean used before calling window.confirm. Update the hasWork
computation (the const hasWork that currently references artifacts, manualNotes,
and hasReviewed) to also include the project edit flag or comparison (e.g.,
projectDirty or projectEdited or a diff between currentProject and
initialProject) so that the if (hasWork && !window.confirm(...)) branch prevents
starting a new report when project fields have unsaved edits.
Summary
Adds a
docs/folder with deep, detailed documentation of the whole project, grounded in the actual codebase.Documents
Notes
Summary by CodeRabbit
New Features
Documentation
Chores