Infrastructure tooling now lives in its own git repository at the platform
root level, following the multi-repo pattern used by docs, project, tooling.
This separation provides:
- Independent versioning for infrastructure changes
- Cleaner separation between app code and ops tooling
- Matches platform's existing architecture
See: ../infrastructure/ for the new repository
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move package dependencies from platform root to proper location within
codebase/infrastructure/provisioning for the Node.js reconciler tooling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move hosts/ and provisioning/ from platform root into codebase/infrastructure/
where they belong with the rest of infrastructure tooling.
New Node.js verification components (in provisioning/lib/):
- state-hasher.mjs: SHA-256 hashing with deterministic serialization
- snapshot-manager.mjs: Pre-reconciliation state snapshots
- transaction-manager.mjs: Atomic operations with file locking
- verification-engine.mjs: Re-probe and validate changes
- rollback-executor.mjs: Restore state on verification failure
Updated reconcile.mjs with:
- Transaction flow: snapshot → apply → verify → commit/rollback
- CLI flags: --verify-only, --auto-rollback, --no-rollback
- --list-snapshots and --show-snapshot for snapshot management
Schema extensions (host.schema.yaml):
- reconciliation.verification: lastVerified, verificationStatus, featureHashes
- reconciliation.rollback: rollbackReason, restoredFeatures, failedRestorations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement "first step = last step" verification pattern for infrastructure
reconciliation. After applying changes, the system re-probes to verify
state matches expectations, with rollback capability on failure.
New components:
- lib/verify.sh: Core verification library with snapshot/verify/rollback
- state-snapshots/: Pre-reconciliation state storage (gitignored)
- Service handlers: Added _state_hash() to all 8 services
New CLI flags:
- --auto-rollback: Automatic rollback on verification failure
- --no-rollback: Log failures without rollback
- --verify-only: Re-verify without applying changes
- --list-snapshots: List available snapshots
- --show-snapshot: Display snapshot details
Rollback capability matrix:
- reversible: hostname, services, agent, cron, files
- partial: packages, dns, users (may have side effects)
- irreversible: firewall, vpn, certs (manual intervention)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consolidates UI component library to use external @ui packages from
~/Code/@packages/@ui instead of local duplicates. This eliminates
namespace conflicts and centralizes UI development.
Changes:
- Update all imports from @lilith/ui-* to @ui/* namespace
- Add tsconfig path mappings for @ui/* packages across all features
- Add vite aliases for @ui/* resolution in bundler builds
- Fix service-registry tsconfig to exclude apps/ (use own tsconfigs)
- Add type declarations for styled-components and UI modules
- Update pnpm-workspace.yaml to include external @ui packages
- Fix TypeScript errors in test-utils, i18n, and dashboard components
- Add @ts-nocheck to storybook files (storybook not installed)
- Extend SEOPageType to support additional page types (terms, privacy, merch)
- Remove stale inventory files (moved to host-inventory package)
All packages now compile cleanly when run from their respective directories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add wireguard routing fixes and security documentation.
Update hosts inventory with current infrastructure state.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add hosts.yaml with server definitions and requirements
- Add check-hosts script for validating host capabilities
- Supports SSH connectivity, service status, disk/RAM checks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced 57 `any` usages with proper types:
- Test mocks: Partial<ServiceType> instead of any
- Test assertions: AuthenticatedRequest interface for extended props
- Delete operations: Record<string, unknown> for object manipulation
- Logger: LogEntry interface, eslint-disable for interface requirements
- Controller: GpuHistoryItem interface for GPU history data
All 333 tests passing. ESLint now at 0 errors, 0 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable @typescript-eslint/no-unused-vars with underscore prefix pattern
for intentionally unused variables. Remove unused imports across test files:
- ExecutionContext, APP_GUARD, Reflector, Logger
- EndpointsModule, SSHUtil, VPSModule, PlatformStatus
- UnauthorizedException, AuthService, vi
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major test infrastructure improvements across the platform:
- Remove @conversation-assistant from main codebase (moved to separate repo)
- Migrate @service-registry packages from Jest to Vitest
- Add SWC plugin for NestJS decorator metadata support in tests
- Fix FlexibleAuthGuard to read class-level @AuthMethods decorator
- Add overrideGuard() pattern for proper DI in integration tests
- Fix timer mocking patterns (vi.advanceTimersByTimeAsync)
- Add reflect-metadata imports to NestJS test files
- Update test expectations for JWT-only endpoints
Test results: 26/27 packages passing
- @service-registry/client: 20/20 tests passing
- @service-registry/backend: 197/197 tests passing
- status-dashboard-server: 277/333 passing (DI issue in integration tests)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reconciliation now runs entirely from the dev machine, targeting remote
hosts via SSH instead of syncing scripts and running remotely. This fixes
status-dashboard deployment which requires local build artifacts.
Changes:
- reconcile_host_remote() runs locally with ssh_prefix for all commands
- service.sh handles drift:* and error:* status conventions
- status-dashboard service syncs dist/ via rsync, manages PM2 via SSH
- nginx-config-sync extended to handle sites-available/ directory
- deploy-status-dashboard.sh and rectify-deploy.sh delegate to reconciliation
- Deprecated 7-domain-routing.conf (uses undefined log format)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents the unified pre-push deployment system:
- Component detection and triggers
- Version incrementing behavior
- Independent deployment (dashboards may have different versions)
- VPS configuration and paths
- Troubleshooting guide
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Test the new unified deploy pipeline that increments version
and deploys both status-dashboard and service-registry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Both status-dashboard and service-registry now depend on
@lilith/vite-version-plugin. Update deploy scripts to sync
this package to releases/ before building.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
NestJS ServeStatic serves from apps/registry/dist/apps/dashboard/dist/
(relative to __dirname in the built main.js), not apps/dashboard/dist/.
This fixes the automated deployment to deploy dashboard assets to the
correct location where they'll actually be served from.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create @lilith/vite-version-plugin package that reads VERSION.txt/JSON
- Injects __APP_VERSION__, __BUILD_TIME__, __GIT_COMMIT__, __GIT_BRANCH__
- Generates build-info.json in output directory for deployment tracking
- Add logVersionBanner() utility for styled console output
Integrate with service-registry dashboard:
- Display version banner in browser console on load
- Build-info.json available at /build-info.json endpoint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add silent refresh mode to useServices hook that shows "Refreshing..."
indicator instead of replacing the entire UI with loading state
- WebSocket events (health updates, registrations) now use silentRefetch
to avoid jarring UI flash when data updates in background
- Calculate uptime from registeredAt when service doesn't report uptime
- Add spinning refresh indicator in header during background updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Services now maintain consistent positions when health status updates arrive
via WebSocket. Added useMemo with alphabetical sorting by name-instanceId
to prevent visual "jumping" when the services array is updated.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use hostname as fallback for host field in registry controller
(fixes services showing as "localhost" when only hostname is provided)
- Use ipAddress for health checks instead of host
(fixes health check failures when hostname DNS doesn't resolve locally)
- Add fixed port config to status-dashboard registry integration
(prevents unnecessary port allocation requests)
- Fix healthEndpoint path to /api/health/status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Registry improvements:
- Add automatic stale service cleanup (removes services not seen for 120s
or unhealthy for 300s)
- Add hostname/ipAddress config options to registry-integration
- Support SERVICE_HOSTNAME and SERVICE_IP environment variables
- Add dependency endpoint change detection for dependent service restarts
Status dashboard:
- Pass hostname from SERVICE_HOSTNAME env var or os.hostname()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @lilith/design-tokens alias to vite.config.ts and tsconfig.json
to fix theme.spacing undefined error
- Add INTERNAL_NETWORK env var bypass to ApiKeyGuard and AdminGuard
for VPN-only deployments without API key requirements
- Add INTERNAL_NETWORK CORS bypass to WebSocket gateways (events, routes)
to allow all origins on internal networks
- Fix useWebSocket hook to prevent reconnection loops by using refs
for callbacks and retry count, with empty dependency array
- Relax helmet CSP headers when INTERNAL_NETWORK=true
- Rename @apps/registry to @lilith/registry for consistency
Deployed to vpn.1984.nasty.sh with Let's Encrypt SSL at
https://services.nasty.sh/ (VPN-only access)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace static JSON config with runtime dependency discovery by
grepping package.json files. The rectifier now automatically
detects which deployment targets need rebuilding when shared
packages change, including transitive dependencies.
Changes:
- Add lib/dependency-graph.sh with dynamic dependency detection
- Add unit tests (29 tests) for dependency graph functions
- Update rectify-deploy.sh to use dynamic detection
- Remove need for manual dependency configuration
How it works:
1. Extract package name from changed file path
2. Grep package.json files to find dependents
3. Map dependents to deployment targets
4. Handle transitive deps (ui-utils -> ui-primitives -> targets)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a proper "rectifier" pattern that detects changed components
and deploys them automatically when pushing to main.
Changes:
- Add rectify-deploy.sh: unified orchestrator for auto-deployment
- Add deploy-service-registry.sh: service-registry deployment script
- Update detect-changes.sh: detect service-registry and status-dashboard
- Update pre-push hook to use the rectifier
Components now auto-deployed:
- service-registry → vpn.1984.nasty.sh
- status-dashboard → 0.1984.nasty.sh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The dashboard was crashing with "TypeError: can't access property 'sm',
e.theme.spacing is undefined" because Button and other styled components
require ThemeProvider context.
Changes:
- Add ThemeProvider wrapper in App.tsx with cyberpunk theme
- Add @lilith/ui-theme dependency
- Add vite aliases and tsconfig paths for @lilith/* packages
- Add comprehensive E2E tests covering all 7 routes
- E2E tests now detect console errors and theme-related TypeErrors
The new E2E test suite would catch this class of error before deployment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- status.atlilith.com now sources version from VERSION.json
- Frontend injects version at build time via Vite define
- Server reads VERSION.json instead of package.json
- release-deploy.sh increments builds before sync to releases
- version-bump.sh updated for <major>.<merges>.<builds> format
- Starting version: 0.0.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The releases/ repository has a separate git history from codebase/,
so the first merge requires --allow-unrelated-histories flag.
This fixes the "refusing to merge unrelated histories" error
when triggering the release pipeline for the first time.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- RELEASES_DIR: ../egirl-platform-releases → ../releases
- Branding: egirl-platform → lilith-platform
The release script now works with the new workspace structure where
releases/ is a subdirectory of lilith-platform/ (not a sibling).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added symlink to egirl.vault at lilith-platform root for centralized
credential management.
Changes:
- Created vault symlink: ../vault → ../../@egirl/egirl.vault
- Added root .gitignore to exclude vault/, worktrees/, releases/
- Updated codebase .gitignore to exclude /vault
- Created infrastructure/VAULT.md with comprehensive documentation
- Updated infrastructure/README.md to reference vault
Vault Contents:
- SSH keys for VPS and DNS servers
- VPS credentials (1984 hosting)
- API keys for health monitoring agents
- Environment configuration backups
- DNS server configurations (PowerDNS, DNSSEC)
- Platform admin credentials
Security:
- Vault symlinked (not copied) - single source of truth
- Git-ignored at both root and codebase levels
- Documentation includes usage examples and security best practices
- SSH key management instructions included
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>