Publish ITWorx Pulse source
Public source validation / validate (push) Failing after 3m8s

This commit is contained in:
ITWorx Pulse release export
2026-09-03 02:09:19 +02:00
commit bd774932d5
614 changed files with 77116 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { buildSoakSummary } from './wallboard-soak-analysis.mjs';
const directory = path.resolve(process.argv[2] ?? 'artifacts/evidence/M10-14/raw');
async function readJSON(name) {
return JSON.parse(await readFile(path.join(directory, name), 'utf8'));
}
async function readNDJSON(name, required = true) {
try {
const content = await readFile(path.join(directory, name), 'utf8');
return content.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line));
} catch (error) {
if (!required && error?.code === 'ENOENT') return [];
throw error;
}
}
const [metadata, recorded, samples, reconnects, events] = await Promise.all([
readJSON('metadata.json'),
readJSON('result.json'),
readNDJSON('samples.ndjson'),
readNDJSON('reconnects.ndjson', false),
readNDJSON('events.ndjson'),
]);
const completedAt = new Date(recorded.completedAt);
const completedMs = completedAt.getTime();
if (!Number.isFinite(completedMs)) throw new Error('result.json has no valid completedAt');
const relevantEvents = events.filter((event) => Date.parse(event.timestamp) <= completedMs);
const openedSockets = relevantEvents.filter((event) => event.type === 'websocket-open').length;
const closedSockets = relevantEvents.filter((event) => event.type === 'websocket-close').length;
const recomputed = buildSoakSummary({
samples,
reconnects,
startedAt: new Date(metadata.startedAt),
completedAt,
durationHours: metadata.durationHours,
sampleSeconds: metadata.sampleSeconds,
counters: {
maxActiveSockets: Math.max(0, ...relevantEvents.map((event) => Number(event.activeSockets) || 0)),
openedSockets,
closedSockets,
websocketErrors: relevantEvents.filter((event) => event.type === 'websocket-error').length,
pageErrors: relevantEvents.filter((event) => event.type === 'page-error').length,
apiFailures: relevantEvents.filter((event) => event.type === 'api-failure').length,
},
requireWallboardTitle: true,
});
const comparison = {
statusMatches: recomputed.status === recorded.status,
sampleCountMatches: recomputed.sampleCount === recorded.sampleCount,
reconnectCountMatches: recomputed.reconnectCount === recorded.reconnectCount,
criticalMetricsMatch: [
'expectedSampleCount', 'minimumSampleCount', 'maxSampleGapSeconds', 'maxAllowedSampleGapSeconds',
'reconnectFailures', 'retainedGrowthBytes', 'heapSlopeBytesPerHour', 'fpsP05',
'frameP95WorstMs', 'longestTaskMs', 'maxActiveSockets', 'openedSockets',
'closedSockets', 'websocketErrors', 'socketChurnBudget', 'pageErrors',
'apiFailures', 'maxDOMNodes', 'horizontalOverflowSamples', 'invalidWallboardSamples',
].every((field) => Object.is(recomputed[field], recorded[field])),
};
const verification = {
directory,
recordedStatus: recorded.status,
recomputedStatus: recomputed.status,
comparison,
recomputed,
};
process.stdout.write(`${JSON.stringify(verification, null, 2)}\n`);
if (!Object.values(comparison).every(Boolean) || recomputed.status !== 'pass') process.exitCode = 1;
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Fail when the documented Pulse API and registered HTTP routes drift apart."""
from __future__ import annotations
import json
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
MANIFEST = ROOT / "specs" / "api-routes.json"
CONTRACT = ROOT / "docs" / "architecture" / "API_CONTRACT.md"
ROUTERS = (ROOT / "cmd" / "api" / "main.go", ROOT / "internal" / "service" / "health.go")
TABLE_ROUTE = re.compile(r"^\| `(?P<method>GET|POST|PUT|PATCH|DELETE) (?P<path>/[^`]+)` \|", re.MULTILINE)
REGISTERED = re.compile(r"\.Handle(?:Func)?\(\s*\"(?P<path>/[^\"]+)\"")
def fail(messages: list[str]) -> int:
for message in messages:
print(f"API CONTRACT: FAIL: {message}", file=sys.stderr)
return 1
def main() -> int:
document = json.loads(MANIFEST.read_text(encoding="utf-8"))
routes = document.get("routes", [])
errors: list[str] = []
keys: list[tuple[str, str]] = []
covered_registrations: set[str] = set()
for index, route in enumerate(routes):
missing = {"method", "path", "registration", "access", "implementation"} - route.keys()
if missing:
errors.append(f"route {index} misses fields: {', '.join(sorted(missing))}")
continue
key = (route["method"], route["path"])
if key in keys:
errors.append(f"duplicate manifest route: {key[0]} {key[1]}")
keys.append(key)
covered_registrations.add(route["registration"])
implementation = ROOT / route["implementation"]
if not implementation.is_file():
errors.append(f"implementation does not exist for {key[0]} {key[1]}: {implementation.relative_to(ROOT)}")
markdown = CONTRACT.read_text(encoding="utf-8")
documented = [(match.group("method"), match.group("path")) for match in TABLE_ROUTE.finditer(markdown)]
manifest_set = set(keys)
documented_set = set(documented)
for method, path in sorted(manifest_set - documented_set):
errors.append(f"manifest route is not documented: {method} {path}")
for method, path in sorted(documented_set - manifest_set):
errors.append(f"documented route is not in manifest: {method} {path}")
if len(documented) != len(documented_set):
errors.append("the route table contains duplicate method/path rows")
registered: set[str] = set()
for source in ROUTERS:
registered.update(match.group("path") for match in REGISTERED.finditer(source.read_text(encoding="utf-8")))
for path in sorted(registered - covered_registrations):
errors.append(f"registered router path is not represented in the manifest: {path}")
for path in sorted(covered_registrations - registered):
errors.append(f"manifest registration does not exist in the router: {path}")
if errors:
return fail(errors)
print(
"API CONTRACT: PASS "
f"({len(manifest_set)} method/path contracts, {len(registered)} router registrations, no drift)"
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
+42
View File
@@ -0,0 +1,42 @@
"""Fail on high-confidence committed secret material or private keys."""
from __future__ import annotations
import pathlib
import re
import subprocess
import sys
SKIP_PARTS = {".git", "node_modules", "dist", "bin", "artifacts"}
PRIVATE_KEY = re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----")
TOKEN_MARKERS = re.compile(r"(?:ghp_|github_pat_|sk-[A-Za-z0-9]{12,}|xox[baprs]-[A-Za-z0-9-]{12,})")
def main() -> int:
root = pathlib.Path(__file__).resolve().parents[1]
files = subprocess.check_output(["git", "ls-files", "-z"], cwd=root).decode().split("\0")
findings: list[str] = []
for name in files:
if not name:
continue
path = root / name
if any(part in SKIP_PARTS for part in path.parts) or path.name in {".env.example", "check_secrets.py"} or path.name.endswith("_test.go"):
continue
try:
content = path.read_text(encoding="utf-8")
except (UnicodeDecodeError, OSError):
continue
if PRIVATE_KEY.search(content):
findings.append(f"private key marker: {name}")
if TOKEN_MARKERS.search(content):
findings.append(f"token marker: {name}")
if findings:
print("SECRET CHECK: FAIL")
print("\n".join(findings))
return 1
print("SECRET CHECK: PASS")
return 0
if __name__ == "__main__":
sys.exit(main())
+329
View File
@@ -0,0 +1,329 @@
#!/usr/bin/env python3
"""Fail when a first-party Go package is implemented but unreachable from a binary.
The audit that motivated this tool found ~2,600 lines of fully implemented,
well-tested Go code with zero non-test importers outside its own package —
`cmd/worker` and `cmd/agent` never called it, so it shipped as dead weight
behind a "done" task. Acceptance checks had only ever exercised each
package's internal behaviour, never whether `go build ./cmd/...` would ever
pull it in.
This tool computes, using pure-Python source parsing (no `go list`, since the
Go toolchain may be unavailable in CI), the transitive set of first-party
packages reachable from the real entry points (`cmd/api`, `cmd/worker`,
`cmd/agent`, `cmd/migrate`) through non-test imports, and fails listing every
`internal/*` package that is implemented but unreachable and not explicitly
allowlisted with a reason and a tracking task id.
"""
from __future__ import annotations
import json
import re
import sys
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
DEFAULT_ALLOWLIST = ROOT / "tools" / "wiring_allowlist.json"
GO_ROOTS = ("cmd", "internal")
SKIP_PARTS = {".git", "node_modules", "vendor"}
MODULE_RE = re.compile(r"(?m)^module\s+(\S+)")
PACKAGE_RE = re.compile(r"(?m)^package\s+\w+\b")
PACKAGE_MAIN_RE = re.compile(r"(?m)^package\s+main\b")
IGNORE_TAG_RE = re.compile(
r"(?m)^//go:build\b.*\bignore\b|^//\s*\+build\b.*\bignore\b"
)
IMPORT_BLOCK_RE = re.compile(r"import\s*\(\s*(.*?)\n\)", re.S)
IMPORT_SINGLE_RE = re.compile(
r'(?m)^\s*import\s+(?:(?:[A-Za-z_][A-Za-z0-9_]*|_|\.)\s+)?"([^"]+)"'
)
IMPORT_LINE_RE = re.compile(
r'^\s*(?:(?:[A-Za-z_][A-Za-z0-9_]*|_|\.)\s+)?"([^"]+)"'
)
class AllowlistError(Exception):
"""Raised when the wiring allowlist file is malformed."""
@dataclass
class WiringReport:
module: str
entry_points: list[str]
implemented_internal: set[str]
reachable: set[str]
unreachable: set[str]
allowlist_entries: list[dict[str, Any]]
allowlisted_active: dict[str, dict[str, Any]]
stale_allowlist: dict[str, dict[str, Any]]
unknown_allowlist: dict[str, dict[str, Any]]
failing: set[str] = field(init=False)
def __post_init__(self) -> None:
self.failing = self.unreachable - set(self.allowlisted_active)
@property
def ok(self) -> bool:
return not self.failing and not self.stale_allowlist and not self.unknown_allowlist
def read_module_path(root: Path) -> str:
text = (root / "go.mod").read_text(encoding="utf-8")
match = MODULE_RE.search(text)
if not match:
raise AllowlistError("go.mod has no module declaration")
return match.group(1)
def discover_go_files(root: Path) -> list[Path]:
files: list[Path] = []
for go_root in GO_ROOTS:
base = root / go_root
if not base.is_dir():
continue
for path in base.rglob("*.go"):
if any(part in SKIP_PARTS for part in path.parts):
continue
files.append(path)
return files
def header_text(text: str) -> str:
"""Return the text preceding the package clause (build tags, doc comments)."""
match = PACKAGE_RE.search(text)
return text[: match.start()] if match else text
def has_ignore_build_tag(text: str) -> bool:
return bool(IGNORE_TAG_RE.search(header_text(text)))
def parse_imports(text: str) -> set[str]:
"""Extract first-party-or-not import paths from grouped and single import forms.
Handles grouped `import (...)` blocks, single `import "x"` statements,
aliases (`alias "x"`), blank imports (`_ "x"`), and dot imports (`. "x"`).
Blank and dot imports are still real reachability edges: they pull the
package into the binary and run its `init()`.
"""
imports: set[str] = set()
for block in IMPORT_BLOCK_RE.finditer(text):
for line in block.group(1).splitlines():
match = IMPORT_LINE_RE.match(line)
if match:
imports.add(match.group(1))
for match in IMPORT_SINGLE_RE.finditer(text):
imports.add(match.group(1))
return imports
def classify_files(
files: list[Path],
) -> tuple[dict[str, list[Path]], dict[str, list[Path]]]:
"""Split files by package directory into (non-test, test) buckets.
Files carrying a `//go:build ignore` (or legacy `// +build ignore`) tag
are dropped entirely: the Go toolchain never compiles them, so they must
not count as either "implemented" or as import edges.
"""
prod_by_dir: dict[str, list[Path]] = {}
test_by_dir: dict[str, list[Path]] = {}
for path in files:
text = path.read_text(encoding="utf-8", errors="replace")
if has_ignore_build_tag(text):
continue
directory = path.parent
key = directory.as_posix()
if path.name.endswith("_test.go"):
test_by_dir.setdefault(key, []).append(path)
else:
prod_by_dir.setdefault(key, []).append(path)
return prod_by_dir, test_by_dir
def relativize(prod_by_dir: dict[str, list[Path]], root: Path) -> dict[str, list[Path]]:
result: dict[str, list[Path]] = {}
for key, paths in prod_by_dir.items():
rel = Path(key).resolve().relative_to(root.resolve()).as_posix()
result[rel] = paths
return result
def build_graph(prod_by_dir: dict[str, list[Path]], module: str) -> dict[str, set[str]]:
prefix = module + "/"
graph: dict[str, set[str]] = {}
for directory, paths in prod_by_dir.items():
edges: set[str] = set()
for path in paths:
text = path.read_text(encoding="utf-8", errors="replace")
for imp in parse_imports(text):
if not imp.startswith(prefix):
continue
target = imp[len(prefix):]
if target in prod_by_dir:
edges.add(target)
graph[directory] = edges
return graph
def find_entry_points(prod_by_dir: dict[str, list[Path]]) -> set[str]:
entries: set[str] = set()
for directory, paths in prod_by_dir.items():
if not directory.startswith("cmd/"):
continue
for path in paths:
text = path.read_text(encoding="utf-8", errors="replace")
if PACKAGE_MAIN_RE.search(text):
entries.add(directory)
break
return entries
def reachable_from(graph: dict[str, set[str]], roots: set[str]) -> set[str]:
seen: set[str] = set()
stack = list(roots)
while stack:
current = stack.pop()
if current in seen:
continue
seen.add(current)
for target in graph.get(current, ()):
if target not in seen:
stack.append(target)
return seen
def load_allowlist(path: Path) -> list[dict[str, Any]]:
if not path.exists():
return []
try:
data = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as error:
raise AllowlistError(f"{path}: invalid JSON ({error})") from error
if isinstance(data, dict):
entries = data.get("entries")
else:
entries = data
if not isinstance(entries, list):
raise AllowlistError(f"{path}: expected an 'entries' list")
validated: list[dict[str, Any]] = []
seen_packages: set[str] = set()
for index, raw in enumerate(entries):
if not isinstance(raw, dict):
raise AllowlistError(f"{path}: entry {index} is not an object")
package = raw.get("package")
reason = raw.get("reason")
task = raw.get("task")
if not isinstance(package, str) or not package.strip():
raise AllowlistError(f"{path}: entry {index} is missing a non-empty 'package'")
if not isinstance(reason, str) or not reason.strip():
raise AllowlistError(
f"{path}: allowlist entry '{package}' is missing a required 'reason'"
)
if not isinstance(task, str) or not task.strip():
raise AllowlistError(
f"{path}: allowlist entry '{package}' is missing a required tracking 'task'"
)
if package in seen_packages:
raise AllowlistError(f"{path}: duplicate allowlist entry for '{package}'")
seen_packages.add(package)
validated.append({"package": package, "reason": reason.strip(), "task": task.strip()})
return validated
def analyze(root: Path = ROOT, allowlist_path: Path = DEFAULT_ALLOWLIST) -> WiringReport:
module = read_module_path(root)
files = discover_go_files(root)
prod_by_dir_abs, _test_by_dir_abs = classify_files(files)
prod_by_dir = relativize(prod_by_dir_abs, root)
graph = build_graph(prod_by_dir, module)
entry_points = find_entry_points(prod_by_dir)
reachable = reachable_from(graph, entry_points)
implemented_internal = {d for d in prod_by_dir if d.startswith("internal/")}
unreachable = implemented_internal - reachable
allowlist_entries = load_allowlist(allowlist_path)
allowlisted_active: dict[str, dict[str, Any]] = {}
stale_allowlist: dict[str, dict[str, Any]] = {}
unknown_allowlist: dict[str, dict[str, Any]] = {}
for entry in allowlist_entries:
package = entry["package"]
if package not in implemented_internal:
unknown_allowlist[package] = entry
elif package in reachable:
stale_allowlist[package] = entry
else:
allowlisted_active[package] = entry
return WiringReport(
module=module,
entry_points=sorted(entry_points),
implemented_internal=implemented_internal,
reachable=reachable,
unreachable=unreachable,
allowlist_entries=allowlist_entries,
allowlisted_active=allowlisted_active,
stale_allowlist=stale_allowlist,
unknown_allowlist=unknown_allowlist,
)
def format_report(report: WiringReport) -> str:
lines: list[str] = []
lines.append(f"module: {report.module}")
lines.append(f"entry points: {', '.join(report.entry_points)}")
reachable_internal = report.reachable & report.implemented_internal
lines.append(
f"reachable internal/* packages: {len(reachable_internal)} of {len(report.implemented_internal)}"
)
lines.append(f"allowlisted (tracked debt, still unreachable): {len(report.allowlisted_active)}")
for package in sorted(report.allowlisted_active):
entry = report.allowlisted_active[package]
lines.append(f" - {package} [{entry['task']}] {entry['reason']}")
lines.append(f"unreachable and NOT allowlisted: {len(report.failing)}")
for package in sorted(report.failing):
lines.append(f" - {package}")
lines.append(f"stale allowlist entries (now reachable — remove from allowlist): {len(report.stale_allowlist)}")
for package in sorted(report.stale_allowlist):
lines.append(f" - {package}")
if report.unknown_allowlist:
lines.append(f"allowlist entries for unknown/nonexistent packages: {len(report.unknown_allowlist)}")
for package in sorted(report.unknown_allowlist):
lines.append(f" - {package}")
return "\n".join(lines)
def main() -> int:
try:
report = analyze(ROOT, DEFAULT_ALLOWLIST)
except AllowlistError as error:
print(f"WIRING CHECK: ERROR — {error}", file=sys.stderr)
return 2
body = format_report(report)
if report.ok:
print(body)
print(f"WIRING CHECK: PASS ({len(report.reachable & report.implemented_internal)} reachable, "
f"{len(report.allowlisted_active)} allowlisted)")
return 0
print(body, file=sys.stderr)
print(
f"WIRING CHECK: FAIL ({len(report.failing)} unreachable, "
f"{len(report.stale_allowlist)} stale, {len(report.unknown_allowlist)} unknown)",
file=sys.stderr,
)
return 1
if __name__ == "__main__":
raise SystemExit(main())
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Independent, dependency-free Pulse liveness check for an external monitor."""
from __future__ import annotations
import argparse
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import urlparse
from urllib.request import HTTPRedirectHandler, Request, build_opener
class NoRedirectHandler(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
def check(url: str, timeout: float = 5.0) -> tuple[bool, str]:
parsed = urlparse(url)
if parsed.scheme not in {"http", "https"} or not parsed.hostname or parsed.username or parsed.password:
return False, "endpoint must be an http(s) URL without embedded credentials"
if timeout < 1 or timeout > 30:
return False, "timeout must be between 1 and 30 seconds"
request = Request(url, headers={"Accept": "text/plain", "User-Agent": "pulse-deadman/1"}, method="GET")
try:
with build_opener(NoRedirectHandler).open(request, timeout=timeout) as response:
body = response.read(64).decode("utf-8", errors="replace").strip()
if response.status != 200 or body != "ok":
return False, f"unexpected liveness response ({response.status})"
except HTTPError as error:
return False, f"liveness returned HTTP {error.code}"
except (URLError, TimeoutError, OSError) as error:
return False, f"liveness request failed ({error.__class__.__name__})"
return True, "ok"
def main() -> int:
parser = argparse.ArgumentParser(description="Check Pulse /healthz from an independent monitor")
parser.add_argument("url", help="HTTPS URL to Pulse /healthz")
parser.add_argument("--timeout", type=float, default=5.0)
args = parser.parse_args()
ok, message = check(args.url, args.timeout)
print(message)
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())
+113
View File
@@ -0,0 +1,113 @@
// Command integrationfixture is an isolated, deterministic external boundary
// used only by the real-stack smoke gate. It behaves as a Prometheus-compatible
// source and a webhook receiver; production images never include it.
package main
import (
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"time"
)
type counters struct {
mu sync.Mutex
prometheusRequests int
webhookRequests int
keys map[string]struct{}
lastEvent string
events map[string]int
}
func main() {
if len(os.Args) == 3 && (os.Args[1] == "health" || os.Args[1] == "get") {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
request, _ := http.NewRequestWithContext(ctx, http.MethodGet, os.Args[2], nil)
response, err := http.DefaultClient.Do(request)
if err != nil || response.StatusCode != http.StatusOK {
os.Exit(1)
}
defer response.Body.Close()
if os.Args[1] == "get" {
_, _ = io.CopyN(os.Stdout, response.Body, 64<<10)
}
return
}
listen := flag.String("listen", ":9090", "listen address")
flag.Parse()
state := &counters{keys: map[string]struct{}{}, events: map[string]int{}}
mux := http.NewServeMux()
mux.HandleFunc("/healthz", func(writer http.ResponseWriter, _ *http.Request) { writer.WriteHeader(http.StatusOK) })
mux.HandleFunc("/api/v1/query", state.prometheus)
mux.HandleFunc("/api/v1/query_range", state.prometheus)
mux.HandleFunc("/webhook", state.webhook)
mux.HandleFunc("/smoke/status", state.status)
server := &http.Server{Addr: *listen, Handler: mux, ReadHeaderTimeout: 2 * time.Second, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, IdleTimeout: 15 * time.Second}
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func (state *counters) prometheus(writer http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodGet || strings.TrimSpace(request.URL.Query().Get("query")) == "" {
http.Error(writer, "invalid query", http.StatusBadRequest)
return
}
state.mu.Lock()
state.prometheusRequests++
state.mu.Unlock()
now := float64(time.Now().UTC().Unix())
data := map[string]any{"resultType": "vector", "result": []any{map[string]any{"metric": map[string]string{"instance": "smoke-host"}, "value": []any{now, "95"}}}}
if request.URL.Path == "/api/v1/query_range" {
data = map[string]any{"resultType": "matrix", "result": []any{map[string]any{"metric": map[string]string{"instance": "smoke-host"}, "values": []any{[]any{now - 60, "90"}, []any{now, "95"}}}}}
}
writeJSON(writer, http.StatusOK, map[string]any{"status": "success", "data": data})
}
func (state *counters) webhook(writer http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodPost {
writer.WriteHeader(http.StatusMethodNotAllowed)
return
}
expected := os.Getenv("PULSE_SMOKE_WEBHOOK_TOKEN")
if expected == "" || request.Header.Get("Authorization") != "Bearer "+expected {
writer.WriteHeader(http.StatusUnauthorized)
return
}
key := request.Header.Get("Idempotency-Key")
var payload struct {
EventType string `json:"eventType"`
}
if key == "" || json.NewDecoder(http.MaxBytesReader(writer, request.Body, 16<<10)).Decode(&payload) != nil {
writer.WriteHeader(http.StatusBadRequest)
return
}
state.mu.Lock()
state.webhookRequests++
state.keys[key] = struct{}{}
state.lastEvent = payload.EventType
state.events[payload.EventType]++
state.mu.Unlock()
writer.WriteHeader(http.StatusNoContent)
}
func (state *counters) status(writer http.ResponseWriter, _ *http.Request) {
state.mu.Lock()
defer state.mu.Unlock()
writeJSON(writer, http.StatusOK, map[string]any{"prometheusRequests": state.prometheusRequests, "webhookRequests": state.webhookRequests, "uniqueDeliveryKeys": len(state.keys), "lastEventType": state.lastEvent, "events": state.events})
}
func writeJSON(writer http.ResponseWriter, status int, value any) {
writer.Header().Set("Content-Type", "application/json")
writer.WriteHeader(status)
_ = json.NewEncoder(writer).Encode(value)
}
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""Validate starter JSON Schemas and their canonical examples.
Requires the development-only `jsonschema` package. The core `projectctl.py`
remains standard-library-only so repository state can be recovered first.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
def load(path: Path) -> Any:
return json.loads(path.read_text(encoding="utf-8"))
def main() -> int:
try:
from jsonschema import Draft202012Validator
from referencing import Registry, Resource
except ModuleNotFoundError:
print(
"ERROR: contract validation requires the development package 'jsonschema'.",
file=sys.stderr,
)
return 2
schema_paths = sorted((ROOT / "specs").glob("*.json"))
schemas: dict[str, dict[str, Any]] = {}
resources: list[tuple[str, Any]] = []
for path in schema_paths:
schema = load(path)
Draft202012Validator.check_schema(schema)
schema_id = schema.get("$id")
if not isinstance(schema_id, str) or not schema_id:
print(f"ERROR: {path.relative_to(ROOT)} has no $id", file=sys.stderr)
return 1
schemas[path.relative_to(ROOT).as_posix()] = schema
resource = Resource.from_contents(schema)
resources.append((schema_id, resource))
resources.append((path.resolve().as_uri(), resource))
registry = Registry().with_resources(resources)
checks: list[tuple[str, str]] = [
("config/metrics/catalog.example.json", "specs/metric-catalog.schema.json"),
("config/dashboards/default-overview.example.json", "specs/dashboard.schema.json"),
("config/alerts/default-rules.example.json", "specs/alert-rule-set.schema.json"),
("config/probes/probe.example.json", "specs/probe.schema.json"),
]
# The canonical private repository validates its implementation ledger. The
# curated public-source export deliberately excludes private planning state.
if (ROOT / "planning" / "task-ledger.json").exists():
checks.insert(0, ("planning/task-ledger.json", "specs/task-ledger.schema.json"))
checks.extend(
(path.relative_to(ROOT).as_posix(), "specs/simulator-scenario.schema.json")
for path in sorted((ROOT / "fixtures" / "scenarios").glob("*.json"))
)
failures = 0
for document_name, schema_name in checks:
document = load(ROOT / document_name)
schema = schemas[schema_name]
validator = Draft202012Validator(schema, registry=registry)
errors = sorted(validator.iter_errors(document), key=lambda item: list(item.path))
if not errors:
print(f"PASS: {document_name}")
continue
failures += len(errors)
print(f"FAIL: {document_name}", file=sys.stderr)
for error in errors:
location = "/".join(str(part) for part in error.path) or "<root>"
print(f"- {location}: {error.message}", file=sys.stderr)
if failures:
print(f"CONTRACT VALIDATION: FAIL ({failures} errors)", file=sys.stderr)
return 1
print(f"CONTRACT VALIDATION: PASS ({len(schema_paths)} schemas, {len(checks)} documents)")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+89
View File
@@ -0,0 +1,89 @@
export function percentile(values, fraction) {
if (values.length === 0) return 0;
const sorted = [...values].sort((a, b) => a - b);
return sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * fraction))];
}
export function median(values) {
return percentile(values, 0.5);
}
export function linearSlopePerHour(samples, field) {
if (samples.length < 2) return 0;
const xs = samples.map((sample) => sample.elapsedMs / 3_600_000);
const ys = samples.map((sample) => sample[field]);
const meanX = xs.reduce((sum, value) => sum + value, 0) / xs.length;
const meanY = ys.reduce((sum, value) => sum + value, 0) / ys.length;
const denominator = xs.reduce((sum, value) => sum + ((value - meanX) ** 2), 0);
if (denominator === 0) return 0;
return xs.reduce((sum, value, index) => sum + ((value - meanX) * (ys[index] - meanY)), 0) / denominator;
}
export function buildSoakSummary({ samples, reconnects, startedAt, completedAt, durationHours, sampleSeconds, counters, requireWallboardTitle = false }) {
if (samples.length === 0) throw new Error('at least one wallboard sample is required');
const hourly = samples.filter((sample) => sample.forcedGC);
if (hourly.length === 0) throw new Error('at least one forced-GC sample is required');
const quarterSize = Math.max(1, Math.ceil(hourly.length / 4));
const firstQuarter = hourly.slice(0, quarterSize).map((sample) => sample.usedHeapBytes);
const lastQuarter = hourly.slice(-quarterSize).map((sample) => sample.usedHeapBytes);
const retainedGrowthBytes = median(lastQuarter) - median(firstQuarter);
const heapSlopeBytesPerHour = linearSlopePerHour(hourly, 'usedHeapBytes');
const maxAllowedGrowthBytes = Math.max(16 * 1024 * 1024, median(firstQuarter) * 0.20);
const elapsedHours = (completedAt.getTime() - startedAt.getTime()) / 3_600_000;
const expectedSampleCount = durationHours * 3_600 / sampleSeconds;
const minimumSampleCount = Math.floor(Math.min(expectedSampleCount * 0.99, Math.max(1, expectedSampleCount - 2)));
const sampleGapsSeconds = samples.slice(1).map((sample, index) => (sample.elapsedMs - samples[index].elapsedMs) / 1_000);
const maxSampleGapSeconds = Math.max(0, ...sampleGapsSeconds);
const maxAllowedSampleGapSeconds = sampleSeconds + 15;
const summary = {
status: 'pass',
startedAt: startedAt.toISOString(),
completedAt: completedAt.toISOString(),
elapsedHours,
sampleCount: samples.length,
forcedGCSampleCount: hourly.length,
expectedSampleCount,
minimumSampleCount,
maxSampleGapSeconds,
maxAllowedSampleGapSeconds,
reconnectCount: reconnects.length,
reconnectFailures: reconnects.filter((item) => !item.recovered).length,
reconnectP95Ms: percentile(reconnects.map((item) => item.durationMs), 0.95),
retainedGrowthBytes,
heapSlopeBytesPerHour,
maxAllowedGrowthBytes,
fpsP05: percentile(samples.map((sample) => sample.fps), 0.05),
frameP95WorstMs: Math.max(...samples.map((sample) => sample.frameP95Ms)),
longestTaskMs: Math.max(...samples.map((sample) => sample.longestTaskMs)),
maxActiveSockets: counters.maxActiveSockets,
openedSockets: counters.openedSockets,
closedSockets: counters.closedSockets,
websocketErrors: counters.websocketErrors ?? 0,
socketChurnBudget: reconnects.length + 4,
pageErrors: counters.pageErrors,
apiFailures: counters.apiFailures,
maxDOMNodes: Math.max(...samples.map((sample) => sample.nodes)),
horizontalOverflowSamples: samples.filter((sample) => sample.bodyWidth > sample.viewportWidth).length,
verticalOverflowSamples: samples.filter((sample) => sample.bodyHeight != null && sample.viewportHeight != null && sample.bodyHeight > sample.viewportHeight).length,
invalidWallboardSamples: samples.filter((sample) => {
if (sample.wallboardTitle == null || sample.activeDashboard == null) return requireWallboardTitle;
return sample.wallboardTitle !== 'Operationeel wallboard' || !/^Wallboard soak [12]$/.test(sample.activeDashboard);
}).length,
};
const failures = [];
if (summary.elapsedHours < durationHours) failures.push('elapsed duration shorter than requested');
if (summary.sampleCount < minimumSampleCount || maxSampleGapSeconds > maxAllowedSampleGapSeconds) failures.push('sample coverage or continuity fell below the uninterrupted-run budget');
if (retainedGrowthBytes > maxAllowedGrowthBytes || heapSlopeBytesPerHour > 1024 * 1024) failures.push('retained heap growth exceeded the bounded budget');
if (summary.reconnectFailures > 0 || summary.reconnectP95Ms > 10_000) failures.push('WebSocket reconnect exceeded 10 seconds');
if (summary.frameP95WorstMs > 50 || summary.fpsP05 < 30 || summary.longestTaskMs > 250) failures.push('visible-jank budget exceeded');
if (summary.maxActiveSockets > 2) failures.push('active WebSocket count was unbounded');
if (summary.openedSockets > summary.socketChurnBudget) failures.push('WebSocket lifecycle churn exceeded the bounded budget');
if (summary.websocketErrors > 0 || summary.pageErrors > 0 || summary.apiFailures > 0) failures.push('runtime browser, API or WebSocket failures occurred');
if (summary.horizontalOverflowSamples > 0 || summary.verticalOverflowSamples > 0) failures.push('wallboard overflowed the viewport');
if (summary.invalidWallboardSamples > 0) failures.push('wallboard content disappeared during the soak');
if (failures.length > 0) {
summary.status = 'fail';
summary.failures = failures;
}
return summary;
}
+280
View File
@@ -0,0 +1,280 @@
import { appendFile, mkdir, writeFile } from 'node:fs/promises';
import { createRequire } from 'node:module';
import path from 'node:path';
import { buildSoakSummary } from './wallboard-soak-analysis.mjs';
const requireFromWebWorkspace = createRequire(new URL('../apps/web/package.json', import.meta.url));
const { chromium } = requireFromWebWorkspace('@playwright/test');
const baseURL = process.env.PULSE_SOAK_BASE_URL;
const outputDirectory = path.resolve(process.env.PULSE_SOAK_OUTPUT_DIR ?? 'artifacts/evidence/M10-14/raw');
const durationHours = Number(process.env.PULSE_SOAK_DURATION_HOURS ?? '24');
const sampleSeconds = Number(process.env.PULSE_SOAK_SAMPLE_SECONDS ?? '60');
const reconnectSeconds = Number(process.env.PULSE_SOAK_RECONNECT_SECONDS ?? '3600');
const dashboardIDs = ['51000000-0000-4000-8000-000000000001', '51000000-0000-4000-8000-000000000002'];
if (!baseURL || !Number.isFinite(durationHours) || durationHours <= 0 || !Number.isFinite(sampleSeconds) || sampleSeconds < 5 || !Number.isFinite(reconnectSeconds) || reconnectSeconds < 30) {
throw new Error('PULSE_SOAK_BASE_URL and positive bounded soak durations are required');
}
await mkdir(outputDirectory, { recursive: true });
const samplesPath = path.join(outputDirectory, 'samples.ndjson');
const reconnectsPath = path.join(outputDirectory, 'reconnects.ndjson');
const eventsPath = path.join(outputDirectory, 'events.ndjson');
const metadataPath = path.join(outputDirectory, 'metadata.json');
const summaryPath = path.join(outputDirectory, 'result.json');
const startedAt = new Date();
const durationMs = durationHours * 60 * 60 * 1000;
const endAt = startedAt.getTime() + durationMs;
let eventWrite = Promise.resolve();
const writeEvent = (type, details = {}) => {
eventWrite = eventWrite.then(() => appendFile(eventsPath, `${JSON.stringify({ timestamp: new Date().toISOString(), type, ...details })}\n`));
return eventWrite;
};
function dashboardDocument(id, index) {
const widgetID = `52000000-0000-4000-8000-00000000000${index}`;
return {
schemaVersion: 2,
id,
slug: `wallboard-soak-${index}`,
name: `Wallboard soak ${index}`,
description: 'Echte 24-uursmeting met begrensde live CPU-data.',
// Mock login intentionally does not provision a durable user row. A
// system-scoped soak dashboard stays visible to the same read principal
// without weakening the production ownership query.
scope: 'system',
variables: [],
widgets: [{
id: widgetID,
type: 'timeseries',
title: 'CPU live',
description: 'Prometheus-query en WebSocket live-buffer.',
data: { sourceType: 'semantic-metric', metric: 'host.cpu.utilization', scope: { serverId: 'smoke-host' }, aggregation: 'avg', groupBy: ['instance'], transformations: [] },
visualization: { unit: 'percent', decimals: 1, legend: true, showSparkline: false, min: 0, max: 100, thresholds: [] },
behavior: { locked: true, hidden: false, hideWhenEmpty: false, showOnlyOnProblem: false, liveIntervalSeconds: 2, independentTimeRange: null },
layouts: {
desktop: { x: 0, y: 0, w: 18, h: 8, visible: true },
tablet: { x: 0, y: 0, w: 8, h: 8, visible: true },
mobile: { x: 0, y: 0, w: 1, h: 8, visible: true },
wallboard: { x: 0, y: 0, w: 24, h: 12, visible: true },
},
}],
settings: { defaultTimeRange: 'live', live: true, refreshSeconds: 10, rotationSeconds: 10 },
};
}
const browser = await chromium.launch({ headless: true, args: ['--enable-precise-memory-info', '--disable-background-timer-throttling', '--disable-renderer-backgrounding'] });
const context = await browser.newContext({ baseURL, viewport: { width: 1920, height: 1080 }, locale: 'nl-BE' });
let page;
const samples = [];
const reconnects = [];
let activeSockets = 0;
let maxActiveSockets = 0;
let openedSockets = 0;
let closedSockets = 0;
let websocketErrors = 0;
let pageErrors = 0;
let apiFailures = 0;
try {
const login = await context.request.get('/auth/test-login');
if (!login.ok()) throw new Error(`mock login failed with ${login.status()}`);
for (let index = 0; index < dashboardIDs.length; index += 1) {
const response = await context.request.post('/api/v1/dashboards', { data: dashboardDocument(dashboardIDs[index], index + 1) });
if (!response.ok() && response.status() !== 409) throw new Error(`dashboard seed failed with ${response.status()}: ${await response.text()}`);
}
await context.addInitScript((ids) => {
for (const id of ids) window.localStorage.setItem(`pulse.dashboard.view.${id}.range`, 'live');
window.__pulseSoak = { longTasks: [], sockets: new Set(), startedAt: Date.now() };
const NativeWebSocket = window.WebSocket;
window.WebSocket = class SoakObservableWebSocket extends NativeWebSocket {
constructor(...args) {
super(...args);
window.__pulseSoak.sockets.add(this);
this.addEventListener('close', () => window.__pulseSoak.sockets.delete(this), { once: true });
}
};
if ('PerformanceObserver' in window) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) window.__pulseSoak.longTasks.push({ at: Date.now(), duration: entry.duration });
});
try { observer.observe({ type: 'longtask', buffered: true }); } catch { /* unsupported browsers remain measurable through frame deltas */ }
}
}, dashboardIDs);
page = await context.newPage();
page.on('pageerror', (error) => { pageErrors += 1; void writeEvent('page-error', { message: error.message.slice(0, 300) }); });
page.on('response', (response) => {
if (new URL(response.url()).pathname.startsWith('/api/') && response.status() >= 400) {
apiFailures += 1;
void writeEvent('api-failure', { status: response.status(), path: new URL(response.url()).pathname });
}
});
page.on('websocket', (socket) => {
openedSockets += 1;
activeSockets += 1;
maxActiveSockets = Math.max(maxActiveSockets, activeSockets);
void writeEvent('websocket-open', { url: new URL(socket.url()).pathname, activeSockets });
socket.on('close', () => {
activeSockets = Math.max(0, activeSockets - 1);
closedSockets += 1;
void writeEvent('websocket-close', { activeSockets });
});
socket.on('socketerror', (error) => {
websocketErrors += 1;
void writeEvent('websocket-error', { message: String(error).slice(0, 300) });
});
});
const cdp = await context.newCDPSession(page);
await cdp.send('Performance.enable');
await cdp.send('HeapProfiler.enable');
await page.goto('/wallboard?interval=10&refresh=10', { waitUntil: 'networkidle' });
await page.getByRole('heading', { level: 1, name: 'Operationeel wallboard' }).waitFor({ state: 'visible', timeout: 30_000 });
await page.getByText(/Wallboard soak [12]/).first().waitFor({ state: 'visible', timeout: 30_000 });
await writeFile(metadataPath, `${JSON.stringify({
startedAt: startedAt.toISOString(),
plannedEndAt: new Date(endAt).toISOString(),
durationHours,
sampleSeconds,
reconnectSeconds,
viewport: { width: 1920, height: 1080 },
browser: await browser.version(),
baseURL: new URL(baseURL).origin,
dashboards: dashboardIDs.length,
}, null, 2)}\n`);
await writeEvent('soak-started');
let nextSampleAt = Date.now();
let nextReconnectAt = startedAt.getTime() + reconnectSeconds * 1000;
let nextGCAt = startedAt.getTime();
let sampleNumber = 0;
while (Date.now() < endAt) {
const now = Date.now();
if (now >= nextReconnectAt) {
const outageMs = 500;
const reconnectStarted = Date.now();
const openedBefore = openedSockets;
await context.setOffline(true);
await page.evaluate(() => {
for (const socket of window.__pulseSoak.sockets) socket.close(4000, 'scheduled soak disconnect');
});
await page.waitForTimeout(outageMs);
await context.setOffline(false);
let recovered = false;
const deadline = Date.now() + 10_000;
while (Date.now() < deadline) {
if (openedSockets > openedBefore && activeSockets > 0) { recovered = true; break; }
await page.waitForTimeout(250);
}
const reconnect = { timestamp: new Date().toISOString(), elapsedMs: Date.now() - startedAt.getTime(), outageMs, durationMs: Date.now() - reconnectStarted - outageMs, recovered, openedBefore, openedAfter: openedSockets, activeSockets };
reconnects.push(reconnect);
await appendFile(reconnectsPath, `${JSON.stringify(reconnect)}\n`);
nextReconnectAt += reconnectSeconds * 1000;
}
if (now >= nextSampleAt) {
sampleNumber += 1;
const elapsedMs = now - startedAt.getTime();
const forcedGC = now >= nextGCAt;
if (forcedGC) {
await cdp.send('HeapProfiler.collectGarbage');
nextGCAt += 3_600_000;
}
const [{ metrics }, heap, frame] = await Promise.all([
cdp.send('Performance.getMetrics'),
cdp.send('Runtime.getHeapUsage'),
page.evaluate(async () => {
const deltas = [];
const started = performance.now();
let previous = started;
await new Promise((resolve) => {
const tick = (timestamp) => {
deltas.push(timestamp - previous);
previous = timestamp;
if (timestamp - started >= 2_000) resolve(); else requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
});
const longTasks = window.__pulseSoak?.longTasks?.splice(0) ?? [];
return {
frameCount: deltas.length,
frameDurationMs: performance.now() - started,
frameP95Ms: deltas.sort((a, b) => a - b)[Math.min(deltas.length - 1, Math.floor(deltas.length * 0.95))] ?? 0,
framesOver50Ms: deltas.filter((value) => value > 50).length,
longTaskCount: longTasks.length,
longestTaskMs: longTasks.reduce((max, task) => Math.max(max, task.duration), 0),
domNodes: document.getElementsByTagName('*').length,
bodyWidth: document.body.scrollWidth,
viewportWidth: window.innerWidth,
bodyHeight: document.documentElement.scrollHeight,
viewportHeight: window.innerHeight,
wallboardTitle: document.querySelector('#wallboard-title')?.textContent ?? '',
activeDashboard: document.querySelector('#dashboard-view-title')?.textContent ?? '',
};
}),
]);
const metricMap = Object.fromEntries(metrics.map((metric) => [metric.name, metric.value]));
const sample = {
sequence: sampleNumber,
timestamp: new Date().toISOString(),
elapsedMs,
forcedGC,
usedHeapBytes: heap.usedSize,
totalHeapBytes: heap.totalSize,
jsHeapUsedBytes: metricMap.JSHeapUsedSize ?? null,
jsHeapTotalBytes: metricMap.JSHeapTotalSize ?? null,
nodes: metricMap.Nodes ?? frame.domNodes,
documents: metricMap.Documents ?? null,
listeners: metricMap.JSEventListeners ?? null,
layoutCount: metricMap.LayoutCount ?? null,
recalcStyleCount: metricMap.RecalcStyleCount ?? null,
taskDurationSeconds: metricMap.TaskDuration ?? null,
fps: frame.frameDurationMs > 0 ? (frame.frameCount * 1000) / frame.frameDurationMs : 0,
frameP95Ms: frame.frameP95Ms,
framesOver50Ms: frame.framesOver50Ms,
longTaskCount: frame.longTaskCount,
longestTaskMs: frame.longestTaskMs,
bodyWidth: frame.bodyWidth,
viewportWidth: frame.viewportWidth,
bodyHeight: frame.bodyHeight,
viewportHeight: frame.viewportHeight,
activeSockets,
openedSockets,
closedSockets,
pageErrors,
apiFailures,
wallboardTitle: frame.wallboardTitle,
activeDashboard: frame.activeDashboard,
};
samples.push(sample);
await appendFile(samplesPath, `${JSON.stringify(sample)}\n`);
nextSampleAt += sampleSeconds * 1000;
}
await page.waitForTimeout(Math.max(100, Math.min(1_000, Math.min(nextSampleAt, nextReconnectAt, endAt) - Date.now())));
}
const summary = buildSoakSummary({
samples,
reconnects,
startedAt,
completedAt: new Date(),
durationHours,
sampleSeconds,
counters: { maxActiveSockets, openedSockets, closedSockets, websocketErrors, pageErrors, apiFailures },
requireWallboardTitle: true,
});
await writeFile(summaryPath, `${JSON.stringify(summary, null, 2)}\n`);
await writeEvent('soak-completed', { status: summary.status });
if (summary.status !== 'pass') throw new Error(`wallboard soak failed: ${summary.failures.join('; ')}`);
} catch (error) {
await writeEvent('soak-failed', { message: error instanceof Error ? error.message : String(error) });
throw error;
} finally {
await page?.close().catch(() => {});
await context.close().catch(() => {});
await browser.close().catch(() => {});
}
+4
View File
@@ -0,0 +1,4 @@
{
"description": "Packages that tools/check_wiring.py has confirmed are implemented but not yet reachable from a running binary (cmd/api, cmd/worker, cmd/agent, cmd/migrate). Every entry requires a 'reason' and a tracking 'task' id — this list makes wiring debt visible, it does not forgive it. Remove an entry as soon as the referenced task wires its package to an entry point; check_wiring.py reports any entry that has become reachable as stale and fails until it is removed.",
"entries": []
}