fix: harden dashboard canary and IOC coverage

This commit is contained in:
Affaan Mustafa
2026-05-15 02:06:46 -04:00
parent 4546a2c144
commit 9af04f3965
5 changed files with 264 additions and 6 deletions

View File

@@ -902,8 +902,16 @@ Project: github.com/affaan-m/everything-claude-code"""
widget.configure(background=bg_color)
except Exception:
logger.debug("Cannot set background on %s", widget.__class__.__name__, exc_info=True)
for child in widget.winfo_children():
update_widget_colors(child)
try:
children = widget.winfo_children()
except Exception:
logger.debug("Cannot list child widgets on %s", widget.__class__.__name__, exc_info=True)
return
for child in children:
try:
update_widget_colors(child)
except Exception:
logger.debug("Cannot update child widget colors on %s", child.__class__.__name__, exc_info=True)
update_widget_colors(self)

View File

@@ -11,10 +11,78 @@ const path = require('path');
const DEFAULT_ROOT = path.resolve(__dirname, '../..');
const MALICIOUS_PACKAGE_VERSIONS = {
'@mistralai/mistralai': ['2.2.3', '2.2.4'],
'@mistralai/mistralai-azure': ['1.7.2', '1.7.3'],
'@mistralai/mistralai-gcp': ['1.7.2', '1.7.3'],
'@opensearch-project/opensearch': ['3.6.2', '3.8.0'],
'@beproduct/nestjs-auth': [
'0.1.2',
'0.1.3',
'0.1.4',
'0.1.5',
'0.1.6',
'0.1.7',
'0.1.8',
'0.1.9',
'0.1.10',
'0.1.11',
'0.1.12',
'0.1.13',
'0.1.14',
'0.1.15',
'0.1.16',
'0.1.17',
'0.1.18',
'0.1.19',
],
'@cap-js/db-service': ['2.10.1'],
'@cap-js/postgres': ['2.2.2'],
'@cap-js/sqlite': ['2.2.2'],
'@dirigible-ai/sdk': ['0.6.2', '0.6.3'],
'@draftauth/client': ['0.2.1', '0.2.2'],
'@draftauth/core': ['0.13.1', '0.13.2'],
'@draftlab/auth': ['0.24.1', '0.24.2'],
'@draftlab/auth-router': ['0.5.1', '0.5.2'],
'@draftlab/db': ['0.16.1', '0.16.2'],
'@mesadev/rest': ['0.28.3'],
'@mesadev/saguaro': ['0.4.22'],
'@mesadev/sdk': ['0.28.3'],
'@ml-toolkit-ts/preprocessing': ['1.0.2', '1.0.3'],
'@ml-toolkit-ts/xgboost': ['1.0.3', '1.0.4'],
'@mistralai/mistralai': ['2.2.2', '2.2.3', '2.2.4'],
'@mistralai/mistralai-azure': ['1.7.1', '1.7.2', '1.7.3'],
'@mistralai/mistralai-gcp': ['1.7.1', '1.7.2', '1.7.3'],
'@opensearch-project/opensearch': ['3.5.3', '3.6.2', '3.7.0', '3.8.0'],
'@squawk/airport-data': ['0.7.4', '0.7.5', '0.7.6', '0.7.7', '0.7.8'],
'@squawk/airports': ['0.6.2', '0.6.3', '0.6.4', '0.6.5', '0.6.6'],
'@squawk/airspace': ['0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5'],
'@squawk/airspace-data': ['0.5.3', '0.5.4', '0.5.5', '0.5.6', '0.5.7'],
'@squawk/airway-data': ['0.5.4', '0.5.5', '0.5.6', '0.5.7', '0.5.8'],
'@squawk/airways': ['0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6'],
'@squawk/fix-data': ['0.6.4', '0.6.5', '0.6.6', '0.6.7', '0.6.8'],
'@squawk/fixes': ['0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6'],
'@squawk/flight-math': ['0.5.4', '0.5.5', '0.5.6', '0.5.7', '0.5.8'],
'@squawk/flightplan': ['0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6'],
'@squawk/geo': ['0.4.4', '0.4.5', '0.4.6', '0.4.7', '0.4.8'],
'@squawk/icao-registry': ['0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6'],
'@squawk/icao-registry-data': ['0.8.4', '0.8.5', '0.8.6', '0.8.7', '0.8.8'],
'@squawk/mcp': ['0.9.1', '0.9.2', '0.9.3', '0.9.4', '0.9.5'],
'@squawk/navaid-data': ['0.6.4', '0.6.5', '0.6.6', '0.6.7', '0.6.8'],
'@squawk/navaids': ['0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6'],
'@squawk/notams': ['0.3.6', '0.3.7', '0.3.8', '0.3.9', '0.3.10'],
'@squawk/procedure-data': ['0.7.3', '0.7.4', '0.7.5', '0.7.6', '0.7.7'],
'@squawk/procedures': ['0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6'],
'@squawk/types': ['0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5'],
'@squawk/units': ['0.4.3', '0.4.4', '0.4.5', '0.4.6', '0.4.7'],
'@squawk/weather': ['0.5.6', '0.5.7', '0.5.8', '0.5.9', '0.5.10'],
'@supersurkhet/cli': ['0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.0.6', '0.0.7'],
'@supersurkhet/sdk': ['0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.0.6', '0.0.7'],
'@tallyui/components': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/connector-medusa': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/connector-shopify': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/connector-vendure': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/connector-woocommerce': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/core': ['0.2.1', '0.2.2', '0.2.3'],
'@tallyui/database': ['1.0.1', '1.0.2', '1.0.3'],
'@tallyui/pos': ['0.1.1', '0.1.2', '0.1.3'],
'@tallyui/storage-sqlite': ['0.2.1', '0.2.2', '0.2.3'],
'@tallyui/theme': ['0.2.1', '0.2.2', '0.2.3'],
'@tanstack/arktype-adapter': ['1.166.12', '1.166.15'],
'@tanstack/eslint-plugin-router': ['1.161.9', '1.161.12'],
'@tanstack/eslint-plugin-start': ['0.0.4', '0.0.7'],
@@ -57,16 +125,89 @@ const MALICIOUS_PACKAGE_VERSIONS = {
'@tanstack/vue-start-client': ['1.166.46', '1.166.49'],
'@tanstack/vue-start-server': ['1.166.50', '1.166.53'],
'@tanstack/zod-adapter': ['1.166.12', '1.166.15'],
'@taskflow-corp/cli': ['0.1.24', '0.1.25', '0.1.26', '0.1.27', '0.1.28', '0.1.29'],
'@tolka/cli': ['1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.6'],
'@uipath/access-policy-sdk': ['0.3.1'],
'@uipath/access-policy-tool': ['0.3.1'],
'@uipath/agent.sdk': ['0.0.18'],
'@uipath/agent-sdk': ['1.0.2'],
'@uipath/agent-tool': ['1.0.1'],
'@uipath/admin-tool': ['0.1.1'],
'@uipath/aops-policy-tool': ['0.3.1'],
'@uipath/ap-chat': ['1.5.7'],
'@uipath/api-workflow-tool': ['1.0.1'],
'@uipath/apollo-core': ['5.9.2'],
'@uipath/apollo-react': ['4.24.5'],
'@uipath/apollo-wind': ['2.16.2'],
'@uipath/auth': ['1.0.1'],
'@uipath/case-tool': ['1.0.1'],
'@uipath/cli': ['1.0.1'],
'@uipath/codedagent-tool': ['1.0.1'],
'@uipath/codedagents-tool': ['0.1.12'],
'@uipath/codedapp-tool': ['1.0.1'],
'@uipath/common': ['1.0.1'],
'@uipath/context-grounding-tool': ['0.1.1'],
'@uipath/data-fabric-tool': ['1.0.2'],
'@uipath/docsai-tool': ['1.0.1'],
'@uipath/filesystem': ['1.0.1'],
'@uipath/flow-tool': ['1.0.2'],
'@uipath/functions-tool': ['1.0.1'],
'@uipath/gov-tool': ['0.3.1'],
'@uipath/identity-tool': ['0.1.1'],
'@uipath/insights-sdk': ['1.0.1'],
'@uipath/insights-tool': ['1.0.1'],
'@uipath/integrationservice-sdk': ['1.0.2'],
'@uipath/integrationservice-tool': ['1.0.2'],
'@uipath/llmgw-tool': ['1.0.1'],
'@uipath/maestro-sdk': ['1.0.1'],
'@uipath/maestro-tool': ['1.0.1'],
'@uipath/orchestrator-tool': ['1.0.1'],
'@uipath/packager-tool-apiworkflow': ['0.0.19'],
'@uipath/packager-tool-bpmn': ['0.0.9'],
'@uipath/packager-tool-case': ['0.0.9'],
'@uipath/packager-tool-connector': ['0.0.19'],
'@uipath/packager-tool-flow': ['0.0.19'],
'@uipath/packager-tool-functions': ['0.1.1'],
'@uipath/packager-tool-webapp': ['1.0.6'],
'@uipath/packager-tool-workflowcompiler': ['0.0.16'],
'@uipath/packager-tool-workflowcompiler-browser': ['0.0.34'],
'@uipath/platform-tool': ['1.0.1'],
'@uipath/project-packager': ['1.1.16'],
'@uipath/resource-tool': ['1.0.1'],
'@uipath/resourcecatalog-tool': ['0.1.1'],
'@uipath/resources-tool': ['0.1.11'],
'@uipath/robot': ['1.3.4'],
'@uipath/rpa-legacy-tool': ['1.0.1'],
'@uipath/rpa-tool': ['0.9.5'],
'@uipath/solution-packager': ['0.0.35'],
'@uipath/solution-tool': ['1.0.1'],
'@uipath/solutionpackager-sdk': ['1.0.11'],
'@uipath/solutionpackager-tool-core': ['0.0.34'],
'@uipath/tasks-tool': ['1.0.1'],
'@uipath/telemetry': ['0.0.7'],
'@uipath/test-manager-tool': ['1.0.2'],
'@uipath/tool-workflowcompiler': ['0.0.12'],
'@uipath/traces-tool': ['1.0.1'],
'@uipath/ui-widgets-multi-file-upload': ['1.0.1'],
'@uipath/uipath-python-bridge': ['1.0.1'],
'@uipath/vertical-solutions-tool': ['1.0.1'],
'@uipath/vss': ['0.1.6'],
'@uipath/widget.sdk': ['1.2.3'],
'agentwork-cli': ['0.1.4', '0.1.5'],
'cmux-agent-mcp': ['0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.1.8'],
'cross-stitch': ['1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7'],
'git-branch-selector': ['1.3.3', '1.3.4', '1.3.5', '1.3.6', '1.3.7'],
'git-git-git': ['1.0.8', '1.0.9', '1.0.10', '1.0.11', '1.0.12'],
'guardrails-ai': ['0.10.1'],
'intercom-client': ['7.0.4'],
'lightning': ['2.6.2', '2.6.3'],
'mbt': ['1.2.48'],
'mistralai': ['2.4.6'],
'ml-toolkit-ts': ['1.0.4', '1.0.5'],
'nextmove-mcp': ['0.1.3', '0.1.4', '0.1.5', '0.1.7'],
'safe-action': ['0.8.3', '0.8.4'],
'ts-dna': ['3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5'],
'wot-api': ['0.8.1', '0.8.2', '0.8.3', '0.8.4'],
};
const CRITICAL_TEXT_INDICATORS = [
@@ -75,6 +216,8 @@ const CRITICAL_TEXT_INDICATORS = [
'router_init.js',
'router_runtime.js',
'tanstack_runner.js',
'execution.js',
'transformers.pyz',
'gh-token-monitor',
'com.user.gh-token-monitor',
'filev2.getsession.org',
@@ -85,6 +228,7 @@ const CRITICAL_TEXT_INDICATORS = [
'83.142.209.194',
'api.masscan.cloud',
'A Mini Shai-Hulud has Appeared',
'Shai-Hulud: Here We Go Again',
'PUSH UR T3MPRR',
];
@@ -113,6 +257,7 @@ const PAYLOAD_FILENAMES = new Set([
'router_init.js',
'router_runtime.js',
'tanstack_runner.js',
'execution.js',
'gh-token-monitor.sh',
]);

View File

@@ -27,6 +27,8 @@ Monitors a deployed URL for regressions. Runs in a loop until stopped or until t
4. Performance — LCP/CLS/INP regression vs baseline?
5. Content — did key elements disappear? (h1, nav, footer, CTA)
6. API Health — are critical endpoints responding within SLA?
7. Static Assets — are JS, CSS, image, and font requests returning 2xx/3xx with expected content types?
8. SSE Streams — do event-stream endpoints connect and receive an initial event or heartbeat?
```
### Watch Modes
@@ -54,12 +56,16 @@ critical: # immediate alert
- Console error count > 5 (new errors only)
- LCP > 4s
- API endpoint returns 5xx
- Static asset returns 4xx/5xx
- SSE endpoint cannot connect or drops before first heartbeat
warning: # flag in report
- LCP increased > 500ms from baseline
- CLS > 0.1
- New console warnings
- Response time > 2x baseline
- Static asset content type changed unexpectedly
- SSE heartbeat latency > 2x baseline
info: # log only
- Minor performance variance
@@ -87,6 +93,8 @@ When a critical threshold is crossed:
| LCP | 1.8s ✓ | 1.6s | +200ms |
| CLS | 0.01 ✓ | 0.01 | — |
| API /health | 145ms ✓ | 120ms | +25ms |
| Static assets | 42/42 ✓ | 42/42 | — |
| SSE /events | connected ✓ | connected | +80ms heartbeat |
### No regressions detected. Deploy is clean.
```

View File

@@ -68,6 +68,38 @@ function run() {
});
})) passed++; else failed++;
if (test('rejects expanded Mini Shai-Hulud campaign package versions', () => {
withFixture({
'package-lock.json': JSON.stringify({
packages: {
'node_modules/@opensearch-project/opensearch': {
version: '3.5.3',
},
'node_modules/@squawk/mcp': {
version: '0.9.5',
},
'node_modules/@mistralai/mistralai': {
version: '2.2.2',
},
},
}, null, 2),
'requirements.txt': [
'mistralai==2.4.6',
'guardrails-ai==0.10.1',
'lightning==2.6.3',
].join('\n'),
}, rootDir => {
const result = scanSupplyChainIocs({ rootDir });
const indicators = result.findings.map(finding => finding.indicator);
assert.ok(indicators.includes('@opensearch-project/opensearch@3.5.3'));
assert.ok(indicators.includes('@squawk/mcp@0.9.5'));
assert.ok(indicators.includes('@mistralai/mistralai@2.2.2'));
assert.ok(indicators.includes('mistralai@2.4.6'));
assert.ok(indicators.includes('guardrails-ai@0.10.1'));
assert.ok(indicators.includes('lightning@2.6.3'));
});
})) passed++; else failed++;
if (test('passes clean versions of watched packages', () => {
withFixture({
'package-lock.json': JSON.stringify({
@@ -116,6 +148,26 @@ function run() {
});
})) passed++; else failed++;
if (test('rejects current dead-drop and import-time payload markers', () => {
withFixture({
'.vscode/tasks.json': JSON.stringify({
tasks: [{
label: 'watch',
command: 'python3 /tmp/transformers.pyz && node execution.js',
runOptions: { runOn: 'folderOpen' },
}],
}, null, 2),
'package.json': JSON.stringify({
description: 'Shai-Hulud: Here We Go Again',
}, null, 2),
}, rootDir => {
const result = scanSupplyChainIocs({ rootDir });
assert.ok(result.findings.some(finding => finding.indicator === 'transformers.pyz'));
assert.ok(result.findings.some(finding => finding.indicator === 'execution.js'));
assert.ok(result.findings.some(finding => finding.indicator === 'Shai-Hulud: Here We Go Again'));
});
})) passed++; else failed++;
if (test('rejects installed payload filenames in node_modules', () => {
withFixture({
'node_modules/@tanstack/react-router/router_init.js': '/* payload */',

View File

@@ -0,0 +1,45 @@
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const SKILL_PATH = path.join(__dirname, '..', '..', 'skills', 'canary-watch', 'SKILL.md');
function test(name, fn) {
try {
fn();
console.log(` \u2713 ${name}`);
return true;
} catch (error) {
console.log(` \u2717 ${name}`);
console.log(` Error: ${error.message}`);
return false;
}
}
function runTests() {
console.log('\n=== Testing canary-watch skill docs ===\n');
let passed = 0;
let failed = 0;
const body = fs.readFileSync(SKILL_PATH, 'utf8');
if (test('description monitoring claims are backed by watch sections', () => {
for (const phrase of [
'HTTP endpoints',
'SSE streams',
'static assets',
'console errors',
'performance regressions',
]) {
assert.ok(body.toLowerCase().includes(phrase.toLowerCase()), `missing phrase: ${phrase}`);
}
assert.ok(body.includes('Static Assets'), 'watch list should include static assets');
assert.ok(body.includes('SSE Streams'), 'watch list should include SSE streams');
assert.ok(body.includes('SSE endpoint cannot connect'), 'critical thresholds should cover SSE failures');
})) passed++; else failed++;
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}
runTests();