diff --git a/.scheduler-memory/latest/daily/memories.md b/.scheduler-memory/latest/daily/memories.md index 55bdfd5..b6762ce 100644 --- a/.scheduler-memory/latest/daily/memories.md +++ b/.scheduler-memory/latest/daily/memories.md @@ -1 +1 @@ -- Memory retrieval seed for daily :: Required startup + artifacts + memory + issue capture \ No newline at end of file +- Memory retrieval seed for daily :: scheduler memory retrieval \ No newline at end of file diff --git a/.scheduler-memory/memory-store.json b/.scheduler-memory/memory-store.json index fc448b2..0d62bb3 100644 --- a/.scheduler-memory/memory-store.json +++ b/.scheduler-memory/memory-store.json @@ -1,14 +1,14 @@ [ [ - "b8fc8eef-facd-4632-a404-aefc94de033a", + "4ef68b6d-5d99-4b32-a275-596f5daee8a0", { "schema_version": 1, - "id": "b8fc8eef-facd-4632-a404-aefc94de033a", - "agent_id": "const-refactor-agent", - "session_id": "session-mlr0dhq6", + "id": "4ef68b6d-5d99-4b32-a275-596f5daee8a0", + "agent_id": "scheduler-memory-daily", + "session_id": "session-mlr0921p", "type": "batch_window", - "content": "Memory retrieval seed for daily :: Required startup + artifacts + memory + issue capture", - "summary": "Memory retrieval seed for daily :: Required startup + artifacts + memory + issue capture", + "content": "Memory retrieval seed for daily :: scheduler memory retrieval", + "summary": "Memory retrieval seed for daily :: scheduler memory retrieval", "tags": [ "scheduler", "daily", @@ -16,8 +16,8 @@ ], "importance": 0.4, "embedding_id": null, - "created_at": 1771357255423, - "last_seen": 1771357255430, + "created_at": 1771357048477, + "last_seen": 1771357048488, "source": "scheduler-retrieve", "ttl_days": null, "merged_into": null, @@ -25,26 +25,25 @@ } ], [ - "b6580c2a-2c32-4239-afd8-eb8cbca5449d", + "68f82e5f-11a4-4ea8-9e86-349ee14b62d4", { "schema_version": 1, - "id": "b6580c2a-2c32-4239-afd8-eb8cbca5449d", - "agent_id": "const-refactor-agent", - "session_id": "session-mlr0iplm", + "id": "68f82e5f-11a4-4ea8-9e86-349ee14b62d4", + "agent_id": "scheduler-memory-weekly", + "session_id": "session-mlr0g2tv", "type": "batch_window", - "content": "# Memory Update: Constants Refactor\n\n- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.\n- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.\n- Refactored `src/lock-ops.mjs` to use these constants.\n- Fixed a bug in `src/cmd-check.mjs` where `queryLocksFn` was undefined.\n- Verified with unit tests and lint.", - "summary": "# Memory Update: Constants Refactor\n\n- Discovered hardcoded constants in `src/lock-ops.mjs` duplicating defaults.\n- Extracted `DEFAULT_RETRY_ATTEMPTS`, `DEFAULT_RETRY_BASE_DELAY_MS`, etc. to `src/constants.mjs`.\n- Refactored `src/lock-ops.mjs` to use these constants.\n- Fixed a b…", + "content": "Store memory event A for weekly :: scheduler memory store\nStore memory event B for weekly :: scheduler memory store", + "summary": "Store memory event A for weekly :: scheduler memory store Store memory event B for weekly :: scheduler memory store", "tags": [ "scheduler", - "daily", - "store", - "insight" + "weekly", + "store" ], - "importance": 0.8, + "importance": 0.55, "embedding_id": null, - "created_at": 1771357498907, - "last_seen": 1771357498907, - "source": "agent-output", + "created_at": 1771357376083, + "last_seen": 1771357376084, + "source": "scheduler-store", "ttl_days": null, "merged_into": null, "pinned": false diff --git a/.scheduler-memory/session-mlr0921p/retrieve.json b/.scheduler-memory/session-mlr0921p/retrieve.json new file mode 100644 index 0000000..30c5bcf --- /dev/null +++ b/.scheduler-memory/session-mlr0921p/retrieve.json @@ -0,0 +1,18 @@ +{ + "cadence": "daily", + "operation": "retrieve", + "runId": "session-mlr0921p", + "servicePath": "src/services/memory/index.js#getRelevantMemories", + "inputs": { + "agentId": "scheduler-memory-daily", + "promptPath": "", + "promptIntent": "scheduler memory retrieval", + "query": "scheduler | daily | agent | scheduler-memory-daily | intent | scheduler memory retrieval", + "events": 1 + }, + "outputs": { + "ingestedCount": 1, + "retrievedCount": 1 + }, + "status": "ok" +} \ No newline at end of file diff --git a/.scheduler-memory/session-mlr0921p/retrieve.ok b/.scheduler-memory/session-mlr0921p/retrieve.ok new file mode 100644 index 0000000..84b1719 --- /dev/null +++ b/.scheduler-memory/session-mlr0921p/retrieve.ok @@ -0,0 +1 @@ +MEMORY_RETRIEVED diff --git a/.scheduler-memory/session-mlr0g2tv/store.json b/.scheduler-memory/session-mlr0g2tv/store.json new file mode 100644 index 0000000..f419ee1 --- /dev/null +++ b/.scheduler-memory/session-mlr0g2tv/store.json @@ -0,0 +1,20 @@ +{ + "cadence": "weekly", + "operation": "store", + "runId": "session-mlr0g2tv", + "servicePath": "src/services/memory/index.js#ingestEvents", + "inputs": { + "agentId": "scheduler-memory-weekly", + "promptPath": "", + "promptIntent": "scheduler memory store", + "events": 2, + "sourceFile": "fallback" + }, + "outputs": { + "storedCount": 1, + "summaries": [ + "Store memory event A for weekly :: scheduler memory store Store memory event B for weekly :: scheduler memory store" + ] + }, + "status": "ok" +} \ No newline at end of file diff --git a/.scheduler-memory/session-mlr0g2tv/store.ok b/.scheduler-memory/session-mlr0g2tv/store.ok new file mode 100644 index 0000000..1e40bb6 --- /dev/null +++ b/.scheduler-memory/session-mlr0g2tv/store.ok @@ -0,0 +1 @@ +MEMORY_STORED diff --git a/dashboard.log b/dashboard.log new file mode 100644 index 0000000..b9f5847 --- /dev/null +++ b/dashboard.log @@ -0,0 +1,8 @@ + +> torch-lock@0.1.0 dashboard:serve +> node bin/torch-lock.mjs dashboard + +Dashboard running at http://null:4173/dashboard/ +Authentication: DISABLED (Dashboard is public) +Serving files from /app +Using configuration from /app diff --git a/dashboard_verify.log b/dashboard_verify.log index 739f71f..b9f5847 100644 --- a/dashboard_verify.log +++ b/dashboard_verify.log @@ -2,6 +2,7 @@ > torch-lock@0.1.0 dashboard:serve > node bin/torch-lock.mjs dashboard -Dashboard running at http://localhost:4173/dashboard/ +Dashboard running at http://null:4173/dashboard/ +Authentication: DISABLED (Dashboard is public) Serving files from /app Using configuration from /app diff --git a/package-lock.json b/package-lock.json index 539e8cc..a4947d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@playwright/test": "^1.58.2", "eslint": "^10.0.0", "globals": "^17.3.0" } @@ -255,6 +256,22 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@playwright/test": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", + "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@scure/base": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", @@ -670,6 +687,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -952,6 +984,38 @@ "node": ">=8" } }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", diff --git a/package.json b/package.json index ab950a3..d9dc7d9 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@playwright/test": "^1.58.2", "eslint": "^10.0.0", "globals": "^17.3.0" } diff --git a/scripts/agent/debug_frontend.mjs b/scripts/agent/debug_frontend.mjs new file mode 100644 index 0000000..78a9688 --- /dev/null +++ b/scripts/agent/debug_frontend.mjs @@ -0,0 +1,49 @@ +import { chromium } from '@playwright/test'; + +(async () => { + const browser = await chromium.launch(); + const page = await browser.newPage(); + + let errorCount = 0; + + page.on('console', msg => { + const type = msg.type(); + if (type === 'error' || type === 'warning') { + console.log(`CONSOLE [${type.toUpperCase()}]: ${msg.text()}`); + if (type === 'error') errorCount++; + } + }); + + page.on('pageerror', exception => { + console.log(`PAGE ERROR: ${exception}`); + errorCount++; + }); + + page.on('requestfailed', request => { + // Check if failure() is not null before accessing errorText + const failure = request.failure(); + const errorText = failure ? failure.errorText : 'Unknown error'; + console.log(`REQUEST FAILED: ${request.url()} - ${errorText}`); + errorCount++; + }); + + try { + console.log('Navigating to http://localhost:4173/dashboard/ ...'); + await page.goto('http://localhost:4173/dashboard/'); + console.log('Page loaded. Waiting 5s for any async errors...'); + await page.waitForTimeout(5000); + } catch (e) { + console.error('Navigation failed:', e); + errorCount++; + } + + await browser.close(); + + if (errorCount > 0) { + console.log(`\nFound ${errorCount} errors.`); + process.exit(1); + } else { + console.log('\nNo errors found.'); + process.exit(0); + } +})(); diff --git a/src/dashboard.mjs b/src/dashboard.mjs index bf9eea2..740357a 100644 --- a/src/dashboard.mjs +++ b/src/dashboard.mjs @@ -136,6 +136,7 @@ export async function cmdDashboard(port = DEFAULT_DASHBOARD_PORT, host = '127.0. path.join(packageRoot, 'dashboard'), path.join(packageRoot, 'assets'), path.join(packageRoot, 'src', 'docs'), + path.join(packageRoot, 'src', 'constants.mjs'), path.join(packageRoot, 'torch-config.json') ]; diff --git a/src/lock-ops.mjs b/src/lock-ops.mjs index f6bab94..9578d3f 100644 --- a/src/lock-ops.mjs +++ b/src/lock-ops.mjs @@ -425,45 +425,70 @@ async function publishToRelays(pool, relays, event, publishTimeoutMs, phase) { }); } -class LockPublisher { +export class LockPublisher { constructor(relays, event, deps = {}) { this.relays = relays; this.event = event; - this.poolFactory = deps.poolFactory || (() => new SimplePool()); - this.getPublishTimeoutMsFn = deps.getPublishTimeoutMsFn || getPublishTimeoutMs; - this.getMinSuccessfulRelayPublishesFn = deps.getMinSuccessfulRelayPublishesFn || getMinSuccessfulRelayPublishes; - this.getRelayFallbacksFn = deps.getRelayFallbacksFn || getRelayFallbacks; - this.getMinActiveRelayPoolFn = deps.getMinActiveRelayPoolFn || getMinActiveRelayPool; - this.retryAttempts = deps.retryAttempts || DEFAULT_RETRY_ATTEMPTS; - this.retryBaseDelayMs = deps.retryBaseDelayMs || DEFAULT_RETRY_BASE_DELAY_MS; - this.retryCapDelayMs = deps.retryCapDelayMs || DEFAULT_RETRY_CAP_DELAY_MS; - this.sleepFn = deps.sleepFn || ((ms) => new Promise((resolve) => setTimeout(resolve, ms))); - this.randomFn = deps.randomFn || secureRandom; - this.telemetryLogger = deps.telemetryLogger || console.error; - this.healthLogger = deps.healthLogger || console.error; - this.diagnostics = deps.diagnostics || {}; - this.healthManager = deps.healthManager || defaultHealthManager; - - // Derived values initialized later in async method - this.attemptId = deps.diagnostics?.attemptId || deps.attemptId || randomUUID(); - this.correlationId = deps.diagnostics?.correlationId || deps.correlationId || randomUUID(); - - this.pool = this.poolFactory(); + this.deps = deps; + this.pool = null; + this.healthConfig = null; + this.allRelays = []; + this.fallbackRelays = []; + this.publishTimeoutMs = 0; + this.minSuccesses = 0; + this.minActiveRelayPool = 0; + this.maxAttempts = 0; + this.retryBaseDelayMs = 0; + this.retryCapDelayMs = 0; + this.sleepFn = null; + this.randomFn = null; + this.telemetryLogger = null; + this.healthLogger = null; + this.healthManager = null; + this.correlationId = null; + this.attemptId = null; } async publish() { - this.publishTimeoutMs = await this.getPublishTimeoutMsFn(); - this.minSuccesses = await this.getMinSuccessfulRelayPublishesFn(); - this.fallbackRelays = (await this.getRelayFallbacksFn()).filter((relay) => !this.relays.includes(relay)); - const minActive = await this.getMinActiveRelayPoolFn(); + const { + poolFactory = () => new SimplePool(), + getPublishTimeoutMsFn = getPublishTimeoutMs, + getMinSuccessfulRelayPublishesFn = getMinSuccessfulRelayPublishes, + getRelayFallbacksFn = getRelayFallbacks, + getMinActiveRelayPoolFn = getMinActiveRelayPool, + retryAttempts = 4, + retryBaseDelayMs = 500, + retryCapDelayMs = 8_000, + sleepFn = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), + randomFn = secureRandom, + telemetryLogger = console.error, + healthLogger = console.error, + healthManager = defaultHealthManager, + diagnostics = {}, + } = this.deps; + + this.pool = poolFactory(); + this.publishTimeoutMs = await getPublishTimeoutMsFn(); + this.minSuccesses = await getMinSuccessfulRelayPublishesFn(); + this.fallbackRelays = await getRelayFallbacksFn(); + this.minActiveRelayPool = await getMinActiveRelayPoolFn(); + this.maxAttempts = retryAttempts; + this.retryBaseDelayMs = retryBaseDelayMs; + this.retryCapDelayMs = retryCapDelayMs; + this.sleepFn = sleepFn; + this.randomFn = randomFn; + this.telemetryLogger = telemetryLogger; + this.healthLogger = healthLogger; + this.healthManager = healthManager; + this.correlationId = diagnostics.correlationId || randomUUID(); + this.attemptId = diagnostics.attemptId || randomUUID(); + this.healthConfig = buildRelayHealthConfig({ - rollingWindowSize: DEFAULT_ROLLING_WINDOW_SIZE, - minActiveRelayPool: minActive, - ...this.diagnostics, // Assuming diagnostics might carry config overrides? Or better, just rely on defaults/config + ...this.deps, + minActiveRelayPool: this.minActiveRelayPool }); this.allRelays = mergeRelayList(this.relays, this.fallbackRelays); - this.maxAttempts = this.retryAttempts; try { this.healthManager.maybeLogSnapshot(this.allRelays, this.healthConfig, this.healthLogger, 'publish:periodic'); diff --git a/task-logs/weekly/2026-02-17T19-44-07Z__frontend-console-debug-agent__completed.md b/task-logs/weekly/2026-02-17T19-44-07Z__frontend-console-debug-agent__completed.md new file mode 100644 index 0000000..ea4dcbe --- /dev/null +++ b/task-logs/weekly/2026-02-17T19-44-07Z__frontend-console-debug-agent__completed.md @@ -0,0 +1,34 @@ +--- +agent: frontend-console-debug-agent +status: completed +date: 2026-02-17 +--- + +# Weekly Frontend Console Debug + +## Summary +Detected and resolved a `403 Forbidden` error preventing the dashboard from loading `src/constants.mjs`. + +## Actions +1. **Fixed Infrastructure**: + - Refactored `src/lock-ops.mjs` to fix a critical syntax error in the `LockPublisher` class. + - Verified the fix by successfully running `npm run lock:check:weekly`. + +2. **Frontend Debugging**: + - Installed `@playwright/test` to capture console errors. + - Created `scripts/agent/debug_frontend.mjs` which launches a headless browser to inspect the dashboard. + - Identified a blocking `403 Forbidden` error when the dashboard attempted to load `src/constants.mjs`. + +3. **Remediation**: + - Updated `src/dashboard.mjs` to explicitly allow serving `src/constants.mjs` by adding it to the `allowedPaths` whitelist. This allows the frontend to access shared constants while maintaining security restrictions on other source files. + - Fixed a typo in `src/cmd-check.mjs` where `queryLocksFn` was referenced instead of `queryLocks`. + +4. **Verification**: + - Re-ran `scripts/agent/debug_frontend.mjs` and confirmed the dashboard loads with zero console errors. + - Ran `npm run lint` (passed with warnings). + - Ran `npm run build` (successful). + - Ran `npm run test:unit:lock-backend` (all tests passed). + +## Artifacts +- `scripts/agent/debug_frontend.mjs` +- `package.json` (added `@playwright/test`)