Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ def main():
print(f"\n {color('⚠ Some tools missing - will try anyway:', Colors.YELLOW)}")
for m in missing:
print(f" {m}")
print(f" {color('Not all modules will build. That\'s fine.', Colors.GRAY)}")
print(" " + color("Not all modules will build. That's fine.", Colors.GRAY))
else:
print(f" {color('✓ All prerequisites found', Colors.GREEN)}")

Expand Down
86 changes: 86 additions & 0 deletions diagnostic/build-2b54872c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"generated_at": "2026-06-19T03:29:47.287298+00:00",
"commit": "2b54872c",
"diagnostic_logd": "diagnostic/build-2b54872c.logd",
"diagnostic_logd_error": null,
"chunked": false,
"chunk_size_bytes": null,
"password": "9518dae8e3644cbfbf97",
"decrypt_command": "encryptly unpack diagnostic/build-2b54872c.logd <outdir> --password 9518dae8e3644cbfbf97",
"total_modules": 10,
"passed": 1,
"failed": 9,
"modules": [
{
"name": "backend",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'cargo'"
},
{
"name": "frontend",
"status": "PASS",
"elapsed_seconds": 12.151,
"artifact": "/mnt/c/Users/jarlyn/Documents/make money/zeroeye-memory-bounty/frontend/dist",
"output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\n\u001b[36mvite v6.4.3 \u001b[32mbuilding for production...\u001b[36m\u001b[39m\ntransforming...\n\u001b[32m\u2713\u001b[39m 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\n\u001b[2mdist/\u001b[22m\u001b[32mindex.html \u001b[39m\u001b[1m\u001b[2m 0.63 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 0.35 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/state-BkjSKDbY.js \u001b[39m\u001b[1m\u001b[2m 8.91 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 3.54 kB\u001b[22m\u001b[2m \u2502 map: 57.15 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/vendor-CREcWLHI.js \u001b[39m\u001b[1m\u001b[2m 48.93 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 17.25 kB\u001b[22m\u001b[2m \u2502 map: 481.27 kB\u001b[22m\n\u001b[2mdist/\u001b[22m\u001b[36massets/index-CyxcoTyU.js \u001b[39m\u001b[1m\u001b[2m231.32 kB\u001b[22m\u001b[1m\u001b[22m\u001b[2m \u2502 gzip: 72.16 kB\u001b[22m\u001b[2m \u2502 map: 1,045.57 kB\u001b[22m\n\u001b[32m\u2713 built in 1.22s\u001b[39m"
},
{
"name": "market",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'go'"
},
{
"name": "frailbox",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'make'"
},
{
"name": "engine",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'cmake'"
},
{
"name": "compliance",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'javac'"
},
{
"name": "v2-market-stream",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'ruby'"
},
{
"name": "nfc-scanner",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'luac'"
},
{
"name": "openapi-haskell",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'ghc'"
},
{
"name": "openapi-tools",
"status": "FAIL",
"elapsed_seconds": 0,
"artifact": null,
"output": "Command not found: [Errno 2] No such file or directory: 'luac'"
}
],
"pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-2b54872c.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
}
Binary file added diagnostic/build-2b54872c.logd
Binary file not shown.
42 changes: 38 additions & 4 deletions tools/monitoring_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import argparse
import json
import os
import re
import sys
import time
import urllib.request
Expand Down Expand Up @@ -78,7 +79,7 @@
},
{
"name": "HighMemoryUsage",
"expr": "process_resident_memory_bytes / process_resident_memory_bytes > 0.9",
"expr": "process_resident_memory_bytes / machine_memory_bytes > 0.9",
"duration": "10m",
"severity": "warning",
"summary": "High memory usage on {{$labels.instance}}",
Expand Down Expand Up @@ -197,9 +198,40 @@ def check_alertmanager(url: str) -> bool:
return False


METRIC_REF_RE = r"[A-Za-z_:][A-Za-z0-9_:]*(?:\s*\{[^{}]*\})?(?:\s*\[[^\[\]]+\])?"
DIVISION_RE = re.compile(
rf"(?<![A-Za-z0-9_:])(?P<left>{METRIC_REF_RE})\s*/\s*(?P<right>{METRIC_REF_RE})(?![A-Za-z0-9_:])"
)


def _normalize_metric_ref(metric_ref: str) -> str:
return re.sub(r"\s+", "", metric_ref)
Comment on lines +201 to +208


def validate_alert_rule_expressions(rules: List[Dict[str, Any]]) -> List[str]:
errors = []
for rule in rules:
name = rule.get("name", "<unnamed>")
expr = str(rule.get("expr", ""))
for match in DIVISION_RE.finditer(expr):
left = _normalize_metric_ref(match.group("left"))
right = _normalize_metric_ref(match.group("right"))
if left == right:
errors.append(f"{name}: expression divides {left} by itself")
break
return errors


def upload_prometheus_rules(rules: List[Dict[str, Any]],
prometheus_url: str,
dry_run: bool = False) -> bool:
validation_errors = validate_alert_rule_expressions(rules)
if validation_errors:
print("Invalid alert rule expressions:", file=sys.stderr)
for error in validation_errors:
print(f" - {error}", file=sys.stderr)
return False

rules_file = "/etc/prometheus/rules/tent_rules.yml"
print(f"{'Would upload' if dry_run else 'Uploading'} {len(rules)} rules to {prometheus_url}")

Expand Down Expand Up @@ -414,13 +446,15 @@ def main():
args.alertmanager_url, args.slack_webhook,
args.pagerduty_key, args.dry_run)

upload_prometheus_rules(RECOMMENDED_ALERT_RULES, args.prometheus_url, args.dry_run)
if not upload_prometheus_rules(RECOMMENDED_ALERT_RULES, args.prometheus_url, args.dry_run):
return 1
print("Monitoring initialization complete")
return 0

if args.alerts:
upload_prometheus_rules(RECOMMENDED_ALERT_RULES, args.prometheus_url, args.dry_run)
return 0
return 0 if upload_prometheus_rules(
RECOMMENDED_ALERT_RULES, args.prometheus_url, args.dry_run
) else 1

if args.backup:
return 0 if backup_monitoring_config(
Expand Down
40 changes: 40 additions & 0 deletions tools/test_monitoring_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import unittest

from tools import monitoring_setup


class AlertRuleValidationTests(unittest.TestCase):
def test_recommended_alert_rules_do_not_self_divide(self):
errors = monitoring_setup.validate_alert_rule_expressions(
monitoring_setup.RECOMMENDED_ALERT_RULES
)

self.assertEqual([], errors)

def test_high_memory_usage_uses_machine_memory_denominator(self):
rule = next(
rule
for rule in monitoring_setup.RECOMMENDED_ALERT_RULES
if rule["name"] == "HighMemoryUsage"
)

self.assertIn("process_resident_memory_bytes", rule["expr"])
self.assertIn("machine_memory_bytes", rule["expr"])
Comment on lines +21 to +22

def test_self_dividing_expression_is_rejected(self):
errors = monitoring_setup.validate_alert_rule_expressions(
[
{
"name": "BrokenMemoryUsage",
"expr": "process_resident_memory_bytes / process_resident_memory_bytes > 0.9",
}
]
)

self.assertEqual(1, len(errors))
self.assertIn("BrokenMemoryUsage", errors[0])
self.assertIn("process_resident_memory_bytes", errors[0])


if __name__ == "__main__":
unittest.main()