update report h6

This commit is contained in:
thanhnv
2026-07-20 23:47:09 +07:00
parent f462079435
commit 4b6819f578
38 changed files with 1244 additions and 62 deletions
@@ -3,8 +3,8 @@
// Mirrors packages/casan-harness/scripts/bash/casan-paths.sh: walk UP from a start dir
// for a marker (`.specify` state dir OR `packages/casan-harness`), so the API reads the
// real harness telemetry whether launched from the repo, a workspace subdir, or a bundle.
// Every path is overridable by the same CASAN_DASHBOARD_* env vars the legacy
// dashboard-server.py honors, so console + dashboard read identical sources.
// Canonical CASAN_TELEMETRY_* variables are shared with harness writers; legacy
// dashboard/control-panel names remain accepted so upgrades do not split sources.
import { existsSync, statSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
@@ -27,35 +27,74 @@ export const APP_ROOT = process.env.CASAN_APP_ROOT
? resolve(process.env.CASAN_APP_ROOT)
: findAppRoot(HERE);
const env = (k: string, fallback: string) => (process.env[k] ? resolve(process.env[k]!) : join(APP_ROOT, fallback));
const env = (keys: string[], fallback: string) => {
const configured = keys.map((key) => process.env[key]).find((value): value is string => Boolean(value));
return configured ? resolve(configured) : join(APP_ROOT, fallback);
};
// Runtime telemetry (regenerated) + generated reports. Names match the harness layout.
export const PATHS = {
metrics: env('CASAN_DASHBOARD_METRICS', '.specify/logs/cost/metrics.jsonl'),
providerUsage: env('CASAN_CP_PROVIDER_USAGE', '.specify/logs/level5/provider-usage.jsonl'),
audit: env('CASAN_CP_AUDIT', '.specify/logs/audit/audit.jsonl'),
auditHead: env('CASAN_CP_AUDIT_HEAD', '.specify/logs/audit/audit-head.txt'),
security: env('CASAN_CP_SECURITY', '.specify/logs/audit/security.jsonl'),
toolRegistry: env('CASAN_CP_TOOL_REGISTRY', '.specify/logs/level5/tool-registry.jsonl'),
actionGate: env('CASAN_CP_ACTION_GATE', '.specify/logs/level5/action-gate.jsonl'),
fallback: env('CASAN_CP_FALLBACK', '.specify/logs/level5/fallback.jsonl'),
incidents: env('CASAN_CP_INCIDENTS', '.specify/logs/level5/incidents.jsonl'),
alerts: env('CASAN_DASHBOARD_ALERTS', '.specify/agentops/alerts.log'),
traceDir: env('CASAN_CP_TRACE_DIR', '.specify/logs/trace'),
traceEventDir: env('CASAN_CP_TRACE_EVENT_DIR', '.specify/logs/trace-events'),
traceability: env('CASAN_CP_TRACEABILITY', 'docs/output/casan/traceability-matrix.json'),
drift: env('CASAN_CP_DRIFT', 'docs/output/casan/level5-evidence/09-drift-report.json'),
businessKpi: env('CASAN_CP_KPI', 'docs/output/casan/level5-evidence/14-business-kpi-report.json'),
benignFp: env('CASAN_CP_BENIGN_FP', 'docs/output/casan/benign-fp-report.json'),
scoringReport: env('CASAN_CP_SCORING_REPORT', 'docs/output/casan/phase3-real-run-scoring.md'),
approvalInbox: env('CASAN_CP_APPROVAL_INBOX', '.specify/level5/approval-inbox.json'),
chatAudit: env('CASAN_CP_CHAT_AUDIT', '.specify/logs/chat/chat-turns.jsonl'),
delegationPolicy: env('CASAN_CP_DELEGATION_POLICY', 'packages/casan-harness/config/delegation-policy.yaml'),
selfImprove: env('CASAN_CP_SELF_IMPROVE', 'packages/casan-harness/scripts/bash/self-improve.py'),
evidencePacks: env('CASAN_CP_EVIDENCE_PACKS', 'docs/output/casan/evidence-packs'),
metrics: env(['CASAN_TELEMETRY_METRICS_LOG', 'CASAN_DASHBOARD_METRICS'], '.specify/logs/cost/metrics.jsonl'),
providerUsage: env(['CASAN_TELEMETRY_PROVIDER_LOG', 'CASAN_CP_PROVIDER_USAGE'], '.specify/logs/level5/provider-usage.jsonl'),
alerts: env(['CASAN_TELEMETRY_ALERTS_LOG', 'CASAN_DASHBOARD_ALERTS'], '.specify/agentops/alerts.log'),
audit: env(['CASAN_CP_AUDIT'], '.specify/logs/audit/audit.jsonl'),
auditHead: env(['CASAN_CP_AUDIT_HEAD'], '.specify/logs/audit/audit-head.txt'),
security: env(['CASAN_CP_SECURITY'], '.specify/logs/audit/security.jsonl'),
toolRegistry: env(['CASAN_CP_TOOL_REGISTRY'], '.specify/logs/level5/tool-registry.jsonl'),
actionGate: env(['CASAN_CP_ACTION_GATE'], '.specify/logs/level5/action-gate.jsonl'),
fallback: env(['CASAN_CP_FALLBACK'], '.specify/logs/level5/fallback.jsonl'),
incidents: env(['CASAN_CP_INCIDENTS'], '.specify/logs/level5/incidents.jsonl'),
traceDir: env(['CASAN_CP_TRACE_DIR'], '.specify/logs/trace'),
traceEventDir: env(['CASAN_CP_TRACE_EVENT_DIR'], '.specify/logs/trace-events'),
traceability: env(['CASAN_CP_TRACEABILITY'], 'docs/output/casan/traceability-matrix.json'),
drift: env(['CASAN_CP_DRIFT'], 'docs/output/casan/level5-evidence/09-drift-report.json'),
businessKpi: env(['CASAN_CP_KPI'], 'docs/output/casan/level5-evidence/14-business-kpi-report.json'),
benignFp: env(['CASAN_CP_BENIGN_FP'], 'docs/output/casan/benign-fp-report.json'),
scoringReport: env(['CASAN_CP_SCORING_REPORT'], 'docs/output/casan/phase3-real-run-scoring.md'),
approvalInbox: env(['CASAN_CP_APPROVAL_INBOX'], '.specify/level5/approval-inbox.json'),
chatAudit: env(['CASAN_CP_CHAT_AUDIT'], '.specify/logs/chat/chat-turns.jsonl'),
delegationPolicy: env(['CASAN_CP_DELEGATION_POLICY'], 'packages/casan-harness/config/delegation-policy.yaml'),
selfImprove: env(['CASAN_CP_SELF_IMPROVE'], 'packages/casan-harness/scripts/bash/self-improve.py'),
evidencePacks: env(['CASAN_CP_EVIDENCE_PACKS'], 'docs/output/casan/evidence-packs'),
};
export const STALE_AFTER_S = Number(process.env.CASAN_DASHBOARD_STALE_S ?? 3600);
const configuredStaleAfter = Number(process.env.CASAN_DASHBOARD_STALE_S ?? 3600);
export const STALE_AFTER_S = Number.isFinite(configuredStaleAfter) && configuredStaleAfter >= 0
? configuredStaleAfter
: 3600;
export interface SourceFreshness {
source: 'metrics' | 'provider' | 'alerts';
path: string;
present: boolean;
updated_at: string | null;
age_s: number | null;
stale: boolean;
required: boolean;
}
export function sourceFreshness(
source: SourceFreshness['source'],
path: string,
required: boolean,
nowMs = Date.now(),
): SourceFreshness {
try {
const mtime = statSync(path).mtime;
const age = Math.max(0, Math.floor((nowMs - mtime.getTime()) / 1000));
return { source, path, present: true, updated_at: mtime.toISOString(), age_s: age, stale: age > STALE_AFTER_S, required };
} catch {
return { source, path, present: false, updated_at: null, age_s: null, stale: required, required };
}
}
export function telemetryFreshness(nowMs = Date.now()): SourceFreshness[] {
return [
sourceFreshness('metrics', PATHS.metrics, true, nowMs),
sourceFreshness('provider', PATHS.providerUsage, false, nowMs),
sourceFreshness('alerts', PATHS.alerts, false, nowMs),
];
}
// Freshness of the primary metrics feed (mtime), used by /healthz + `stale` flags.
export function metricsAgeSeconds(): number | null {