Release diff: master → previous_release - #16
Closed
Th0rgal wants to merge 2 commits into
Closed
Conversation
- Add .claude/CLAUDE.md with project documentation - Add .claude/settings.json with tool permissions - Add secrets.json.example template for local development - Update .gitignore to exclude .claude/ and secrets.json
* Add .gitignore
* Add .gitignore
* Initial commit: Async Anticheat Dashboard
* Initial commit: Async Anticheat API
* Fix: RGBA conversion for hex colors, validate selected server exists, reset canvas transform on resize
- Added hexToRgba helper function to properly convert hex colors to rgba
(severityColors uses hex but alpha styling expected rgb format)
- Validate stored workspace ID exists in server list before using it
(prevents selecting deleted/missing servers)
- Reset canvas transform before scaling in resize handler
(prevents compounding scale on multiple window resizes)
* Add legacy modules, dashboard API routes
- Implement legacy module with 47 feature IDs (delays, movement, aimbot, autoclicker, hitbox, interact, misc)
- Implement legacy module with 100+ checks (combat, movement, player categories)
- Add dashboard API routes for stats, findings, players, modules
- Both modules feature buffer system, statistical analysis, VL tracking
- Modules connect to API callback endpoint for findings
* Add API client and connect dashboard to backend
- Add lib/api.ts with API client for dashboard
- Integrate findings, modules pages with real API
- Update layout to pass server context
- Fallback to mock data when API unavailable
* fix: multiple bug fixes for legacy modules and API
- Fix no-swing false positives before first swing seen
- Fix legacy buffer multiplier logic (remove .max(1.0))
- Fix hitbox check using wrong distance metric (offsets vs reach)
- Fix incorrect packet type parsing (BLOCK_PLACE vs USE_ITEM)
- Fix runtime config updates not affecting checks
- Fix speed ratio using wrong max speed variable
- Fix fall distance never accumulating (order of operations)
- Fix S3 path-style addressing for AWS (only use for custom endpoints)
- Fix orphaned S3 objects on DB failure (reorder operations)
- Fix ncp_fight_v1 seeding bogus zero positions
- Add dashboard status endpoint with real ping measurements
* Fix multiple website bugs
Dashboard page:
- Use stable uuid instead of array index for player IDs
- URL-encode player name in findings link query param
Findings page:
- Guard against stale fetch responses with fetchId ref
- Fix Unknown player selection/highlighting consistency
- Update lastSeen when processing findings (use most recent)
Modules page:
- Prevent toggle desync on rapid clicks with pendingToggles guard
Landing page:
- Add sandbox and referrerPolicy to third-party iframe
CSS:
- Fix light mode by adding html.light { color-scheme: light }
* Add env.example template and update .gitignore for .env.prod
* feat: real-time connection status and UI improvements
- Replace mock ping data with real API measurements
- Add Dashboard → API latency tracking
- Add API → Server TCP ping (port 25565)
- Add Plugin heartbeat status monitoring
- Improve connection status panel display
- Add getConnectionStatus endpoint to API client
* Fix misc rotation windows, legacy alert guard, and autoclicker out-of-order handling
- Fix rotation anomaly windows by using separate short/medium/long window starts
- Guard legacy buffer should_alert against interval=0 modulo panic
- Ignore negative click intervals and prevent timestamp regressions in autoclicker
- Keep existing modules behavior intact
* Add .env.example and update .gitignore for .env.prod
* Fix globe rendering and server selection bugs
- Fix UUID parsing for globe animation (use hashString instead of parseFloat)
- Use selected server ID from localStorage instead of hardcoded DEFAULT_SERVER_ID
- Apply to dashboard, findings, and modules pages
* fix(dashboard): support player filter for findings
* Fix server switching not refreshing page data
- Add ServerProvider context to share selectedServerId across dashboard pages
- Update DashboardPage, FindingsPage, ModulesPage to use useSelectedServer hook
- Add selectedServerId as useEffect dependency to trigger refetch on server change
* Fix dashboard stale data and module toggle bugs
- Add currentServerIdRef to guard against stale responses after server switch
- Fix state updates inside state updater (move setSelectedModule outside)
- Fix async toggle overwriting module selection using functional updates
- Fix search crash on missing player_name (use 'Unknown' fallback)
* Enable module processing for new servers
- Auto-create default server_modules rows (legacy + legacy) on first ingest
- Dispatch batches to module /process endpoint with JSON ProcessBatchRequest
by parsing gz NDJSON into module packet records
* Fix server switch race conditions and no-server loading states
- Guard modules fetch against out-of-order responses when switching servers
- Clear module selection on server change to avoid wrong-server detail panel
- Prevent dashboard/modules/findings loading from getting stuck when no server selected
- Keep dashboard state guarded against stale responses after server change
* feat: track active players per-server for dashboard globe
* Clarify Players metric on dashboard
* Fix dashboard server_id handling + log dashboard query errors
* fix(dashboard): prevent stale toggles and support player deeplinks
* Discover servers from API for dashboard selection
- Fetch /dashboard/servers on mount and merge into local server list
- Ensures real plugin server_id values are selectable in the sidebar
- Keeps local fallback when API is unavailable
* Reliability: speed up callbacks/findings + retry module callbacks
* feat: show active players as gray dots on globe
* fix(findings): sortable history + clear deep-link filter
* Findings: aggregate per-minute occurrences and update dashboard counts
* fix(dashboard): stable module stats + globe animation
* Enhance NCP module with NoSwing, Timer, FlyingFrequency, FastClick checks
* Dashboard: show active players even when there are no findings
* fix: bugs
* UI: show aggregated finding occurrences
* Implement server registration flow with token-based authentication
- Add handshake endpoint for initial server registration
- Implement SHA256 token hashing for secure authentication
- Add database columns for auth_token_hash, owner_user_id, registered_at
- Update ingest endpoint to check registration status
- Return 409 CONFLICT with waiting_for_registration status for unregistered servers
* feat: new features
* feat: login
* feat: auth
* fix: infer server ping address from forwarded IP
Best-effort capture of the connecting server IP into servers.callback_url so dashboard status can perform API→server ping.
* feat: integrate docs into website
Merge the landing page + dashboard with the documentation site.
Docs are now served via Nextra under /docs (with Pagefind indexing).
* refactor: reorganize detection modules by category
Replace legacy, legacy, and NCP modules with category-based architecture:
- Combat Module (port 4021): KillAura, Aim, AutoClicker, Reach, NoSwing
- Movement Module (port 4022): Flight, Speed, NoFall, Timer, Step, GroundSpoof, Velocity, NoSlow
- Player Module (port 4023): BadPackets, Scaffold, FastPlace, FastBreak, Interact, Inventory
This consolidates redundant checks while keeping different detection approaches
for improved accuracy. Each module focuses on a specific cheat category rather
than mimicking a specific anticheat implementation.
* fix: keep server token through login
Preserve the register-server token across auth redirects and improve connection status UI. Also simplify docs around install/linking flow.
* chore: add previous_release PR workflow
Keeps a moving previous_release branch at the pre-push SHA of master/main
and opens/maintains a PR from the default branch into previous_release.
* fix: code formatting
* fix: use PAT secret for PR creation in workflow
* chore: add previous_release PR workflow
Keeps a moving previous_release branch at the pre-push SHA of master/main
and opens/maintains a PR from the default branch into previous_release.
* lgtm
* fix: add workflows permission for pushing branches with workflow files
* fix: use PAT secret for PR creation in workflow
* fix: remove invalid 'workflows' permission from GitHub Actions
The 'workflows' key is not a valid permission in GitHub Actions.
* fix: add workflows permission for pushing branches with workflow files
* feat: improve style
* fix: push previous_release using PAT
Use PREVIOUS_RELEASE_PR_TOKEN for git pushes so updates that include .github/workflows/** are allowed.
* chore: allow manual runs for previous_release workflow
Add workflow_dispatch so the branch sync can be triggered manually.
* fix: remove invalid 'workflows' permission from GitHub Actions
The 'workflows' key is not a valid permission in GitHub Actions.
* fix: push previous_release using PAT
Use PREVIOUS_RELEASE_PR_TOKEN for git pushes so updates that include .github/workflows/** are allowed.
* wip: modules
* feat: migrate to category-based modules (Combat/Movement/Player)
- module_pipeline: dispatch gzipped NDJSON to /ingest (not /process)
- ingest: auto-migrate legacy legacy modules to new categories
- dashboard: best-effort migration on module list fetch
- heartbeat: new route for plugin heartbeat support
- e2e_local: update test script for category modules + DB seeding
Breaking: modules now receive raw gzipped NDJSON at /ingest endpoint
with X-Server-Id, X-Session-Id, X-Batch-Id, X-S3-Key headers.
* chore: allow manual runs for previous_release workflow
Add workflow_dispatch so the branch sync can be triggered manually.
* docs: update module names and API endpoints documentation
- Update FAQ on landing page to reference Combat/Movement/Player modules
- Fix API endpoints docs (/ingest headers, /callbacks/findings path)
- Update module creation guide with correct /ingest endpoint and session_id
- Update official modules list to category-based (Combat, Movement, Player)
* feat: test bugbot
* chore: trigger previous_release diff
* chore: trigger previous_release diff
* fix: make e2e_local.sh work without modules
If local detection modules are not present, the script now runs an ingest-only
smoke test by verifying batch ingestion instead of requiring findings.
* fix: pat token
* chore: update all logos and favicons with new async_logo
Replace all icon sizes (16px-512px), favicon.ico, apple-touch-icon,
and logo.png with the new pixel art logo upscaled using nearest neighbor.
* feat: header
* fix: grain overlay
* docs: update MODULES.md with tiered Core/Advanced architecture
Split detection modules into Pareto tiers:
- Core modules (ports 4021-4023): simple high-signal checks, 80% detection
- Advanced modules (ports 4024-4026): statistical analysis for subtle cheats
* feat: migrate to tiered Core/Advanced modules
- Update auto-registration to create 6 modules (Core + Advanced for each category)
- Delete old combined modules (Combat/Movement/Player Module)
- Update detector_like patterns for new module naming
* feat: refactor modules page for tiered Core/Advanced modules
- Remove store tab (feature deferred)
- Update module metadata for 6 tiered modules
- Add "Add Module" card with slide-out modal
- Add configuration modal for module settings
- Show tier badges (core/advanced) on cards
- Update mock modules to reflect new architecture
* fix: improve modules page UI
- Remove tier badges from cards and detail panel (just show name)
- Redesign Add Module modal with cleaner full-width list layout
- Show port numbers next to module names in selector
- Expand checks preview section with full description
* feat: add dashboard endpoint to create modules
POST /dashboard/:server_id/modules now creates/updates modules
without requiring ingest auth, enabling the dashboard UI to add modules.
* feat: wire up Add Module to create via API
- Add createModule method to API client
- Call API from handleAddModule instead of just logging
- Update local state on successful creation
* refactor: remove auto-migration from get_modules
Database modules are now managed via manual migration rather than
on-the-fly migration during GET requests. Also simplified detector_like
pattern generation.
* fix: remove NCP references from homepage
- Remove NCP-style Checks card
- Update slide to highlight two-tier system instead
- Link Open Source card to GitHub repo
* chore: remove GPL references
- Update FAQ to not mention specific license
- Update slides, README, and docs to reference LICENSE file
* fix: update LICENSE link to LICENSE.md
* fix: update default module ports
Align dashboard module defaults and mock data with the tiered module ports (4030-4035) so new registrations don’t suggest deprecated ports.
* fix: stop ingest from recreating legacy modules
Ingest previously auto-seeded deprecated combined module rows (Combat/Movement/Player Module), causing them to reappear in the dashboard. Seed tiered Core/Advanced defaults instead and delete legacy names during ingest.
* refactor: async ac
* feat: parse PLAYER_STATE packets and skip checks when context allows
- Add builtin_modules.rs as canonical registry for module metadata
- Update ingest.rs to use registry for auto-seeding
- Update dashboard.rs to expose builtin module info to frontend
- Add PlayerStatePacket parsing to movement modules
- Add PlayerContext to player state with exemption helpers
- Skip flight checks when player is swimming, climbing, gliding, etc.
- Add deploy scripts (gitignored) for easier deployment
Fixes false positives when swimming was flagged as flight.
* docs: update for Folia support and network setup
- Add Folia to platform support table
- Remove proxy-only installation instructions
- Add network setup section for BungeeCord/Velocity users
- Explain why to install on each backend server
* feat: add Players page and reporting capabilities
- Add new Players page with player cards showing Minecraft avatars, session history, and finding counts
- Add Report False Positive dialog to Findings page for flagging incorrect detections
- Add Report Undetected Cheat dialog to Players page for reporting missed cheating behavior
- Add reusable UI components (Dialog, Select, Textarea, Label)
- Fix cursor pointer on player cards
- Improve Plugin Status display to show human-readable relative time (e.g., "9m ago" instead of "9999 ms")
- Add Players link to sidebar navigation
* ci: add GitHub Action for release deployment
Triggers on GitHub release publish to deploy to Vercel production.
Also supports manual workflow dispatch for on-demand deployments.
* ci: remove deploy workflow (Vercel auto-deploys on push)
* docs: reorganize documentation for beta testers and developers
- Add Beta Testing Guide explaining current capabilities and limitations
- Add Reporting Issues guide for false positives and missed detections
- Add Dashboard Guide with pages for Players, Findings, Modules, Settings
- Add Puppeteer screenshot capture script for documentation images
- Reorganize nav structure with sections for Getting Started, Beta Testers, Reference, Developers
* feat: add auto-login to screenshot script
- Reads dev_user credentials from secrets.json
- Automatically fills email and requests magic link
- Falls back to manual login if needed
- Updates secrets.mdc to document shared dev_user pattern
* fix: improve auto-login to handle password field correctly
The login form auto-detects if user has password set - script now waits
for password field to appear and fills it in before submitting.
* docs: add dashboard screenshots to documentation
- Captured 8 screenshots of dashboard pages
- Added images to Dashboard Guide sections
- Players, Findings, Modules, Settings pages now have visuals
* fix: use relative links in documentation
Absolute links like /checks/movement were resolving outside the /docs
route. Changed to relative paths (./movement, ../checks) so links work
correctly within the docs section.
* chore: convert screenshots to WebP format (95% quality)
- Updated capture script to output WebP directly via sharp
- Changed output directory to public/docs
- Converted existing PNG screenshots to WebP (~70% smaller)
- Updated all MDX documentation references to .webp
* docs: replace em dashes with regular dashes
* feat: add report dialog screenshots to capture script
- Added findings-report-false-positive screenshot
- Added players-report-cheat screenshot
- These will populate the commented-out images in reporting.mdx
* docs: add report dialog screenshots
- Captured all 10 dashboard screenshots as WebP
- Uncommented image references in reporting.mdx and beta-testing.mdx
- Added findings-report-false-positive and players-report-cheat screenshots
* chore: increase screenshot quality to 98%
* docs: add direct download link for latest release
* fix: disable Next.js image optimization for static screenshots
The screenshots are already high-quality WebP files. Next.js Image
optimization was re-compressing them and degrading quality.
* docs: split installation into subpages
- Main installation page (plugin-focused, shorter)
- Network Setup subpage (BungeeCord/Velocity)
- Self-Hosted API subpage
* fix: exclude scripts folder from TypeScript build
The capture-screenshots.ts uses Bun-specific import.meta.dir which
is not compatible with Next.js TypeScript compilation.
* fix: build
* Update Discord link to discord.gg/2ng6q3JNQ7
* feat: add POST /observations endpoint for in-game recordings
- New observations.rs route for receiving cheat recordings
- Authenticates via server token (same as ingest)
- Validates server is registered before accepting
- Inserts into cheat_observations with source='ingame'
* docs: add packet format documentation and bump module version to 0.2.0
- Document the plugin packet format (pkt + fields structure)
- Add packet type mapping table for all supported packet names
- Modules now correctly parse:
- INTERACT_ENTITY (combat attacks)
- PLAYER_ROTATION (look only)
- PLAYER_POSITION_AND_ROTATION (position + look)
- PLAYER_BLOCK_PLACEMENT (block place)
- HELD_ITEM_CHANGE (slot change)
- And other plugin-sent packet names
This fixes detection issues where modules were looking for
legacy packet type names that the plugin doesn't send.
* docs: add in-game recording documentation
Document the /aac record command for staff to capture suspected cheaters:
- Command syntax and examples
- Cheat type options (killaura, aimbot, reach, etc.)
- How recording works under the hood
- Tips for effective recordings
- Required permissions
* docs: fix cheat types list in recording documentation
Corrected to match actual plugin CHEAT_TYPES:
- Added: xray, bhop, nofall, antiknockback
- Removed: nuker (not in plugin)
* schema: add false_positive_reports table
Stores user reports for findings flagged as false positives:
- finding_id, server_id (foreign keys)
- reporter_user_id (nullable)
- player_activity, suspected_cause, additional_context (text fields)
RLS policies allow authenticated users to insert and view own reports.
* wip: website
* chore: add Claude context and secrets configuration (#38)
- Add .claude/CLAUDE.md with project documentation (tech stack, structure, conventions)
- Add .claude/settings.json with tool permissions for Claude
- Copy relevant AsyncAnticheat secrets from ~/minecraft/secrets.json
- Update .gitignore to exclude secrets.json from version control
* fix: resolve 5 critical bugs in module management and webhook notifications (#15)
- Fix webhook occurrence count doubling: Initialize occurrences to 0 before incrementing to match correct aggregation pattern
- Fix DELETE removing custom modules by name: Add base_url filter to only delete localhost:402x modules, preserving user custom hosts
- Fix migration failing for existing servers: Expand legacy port cleanup to include 4021-4026 to migrate servers from old tiered modules
- Fix missing server_id validation: Add validation for empty server_id in create_module to match other write endpoints
- Fix hardcoded zero detections on upsert: Query actual detection count instead of returning 0 for module responses
* Th0rgal/claude context setup (#40)
* chore: add Claude context and secrets configuration
- Add .claude/CLAUDE.md with project documentation (tech stack, structure, conventions)
- Add .claude/settings.json with tool permissions for Claude
- Copy relevant AsyncAnticheat secrets from ~/minecraft/secrets.json
- Update .gitignore to exclude secrets.json from version control
* fix: use stable latest download URL for plugin JAR
Update download link to use /releases/latest/download/async-anticheat.jar
instead of hardcoded version, ensuring docs always point to latest release.
* feat: show clean pill for check
* Add module badge UI to findings display (#43)
* wip
* Remove redundant scope badge from detector display
The module badge already contains scope info (e.g., "Movement Core"),
making the separate scope badge redundant.
* Web client improvements: Phase 1 and Phase 2 (#45)
* feat: Add web client improvements - phase 1 and phase 2
Phase 1 - Quick wins:
- Add hamburger menu to landing page for mobile navigation
- Fix mobile docs sidebar visibility and layout
- Add loading skeleton screens to dashboard and findings
- Set up Playwright E2E test suite with multi-browser support
Phase 2 - PWA enhancements:
- Add comprehensive PWA manifest with shortcuts and maskable icons
- Implement service worker with network-first and cache-first strategies
- Add offline dashboard and findings caching via service worker
- Implement 'Add to Home Screen' install prompt with dismissal logic
- Add web push notification utilities and UI infrastructure
- Responsive PWA install/update/offline notice banners
Changes:
- app/page.tsx: Mobile hamburger menu with state management
- app/docs/docs.css: Mobile sidebar fixes with fixed positioning
- app/layout.tsx: PWA install banner integration
- components/ui/skeleton.tsx: Loading skeleton components
- components/pwa/install-banner.tsx: PWA UI with multiple states
- lib/use-pwa.ts: PWA state and action hooks
- lib/notifications.ts: Push notification utilities
- public/sw.js: Service worker with caching strategies
- public/manifest.json: Enhanced PWA manifest
- playwright.config.ts: E2E test configuration
- e2e/: Complete test suite for landing, auth, and docs pages
* fix: resolve TypeScript errors in notifications.ts
* fix: service worker returns proper Response on cache/network failures
* feat: show false positive reports in findings UI
* fix: vertically center module badges with player name in findings list
* fix: race condition in false positive fetch and event listener accumulation in PWA update
* fix: prevent service worker from pre-caching authenticated routes
Remove /dashboard from STATIC_ASSETS to prevent caching the login
redirect page at the /dashboard URL when user isn't authenticated.
Authenticated routes are now cached dynamically when accessed while
logged in.
* Remove yarn.lock, use bun exclusively (#47)
The project uses bun for package management. Removed yarn.lock to keep
lock files consistent and avoid duplication between bun.lock and yarn.lock.
* feat: add /aac token command for dashboard server linking
* refactor: move plugin code to plugin/ directory with renamed modules
* chore: remove duplicate .github from web/
* chore: remove duplicate .github from api/
* feat: add detection modules as git submodule
* chore: create unified configuration files (.gitignore, README, .claude/CLAUDE.md)
* chore: remove accidentally committed build artifacts
* chore: add root .gradle and build to gitignore
* ci: update GitHub workflow for monorepo plugin/ structure
* docs: add contribution workflow for monorepo and submodule
* fix: address Cursor Bugbot review comments
- Fix blocking HTTP on main thread: run updateToken() on executor
- Fix thread-unsafe access to backoff state: same fix, runs on executor
- Register heartbeat module in routes/mod.rs and main.rs
- Fix mtime fallback: use Utc::now() instead of UNIX_EPOCH so files
with unreadable mtime are kept (not deleted)
- Add playwright artifacts to .gitignore
* fix: address additional Bugbot review comments
- Handshake: validate token BEFORE updating last_seen_at to prevent
attackers from spoofing server online status with invalid tokens
- Spawn object store cleanup background task in main.rs (was dead code)
* fix: add missing cheat_observations table to schema
The /observations endpoint inserts into public.cheat_observations
but this table was not defined in schema.sql. Updated to match
the actual production schema with all columns and CHECK constraints.
Note: The table already exists in the live database via migration
20251223102345_create_unified_cheat_observations.
Reported by Cursor Bugbot.
* fix: reject bare IPv6 addresses in extract_host_port
Bare IPv6 addresses like 2001:db8::1 were incorrectly parsed by
splitting on ':', yielding host='2001' and failing port parse.
Now detects multiple colons without brackets and returns None,
forcing callers to use the documented bracketed form [::1]:port.
Reported by Cursor Bugbot.
* fix: validate auth token before updating last_seen_at in ingest
Same vulnerability as fixed in handshake.rs - an attacker could
spoof server online status by sending requests with invalid tokens
since last_seen_at was updated before token validation.
Now validates token FIRST, then updates timestamp only if valid.
Reported by Cursor Bugbot.
* fix: prevent panic on NaN/Infinity in movement transform
The movement_events_v1 transform used .unwrap() on from_f64() which
panics on NaN/Infinity. Malicious packets with invalid coordinates
or zero dt_ms (causing infinite speed) would crash the transform.
Fix:
- Skip packets with non-finite coordinates early
- Use existing json_f64() helper that safely falls back to 0
- Guard against division by zero in speed calculation
Reported by Cursor Bugbot.
* Add dashboard auth guard and CORS configuration
* docs: add Vercel environment sync instructions to CLAUDE.md
Document how to sync web/ environment variables from Vercel project
lfglabs/asyncanticheat.com for both development and production.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| return Err(ApiError::Unauthorized); | ||
| } | ||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
Case-sensitive Bearer token check breaks RFC 6750 compliance
The require_callback_auth function performs case-sensitive comparison (auth != expected) where expected is "Bearer {token}". This differs from all other auth functions in the codebase (like require_dashboard and parse_bearer_token) which use eq_ignore_ascii_case for the "Bearer" prefix. Per RFC 6750, the Bearer keyword must be case-insensitive. Modules sending bearer <token> (lowercase) will fail authentication at callback endpoints while succeeding at other endpoints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated PR. The 'previous_release' branch is force-updated on every push to master to point at the commit before the push, so this PR always represents the current release diff.
Note
Establishes a production-ready ingestion/service layer and monorepo scaffolding.
api/Rust service (Axum) with/ingest,/callbacks/findings, player-state get/set (single and batch),/handshake,/heartbeat, and/dashboard/*routes; includes module dispatch pipeline, health checks, and webhook notificationsapi/env.exampleapi/schema.sql) for servers, sessions, batches, modules, findings, and module stateapi/docs/*, NCP reference),MODULES.md, and local E2E scripts (api/scripts/*)README.md, add.claude/CLAUDE.md, expand.gitignore, add.gitmodules(modules submodule)plugin/and adjust artifact paths/namesWritten by Cursor Bugbot for commit 2a0c6a8. This will update automatically on new commits. Configure here.