@miller-tech/uap 2.21.3 → 2.36.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/config/model-profiles/qwen38-coder390.json +46 -0
- package/config/model-profiles/qwen38.json +3 -2
- package/config/model-registry.json +110 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/types.d.ts +2 -2
- package/dist/bin/cli.js +315 -20
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/attention.d.ts +6 -0
- package/dist/cli/attention.d.ts.map +1 -0
- package/dist/cli/attention.js +115 -0
- package/dist/cli/attention.js.map +1 -0
- package/dist/cli/bench-report.d.ts +82 -0
- package/dist/cli/bench-report.d.ts.map +1 -0
- package/dist/cli/bench-report.js +237 -0
- package/dist/cli/bench-report.js.map +1 -0
- package/dist/cli/clients.d.ts +6 -0
- package/dist/cli/clients.d.ts.map +1 -0
- package/dist/cli/clients.js +142 -0
- package/dist/cli/clients.js.map +1 -0
- package/dist/cli/dashboard-grants.d.ts +26 -0
- package/dist/cli/dashboard-grants.d.ts.map +1 -0
- package/dist/cli/dashboard-grants.js +69 -0
- package/dist/cli/dashboard-grants.js.map +1 -0
- package/dist/cli/dashboard-pace.d.ts +31 -0
- package/dist/cli/dashboard-pace.d.ts.map +1 -0
- package/dist/cli/dashboard-pace.js +42 -0
- package/dist/cli/dashboard-pace.js.map +1 -0
- package/dist/cli/dashboard-session.d.ts +25 -0
- package/dist/cli/dashboard-session.d.ts.map +1 -0
- package/dist/cli/dashboard-session.js +814 -0
- package/dist/cli/dashboard-session.js.map +1 -0
- package/dist/cli/dashboard-types.d.ts +18 -0
- package/dist/cli/dashboard-types.d.ts.map +1 -0
- package/dist/cli/dashboard-types.js +9 -0
- package/dist/cli/dashboard-types.js.map +1 -0
- package/dist/cli/dashboard.d.ts +2 -18
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +43 -793
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/deliver.d.ts +35 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +93 -9
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/diff.d.ts +85 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +293 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eta.d.ts +35 -0
- package/dist/cli/eta.d.ts.map +1 -0
- package/dist/cli/eta.js +101 -0
- package/dist/cli/eta.js.map +1 -0
- package/dist/cli/handsfree.d.ts +7 -0
- package/dist/cli/handsfree.d.ts.map +1 -1
- package/dist/cli/handsfree.js +27 -0
- package/dist/cli/handsfree.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +126 -5
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/loops.d.ts +24 -5
- package/dist/cli/loops.d.ts.map +1 -1
- package/dist/cli/loops.js +92 -12
- package/dist/cli/loops.js.map +1 -1
- package/dist/cli/models.d.ts +62 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +567 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +9 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +57 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/proxy-relay.d.ts +55 -0
- package/dist/cli/proxy-relay.d.ts.map +1 -0
- package/dist/cli/proxy-relay.js +116 -0
- package/dist/cli/proxy-relay.js.map +1 -0
- package/dist/cli/proxy.d.ts +4 -0
- package/dist/cli/proxy.d.ts.map +1 -1
- package/dist/cli/proxy.js +26 -1
- package/dist/cli/proxy.js.map +1 -1
- package/dist/cli/sandbox.d.ts +101 -4
- package/dist/cli/sandbox.d.ts.map +1 -1
- package/dist/cli/sandbox.js +393 -44
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/self.d.ts +13 -0
- package/dist/cli/self.d.ts.map +1 -0
- package/dist/cli/self.js +94 -0
- package/dist/cli/self.js.map +1 -0
- package/dist/cli/systemd-services.d.ts +2 -8
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +5 -20
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/cli/task.js +1 -1
- package/dist/cli/task.js.map +1 -1
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +31 -2
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/config/settings-registry.d.ts +1 -1
- package/dist/config/settings-registry.d.ts.map +1 -1
- package/dist/config/settings-registry.js +108 -0
- package/dist/config/settings-registry.js.map +1 -1
- package/dist/coordination/capability-router.js +2 -2
- package/dist/coordination/capability-router.js.map +1 -1
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -1
- package/dist/coordination/database.js +63 -7
- package/dist/coordination/database.js.map +1 -1
- package/dist/coordination/eta-inject.d.ts +32 -0
- package/dist/coordination/eta-inject.d.ts.map +1 -0
- package/dist/coordination/eta-inject.js +64 -0
- package/dist/coordination/eta-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +14 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/coordination/service.d.ts +18 -8
- package/dist/coordination/service.d.ts.map +1 -1
- package/dist/coordination/service.js +38 -28
- package/dist/coordination/service.js.map +1 -1
- package/dist/dashboard/client-registry.d.ts +163 -0
- package/dist/dashboard/client-registry.d.ts.map +1 -0
- package/dist/dashboard/client-registry.js +549 -0
- package/dist/dashboard/client-registry.js.map +1 -0
- package/dist/dashboard/controls.d.ts.map +1 -1
- package/dist/dashboard/controls.js +33 -4
- package/dist/dashboard/controls.js.map +1 -1
- package/dist/dashboard/data-seeder.d.ts +10 -7
- package/dist/dashboard/data-seeder.d.ts.map +1 -1
- package/dist/dashboard/data-seeder.js +31 -75
- package/dist/dashboard/data-seeder.js.map +1 -1
- package/dist/dashboard/data-service.d.ts +9 -0
- package/dist/dashboard/data-service.d.ts.map +1 -1
- package/dist/dashboard/data-service.js +32 -3
- package/dist/dashboard/data-service.js.map +1 -1
- package/dist/dashboard/placement-routes.d.ts +119 -0
- package/dist/dashboard/placement-routes.d.ts.map +1 -0
- package/dist/dashboard/placement-routes.js +331 -0
- package/dist/dashboard/placement-routes.js.map +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +408 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/delivery/attention.d.ts +130 -0
- package/dist/delivery/attention.d.ts.map +1 -0
- package/dist/delivery/attention.js +341 -0
- package/dist/delivery/attention.js.map +1 -0
- package/dist/delivery/decompose.d.ts +18 -0
- package/dist/delivery/decompose.d.ts.map +1 -1
- package/dist/delivery/decompose.js +22 -1
- package/dist/delivery/decompose.js.map +1 -1
- package/dist/delivery/eta-estimate.d.ts +111 -0
- package/dist/delivery/eta-estimate.d.ts.map +1 -0
- package/dist/delivery/eta-estimate.js +171 -0
- package/dist/delivery/eta-estimate.js.map +1 -0
- package/dist/delivery/eta.d.ts +23 -0
- package/dist/delivery/eta.d.ts.map +1 -0
- package/dist/delivery/eta.js +59 -0
- package/dist/delivery/eta.js.map +1 -0
- package/dist/delivery/orchestrated-mission.d.ts +10 -0
- package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
- package/dist/delivery/orchestrated-mission.js +15 -1
- package/dist/delivery/orchestrated-mission.js.map +1 -1
- package/dist/delivery/plan-check.d.ts +7 -1
- package/dist/delivery/plan-check.d.ts.map +1 -1
- package/dist/delivery/plan-check.js +23 -2
- package/dist/delivery/plan-check.js.map +1 -1
- package/dist/delivery/run-state.d.ts +1 -1
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +8 -1
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/task-orchestrator.d.ts +8 -3
- package/dist/delivery/task-orchestrator.d.ts.map +1 -1
- package/dist/delivery/task-orchestrator.js +75 -43
- package/dist/delivery/task-orchestrator.js.map +1 -1
- package/dist/delivery/task-sync.d.ts +21 -0
- package/dist/delivery/task-sync.d.ts.map +1 -1
- package/dist/delivery/task-sync.js +44 -8
- package/dist/delivery/task-sync.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +3 -3
- package/dist/delivery/task-workspace.js +3 -3
- package/dist/generators/self-card.d.ts +65 -0
- package/dist/generators/self-card.d.ts.map +1 -0
- package/dist/generators/self-card.js +256 -0
- package/dist/generators/self-card.js.map +1 -0
- package/dist/inference/probe.js +1 -1
- package/dist/inference/probe.js.map +1 -1
- package/dist/memory/prepopulate.d.ts.map +1 -1
- package/dist/memory/prepopulate.js +2 -0
- package/dist/memory/prepopulate.js.map +1 -1
- package/dist/models/analytics.d.ts +32 -0
- package/dist/models/analytics.d.ts.map +1 -1
- package/dist/models/analytics.js +68 -5
- package/dist/models/analytics.js.map +1 -1
- package/dist/models/plan-readability.d.ts +55 -0
- package/dist/models/plan-readability.d.ts.map +1 -0
- package/dist/models/plan-readability.js +339 -0
- package/dist/models/plan-readability.js.map +1 -0
- package/dist/placement/admission.d.ts +59 -0
- package/dist/placement/admission.d.ts.map +1 -0
- package/dist/placement/admission.js +197 -0
- package/dist/placement/admission.js.map +1 -0
- package/dist/placement/auto.d.ts +44 -0
- package/dist/placement/auto.d.ts.map +1 -0
- package/dist/placement/auto.js +212 -0
- package/dist/placement/auto.js.map +1 -0
- package/dist/placement/enforce.d.ts +128 -0
- package/dist/placement/enforce.d.ts.map +1 -0
- package/dist/placement/enforce.js +655 -0
- package/dist/placement/enforce.js.map +1 -0
- package/dist/placement/idle.d.ts +50 -0
- package/dist/placement/idle.d.ts.map +1 -0
- package/dist/placement/idle.js +213 -0
- package/dist/placement/idle.js.map +1 -0
- package/dist/placement/ledger.d.ts +323 -0
- package/dist/placement/ledger.d.ts.map +1 -0
- package/dist/placement/ledger.js +263 -0
- package/dist/placement/ledger.js.map +1 -0
- package/dist/placement/preview.d.ts +51 -0
- package/dist/placement/preview.d.ts.map +1 -0
- package/dist/placement/preview.js +61 -0
- package/dist/placement/preview.js.map +1 -0
- package/dist/placement/probes.d.ts +47 -0
- package/dist/placement/probes.d.ts.map +1 -0
- package/dist/placement/probes.js +207 -0
- package/dist/placement/probes.js.map +1 -0
- package/dist/placement/proxy-env.d.ts +21 -0
- package/dist/placement/proxy-env.d.ts.map +1 -0
- package/dist/placement/proxy-env.js +42 -0
- package/dist/placement/proxy-env.js.map +1 -0
- package/dist/placement/registry.d.ts +1038 -0
- package/dist/placement/registry.d.ts.map +1 -0
- package/dist/placement/registry.js +274 -0
- package/dist/placement/registry.js.map +1 -0
- package/dist/policies/liveness.d.ts +6 -8
- package/dist/policies/liveness.d.ts.map +1 -1
- package/dist/policies/liveness.js +6 -25
- package/dist/policies/liveness.js.map +1 -1
- package/dist/policies/sandbox-anchor.d.ts +91 -0
- package/dist/policies/sandbox-anchor.d.ts.map +1 -0
- package/dist/policies/sandbox-anchor.js +187 -0
- package/dist/policies/sandbox-anchor.js.map +1 -0
- package/dist/policies/sandbox-grants.d.ts +131 -0
- package/dist/policies/sandbox-grants.d.ts.map +1 -0
- package/dist/policies/sandbox-grants.js +562 -0
- package/dist/policies/sandbox-grants.js.map +1 -0
- package/dist/state/manifest.d.ts +4 -2
- package/dist/state/manifest.d.ts.map +1 -1
- package/dist/state/manifest.js +32 -16
- package/dist/state/manifest.js.map +1 -1
- package/dist/utils/checkout-root.d.ts +2 -0
- package/dist/utils/checkout-root.d.ts.map +1 -0
- package/dist/utils/checkout-root.js +43 -0
- package/dist/utils/checkout-root.js.map +1 -0
- package/dist/utils/resolve-uap-bin.d.ts +5 -0
- package/dist/utils/resolve-uap-bin.d.ts.map +1 -0
- package/dist/utils/resolve-uap-bin.js +33 -0
- package/dist/utils/resolve-uap-bin.js.map +1 -0
- package/dist/utils/terminal-safe.d.ts +12 -0
- package/dist/utils/terminal-safe.d.ts.map +1 -0
- package/dist/utils/terminal-safe.js +53 -0
- package/dist/utils/terminal-safe.js.map +1 -0
- package/docs/ATTRIBUTION.md +1 -0
- package/docs/DASHBOARD_UPLIFT_SPEC.md +8 -8
- package/docs/INDEX.md +6 -5
- package/docs/architecture/OVERVIEW.md +15 -3
- package/docs/architecture/PROTOCOL.md +7 -1
- package/docs/architecture/adr/0006-operator-directed-model-placement.md +86 -0
- package/docs/architecture/adr/0007-auto-displacement-allowlist-as-standing-consent.md +79 -0
- package/docs/architecture/adr/0008-fleet-clients-link-out.md +92 -0
- package/docs/architecture/adr/0009-completion-triggered-dispatch-and-per-leaf-model-dials.md +71 -0
- package/docs/architecture/adr/0010-attention-queue-and-afk-auto-decider.md +159 -0
- package/docs/architecture/adr/0011-sandbox-grants-and-network-egress-boundary.md +219 -0
- package/docs/architecture/adr/0012-operator-legibility-surfaces.md +175 -0
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
- package/docs/guides/LOCAL_MODELS.md +1 -1
- package/docs/guides/PROXY.md +2 -1
- package/docs/guides/SANDBOX.md +91 -4
- package/docs/integrations/MCP_ROUTER.md +1 -1
- package/docs/plans/model-performance-proof-options.md +176 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +169 -4
- package/docs/reference/COMPARISON.md +1 -1
- package/docs/reference/CONFIGURATION.md +12 -3
- package/docs/reference/CONFIGURATION_REFERENCE.md +269 -14
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +15 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +14 -1
- package/docs/specs/operator-model-placement.md +1314 -0
- package/docs/specs/operator-model-placement.review.md +339 -0
- package/package.json +2 -2
- package/scripts/maintenance/publish-npm.sh +23 -11
- package/scripts/version-bump.sh +6 -51
- package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
- package/src/policies/schemas/policies/mandatory-testing-deployment.md +2 -5
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
- package/templates/hooks/session-start.sh +44 -0
- package/tools/agents/UAP/cli.py +14 -3
- package/tools/agents/UAP/paths.py +50 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +1420 -100
- package/tools/agents/scripts/toolcall_path_normalizer.py +46 -1
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +29 -6
- package/tools/agents/tests/test_doubling_break.py +64 -5
- package/tools/agents/tests/test_error_loop_break.py +10 -4
- package/tools/agents/tests/test_error_loop_ignores_correctives.py +13 -2
- package/tools/agents/tests/test_lockstep_escalation.py +280 -9
- package/tools/agents/tests/test_path_containment.py +94 -0
- package/tools/agents/tests/test_proxy_unix_socket.py +162 -0
- package/tools/agents/tests/test_signature_quality.py +400 -0
- package/tools/agents/tests/test_uap_compliance.py +11 -1
- package/web/dash/core.js +1 -0
- package/web/dash/tab-clients.js +196 -0
- package/web/dash/tab-models.js +387 -8
- package/web/dash/tab-policies.js +87 -4
- package/web/dash/tabs.js +77 -73
- package/web/dashboard.html +6 -0
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/web/dash/tab-agents.js +0 -21
- package/web/dash/tab-deliver.js +0 -12
- package/web/dash/tab-memory.js +0 -12
- package/web/dash/tab-orchestration.js +0 -21
- package/web/dash/tab-overview.js +0 -21
- package/web/dash/tab-tasks.js +0 -21
package/web/dash/tab-policies.js
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
)
|
|
83
83
|
);
|
|
84
84
|
var actions = el('div', { class: 'pol-actions' },
|
|
85
|
-
el('button', { class: 'btn btn-sm', title: 'View description + prompt', onclick: function () { openDetail(p.id); } }, 'View'),
|
|
85
|
+
el('button', { class: 'btn btn-sm', title: 'View description + prompt', onclick: function () { openDetail(p.id, listEl); } }, 'View'),
|
|
86
86
|
el('button', { class: 'btn btn-sm', title: 'Duplicate', onclick: function () { duplicate(p.id, listEl); } }, 'Duplicate'),
|
|
87
87
|
el('button', {
|
|
88
88
|
class: 'btn btn-sm ' + (p.isActive ? 'btn-on' : 'btn-off'),
|
|
@@ -117,8 +117,15 @@
|
|
|
117
117
|
}).catch(function () {});
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
function openDetail(id) {
|
|
120
|
+
function openDetail(id, listEl) {
|
|
121
121
|
get('/api/policy/' + id).then(function (p) {
|
|
122
|
+
var after = function () { if (listEl) reloadInto(listEl); };
|
|
123
|
+
var prioInput = el('input', { type: 'number', min: '0', step: '1', value: String(p.priority == null ? '' : p.priority), style: { width: '60px' } });
|
|
124
|
+
prioInput.addEventListener('change', function () {
|
|
125
|
+
var n = Math.max(0, Math.round(Number(prioInput.value)));
|
|
126
|
+
if (!isFinite(n)) return;
|
|
127
|
+
api('/api/policy/' + id + '/priority', { priority: n }).then(function () { toast('Priority updated', 'ok'); after(); });
|
|
128
|
+
});
|
|
122
129
|
var body = el('div', { class: 'pol-detail' },
|
|
123
130
|
el('div', { class: 'pol-badges' },
|
|
124
131
|
badge(p.level, 'lvl-' + String(p.level || '').toLowerCase()),
|
|
@@ -127,10 +134,12 @@
|
|
|
127
134
|
badge('prio ' + p.priority, 'prio'),
|
|
128
135
|
badge(p.isActive ? 'enabled' : 'disabled', p.isActive ? 'on' : 'off')
|
|
129
136
|
),
|
|
137
|
+
el('label', { class: 'field' }, 'Priority',
|
|
138
|
+
prioInput),
|
|
130
139
|
el('label', { class: 'field' }, 'Level',
|
|
131
|
-
selectFor(LEVELS, p.level, function (v) { api('/api/policy/' + id + '/level', { level: v }).then(function () { toast('Level updated', 'ok'); }); })),
|
|
140
|
+
selectFor(LEVELS, p.level, function (v) { api('/api/policy/' + id + '/level', { level: v }).then(function () { toast('Level updated', 'ok'); after(); }); })),
|
|
132
141
|
el('label', { class: 'field' }, 'Stage',
|
|
133
|
-
selectFor(STAGES, p.stage, function (v) { api('/api/policy/' + id + '/stage', { stage: v }).then(function () { toast('Stage updated', 'ok'); }); })),
|
|
142
|
+
selectFor(STAGES, p.stage, function (v) { api('/api/policy/' + id + '/stage', { stage: v }).then(function () { toast('Stage updated', 'ok'); after(); }); })),
|
|
134
143
|
el('div', { class: 'pol-section-label', text: 'Description' }),
|
|
135
144
|
el('div', { class: 'pol-desc-full', text: p.description || '(none)' }),
|
|
136
145
|
el('div', { class: 'pol-section-label', text: 'Prompt (rawMarkdown)' }),
|
|
@@ -213,6 +222,79 @@
|
|
|
213
222
|
document.body.removeChild(input);
|
|
214
223
|
}
|
|
215
224
|
|
|
225
|
+
// ── Compliance & Audit (restored from the inline tab this file overrides —
|
|
226
|
+
// the override dropped it, but the data still ships in every snapshot) ──
|
|
227
|
+
function fillEvents(feed) {
|
|
228
|
+
UAP.clear(feed);
|
|
229
|
+
var ev = (UAP.liveEvents || []).slice(0, 20);
|
|
230
|
+
if (!ev.length) { feed.appendChild(el('div', { class: 'empty', text: 'Waiting for events…' })); return; }
|
|
231
|
+
ev.forEach(function (e) {
|
|
232
|
+
if (typeof UAP.eventRow === 'function') feed.appendChild(UAP.eventRow(e));
|
|
233
|
+
else feed.appendChild(el('div', { class: 'audit-row', text: (e.title || e.message || '') + ' — ' + (e.detail || '') }));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
UAP.onEvents(function () {
|
|
237
|
+
var f = document.getElementById('pol-live-events');
|
|
238
|
+
if (f) fillEvents(f);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
function renderCompliance(root) {
|
|
242
|
+
var d = UAP.state || {};
|
|
243
|
+
var compliance = d.compliance || {};
|
|
244
|
+
var audit = d.auditTrail || [];
|
|
245
|
+
var cp = el('div', { class: 'panel' }, el('h2', {}, 'Compliance & Audit'));
|
|
246
|
+
cp.appendChild(el('h3', {}, 'Block Rate Trend'));
|
|
247
|
+
cp.appendChild(el('div', { class: 'chart-container chart-spark', id: 'pol-chart-block' }));
|
|
248
|
+
cp.appendChild(el('h3', {}, 'Failures by Mechanism'));
|
|
249
|
+
var fbm = compliance.failuresByMechanism || {};
|
|
250
|
+
var me = Object.keys(fbm).map(function (k) { return [k, fbm[k]]; }).sort(function (a, b) { return b[1] - a[1]; });
|
|
251
|
+
if (me.length) {
|
|
252
|
+
var max = Math.max.apply(null, me.map(function (x) { return x[1]; }).concat([1]));
|
|
253
|
+
var mb = el('div', {});
|
|
254
|
+
me.forEach(function (m) {
|
|
255
|
+
mb.appendChild(el('div', { class: 'bar-container' },
|
|
256
|
+
el('span', { class: 'bar-label', style: { width: '120px' }, text: m[0] }),
|
|
257
|
+
el('div', { class: 'bar red', style: { width: Math.round((m[1] / max) * 180) + 'px' } }),
|
|
258
|
+
el('span', { class: 'bar-value', text: String(m[1]) })));
|
|
259
|
+
});
|
|
260
|
+
cp.appendChild(mb);
|
|
261
|
+
} else cp.appendChild(el('div', { class: 'empty', text: 'No failure mechanisms' }));
|
|
262
|
+
cp.appendChild(el('h3', {}, 'Recent Failures'));
|
|
263
|
+
var rf = compliance.recentFailures || [];
|
|
264
|
+
var thead = el('tr', {}); ['Time', 'Policy', 'Op', 'Mechanism', 'Reason'].forEach(function (x) { thead.appendChild(el('th', { text: x })); });
|
|
265
|
+
var ft = el('table', {}, thead);
|
|
266
|
+
rf.slice(0, 10).forEach(function (f) {
|
|
267
|
+
var tr = el('tr', {},
|
|
268
|
+
el('td', { text: (f.executedAt || '').slice(11, 19) }),
|
|
269
|
+
el('td', { text: f.policyName || f.policyId || '-' }),
|
|
270
|
+
el('td', { text: f.operation || '-' }),
|
|
271
|
+
el('td', { text: f.defeatedMechanism || '-' }),
|
|
272
|
+
el('td', { text: (f.reason || '-').slice(0, 60) }));
|
|
273
|
+
ft.appendChild(tr);
|
|
274
|
+
});
|
|
275
|
+
cp.appendChild(rf.length ? el('div', { class: 'table-wrap' }, ft) : el('div', { class: 'empty', text: 'No recent failures' }));
|
|
276
|
+
cp.appendChild(el('h3', {}, 'Audit Trail'));
|
|
277
|
+
var at = el('div', {});
|
|
278
|
+
if (audit.length) {
|
|
279
|
+
audit.slice(0, 15).forEach(function (e) {
|
|
280
|
+
var ts = (typeof e.executedAt === 'string' && e.executedAt.length >= 19) ? e.executedAt.slice(11, 19) : (e.executedAt || '-');
|
|
281
|
+
at.appendChild(el('div', { class: 'audit-row' },
|
|
282
|
+
el('span', { class: 'audit-time', text: ts }),
|
|
283
|
+
el('span', { class: 'audit-icon ' + (e.allowed ? 'pass' : 'block'), text: e.allowed ? 'PASS' : 'BLOCK' }),
|
|
284
|
+
el('span', { class: 'audit-policy', text: (e.policyId || '').slice(0, 8) }),
|
|
285
|
+
el('span', { class: 'audit-op', text: e.operation || '' }),
|
|
286
|
+
el('span', { class: 'audit-reason', text: e.reason || '' })));
|
|
287
|
+
});
|
|
288
|
+
} else at.appendChild(el('div', { class: 'empty', text: 'No audit entries' }));
|
|
289
|
+
cp.appendChild(at);
|
|
290
|
+
cp.appendChild(el('h3', {}, 'Live Events'));
|
|
291
|
+
var feed = el('div', { class: 'event-feed', id: 'pol-live-events' });
|
|
292
|
+
fillEvents(feed);
|
|
293
|
+
cp.appendChild(feed);
|
|
294
|
+
root.appendChild(cp);
|
|
295
|
+
UAP.charts.syncSpark('pol-chart-block', d.timeSeries || [], UAP.charts.parseBR, UAP.charts.CC.blockRate, 'Block Rate %');
|
|
296
|
+
}
|
|
297
|
+
|
|
216
298
|
function render(root) {
|
|
217
299
|
UAP.clear(root);
|
|
218
300
|
var listEl = el('div', { class: 'pol-list' });
|
|
@@ -227,6 +309,7 @@
|
|
|
227
309
|
root.appendChild(toolbar);
|
|
228
310
|
root.appendChild(listEl);
|
|
229
311
|
reloadInto(listEl);
|
|
312
|
+
renderCompliance(root);
|
|
230
313
|
}
|
|
231
314
|
|
|
232
315
|
UAP.registerTab('policies', { label: 'Policies', render: render });
|
package/web/dash/tabs.js
CHANGED
|
@@ -91,13 +91,49 @@
|
|
|
91
91
|
if (ev.length) ev.forEach(function (e) { feed.appendChild(eventRow(e)); }); else feed.appendChild(empty('Waiting for events…'));
|
|
92
92
|
ep.appendChild(feed); host.appendChild(ep);
|
|
93
93
|
}
|
|
94
|
+
// Service health strip (uap doctor): fetched ON DEMAND from /api/doctor —
|
|
95
|
+
// the probes are bounded-but-blocking (up to ~5s each), so it never rides
|
|
96
|
+
// the 2s snapshot tick. Persists across update() rebuilds; Refresh re-fetches.
|
|
97
|
+
function doctorPanel() {
|
|
98
|
+
var p = panel('Service Health (uap doctor)');
|
|
99
|
+
p.appendChild(el('button', { class: 'btn btn-sm', style: { marginBottom: '8px' }, onclick: function () { loadDoctor(host); } }, 'Refresh'));
|
|
100
|
+
var host = el('div', { id: 'ov-doctor' });
|
|
101
|
+
host.appendChild(el('div', { class: 'muted', text: 'Probing services…' }));
|
|
102
|
+
p.appendChild(host);
|
|
103
|
+
loadDoctor(host);
|
|
104
|
+
return p;
|
|
105
|
+
}
|
|
106
|
+
function loadDoctor(host) {
|
|
107
|
+
U.clear(host);
|
|
108
|
+
host.appendChild(el('div', { class: 'muted', text: 'Probing services…' }));
|
|
109
|
+
fetch(U.API_URL + '/api/doctor').then(function (r) { return r.json(); }).then(function (rep) {
|
|
110
|
+
U.clear(host);
|
|
111
|
+
if (rep.error) { host.appendChild(el('div', { class: 'empty', text: 'doctor unavailable: ' + rep.error })); return; }
|
|
112
|
+
var services = rep.services || [];
|
|
113
|
+
if (!services.length) { host.appendChild(empty('No services declared in the capacity policy')); return; }
|
|
114
|
+
var cls = function (h) { return h === 'GREEN' ? 'green' : (h === 'RED' ? 'red' : (h === 'DARK' ? 'red' : '')); };
|
|
115
|
+
var thead = el('tr', {}); ['Service', 'Health'].forEach(function (x) { thead.appendChild(el('th', { text: x })); });
|
|
116
|
+
var t = el('table', {}, thead);
|
|
117
|
+
services.forEach(function (s) {
|
|
118
|
+
var tr = el('tr', {},
|
|
119
|
+
el('td', { text: s.name || '-' }),
|
|
120
|
+
el('td', {}, el('span', { class: 'badge ' + cls(s.health), text: s.health || '-' }),
|
|
121
|
+
(s.reasons && s.reasons.length) ? el('span', { class: 'muted', text: ' — ' + s.reasons[0] }) : null));
|
|
122
|
+
t.appendChild(tr);
|
|
123
|
+
});
|
|
124
|
+
host.appendChild(el('div', { class: 'table-wrap' }, t));
|
|
125
|
+
}).catch(function () {
|
|
126
|
+
U.clear(host);
|
|
127
|
+
host.appendChild(el('div', { class: 'empty', text: 'doctor request failed' }));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
94
130
|
function build(root, d) {
|
|
95
131
|
var tiles = el('div', { class: 'tile-grid', id: 'ov-tiles' });
|
|
96
132
|
var hero = el('div', { class: 'hero-row' },
|
|
97
133
|
panelWith('Tasks & Agents', el('div', { class: 'chart-container chart-hero', id: 'ov-chart-tasks' })),
|
|
98
134
|
panelWith('Compression & Memory', el('div', { class: 'chart-container chart-hero', id: 'ov-chart-comp' })));
|
|
99
135
|
var summaries = el('div', { class: 'metrics-row', id: 'ov-summaries', style: { gridTemplateColumns: 'repeat(auto-fit,minmax(280px,1fr))' } });
|
|
100
|
-
root.appendChild(tiles); root.appendChild(hero); root.appendChild(summaries);
|
|
136
|
+
root.appendChild(tiles); root.appendChild(hero); root.appendChild(summaries); root.appendChild(doctorPanel());
|
|
101
137
|
fillTiles(tiles, d); fillSummaries(summaries, d); paintCharts(d);
|
|
102
138
|
}
|
|
103
139
|
function panelWith(title, node) { var p = panel(title); p.appendChild(node); return p; }
|
|
@@ -117,6 +153,8 @@
|
|
|
117
153
|
var msg = (title && detail) ? (title + ' — ' + detail) : (title || detail || String((ev.data && JSON.stringify(ev.data)) || '').slice(0, 80));
|
|
118
154
|
return el('div', { class: 'event-row' }, el('span', { class: 'event-time', text: ts }), el('span', { class: 'event-cat cat-' + cat, text: cat }), el('span', { class: 'event-msg', text: msg }));
|
|
119
155
|
}
|
|
156
|
+
// Shared with the tab-policies.js override (it rebuilds the Live Events feed).
|
|
157
|
+
U.eventRow = eventRow;
|
|
120
158
|
|
|
121
159
|
// ═══════════════════════════ TASKS & EPICS ═══════════════════════════
|
|
122
160
|
U.registerTab('tasks', (function () {
|
|
@@ -222,7 +260,7 @@
|
|
|
222
260
|
]).then(function (v) { if (v && v.title) U.api('/api/tasks', { title: v.title, type: v.type, priority: Number(v.priority) || 2, assignee: v.assignee || undefined }).then(function () { U.toast('Task created', 'ok'); }); });
|
|
223
261
|
} }, '+ New Task'),
|
|
224
262
|
]);
|
|
225
|
-
var counts = el('div', { class: 'section-note', text: (tasks.total || 0) + ' tasks · ' + (tasks.done || 0) + ' done · ' + (tasks.inProgress || 0) + ' active · ' + (tasks.blocked || 0) + ' blocked · ' + (tasks.open || 0) + ' open' });
|
|
263
|
+
var counts = el('div', { class: 'section-note', text: (tasks.total || 0) + ' tasks · ' + (tasks.done || 0) + ' done · ' + (tasks.inProgress || 0) + ' active · ' + (tasks.blocked || 0) + ' blocked · ' + (tasks.open || 0) + ' open · board shows newest ' + (tasks.boardShown != null ? tasks.boardShown : (tasks.items || []).length) + ' of ' + (tasks.boardTotal != null ? tasks.boardTotal : (tasks.total || 0) - (tasks.done || 0)) + ' not-done' });
|
|
226
264
|
p.appendChild(counts);
|
|
227
265
|
p.appendChild(el('div', { class: 'toolbar' }, el('span', { class: 'label', text: 'Filter:' }), filterSel));
|
|
228
266
|
var board = el('div', { class: 'kanban', id: 'kanban-board' });
|
|
@@ -259,7 +297,7 @@
|
|
|
259
297
|
function mergeAgents(d) {
|
|
260
298
|
var out = {}, order = [];
|
|
261
299
|
var coord = (d.coordination && d.coordination.agents) || [];
|
|
262
|
-
coord.forEach(function (a) { out[a.id] = { id: a.id, name: a.name, status: a.status, task: a.task || a.type || '', type: a.type || 'main' }; order.push(a.id); });
|
|
300
|
+
coord.forEach(function (a) { out[a.id] = { id: a.id, name: a.name, status: a.status, task: a.task || a.type || '', type: a.type || 'main', lastHeartbeat: a.lastHeartbeat || a.startedAt || null }; order.push(a.id); });
|
|
263
301
|
var sess = (d.session && d.session.agents) || [];
|
|
264
302
|
sess.forEach(function (a) { var e = out[a.id] || { id: a.id, name: a.name, status: a.status, task: a.task, type: a.type }; e.tokensIn = a.tokensIn; e.tokensOut = a.tokensOut; e.tokensUsed = a.tokensUsed; e.model = a.model; e.cost = a.cost; e.durationMs = a.durationMs; e.taskCount = a.taskCount; if (!out[a.id]) order.push(a.id); out[a.id] = e; });
|
|
265
303
|
return order.map(function (id) { return out[id]; });
|
|
@@ -309,11 +347,22 @@
|
|
|
309
347
|
}
|
|
310
348
|
function build(root, d) {
|
|
311
349
|
var agents = mergeAgents(d);
|
|
350
|
+
// Freshest heartbeats first — a stale agent sinks to the bottom instead
|
|
351
|
+
// of hiding among fresh ones.
|
|
352
|
+
agents.sort(function (x, y) {
|
|
353
|
+
var ax = x.lastHeartbeat ? new Date(x.lastHeartbeat).getTime() : 0;
|
|
354
|
+
var ay = y.lastHeartbeat ? new Date(y.lastHeartbeat).getTime() : 0;
|
|
355
|
+
return ay - ax;
|
|
356
|
+
});
|
|
312
357
|
var ap = panel('Agents', [el('button', { class: 'btn', onclick: function () { U.confirm('Clean up stale agents (stale heartbeats)?').then(function (ok) { if (ok) U.api('/api/agents/clean', {}).then(function (r) { U.toast('Cleaned ' + ((r && r.cleaned) || 0) + ' stale agents', 'ok'); }); }); } }, 'Clean stale')]);
|
|
313
358
|
if (!agents.length) ap.appendChild(empty('No agents registered'));
|
|
314
359
|
else { var grid = el('div', { class: 'card-grid' }); agents.forEach(function (a) {
|
|
360
|
+
// Heartbeat age: agents re-beat every ~30s, so >5m (300s) is stale.
|
|
361
|
+
var hbAgeMs = a.lastHeartbeat ? (Date.now() - new Date(a.lastHeartbeat).getTime()) : null;
|
|
362
|
+
var hbAgeS = hbAgeMs != null && isFinite(hbAgeMs) ? Math.floor(hbAgeMs / 1000) : null;
|
|
363
|
+
var hbNode = hbAgeS == null ? null : el('span', { class: hbAgeS > 300 ? 'value red' : 'muted', text: 'hb ' + U.timeAgo(a.lastHeartbeat) + (hbAgeS > 300 ? ' (stale)' : '') });
|
|
315
364
|
grid.appendChild(el('div', { class: 'entity-card', tabindex: '0', role: 'button', onclick: function () { agentDrawer(a, d); }, onkeydown: function (e) { if (e.key === 'Enter') agentDrawer(a, d); } },
|
|
316
|
-
el('div', { class: 'ec-head' }, el('span', { class: 'badge ' + (a.type || 'main') }, a.type || 'agent'), el('span', { class: 'ec-name', text: a.name || a.id }), statusBadge(a.status)),
|
|
365
|
+
el('div', { class: 'ec-head' }, el('span', { class: 'badge ' + (a.type || 'main') }, a.type || 'agent'), el('span', { class: 'ec-name', text: a.name || a.id }), statusBadge(a.status), hbNode),
|
|
317
366
|
el('div', { class: 'ec-task', text: a.task || '-' }),
|
|
318
367
|
el('div', { class: 'ec-metrics' }, el('span', {}, fmtNum((a.tokensIn || 0) + (a.tokensOut || 0) || a.tokensUsed || 0) + ' tok'), a.model ? el('span', { class: 'muted', text: modelName(a.model) }) : null, el('span', {}, fmtUsd(a.cost || 0)))));
|
|
319
368
|
}); ap.appendChild(grid); }
|
|
@@ -329,7 +378,7 @@
|
|
|
329
378
|
return {
|
|
330
379
|
label: 'Agents & Sessions',
|
|
331
380
|
render: function (root, d) { build(root, d); },
|
|
332
|
-
update: function (root, d) { var s = sig({ a: (d.coordination || {}).agents, se: (d.session || {}).agents, h: d.sessions }); if (s !== lastSig) { lastSig = s; U.clear(root); build(root, d); } },
|
|
381
|
+
update: function (root, d) { var s = sig({ a: (d.coordination || {}).agents, se: (d.session || {}).agents, h: d.sessions, hb: ((d.coordination || {}).agents || []).map(function (a) { return a.lastHeartbeat || ''; }) }); if (s !== lastSig) { lastSig = s; U.clear(root); build(root, d); } },
|
|
333
382
|
};
|
|
334
383
|
})());
|
|
335
384
|
|
|
@@ -373,7 +422,14 @@
|
|
|
373
422
|
else shown.forEach(function (m) { tp.appendChild(node(m, 0)); });
|
|
374
423
|
root.appendChild(tp);
|
|
375
424
|
}
|
|
376
|
-
|
|
425
|
+
var lastSig = null;
|
|
426
|
+
return {
|
|
427
|
+
label: 'Orchestration',
|
|
428
|
+
render: function (root, d) { lastSig = sig({ t: d.orchestrationTree, o: d.orchestrate }); build(root, d); },
|
|
429
|
+
// Rebuild only on real change — the 2s tick used to wipe the tab every
|
|
430
|
+
// refresh (scroll/select resets) even when nothing moved.
|
|
431
|
+
update: function (root, d) { var s = sig({ t: d.orchestrationTree, o: d.orchestrate }); if (s === lastSig) return; lastSig = s; U.clear(root); build(root, d); },
|
|
432
|
+
};
|
|
377
433
|
})());
|
|
378
434
|
|
|
379
435
|
// ═══════════════════════════ DELIVER ═══════════════════════════
|
|
@@ -419,76 +475,24 @@
|
|
|
419
475
|
}, function (r) { runDrawer(r); }) : empty('No deliver runs tracked yet'));
|
|
420
476
|
root.appendChild(p);
|
|
421
477
|
}
|
|
422
|
-
|
|
478
|
+
var lastSig = null;
|
|
479
|
+
return {
|
|
480
|
+
label: 'Deliver',
|
|
481
|
+
render: function (root, d) { lastSig = sig(d.deliverRuns); build(root, d); },
|
|
482
|
+
// Rebuild only on real change — the 2s tick used to wipe the tab every
|
|
483
|
+
// refresh (scroll/select resets) even when no run moved.
|
|
484
|
+
update: function (root, d) { var s = sig(d.deliverRuns); if (s === lastSig) return; lastSig = s; U.clear(root); build(root, d); },
|
|
485
|
+
};
|
|
423
486
|
})());
|
|
424
487
|
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
policies.forEach(function (p) { var key = p.name || p.id; pm[key] = Object.assign({}, p, { source: 'db' }); order.push(key); });
|
|
431
|
-
policyFiles.forEach(function (pf) { if (!pm[pf.name]) { pm[pf.name] = { id: pf.filename, name: pf.name, category: pf.category, level: '-', enforcementStage: '-', isActive: null, source: 'file' }; order.push(pf.name); } });
|
|
432
|
-
var all = order.map(function (k) { return pm[k]; });
|
|
488
|
+
// NOTE: there is no inline 'policies' tab here — tab-policies.js (loaded
|
|
489
|
+
// after this file) owns the Policies tab outright, including the Compliance
|
|
490
|
+
// & Audit panel and the Live Events feed it used to shadow from here. The
|
|
491
|
+
// shadowed inline copy (and its duplicate U.onEvents fill of the same
|
|
492
|
+
// 'pol-live-events' element) was deleted (architecture review P2).
|
|
433
493
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
var tbl = el('table', {}, thead);
|
|
437
|
-
all.forEach(function (p) {
|
|
438
|
-
var isDb = p.source === 'db';
|
|
439
|
-
var actions = el('span', {});
|
|
440
|
-
if (isDb) {
|
|
441
|
-
actions.appendChild(el('button', { class: 'btn', onclick: function () { U.api('/api/policy/' + encodeURIComponent(p.id) + '/toggle', undefined).then(function (r) { U.toast('Policy ' + (r.isActive ? 'enabled' : 'disabled'), 'ok'); }); } }, p.isActive ? 'Disable' : 'Enable'));
|
|
442
|
-
var stageSel = el('select', { onchange: function (e) { U.api('/api/policy/' + encodeURIComponent(p.id) + '/stage', { stage: e.target.value }).then(function () { U.toast('Stage: ' + e.target.value, 'ok'); }); } });
|
|
443
|
-
['pre-exec', 'post-exec', 'review', 'always'].forEach(function (s) { stageSel.appendChild(el('option', { value: s }, s)); }); stageSel.value = p.enforcementStage;
|
|
444
|
-
var lvlSel = el('select', { onchange: function (e) { U.api('/api/policy/' + encodeURIComponent(p.id) + '/level', { level: e.target.value }).then(function () { U.toast('Level: ' + e.target.value, 'ok'); }); } });
|
|
445
|
-
['REQUIRED', 'RECOMMENDED', 'OPTIONAL'].forEach(function (l) { lvlSel.appendChild(el('option', { value: l }, l)); }); lvlSel.value = p.level;
|
|
446
|
-
actions.appendChild(document.createTextNode(' ')); actions.appendChild(stageSel); actions.appendChild(document.createTextNode(' ')); actions.appendChild(lvlSel);
|
|
447
|
-
} else actions.appendChild(el('span', { class: 'mono-sm', text: 'file-only' }));
|
|
448
|
-
var status = isDb ? el('span', { class: 'badge ' + (p.isActive ? 'on' : 'off') }, p.isActive ? 'ON' : 'OFF') : el('span', { class: 'badge file-only' }, 'FILE');
|
|
449
|
-
var tr = el('tr', {},
|
|
450
|
-
el('td', {}, el('span', { style: { fontWeight: '500' }, text: p.name || '-' })),
|
|
451
|
-
el('td', { text: p.category || '-' }),
|
|
452
|
-
el('td', {}, el('span', { class: 'badge ' + (p.level || '').toLowerCase() }, p.level || '-')),
|
|
453
|
-
el('td', { text: p.enforcementStage || '-' }),
|
|
454
|
-
el('td', {}, status),
|
|
455
|
-
el('td', {}, actions));
|
|
456
|
-
tbl.appendChild(tr);
|
|
457
|
-
});
|
|
458
|
-
pp.appendChild(all.length ? el('div', { class: 'table-wrap' }, tbl) : empty('No policies'));
|
|
459
|
-
root.appendChild(pp);
|
|
460
|
-
|
|
461
|
-
var cp = panel('Compliance & Audit');
|
|
462
|
-
cp.appendChild(el('h3', {}, 'Block Rate Trend'));
|
|
463
|
-
cp.appendChild(el('div', { class: 'chart-container chart-spark', id: 'pol-chart-block' }));
|
|
464
|
-
cp.appendChild(el('h3', {}, 'Failures by Mechanism'));
|
|
465
|
-
var fbm = compliance.failuresByMechanism || {}; var me = Object.keys(fbm).map(function (k) { return [k, fbm[k]]; }).sort(function (a, b) { return b[1] - a[1]; });
|
|
466
|
-
if (me.length) { var max = Math.max.apply(null, me.map(function (x) { return x[1]; }).concat([1])); var mb = el('div', {}); me.forEach(function (m) { mb.appendChild(el('div', { class: 'bar-container' }, el('span', { class: 'bar-label', style: { width: '120px' }, text: m[0] }), el('div', { class: 'bar red', style: { width: Math.round((m[1] / max) * 180) + 'px' } }), el('span', { class: 'bar-value', text: String(m[1]) }))); }); cp.appendChild(mb); }
|
|
467
|
-
else cp.appendChild(empty('No failure mechanisms'));
|
|
468
|
-
cp.appendChild(el('h3', {}, 'Recent Failures'));
|
|
469
|
-
var rf = compliance.recentFailures || [];
|
|
470
|
-
cp.appendChild(rf.length ? tableNode(['Time', 'Policy', 'Op', 'Mechanism', 'Reason'], rf.slice(0, 10), function (f) { return [el('span', { class: 'mono-sm', text: (f.executedAt || '').slice(11, 19) }), el('span', { class: 'value red', text: f.policyName || f.policyId || '-' }), f.operation || '-', el('span', { class: 'badge required' }, f.defeatedMechanism || '-'), el('span', { class: 'muted', text: (f.reason || '-').slice(0, 60) })]; }) : empty('No recent failures'));
|
|
471
|
-
cp.appendChild(el('h3', {}, 'Audit Trail'));
|
|
472
|
-
var at = el('div', {});
|
|
473
|
-
if (audit.length) audit.slice(0, 15).forEach(function (e) { var ts = (typeof e.executedAt === 'string' && e.executedAt.length >= 19) ? e.executedAt.slice(11, 19) : (e.executedAt || '-'); at.appendChild(el('div', { class: 'audit-row' }, el('span', { class: 'audit-time', text: ts }), el('span', { class: 'audit-icon ' + (e.allowed ? 'pass' : 'block'), text: e.allowed ? 'PASS' : 'BLOCK' }), el('span', { class: 'audit-policy', text: (e.policyId || '').slice(0, 8) }), el('span', { class: 'audit-op', text: e.operation || '' }), el('span', { class: 'audit-reason', text: e.reason || '' }))); });
|
|
474
|
-
else at.appendChild(empty('No audit entries'));
|
|
475
|
-
cp.appendChild(at);
|
|
476
|
-
cp.appendChild(el('h3', {}, 'Live Events'));
|
|
477
|
-
var feed = el('div', { class: 'event-feed', id: 'pol-live-events' });
|
|
478
|
-
fillEvents(feed);
|
|
479
|
-
cp.appendChild(feed);
|
|
480
|
-
root.appendChild(cp);
|
|
481
|
-
U.charts.syncSpark('pol-chart-block', d.timeSeries || [], U.charts.parseBR, U.charts.CC.blockRate, 'Block Rate %');
|
|
482
|
-
}
|
|
483
|
-
function fillEvents(feed) {
|
|
484
|
-
U.clear(feed);
|
|
485
|
-
var ev = (U.liveEvents || []).slice(0, 20);
|
|
486
|
-
if (!ev.length) { feed.appendChild(empty('Waiting for events…')); return; }
|
|
487
|
-
ev.forEach(function (e) { feed.appendChild(eventRow(e)); });
|
|
488
|
-
}
|
|
489
|
-
U.onEvents(function () { var f = document.getElementById('pol-live-events'); if (f) fillEvents(f); });
|
|
490
|
-
return { label: 'Policies', render: build };
|
|
491
|
-
})());
|
|
494
|
+
// NOTE: there is likewise no inline 'clients' tab — tab-clients.js (loaded
|
|
495
|
+
// after this file) owns the Clients fleet panel outright (same precedent).
|
|
492
496
|
|
|
493
497
|
// ═══════════════════════════ MODELS ═══════════════════════════
|
|
494
498
|
U.registerTab('models', (function () {
|
package/web/dashboard.html
CHANGED
|
@@ -50,5 +50,11 @@
|
|
|
50
50
|
<!-- Loaded AFTER tabs.js so its registerTab('policies') overrides the inline
|
|
51
51
|
stub with the full policy-management panel (view/duplicate/reorder/AI-order/import/export). -->
|
|
52
52
|
<script src="/dash/tab-policies.js"></script>
|
|
53
|
+
<!-- Loaded AFTER tabs.js so registerTab('models') overrides the routing-only
|
|
54
|
+
stub with the full Models & Placement panel (registry, ledger, preview). -->
|
|
55
|
+
<script src="/dash/tab-models.js"></script>
|
|
56
|
+
<!-- Loaded AFTER tabs.js; owns the Clients fleet tab outright (tab-policies.js
|
|
57
|
+
precedent): per-client cards + spawn-on-demand link-out. -->
|
|
58
|
+
<script src="/dash/tab-clients.js"></script>
|
|
53
59
|
</body>
|
|
54
60
|
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/web/dash/tab-agents.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-agents.js — Stub tab: Agents
|
|
3
|
-
* Registers with UAP.registerTab and renders a 'coming soon' message.
|
|
4
|
-
*/
|
|
5
|
-
(function () {
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
function render() {
|
|
9
|
-
var el = document.createElement('div');
|
|
10
|
-
el.className = 'coming-soon';
|
|
11
|
-
el.innerHTML =
|
|
12
|
-
'<div class="icon">🤖</div>' +
|
|
13
|
-
'<h2>Agents</h2>' +
|
|
14
|
-
'<p>Coming soon</p>';
|
|
15
|
-
return el;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (typeof UAP !== 'undefined' && typeof UAP.registerTab === 'function') {
|
|
19
|
-
UAP.registerTab('agents', { render: render });
|
|
20
|
-
}
|
|
21
|
-
})();
|
package/web/dash/tab-deliver.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-deliver.js — Deliver tab stub
|
|
3
|
-
* Registers with UAP.registerTab and renders a "coming soon" message
|
|
4
|
-
* (textContent only, per the module contract — no innerHTML).
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
UAP.registerTab('deliver', {
|
|
8
|
-
label: 'Deliver',
|
|
9
|
-
render(root, state) {
|
|
10
|
-
root.textContent = 'Deliver — coming soon';
|
|
11
|
-
}
|
|
12
|
-
});
|
package/web/dash/tab-memory.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-memory.js — Memory tab stub
|
|
3
|
-
* Registers with UAP.registerTab and renders a "coming soon" message
|
|
4
|
-
* (textContent only, per the module contract — no innerHTML).
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
UAP.registerTab('memory', {
|
|
8
|
-
label: 'Memory',
|
|
9
|
-
render(root, state) {
|
|
10
|
-
root.textContent = 'Memory — coming soon';
|
|
11
|
-
}
|
|
12
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-orchestration.js — Stub tab: Orchestration
|
|
3
|
-
* Registers with UAP.registerTab and renders a 'coming soon' message.
|
|
4
|
-
*/
|
|
5
|
-
(function () {
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
function render() {
|
|
9
|
-
var el = document.createElement('div');
|
|
10
|
-
el.className = 'coming-soon';
|
|
11
|
-
el.innerHTML =
|
|
12
|
-
'<div class="icon">🔄</div>' +
|
|
13
|
-
'<h2>Orchestration</h2>' +
|
|
14
|
-
'<p>Coming soon</p>';
|
|
15
|
-
return el;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (typeof UAP !== 'undefined' && typeof UAP.registerTab === 'function') {
|
|
19
|
-
UAP.registerTab('orchestration', { render: render });
|
|
20
|
-
}
|
|
21
|
-
})();
|
package/web/dash/tab-overview.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-overview.js — Stub tab: Overview
|
|
3
|
-
* Registers with UAP.registerTab and renders a 'coming soon' message.
|
|
4
|
-
*/
|
|
5
|
-
(function () {
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
function render() {
|
|
9
|
-
var el = document.createElement('div');
|
|
10
|
-
el.className = 'coming-soon';
|
|
11
|
-
el.innerHTML =
|
|
12
|
-
'<div class="icon">📊</div>' +
|
|
13
|
-
'<h2>Overview</h2>' +
|
|
14
|
-
'<p>Coming soon</p>';
|
|
15
|
-
return el;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (typeof UAP !== 'undefined' && typeof UAP.registerTab === 'function') {
|
|
19
|
-
UAP.registerTab('overview', { render: render });
|
|
20
|
-
}
|
|
21
|
-
})();
|
package/web/dash/tab-tasks.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tab-tasks.js — Stub tab: Tasks
|
|
3
|
-
* Registers with UAP.registerTab and renders a 'coming soon' message.
|
|
4
|
-
*/
|
|
5
|
-
(function () {
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
function render() {
|
|
9
|
-
var el = document.createElement('div');
|
|
10
|
-
el.className = 'coming-soon';
|
|
11
|
-
el.innerHTML =
|
|
12
|
-
'<div class="icon">📋</div>' +
|
|
13
|
-
'<h2>Tasks</h2>' +
|
|
14
|
-
'<p>Coming soon</p>';
|
|
15
|
-
return el;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (typeof UAP !== 'undefined' && typeof UAP.registerTab === 'function') {
|
|
19
|
-
UAP.registerTab('tasks', { render: render });
|
|
20
|
-
}
|
|
21
|
-
})();
|