1180 Commits

Author SHA1 Message Date
5518a943c9 Publish catalog 8c3a5f4ed35e (publication 648074be) 2026-10-05 13:55:09 +03:00
eb9ea056e6 Publish catalog 664dc1c7d70b (publication 1f47ff5f) 2026-10-05 13:03:02 +03:00
3c99e3ca77 feat(dashboard-testing): add chart health diagnostics and per-tab evidence
Focused matrix and cleanup checks pass. Native Superset error/recovery acceptance and final semantic freeze remain open; this is not release GO.
2026-10-02 16:23:22 +03:00
54bdbcc403 refactor(semantics): close dashboard testing protocol audit 2026-10-02 12:47:12 +03:00
aacd1bd039 docs(dashboard-testing): retain Luna semantic audit of bcc69f4b 2026-10-02 11:04:41 +03:00
bcc69f4bbe feat(dashboard-testing): add sampled traversal and ClickHouse test lab
Add versioned metric graph authority, owned browser evidence, paginated and all-tab traversal, deterministic sampling policies, and analyst-facing run inspection.

Provision the DEV/PREPROD/PROD Superset, Gitea and million-row ClickHouse lab; retain reproducible lifecycle evidence and explicit incomplete-traversal limits.
2026-10-02 10:54:42 +03:00
3406433b8f fix: make profile migration idempotent 2026-09-29 20:57:27 +03:00
1a3d3958ea fix: chain T029a profile migrations 2026-09-29 20:52:39 +03:00
1b6edaf701 fix: keep unresolved baseline profile ineligible 2026-09-29 20:22:25 +03:00
ce3dc56bbc feat: persist owner-scoped profile resolutions 2026-09-29 20:21:24 +03:00
2f09491539 feat: bind profile eligibility receipt to handles 2026-09-29 20:18:56 +03:00
65337fe622 merge: typed MCP test-pack profile 2026-09-29 14:47:45 +03:00
596d6cc84c docs: update maintenance effort estimate 2026-09-29 14:27:58 +03:00
f73169b371 feat(mcp): add typed test-pack profile preview 2026-09-29 14:15:17 +03:00
e99306eb54 fix(dashboard-testing): bind launches to published baselines 2026-09-28 19:43:57 +03:00
f38a1b7f5e fix(browser): support live native filter permalinks 2026-09-28 08:29:15 +03:00
935a4ccacf Merge remote-tracking branch 'origin/master' 2026-09-25 11:48:27 +03:00
354c6684d8 feat(dashboard-testing): pin published baselines in schedules 2026-09-25 11:44:44 +03:00
f9d2f8d9bc docs(handoff): point agents to committed reference URL state 2026-09-25 10:39:59 +03:00
e7bac04e98 feat(dashboard-testing): add reference URL baseline workflow and analyst UX
Discover dashboard filters, datasets and metrics from a parsed reference URL; capture and review baseline candidates with source provenance. Improve scenario DAG and run result views, add isolated browser coverage, and align contracts and ADRs.
2026-09-25 10:36:37 +03:00
1c57734afd docs(acceptance): refresh analyst UX handoff 2026-09-24 11:19:02 +03:00
9acd9badab feat(frontend): improve investigation analyst UX 2026-09-24 11:09:41 +03:00
870df0ac35 docs(acceptance): record analyst UX handoff 2026-09-24 09:56:27 +03:00
6d58bb97d0 fix(dashboard-testing): authenticate browser SSE run stream via query token 2026-09-24 09:39:49 +03:00
233edfd135 fix(dashboard-testing): require run ACL principal and share VIEW predicate 2026-09-24 09:34:51 +03:00
d8b0bd58ad fix(dashboard-testing): enforce run/case object ACLs and recurrence guards 2026-09-24 09:32:58 +03:00
a2c6bb00d8 Publish 037 published envelope ss-prod-visual v1 (canary v5 binding) 2026-09-24 00:51:42 +03:00
fa531225ce chore(agent-manager): persist session state 2026-09-24 00:33:32 +03:00
1152fd95c4 docs(specs): update dashboard testing acceptance state 2026-09-24 00:33:15 +03:00
05072f8547 feat(frontend): update maintenance settings and UI contracts 2026-09-24 00:33:04 +03:00
a122c328a1 feat(backend): harden automation retention and execution 2026-09-24 00:32:05 +03:00
fc3697f35f feat(dashboard-testing): complete analyst workflows 2026-09-24 00:31:22 +03:00
c4d6faa0f4 feat(frontend,automation): quarantine recovery UI, run-monitor reload/reconnect, disposition e2e spec
Wave UI (G-DLQ-SOAK operator recovery, G-MONITOR reload/reconnect, G-INVESTIGATION-UI spec):
- AutomationQuarantineModel (FSM, CAS-release of displayed version, 409->reload+stale_version,
  404->reload+already_released) + QuarantinePanel mounted on automation page, i18n ru/en
- RunMonitorModel reload/reconnect L1 vectors (waiting_human restore without duplicate checkpoint,
  repeated bindEvents closes previous EventSource)
- scenario-disposition.e2e.js spec (queue->case->disposition + STALE_CASE CAS vector; skips with
  explicit reason until the isolated stand has a queue-seeding path)
- Matrix/traceability/WORKSTATE accounting for the UI wave; handoff docs + safety patch

Verified: frontend vitest 3425 passed (220 files); npm run build ok
2026-09-23 16:11:09 +03:00
300c2a2954 feat(maintenance): add dashboard-targeted banners and template library 2026-09-22 21:18:15 +03:00
f0d7b79523 fix(rbac): single admin authority, gate privileged surfaces, enforce session on dual-auth
- is_admin flag is the sole admin authority; remove role-name fallbacks (dependencies, reports, tasks, agent lifecycle, security badge, frontend)
- normalize (resource, ACTION) across REST/MCP/catalog; strict admin role/permission parsing (400 on unknown)
- gate LLM provider CRUD/status/test on admin:settings; require auth on agent llm-status; quarantine listing requires scenario:automation MANAGE
- enforce logical-session revocation/idle in require_api_key_or_jwt
- last-admin lockout guards for user/role CRUD; block non-admin from granting is_admin
- frontend: flag-only admin, route permission map from the nav registry, write-control gating, 403 dedupe
- tests: orthogonal edge coverage (flag-only admin, lockout boundaries, session states, normalization)
2026-09-22 21:14:35 +03:00
5a5ac4dd7c feat(dashboard-testing): wave 4 offline P0 — revision-log wiring, period rollover gate, injection-safe prompt
G-BSL-CATALOG: consume/materialization appends the server-owned CatalogRevision under the catalog lock and rolls it back with the YAML on any failure (no phantom revision); the publish settle mirrors the outcome onto the digest-matched head without demoting a landed commit.

G-BSL-DERIVED: a closed period that is not the launch-declared reporting_period blocks the start typed (BaselinePeriodStale = BASELINE_STALE) with a facts-only rebaseline proposal, no automatic rebaseline, and REPORTING_PERIOD_INVALID for a malformed declaration.

G-LLM-SECURITY: the evaluation prompt declares evidence-as-data, coerces the verdict to the closed enum, drops findings for undeclared criteria and refuses provider-owned identity; 7 injection vectors run through the submit seam with no live LLM.

INV_7: publication/baseline/start/evaluation modules split under 400 lines and CC<=10; moved contracts tombstoned with @REPLACED_BY. Matrix, 037/044 traceability and WORKSTATE accounting.
2026-09-22 21:13:52 +03:00
965d602369 docs(handoff): preserve wave3 agent worktrees, specs, patches, and blockers 2026-09-22 13:52:47 +03:00
07145ac961 docs(specs): wave 3 operations accounting — notifications, atomic investigation, poisoned-run, MCP parity
- 046: T022 CLOSED (notification wiring, NOTIFY-001); T023 offline CLOSED (poisoned-run
  quarantine/recovery, SCHED-SOAK offline); T024 remains live-blocked (72h soak).
- 047: T019/T020/T021 CLOSED (atomic triage, one-active, exact-context; 22 unit + 7 PG race
  vectors); T026 CLOSED (INV-NOTIFY-001); T028 CLOSED (INV-ATOMIC-001).
- 050: T051 CLOSED (shared start-error classifier + 17-vector REST/MCP parity matrix).
- Matrix: G-NOTIFICATIONS, G-INVESTIGATION-ATOMIC, G-MCP-PARITY -> CLOSED; G-DLQ-SOAK ->
  PARTIAL (offline policy closed; 72h soak and tab canaries remain live).
- WORKSTATE: wave-3 checkpoint incl. stale-base integration adaptations and the resolved
  PostgreSQL host-routing (VPN/bridge) incident.
- Full backend suite on the integrated release commit: 11472 passed, 0 failed.
2026-09-22 12:57:19 +03:00
65684d6c65 test(mcp): REST/MCP error-shape parity matrix with a shared start-error classifier (050 T051)
- start_run.py: classify_start_error — one canonical mapper for ENVIRONMENT_NOT_CONFIGURED,
  every BASELINE_* code, IDEMPOTENCY_KEY_REUSED and existing UPPER_SNAKE typed codes; unknown
  ValueErrors collapse to RUN_START_CONFLICT. REST and MCP now share it, so the same failure
  can no longer present a transport-dependent error vocabulary (the divergence the matrix caught:
  MCP returned raw exception text while REST collapsed to RUN_START_CONFLICT).
- Parity matrix (12+ vectors): env/baseline/conflict/disabled-action/disabled-automation/
  investigation-RBAC/unauthenticated, plus service-principal human-gate denial.
- Base-drift adaptations during integration: the investigation-case ACL vector now asserts the
  real no-bypass invariant (foreign case collapses to not_found via MCP, no content leak) since
  the investigation MCP tools exist on this release; terminal-transition atomicity expectations
  now include the queue_created receipt and pin replay idempotency (2 receipts, no growth).
- 17 parity tests; union wave-3 verification: 1845 passed.
2026-09-22 12:45:28 +03:00
223296bc57 feat(analytics): atomic investigation triage and exact-context comparability (INV-ATOMIC-001)
- locking.py: transaction-scoped pg_advisory_xact_lock per fingerprint (no-op on SQLite);
  serializes queue/case/episode writers without new migrations (D11).
- investigation.py: queue_signal/open_case lock then SELECT FOR UPDATE + populate_existing;
  set_disposition validates case CAS then performs case status/version, queue closure,
  AgentAction and episode resolution inside one savepoint (zero partial projection), and
  emits the idempotent case_dispositioned receipt after the savepoint commits.
- recurring.py: record_occurrence locked + FOR UPDATE (one open episode).
- context.py: AnalyticsContextKey and assess_comparability — same environment with a differing
  baseline family/release/RLS/principal is typed ineligible/mismatch; eligible-sequence
  classification separates regression/flaky from model variance.
- comparison.py: compatibility carries comparable = same_scenario AND exact-context + context ids.
- Tests: 22 unit (13 new) + 7 PostgreSQL Testcontainers concurrency vectors (--run-integration).
- Merged with the notification wiring on analytics/investigation.py (both changes kept).
2026-09-22 12:38:00 +03:00
def2bf4038 feat(automation): poisoned-run quarantine policy with durable failure signatures (SCHED-SOAK offline)
- poisoned_store.py: durable JSONL identical-failure counter (fcntl.flock + intra-process lock
  + thread-local reentrancy, append+fsync, torn-line tolerant, CAS quarantine epoch); no
  Alembic/ORM changes (046 migrations frozen).
- poisoned.py: N=3 identical infra failures -> typed POISONED_RUN_QUARANTINE, matching
  schedules disabled, exactly one blocked notification carrying the DLQ payload; success
  resets the pair; operator unquarantine (CAS) re-enables schedules and resets counters.
- REST: GET /scenario-automation/quarantine and POST /quarantine/{scenario_id}/release
  (scenario:automation MANAGE; 404 NOT_QUARANTINED / 409 STALE_QUARANTINE_VERSION).
- Tests: 13 policy + 2 API quarantine vectors; merged with the master ReadAcl/RetentionReceipts
  classes (conflict resolved keeping both). Focused 31 passed; 046 T023 offline slice.
2026-09-22 12:35:39 +03:00
93e97228e9 feat(automation): notification wiring for terminal, queue and case lifecycle events (NOTIFY-001)
- notify.py: fail-closed emit vs durable domains (durable rejects 'human', zero-human policy),
  channel/sla_seconds on the receipt payload, optional idempotency_key with receipt dedupe.
- analytics/investigation.py: idempotent queue_created / case_opened / case_dispositioned
  receipts keyed on the immutable fingerprint and case id + prior decision_version.
- execution/terminal_effects.py: idempotent terminal receipts; BASELINE_STALE runs emit a
  dedicated baseline_stale receipt instead of a generic blocked one.
- test_notifications_wiring.py: 6 gate vectors + fail-closed + emit/persist domain split (8 tests).
- 047 T026 / 046 T022 wiring; focused 8 passed, tests/services/dashboard_testing 1313 passed, ruff clean.
2026-09-22 12:33:27 +03:00
a4db469077 fix(translate): typed temporal transfer, language arbitration, MERGE key
- sql_generator: normalize ISO/epoch values only against a resolved target type
  (Nullable/LowCardinality unwrapped); untyped epoch-looking strings are preserved and
  unparseable temporal values raise instead of coercing. Removes the heuristic that
  wrote sentinel dates (2106-02-07 = UInt32 max) into business date columns.
- sql_generator: ClickHouse string-literal escaping — backslash, quote and control
  characters escaped; ANSI '' doubling alone silently rewrote paths and tabs on insert.
- service_target_schema: one fetch_target_column_types resolver for both direct_db and
  SQL Lab insert paths (300s cache) plus a single column-catalog SQL builder; EXPLORE
  trace when the catalog is unreachable/empty instead of a silent untyped fallback.
- _lang_detect: script-conflict downgrade no longer depends on the target language list;
  letterless text becomes und; short/number-heavy Cyrillic cannot survive as a Latin
  language; sanitize_detected_language validates the LLM arbitration answer by script.
- _batch_proc/_utils: und rows actually reach LLM arbitration (same-language, cache and
  preview short-circuits blocked) and trust a cache entry only when its stored source
  language is confirmed; detector version bumped to invalidate the v2 cache.
- _key_mapping: single source->target key mapping; MERGE with target_language_column
  absent from target_key_cols rejected in preflight before any fetch/LLM; lang_code is a
  target-only discriminator (no fictitious source key). Removes 5 divergent copies.
- frontend: global run indicator elapsed timer (1s tick, server started_at, cleanup)
  reusing formatDuration; MERGE-key inline validation with en/ru i18n keys; UX contract
  and decision-memory updates.
- tests: real ClickHouse testcontainers coverage on dm.debt_comment_translations
  (Date32/DateTime transfer, epoch/millis/sentinel/boundaries, NULL semantics, text
  escaping round-trip, MERGE language discriminator, chunked batch, production
  projection); unit coverage for typed normalization, escaping, key mapping and the
  arbitration cache. Existing integration module had a stale untyped-epoch expectation.
2026-09-22 11:36:44 +03:00
c5e3303e35 docs(specs): live evaluation-binding wave accounting — canary v5 evidence, gates closed, matrix updates
- live_canary_v5_binding.py: sibling-topology live harness (published baseline envelope ->
  browser -> capture -> compare + evaluate with declared comparison_refs, required policy).
- Evidence live-canary-v5-binding-20260921T164034Z (+eval-record): complete live chain —
  8 durable artifacts, real-LLM evaluation persisted (ce4685e7, succeeded), walker binds it
  into the compare decision; honest LOW_CONFIDENCE terminal (all gateway vision routes
  upstream-502 since 2026-09-21; text-only model cannot judge visual criteria).
- Tasks: T052/T053 CLOSED (shutdown/readback), T046/T051 live-proven (terminal PASS
  external-blocked on the vision gateway), T068/T069 CLOSED, T082-T088 accounted.
- CHK038 PARTIAL (date filter absent on stand), CHK039/040 CLOSED.
- Matrix: G-PROVIDER-SHUTDOWN and G-MUTATION-RECON CLOSED; G-BROWSER-FILTERS PARTIAL
  (external); G-BSL-CATALOG core proven; G-BSL-DERIVED offline axes closed;
  G-E2E-EVALUATION chain live-proven, terminal PASS external-blocked.
- WORKSTATE: wave checkpoints 2026-09-18/21 (runtime safety, correctness chain, live).
2026-09-22 10:12:14 +03:00
fc0c426537 feat(baseline): correctness truth chain — catalog CAS log, transform provenance, selection proposal, walker evaluation binding (AGBASE-FR-014..018, T082-T088, T051/T068/T069)
- catalog_revision_log.py: append-only JSONL revision log with If-Match CAS, duplicate
  baseline/coordinate rejection, thread-race single-head proof, retire/invalidate
  history preservation, publish_failed reconcile on the same revision (T082-T084 core).
- scenario_transform_provenance.py: server-owned 044 ScenarioArtifact chain for
  scenario_transform candidates — run/owner/activeness/digest/passed-step/value equality,
  forged refs typed-rejected (T086, AGBASE-FR-017).
- baseline_selection.py + schemas: facts-only BaselineSelectionProposal (cross_check ->
  checklist -> big-number/closed-period -> filter_sentinel -> lineage_repr), hard 50-entry
  budget with recorded exclusions, default+business filter contexts, CAS review with
  accept/drop/adjust (T087, AGBASE-FR-016); observatory_entries tier in the catalog
  revision schema + resolver smuggle-guard (T088, AGBASE-FR-015).
- transform_dsl.py: bounded structured op-tree DSL (sum_column/difference/ratio/scale,
  depth<=4, 10k rows, canonical decimals, byte-stable) wired as derive_value into
  bounded_transform (T068, AGSCN-FR-018).
- evaluation_aggregation.py: verdict policy single_shot/best_of_n with strict-majority
  quorum, tie/all-error/quorum-miss/below-threshold typed non-pass (T069, AGSCN-FR-022).
- evaluation_binding.py + walker: dependency-ordered binding of the persisted covering
  AgentEvaluation into the comparison decision (T051/T046); deferral until the covering
  evaluation persists with a deadlock guard (_step_feeds_evaluation); semantic_comparison
  scope in the policy mapper — required-mode evidence producers pass rows 1-8, the
  semantic overlay binds to comparison steps only (production-chain ordering);
  capacity_block.py extracted (INV_7 walker 398 LOC).
2026-09-22 09:39:43 +03:00
c01fcffdbe feat(execution): P0 runtime safety wave — provider shutdown drain, mutation readback, filter canary (SCEX-FR-037/038, BSC-FILT-001)
- ProviderEventLoop.stop(): close_all_sessions fan-out on the live loop before detach +
  bounded pending-task drain before loop.close() (zero 'Task was destroyed' live-proven);
  close_all_sessions weak-registry shutdown fan-out in browser_session_managers.
- SCEX-FR-038 independent mutation readback: browser_readback.py (same-session fresh
  client_id SELECT, cleanup-aware expectation, canonical 6dp float normalization);
  transport wiring adds readback_verified checkpoint; BrowserTransportReadbackMismatch ->
  reconciliation_required/effect unknown/retry blocked; INV_7 kept (browser.py 395 LOC
  via factory-helpers extraction).
- Live canaries: actions/mutation (readonly-canary-20260918T174659/174740/184343Z) and
  native filters (filters-canary-20260918T195946Z: values/clear/replay/chart PASS; date
  vector absent on stand — external prerequisite).
- Robustness fixes from live flake: pre-apply Escape (stale overlay in reused sessions)
  and bounded antd dropdown settle in browser_native_filter.
- Root-cause of the 82.75/82.74 divergence: mid-step post-SELECT vs post-restore
  lifecycle skew, not a cache defect.
2026-09-22 09:39:17 +03:00
6e20664b22 docs(specs): unify production acceptance matrix and live residual gates 2026-09-18 17:10:37 +03:00
0a2379c0ed test(canary): retain 2026-09-18 live Superset wave-2 observe and mutation evidence 2026-09-18 15:56:54 +03:00
c9e6e642e3 fix(analytics): implement case index API for investigation findability (SCAN-FR-020) 2026-09-18 14:54:09 +03:00
67c7b1d89e feat(baseline): scenario_transform candidate kind with run/expression provenance (AGBASE-FR-017) 2026-09-18 13:36:59 +03:00