feat(ci): add SLSA L1 npm provenance attestation (OWASP A03) - #133
Open
SabaTech-dev wants to merge 91 commits into
Open
feat(ci): add SLSA L1 npm provenance attestation (OWASP A03)#133SabaTech-dev wants to merge 91 commits into
SabaTech-dev wants to merge 91 commits into
Conversation
added 30 commits
March 23, 2026 19:57
…after upstream merge - 8 custom pages: actions, calendar, costs-alerts, handoffs, live, morning, notepad, workflows - 10 custom API routes: costs-alerts/config, costs-alerts/usage, debug, debug/secret, debug/validate, handoffs, live, morning/brief, morning/system, notepad - 9 AlfredMC components: ActivityRow, AgentRow, CronRow, Dock, MetricCard, SectionHeader, StatusBar, TopBar, index - 6 agent sprites: main, coder, debug, research, security, refactor-expert - 4 critical fixes reapplied: gateway scopes, sessions JSON filter, transcript regex, terminal validation - Systemd: fixed ExecStart (next start, not next dev), added EnvironmentFile - next.config: removed turbopack root override causing build failures
…tional data, secrets
- Fixed transcript route to correctly map session key → sessionId
- Now reads sessions.json to lookup sessionId from session key
- Uses correct path: /agents/main/sessions/{sessionId}.jsonl
- Added authentication using requireAuth from @/lib/auth-helpers
- Added comprehensive tests for auth and input validation
- Improved session key validation with stricter pattern
Closes: transcript-route-refactor
…ndpoints Phase 1 of systematic auth rollout (Option B). Protected endpoints: - /api/agents/config (HIGH risk - exposes agent config) - /api/agents/status (MEDIUM risk) - /api/agents/workload (MEDIUM risk) Using requireAuth() helper from auth-helpers.ts. Skipped: gateway/status, live, telemetry, models (read-only, low risk). Related: MC Security: Protect Unauthenticated Endpoints
- Add requireAuth mock returning authorized: true - Pass mock NextRequest to GET() handler
Fix TypeError: agent.model.split is not a function in dashboard.
agent.model can be {primary, fallbacks} object or string. Created
getModelDisplayName() helper in src/lib/model-utils.ts and applied
across 7 components: DashboardClient, AgentsClient, morning page,
AgentOrganigrama, AgentInspectPanel, AgentPanel, SystemInfo.
SECURITY: - Added middleware.ts to enforce authentication on all dashboard routes - Pages redirect to /login, API routes return 401 - Public routes: /login, /api/auth/*, /api/health, /api/heartbeat/tasks, /api/kanban/agent/*, /office, /reports/[token], static assets - Agent auth paths (/api/heartbeat/*, /api/kanban/agent/*) pass through to route-level auth BRANDING: - Replaced all 'Carlos' references → 'Joker' in workflows/page.tsx - Replaced 'Tenacitas' → 'Alfred' in workflows/page.tsx - Zero remaining references to Carlos, Tenacitas, SuperBotijo, or Botijo UI FIX: - About section avatar: replaced next/image fill with explicit width/height - Prevents image from rendering full-size in viewport
…api/auth/* - Simplified middleware: only /login and /api/auth/* are public - Added auth to /api/health endpoint (was exposing system info) - All 26 page routes → 307 redirect to /login - All 28 API routes → 401 without auth, 200 with auth - Verified: login works, protected access works, wrong password rejected
33 references across src/ replaced from original SuperBotijo author path to actual server path. Zero 'daniel' references remaining.
ICONS: - Regenerated all icon sizes (16-512px) from Alfred logo.png - logo-small.png, favicon-16x16/32x32/192x192, apple-touch-icon - android-chrome-192x192/512x512, icon-192/512 CHAT FIX: - checkGatewayStatus() now uses HTTP /health instead of WebSocket - WebSocket auth was failing with 'pairing required' after gateway restart - HTTP health check is lightweight and doesn't require device pairing - Chat is now writable (readOnly: false, gateway: available)
- SuperBotijo → Alfred Mission Control across 20 .md files - Carlos Azaustre/Tenacitas → Alfred/Joker - /home/daniel paths → /home/ubuntu - SUPERBOTIJO_* env vars → MISSION_CONTROL_* - Archived: FUNCIO.md, README_ADDITION.md, design-system/ - Attribution to original SuperBotijo project preserved in READMEs
- Fixed OPENCLAW_DIR default: /root/.openclaw → /home/ubuntu/.openclaw - Fixed DB path: auto-detect from script location - Renamed SUPERBOTIJO_DB → MISSION_CONTROL_DB - Added mtime-based delta: only processes modified files - Added batch SQL inserts for performance - Added 50MB file size limit to prevent timeout - System cron: every 5 minutes (sessions + messages, staggered 30s) - Result: 3907 activities synced (3346 messages + 210 sessions + 100 tasks + 3 commands)
- Remove 'server-only' import from pricing.ts (breaks CLI scripts) - Fix OPENCLAW_DIR default: /root/.openclaw → /home/ubuntu/.openclaw - Add missing aliases: glm-4.6v, xiaomi/mimo-v2-pro, free model variants - Cron: /etc/cron.d/alfred-mc-usage-collect (every 15 min) - Dashboard now shows real cost data: $1.61 today across 6 agents
1. Removed 'server-only' import from pricing.ts (blocked CLI execution) 2. Fixed OPENCLAW_DIR default: /root/.openclaw → /home/ubuntu/.openclaw 3. Fixed double provider prefix in getModelsFromOpenClawConfig() (openrouter/openrouter/xiaomi/mimo-v2-pro → openrouter/xiaomi/mimo-v2-pro) 4. getUsedModels() now includes agent fallbacks (not just primary) 5. Added legacy openrouter/minimax/minimax-m2.5 to pricing constants Cron: /etc/cron.d/alfred-mc-usage-collect (every 15 min) Result: $0.87 today, 13 snapshots, zero 'unknown model' warnings
…ring - Create PerformanceClient.tsx client component for performance dashboard - Add /api/performance endpoint to serve monitor results and baseline data - Include response time comparison, baseline variation, and log viewer - Fix build error (missing @/components/PerformanceClient import) - Performance monitor now connects successfully (all endpoints OK) - Add baseline results and monitor scripts from Phase 1
…provements - Alert system (alert-system.js): severity levels (INFO/WARN/CRITICAL), persistence to JSON, rolling window of 200 alerts, category filtering - Historical tracker (historical-tracker.js): rolling window of 2880 data points (~24h at 30s), trend analysis with degradation detection - Performance monitor v2: integrates alert + history, graceful Lighthouse skip after first failure (fixes noisy ERROR logs every 30s) - New API endpoints: /api/performance/alerts (with level/category filters), /api/performance/history (with trend summary per endpoint) - Dashboard overhaul: tabbed UI (Overview/Alerts/History), sparkline charts, trend stats (avg/min/max), alert feed with severity badges, temporal evolution table - 13 new tests for alert-system and historical-tracker (29 total perf tests) - Build: ✅ 615 passing (3 pre-existing failures for @testing-library/dom)
…ars, connection status - LiveStatusIndicator component: 3 animation modes (pulse/blink/wave), Web Animations API for smooth rendering, configurable size/speed - Live page overhaul: summary cards (sessions, tokens in/out, total), token proportion bars per session, connection indicator (Wifi icon), status transition flash animation, time-ago labels, poll counter - Fixed TopBar usage of LiveStatusIndicator in Alfred/ and AlfredMC/ - Build: ✅ passing
…ignore hardening - Added requireAuth() to /api/system/performance, /api/system/backups, /api/system/uptime - All 3 endpoints now return 401 without valid Bearer token or auth cookie - Added auth denial test (13/13 performance tests pass) - Removed /api/debug/secret and /api/debug/validate (exposed AUTH_SECRET prefix) - Added src/app/api/debug/ to .gitignore - Updated tests to mock auth-helpers
Task: MC-Tab /mission — Mission Statement Page (4cc7c19c) Created /mission route that assembles MissionCard + mission-storage: - page.tsx: Server component loads mission via getMission(), passes to client - actions.ts: Server actions for saveMissionAction + resetMissionAction with revalidatePath - MissionPageClient.tsx: Client component with full CRUD UI * View mode: renders MissionCard component (existing) * Edit mode: textarea for statement, tag-based goals/values with add/remove * Save/Reset actions via server actions * Auto-opens edit mode when no mission exists * Responsive (mobile-first, max-w-4xl container) * i18n support via useI18n hook * Confirmation dialog before reset * Loading states on save/reset No auth changes. No MissionCard rewrites. No new API routes. Build: clean (0 errors)
MC runs as systemd user service, so systemctl needs --user flag to discover and query services correctly. Without it, /logs tab was broken. Files changed: - src/app/api/system/monitor/route.ts — systemctl is-active --user - src/app/api/system/services/route.ts — list-units/list-unit-files --user - src/app/api/logs/stream/route.ts — list-units/list-unit-files --user - src/operations/service-discovery-ops.ts — list-units/list-unit-files --user - src/operations/system-monitor-ops.ts — systemctl is-active --user - src/lib/system-stats.ts — systemctl is-active --user - src/lib/terminal-command.ts — allow --user flag in systemctl whitelist - src/lib/system-stats.test.ts — update test mocks to match --user calls
Dashboard was loading in 7.2s because page.tsx awaited telemetry data
(blocking execFileSync calls) before SSR. Now:
- page.tsx passes initialTelemetry={null} — no blocking SSR
- DashboardClient shows loading skeleton while telemetry loads
- Telemetry fetches client-side via /api/telemetry/dashboard (already polling every 15s)
- SSR is now instant (no await)
Files changed:
- src/app/(dashboard)/page.tsx — removed getInitialTelemetry() await
- src/app/(dashboard)/DashboardClient.tsx — nullable initialTelemetry, loading skeleton
Skills tab was loading 1MB+ payload in SSR because all skills including fullContent were fetched server-side. Now: - page.tsx: no SSR data fetching, instant render - GET /api/skills: added ?page=&limit=&search=&source= params * Strips fullContent from listing (summary mode by default) * Supports server-side search and source filtering * Returns pagination metadata (page, limit, total, totalPages) - GET /api/skills/[id]: new endpoint for full skill details on-demand - SkillsClient.tsx: * Loads skills client-side with pagination (50 per page) * Debounced search (300ms) via server-side filtering * fullContent loaded on-demand when user clicks a skill * Pagination controls (Prev/Next with page indicator) * Loading skeleton while fetching * Loading indicator for skill detail modal Payload reduction: ~1MB+ → <50KB per page (estimated)
MC-Tab: /projects — Projects Dashboard Page (fdd150bb) Created /projects route that displays all projects with statistics: - page.tsx: Server Component loads projects via kanban-db, calculates progress - ProjectsClient.tsx: Client Component with full UI * Grid layout (responsive: 1/2/3 columns mobile/tablet/desktop) * Filters by status (all/active/completed/paused) * Shows project name, description, progress bar, task count * Status badges with color coding (active=accent, completed=success, paused=info) * Last updated timestamp * Loading state * Empty state when no projects match filter Uses existing /api/projects endpoint (no API changes). Build: clean
MC-Tab: /journal — Journal Operations Page (023bdef0) Created /journal route with full CRUD using existing components: - page.tsx: Server Component loads entries via kanban-db - JournalClient.tsx: Client Component with full UI * Ensambla JournalTimeline, JournalFilters, JournalEditorModal existentes * GET /api/journal con filtros startDate/endDate * POST /api/journal para crear entradas nuevas * PUT /api/journal/[id] para actualizar * DELETE /api/journal/[id] para eliminar * Botón "Nueva Entrada" abre modal * Editar/eliminar cada entrada (JournalEntryCard) * Filtros por rango de fechas con botón "Aplicar" * Responsive (mobile + tablet + desktop) Usa API existente sin modificaciones. Build: clean
MC-Tab: /activity — Activity Feed Page (326a2b5) Created /activity route with monitoring capabilities: - page.tsx: Server Component (empty - client-side rendering) - ActivityClient.tsx: Client Component * ActivityHeatmap (GitHub-style 30-day activity map) * Filtros por estado (todos/exitosos/errores/pendientes) * ActivityFeed con 50 actividades más recientes * Filtros reactivos - reload al cambiar filtro - Modified ActivityFeed.tsx: Añadidos props status + agent Usa API existente /api/activities con query params. Build: clean
MC-Tab: /calendar — Weekly Calendar Page (54ab3773) Created /calendar route with weekly task calendar: - page.tsx: Server Component con header + WeeklyCalendar existente - WeeklyCalendar.tsx ya existe (componente completo con navegación por semanas) * Navegación: semana anterior/siguiente/volver a hoy * Vista de 7 días x 24 horas (grid) * Filtra tareas de /api/tasks (cron + heartbeat + scheduled) * Muestra tareas como cards con iconos tipo/estado * Color-coding por estado (success=green, error=red, running=yellow, pending=gray) Usa API existente /api/tasks sin modificaciones. Build: clean
…questAnimationFrame
- SwarmClient.tsx: Complete UI with tasks table, agents sidebar, create modal - SwarmClient.tsx: Auto-refresh polling every 10s - SwarmClient.tsx: Status and agent filters - SwarmClient.tsx: Uses AMC proxy routes instead of direct Swarm API - API proxy: /api/swarm/tasks (GET/POST) and /api/swarm/tasks/[id] (GET/PATCH/DELETE) - API proxy: /api/swarm/health and /api/swarm/agents (already existed) - swarm-proxy.ts: Shared proxy utility with timeout and error handling - i18n: Added filter translations (EN/ES) - .env: Added SWARM_API_URL and SWARM_API_KEY configuration - Dock: /swarm tab already present in agents section - Build: Next.js build successful
- SwarmClient now uses credentials:include for browser session auth - All fetch calls use AMC proxy routes (/api/swarm/*) - Proxy verified working: health, tasks, agents all return 200 - Build successful
Lead scraper completo movido desde workspace/scripts/lead-scraper: - Normalizer: toLead() schema unificado - Scrapers: Malt + Workana con Cheerio (sin Playwright) - Scoring Engine: 0-100 con regex extraction - ICP Filter: threshold + keywords + skill/budget matching - Telegram Alerts: alerts configurables por score - Pipeline: processLead() integra score → filter → send → alert - MCP Server v0 + Dashboard + Monitoring - 60/60 tests PASS Co-authored-by: OpenCode
…n-Control repo - HIGH-001: Remove child_process import from mcp-server/index.js - MEDIUM-001: Remove AGENT_KEY hardcoded fallback in http-server.js + monitoring/index.js - LOW-001: Add source parameter validation (F-011) in http-server.js run_scraper endpoint All 3 files pass node --check syntax validation. Note: Previous fixes were applied to wrong repo (scripts/lead-scraper vs Alfred-Mission-Control/scrapers/lead-scraper)
Preserved changes from amc/ copy before cleanup: - 47 source files with uncommitted modifications - Includes: middleware, auth, JWT, auto-enforce, pipeline, tests - Created: 2026-06-02T12:07:23Z This commit ensures no work is lost during deduplication.
Workspace/ had local modifications that conflicted with amc/ merge. Preserving here to ensure clean merge from VPS migration copy.
Conflict resolution strategy: - Source code (src/, scripts/): accepted amc/ (more recent) - Build configs (package.json, next.config.mjs): accepted amc/ - Lock files: accepted amc/ - Local runtime files: kept workspace/ All changes from VPS migration now integrated into workspace/ copy.
- Create /actions page with ActionsClient component (quick actions: heartbeat, usage-stats, git-status, clear-temp, restart-gateway, npm-audit) - Create /api/cron-jobs/route.ts as re-export alias of /api/cron/route.ts - Add actions.title and actions.subtitle i18n keys (en + es) - All routes verified: /api/cron-jobs returns 401 (correct), /actions returns 307 redirect to login (correct) - Build passes: 0 errors
… expand REPORT_DIRS - Copy 39 cierre-del-dia, 7 evening-agenda, and 47 ai-social-digest reports from Alfred_Reports_Docs/ to reports/cron/ (VPS migration gap) - Expand REPORT_DIRS from 10 to 25 entries covering ALL cron directories - Add type mappings for all new subdirectories in getReportType() - Reports tabs now show historical data correctly
- Add /api/mission/route.ts for mission CRUD operations - Import and render MissionCard at top of HeartbeatStatus - Support optional mission prop (shows card when available) - Mission persists to data/mission.json Completes roadmap item 14.2: Mission card in HeartbeatStatus
- system-health page now fetches live data from /api/health every 30s - Grouped by category: Core, LLM, Services, Dev - Overall status bar with up/total count + uptime + last refresh - Added 9 missing services to stack-health checks: browserless, langfuse, qmd-mcp, llama.cpp-gpu/embed, searxng, engram, pr-agent, osint-nexus - Real-time auto-refresh + manual refresh button
canConnectTcpAny() tries 127.0.0.1 and 192.168.1.39. checkHttpService() falls back to alt IP. Fixes false DOWN for llama.cpp-gpu, llama.cpp-embed, searxng.
- Add mission category to suggestions types - Create suggestions-scoring-mission.ts with 4 analyzers: - Mission setup suggestion when no mission defined - Mission enrichment (goals/values) suggestions - Mission review suggestion after 30 days - Task alignment suggestion when <30% tasks linked to projects - Integrate mission analyzer into main suggestions engine - Add MissionStats interface to suggestions types Completes: 14.3 Integration Mission context en Suggestions Engine
…tbeat-ops through HeartbeatTab - Add mission field to HeartbeatStatus interface in heartbeat-ops - Import getMission in heartbeat-ops and include in returned data - Pass mission prop through HeartbeatTab to HeartbeatStatus component - Remove redundant getMission import from cron page - Roadmap item 14.2 deferred: Mission card en HeartbeatStatus → DONE
- Add floating name labels above each agent desk (emoji + name + role) - Update monitor lines to show identity (role, emoji) instead of generic status - Mark Office3D identity and Heartbeat identity roadmap items as complete - Build verified (next build exit 0)
- Add provenance.yml with attest-build-provenance for npm packages - Add verify-provenance.yml for PR verification - Add ci.yml with lint, test, build jobs - Implements SLSA L1 supply chain security requirement - NOTE: Requires NPM_TOKEN secret for npm publish with provenance
- PRs verify attestation exists on base branch commit - Prevents false negatives from merge commit SHAs - Verified with actionlint
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.
Qué
Por qué
OWASP 2025 A03: Supply Chain Failures requires verifiable provenance for npm packages. SLSA L1 ensures packages have signed provenance attestations.
Changes
Tests
Edge Cases