Commit Graph

263 Commits

Author SHA1 Message Date
f73169b371 feat(mcp): add typed test-pack profile preview 2026-09-29 14:15:17 +03:00
f38a1b7f5e fix(browser): support live native filter permalinks 2026-09-28 08:29:15 +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
1152fd95c4 docs(specs): update dashboard testing acceptance state 2026-09-24 00:33:15 +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
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
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
3633e6751d docs(workstate): wave-2 checkpoint — observe drivers and zero-human mapper closed 2026-09-18 13:08:54 +03:00
2fcd50564f docs(workstate): wave-1 implementation checkpoint — four amendment branches verified and merged 2026-09-18 12:07:13 +03:00
fcf4e6eb87 docs(specs): design amendments 2026-09-17 — complex browser scenarios, D/M/E taxonomy, zero-human runtime, evidence tiering, investigation loop 2026-09-17 19:41:49 +03:00
ec917ac677 feat(scenario): 044 provider INV_7 decomposition + T044/T045 live canaries; evidence-backed spec status
The 044 provider lifecycle is decomposed to satisfy INV_7 and closed with live canaries;
the remaining acceptance row (T046 graph-level terminal PASS) is diagnosed with executable proof.

- split browser_readonly_actions (534->160), browser_session (501->58) and browser.py (407->398)
  into sibling modules with frozen contract IDs and frozen import surface (facades re-export every
  moved public name); monkeypatch seams follow the owning modules
- gates per phase: scoped 044 suite 1590 passed and full backend 11269 passed / 0 failed, no delta
- T042b: six PREPROD browser canaries GREEN under the Wave-C run-scoped session architecture;
  harness gains SS_CANARY_STORAGE_ROOT and fixes the dead-loop scheduler drain hang
- T044: new artifact-content live HTTP canary 11/11 (real app, PostgreSQL, JWTs, live-captured bytes)
- T045: new fault-injection canary 16/16 (bounded loop refusals, deadline cancellation, shutdown
  drain, capacity quarantine + TTL reconcile, receipt CAS, late response, cancel drain)
- T046: walker-level evaluation->comparison binding diagnosed (compare-only + mandatory ->
  EVALUATION_UNAVAILABLE; bound evaluation -> BASELINE_AND_SEMANTIC_PASS); T043/T046 stay open
- refresh 044 spec/traceability/checklist/quickstart/SESSION_STATE/contracts/plan/data-model and the
  037/050 rows to evidence-backed states; split three malformed multi-target @RELATION lines
- fix skill drift in semantics-python/semantics-svelte (logger facade, notify(), i18n proxy)
2026-09-17 18:05:45 +03:00
4746af2f3e fix(health): address consolidation review findings 2026-09-16 16:11:02 +03:00
8522a2ee3c feat(scenario): complete dashboard testing UX flow 2026-09-15 10:12:17 +03:00
b4148cfe5f fix(automation): scheduled runs execute as schedule-owner principal; MCP upsert signature parity — live scheduled happy path proven (046 T018 CLOSED) 2026-09-11 20:22:47 +03:00
d0466a2c1e fix(automation): deterministic scheduled-run idempotency key + typed scheduled-reject observability (046 happy path) 2026-09-11 20:01:53 +03:00
578a6110e7 fix(scenario): T045 review hardening — RUN_PROD REST gate, fail-marked typed errors, marker-bound adoption, unique idempotency, path guard 2026-09-11 19:05:20 +03:00
6dde7e15c3 feat(scenario): 050 T045 — gated MCP publish_baseline_catalog + 037 publication worker (CAS, receipts, reconcile), REST parity 2026-09-11 18:13:09 +03:00
605c5d0552 docs(specs): refresh 017/036/037/038/039 production contracts
Add production contract refresh sections and normative contracts: 017/050
capture-reuse trust, 036 evidence promotion, 037 catalog lifecycle/revision,
038 browser actions/decision policy, 044-047 production chain/evidence/atomic
triage, and 050 MCP interface artifacts. Requirements marked OPEN pending
executable evidence.
2026-09-11 17:27:48 +03:00
de5e098a1b fix(scenario): review hardening — run.sh key reuse, resolver-canonical publisher envelope, strict pin asserts, honest T045/T046 statuses 2026-09-11 15:09:16 +03:00
7d3fb8a770 feat(scenario): live baseline pin via published Gitea catalog — publisher POST/PUT contract, run.sh key-wipe fix, T045/T046 closed 2026-09-11 14:07:20 +03:00
1411c03f9b fix(scenario): orthogonal review hardening — binding fingerprint guard, strict image digest, typed publisher errors, T029m human-loop closure 2026-09-11 10:10:01 +03:00
d04927bda7 feat(scenario): T029m live MCP replay — binding identity fixes, Gitea catalog publisher, 050 statuses 2026-09-11 08:40:37 +03:00
d2444f404b docs(specs): session-2 handoff + evidence-based 044/050 task statuses and session-state update 2026-09-10 20:49:50 +03:00
edc9a98a86 fix(scenario): code-review hardening — drop unknown criterion findings, fail closed on unsupported verdict, remove dead branch 2026-09-10 20:29:27 +03:00
bf8abff753 docs(specs): live canary v2 trace + restore operation_id in browser evidence details 2026-09-10 20:14:49 +03:00
3458343d89 fix(scenario): live agent-evaluation chain — manifest byte-lengths, response normalization, prompt contract 2026-09-10 20:02:09 +03:00
043a14558f docs(specs): record live provider canary evidence in quickstart statuses 2026-09-10 18:32:25 +03:00
83727aa7f9 feat(scenario): complete offline agentic runtime chain 2026-09-10 14:14:40 +03:00
9c1a1e093c feat(mcp): Phase 2d field-run remediation — ADR-0024 agent-run surface, derived capabilities, disposition clarity
Source: live external MCP run against ss-prod Sales Dashboard (docs/2026-09-07-sales-prod-mcp-run.md) proved the initial-bootstrap chain externally unreachable: register_draft_pack requires a principal-owned AgentRun but no MCP operation created one after the chat decommission; the vertical E2E masked the gap with a raw-ORM prerequisite seed.

T029i: MCP create_agent_run/get_agent_run (mcp_server/tools_agent_run.py) over Services.AgentRuns.Service.Create — REST-parity EXECUTE/READ permissions, human-only, server-pinned UIContext, idempotency-key replay; catalog 2.1.0->2.2.0; MCPX-FR-027 external-reachability invariant pinned; initial-scenario E2E converted to the fully external chain (zero non-MCP seeding); strict-xfail pin flipped as designed, unmarked and hardened (E2E-EXT-001 CLOSED).

T029k: ScenarioGraph.CapabilityAuthority — truthful capability facts derived from the authoritative DashboardQueryModel (mutation-context capabilities never derived), derived-wins merge over caller declarations, single choke point wired into MCP inspect_scenario / inspect_dashboard_context and REST api_compile_scenario; CAP-001 classification-fix test on the sales-shape fixture (B02-B04/T01-T03 automated, C04-C06 unsupported, unsafe-mutation cases legitimately human).

T029l: disposition vocabulary clarity — RU/EN labels name the persisted outcome (confirm->passed), confirm restyled bg-destructive->bg-primary, decide_checkpoint description carries the immutable outcome table; lifecycle mapping and API vocabulary unchanged (DISP-001 CLOSED).

Decision memory: ADR-0024 (IMPLEMENTED, 4 rejected alternatives incl. no-AgentRun boundary and implicit auto-create) + README registry; 050 MCPX-FR-027/028/029 + release-gate rows + Clarifications session 2026-09-07; 038/044/045 field-run amendments -> IMPLEMENTED; WORKSTATE checkpoints (plan round + execution round).

Pre-existing HEAD regressions surfaced by the first full-suite rerun since 4d5ef6be/58c5ae39 and fixed: (1) stale SC-007 resource pin — canonical identifier is the post-redirect /mcp/ (code + twin pin aligned since the batches; test_mcp_client_flow_http pin updated with rationale); (2) app-lifespan tests re-entered the run-once StreamableHTTPSessionManager module singleton — autouse fresh-transport-app fixture (production lifespan runs once per process; singleton stays correct there).

Gates: full backend suite 11357 passed / 243 skipped / 1 xpassed / 0 failed (first green full run since the batches); MCP+catalog slice 70 passed; capability slice 67 passed; frontend vitest 3507 passed (206 files), lint 0 errors (364 baseline warnings), build OK; ruff/compileall clean; anchors balanced; scoped git diff --check clean. INV_7 watch: tools_scenario.py 508 LOC and routes scenario.py 442 LOC flagged for the next decomposition pass (new code lives in new modules 155/236 LOC).

OPEN: T029m / E2E-EXT-002 — live-stand replay of the sales scenario through the full external chain. Not included (foreign uncommitted workstream): translate/migration integration tests, _job_routes.py, .kilo/agent-manager.json, specs-036-050-20260907-111314.md.
2026-09-07 16:52:38 +03:00
58c5ae39cb feat(scenario): server-owned handle pipeline T029d–h + MCP bootstrap/automation + UI launch/approval
Backend (Phase 2c, closes ADR-0023):
- T029b/c: 9 automation MCP tools (REST-parity RBAC, scheduler registration, idempotency), migration 0018; fresh-DB MCP E2E.
- Guard BOOTSTRAP_REVISION_NOT_RUNNABLE in derive_runner_plan (provenance-only revisions never queue a vacuous zero-step PASS); demoted to defense-in-depth after materialization landed.
- T029d: CompiledScenarioHandle/ValidationResultHandle/DraftPackHandle (immutable, owner-bound, content-addressed canonical-bytes store), migrations 0019/0021; minting at REST compile/validate/resolve/draft-pack boundaries; single consumption under SELECT...FOR UPDATE + populate_existing, proven on PostgreSQL (Testcontainers).
- T029e: handle-first create_scenario/create_initial materialize canonical graph_snapshot (+ server-owned action_registry identity) in-transaction; OutboxEvent + RevisionMaterialization (0020) with idempotent worker wired into the scheduler poll loop (30s tick).
- T029f: MCP register_draft_pack write tool; bootstrap accepts only stored handle ids (transitional compile:{run}:{digest} removed); legacy REST POST /scenarios/{id}/revisions retired -> 410; catalog 2.0.0 (pinned-major ritual); ActionRegistry 038.2.0 — generate_report reclassified non-mutating (local draft write), register_artifact/row_edit/bulk_edit stay mutating.
- T029h (hybrid C+X1): inspect_dashboard_context MCP tool (live DashboardQueryModel resolver); context_authority evaluation — server recomputes client-context fingerprint (claimed values ignored), sentinel fingerprints never verify, unreachable env fails open to unverified, live-env mismatches reject typed with zero rows; marker persists on DraftPackHandle, materializes into graph_snapshot; PROD start refuses explicit non-verified (CONTEXT_AUTHORITY_REQUIRED_FOR_PROD); validator recursively rejects query_context/SQL smuggling in dashboard_context; catalog 2.1.0. 043 editor path provably inherits the marker.

Frontend:
- D2: scenario detail route scenarios/[id] — first production host of RunConfigurationPanel (typed 044 launch + Idempotency-Key + redirect to run monitor); ROUTES.scenarioDetail SSOT; registry index links to detail (launch stays off the index).
- D4: ApprovalDecisionPanel + RunMonitorModel.decideApproval — PROD gates decidable from the web UI (run-detail aside on pending_approval).
- Pre-existing suite repairs: oauth-consent raw goto -> ROUTES.login(); InvestigationModels stale dispose signature; settings mcp_oauth_* bind:value undefined crash (backend defaults 15/30/90).
- i18n: approval_* + scenario_detail_* keys in en+ru.

Specs/docs (amendments 2026-09-06/07):
- 038: PackCompiler.Generate contract corrected (pure manifest); ServerOwnedPipeline handle-persistence amendment; verification-program reconciliation (implemented vs PROPOSED IR entities).
- 042: synchronous graph materialization + outbox scope; CreateInitial amendments; RevisionChain @REJECTED for raw client graph_snapshot.
- 050: stage-table implementation-status note, handle-rules status, T029–T029h evidence; WORKSTATE checkpoints; ADR-0023 -> IMPLEMENTED.

Gates: backend full regression 3360 passed (+ PostgreSQL integration green), alembic single head 0021; frontend vitest 3506 passed, lint 0 errors, build OK.
2026-09-07 11:26:34 +03:00
4d5ef6bed0 feat: dashboard-testing UX remediation + admin MCP governance + i18n sweep
- UX audit Fix 1-5: actionable MCP HandoffSurface (endpoint/discovery/onboarding), reachable
  approval loop (sidebar section + waiting-for-me badge), honest MCP entry labels, ROUTES SSOT
  for dashboard-testing/load-testing (+ link-integrity coverage)
- scenario registry hub (/dashboard-testing/scenarios) built on ScenarioRegistryModel
- admin MCP governance: read-only GET /api/admin/mcp/catalog (catalog x roles + DCR clients) +
  /admin/mcp page/model/api + ROUTES.admin.mcp + sidebar entry
- full i18n sweep of dashboard-testing routes and scenario-* component trees (ru/en)
- accumulated workspace: MCP OAuth/DCR, automation idempotency migration, docker/nginx, specs
2026-09-05 20:16:26 +03:00
34a6507fa3 chore(semantics): Axiom live re-review — curator pass 46 edges (unresolved 446→401) + MCP happy-path UX audit
Closure-gate re-review of rounds 1-5 with the Axiom index live (full rebuild 10534 contracts): remediation matrix all CLOSED, SC-001..SC-009 walkthrough carried current executable pins, verdict recorded in specs/WORKSTATE-043-047.md.

Curator pass (comment-only, zero runtime change; every target verified against the live index before retargeting): mcp_server zone 6 edges fixed (Services.AgentAuthoringWorkspace.Service, McpServer.Package→McpServer, phantom SupersetClient.DashboardWrite → three verified Core.DashboardsWrite/Datasets contracts, AgentSuperset.SqlFormat) — scoped audit now 0 unresolved; plus 35 historical retargets (scenario chain → function-level contracts, Superset-client alias/path forms → Core.Init.SupersetClientModule, Models.User→Models.Auth.User ×5, ExecuteEnvelope→ExecuteQueryEnvelope ×6, GitService/Deployment/StructureSnapshot/DashboardTesting.Core, client_registry python-path forms) and 11 malformed multi-target translate-plugin lines split into individual @RELATION lines with verified IDs. Workspace unresolved relations 446→401; remainder classified and queued (logging-SSOT zone owned by the concurrent shared→backend migration, function-shaped targets, legacy single-# regions).

UX audit (read-only, findings + prioritized fix plan persisted in WORKSTATE): MCP happy path for a BI analyst scores 2/5 — CRITICAL: handoff surface gives no endpoint URL/discovery/client onboarding; approval loop (/dashboard-testing/runs WaitingForMeView, HumanCheckpointPanel) unreachable via navigation (absent from ROUTES.ts and sidebar). HIGH: AI/Ассистент buttons promise chat but land on a decommission stub; no MCP settings/status surface anywhere. MEDIUM: dashboard-testing/load-testing routes bypass the ROUTES SSOT.
2026-09-04 20:41:38 +03:00
4c57789218 fix(mcp): closure-gate remediation rounds 2-5 — unified CoT logging, server.py decomposition, 050 P2 queue closed
Round 2 — P1 MCL + GRACE:
- logger intent-drop repaired across 182 call sites; logging unified repo-wide on the
  intent-first facade (211 direct SSOT log() sites migrated); facade level= support;
  molecular-cot-logging skill synced with the module (.agents -> .kilo).
- EXPLORE/REASON-REFLECT gaps closed: poll-dispatch failure path, exploration fail-closed
  choke point in _finish(), 9 silent mcp_ops_dispatch adapters.
- INV_6: dead agent/app.py edge removed (_llm_health); specs 033/035/036/039 sweep ->
  0 dead edges (5 retargeted to live IDs, 15 tombstoned with successors).
- INV_9 dedupes (TaskDrawer BINDS_TO, vestigial assistantOffset, duplicated @SIDE_EFFECT);
  INV_1: migrations 0014-0016 anchored, exploration_sandbox module-region span fixed.
- Full-suite defect root-caused: leaked DI singleton mocks from test_dependencies_unit ->
  autouse restore fixture + get_session_idle_timeout_minutes hardening (int validation,
  EXPLORE fallback SESSION_POLICY_CONFIG_INVALID).
- Executable pins: tests/test_core/test_logger_wire_format.py (wire fields, misuse proof,
  repo-wide AST sweeps over both forbidden shapes).

Round 3 — server.py decomposition EXECUTED per the binding gate plan
(specs/050-mcp-interface/plans/server-decomposition-gate.md, execution log included):
- 1571 -> 177 LOC: scenario_inputs.py (268), auth.py (238, single _access_token_context
  site), rbac_server.py (393), tools_authoring.py (367), tools_scenario.py (373).
- Addendum E: pre-existing ops_tools.py INV_7 offender split 420 -> 215 + tools_review.py (253).
- Contract IDs frozen, import surface frozen, registration order frozen; monkeypatch seams
  relocated to owning modules (recorded); zero behavior diff.

Round 4 — P2 queue closed:
- Story 5 AC2: HandoffSurface copyable prompt parameterized with dashboard context
  (/agent route forwards objectType/objectId/objectName/envId/route/intent; i18n
  handoff_context_label ru/en; contract + render tests).
- E6 / MCPX-FR-007a: McpTransportGuard enforces server-owned JSON-depth bound (typed
  400 json_depth_exceeded pre-dispatch, iterative fail-closed walker) and per-session
  sliding-window rate limit (typed 429 rate_limited + standard Retry-After); rejections
  create no mutable state. Limits live in McpServerConfiguration.
- SC-005 remnants CLOSED: /api/assistant router unmounted (package retained as MCP parity
  provenance, header records rationale); /api/agent/llm-config REMOVED with in-place
  Tombstone + dead strict service DI deleted; assistant.ts deleted (inbound edge removed
  first); SystemSettings assistant-retention UI + 16 i18n keys removed; .env.example
  7860/GRADIO vars removed (zero consumers verified repo-wide).
- SC-004 + SC-009: exact RBAC catalog pins (admin 47 / analyst 21 / viewer 15 derived from
  the live catalog); mid-flow role revocation hides tools in the next tools/list AND denies
  cached-catalog calls by name on the same identity-only token; mid-flow grant exposes the
  approvals surface without new consent.
- Browser cookie-consent decision recorded (tasks.md T008): not built in 050.

Round 5 — last 050 task + FR-010:
- T008b: Core.EndpointLocality deny-by-default perimeter guard for LLM/VLM provider base_url
  at the create/update choke points (private ranges, enterprise DNS suffixes, all-private
  resolution; fail closed; anti-substring-spoofing; empty URL denied); typed 400
  endpoint_not_local:<reason> pre-persistence; EXPLORE audit line on every denial; env
  escape hatches documented (INSTALL.md "Локальный периметр").
- MCPX-FR-010: MCP_CATALOG_VERSION published as serverInfo.version at initialize;
  deprecated/deprecation_note on McpToolDefinition; [DEPRECATED] marker at the single
  list_tools choke point (entry stays listed/callable one minor cycle); deliberate
  major-bump ritual pinned by test.

Evidence: full backend suite 11243 passed / 240 skipped / 1 xpassed / 0 failed;
frontend vitest 3435 passed / lint 0 errors; MCP slice 103; locality slice 107;
anchor+AST sweeps ALL BALANCED over 138 touched files; 050 tasks.md fully [x] with proof.
2026-09-04 13:07:08 +03:00
a0450b33a9 fix(mcp): closure-gate remediation round 1 (P0) — checkpoint tools, client_credentials, gate shape-unwrap, SC-007 HTTP flows
FR-019 (was a false [x]): MCP list_checkpoints + decide_checkpoint over the
044 CAS lifecycle (server-resolved pending checkpoint, decision_version CAS,
continue_after_human_decision, typed conflict/not_found); catalog scenario:RUN
and service_allowed=False — automation has no path to checkpoints.
tests/test_mcp_checkpoints.py: 3 passed.

FR-013/SC-007: client_credentials grant for machine clients — confidential DCR
(one-time client_secret, sha256-only via migration 0017_oauth_client_secret
with idempotent guard), signed identity-only service-principal tokens
(principal_type=service, aud=mcp, no refresh), McpTokenVerifier service
short-circuit, AS metadata grants/auth-methods, INSTALL.md §MCP-client docs.
tests/test_mcp_client_flow_http.py: full scripted-client flows over real HTTP
(machine: discovery→DCR→client_credentials→/mcp initialize→tools/list→call;
user: DCR→PKCE S256 authorize via Bearer web session→exchange→/mcp live-RBAC
listing). 2 passed; oauth suite 10 passed.

PRODUCTION DEFECTS fixed en route: call_tool argument-inspection gates parsed
only the FLAT shape while FastMCP delivers {"request": {...}} —
start_scenario_run was uncallable over MCP and the PROD-SQL terminal denial was
bypassable by the wrapped shape. Both gates now unwrap via _gate_arguments;
regression pinned by flat x wrapped PROD matrix (6 combos).

E2E-AUTH-001..003 release-gate rows closed with evidence: T028 chain gained
propose_test_plan (single-trace 001); T023 extended with post-activation
start_scenario_run on the canonical runner-shaped fixture graph, asserting the
queued run pins promoted revision_id + content_hash (003); 002 already proven.

Record honesty: tasks.md T025/T008/T008b/T032 downgraded at review time;
T025+T008 re-closed with executable evidence; T032/T008b/T005a remain open in
the round-2 queue (recorded in WORKSTATE checkpoint with the full P1/P2 list:
MCL intent repair, dispatch/sandbox EXPLORE traces, INV_6 tombstones,
SC-005 remnants, FR-010 versioning, depth/rate limits).

Evidence: combined MCP slice 95 passed; alembic single head 0017; ruff and
compileall clean; anchors balanced in all touched files.
2026-09-03 13:02:57 +03:00
731aaaa8df feat(mcp): 050 unified MCP interface — parity tools, durable gates, authoring E2E, assistant decommission
044 provider runtime completion (pre-staged workstream): capacity/operator
stores, provider ops/protocol/reconciler/dispatch revalidation, exploration
sandbox runtime, alembic 0014-0016, live canary evidence (browser provider
6/6 against the live stand).

050 Phases 0-2: RBAC FastMCP server with a 45-tool explicit catalog,
OAuth/DCR transport guards with bounded bodies, per-call provenance
(McpToolInvocationRecord), durable ActionApprovalGate + CAS decide +
leased/fenced poller, authoring workspace ops, bounded-response discipline,
hidden-vs-gated matrices.

Parity domains (T012-T014): gated git/deploy/migration/backup/llm tools with
reviewed dispatch adapters in explicit poll chains; Superset reads/writes with
a dedicated plugin:superset_sql risk class (terminal PROD denial via the
canonical execution-policy criterion, hardened danger-SQL guard covering
INTO/CALL/SET/REFRESH/file primitives/multi-statement); baseline 037 tools
over the shared REST-surface services.

Evidence (T016/T023/T028): REST-vs-MCP field parity on shared 037 fixtures;
vertical E2E from tools/list through registry revision activation with real
scenario:EDIT RBAC; sandbox-to-revision promotion E2E with unsafe-payload and
caller-digest rejection; dispatcher soak (three poll cycles, exactly-once).

Orthogonal QA+security audit hardening: enforced response_limit fail-closed
envelope, poisoned-exploration fail-closed (EXPLORATION_TARGET_UNRESOLVED),
sha256 exploration evidence digests, actor-UUID task ownership, is_active
guard on baseline consume, 038 resolver description=None selector fix.

Phase 3/4 decommission: HandoffSurface behind the MCP_DECOMMISSION flag,
then unconditional removal — agent/ service tree, chat components/models/
stores/types, gradio proxies (vite + nginx), agent service in run.sh,
docker-compose profiles, build.sh bundles; /agent renders the handoff only.
Docs: AGENTS.md/INSTALL.md two-service rewrite; 036-047 drift amendments
marked done; WORKSTATE checkpoints with all evidence.

Suites: backend 11199 passed / 240 skipped / 1 xpassed; frontend 3454 passed
(197 files), lint 0 errors, build OK; browser E2E login+handoff 6/6 twice on
the isolated compose stack (no 7860); ruff/compileall clean.

Misc: gitignore hardening (tmp/, tool model cache); E2E selector repairs
(nav strict-mode, invalid-credentials passthrough detail).
2026-09-03 07:37:14 +03:00
341d54399a fix(semantics): repair GRACE-Poly anchors, relations, and metadata
Repair broken/unclosed semantic-protocol markup across the codebase:

- INV_3 region pairing: restore 87 bare '# #endregion' (6 test_structure_*
  files) and 321 bare '// #endregion' (13 frontend test files) with their
  matching IDs; hand-fix 26 Python + 12 frontend + 2 E2E files with
  mismatched/missing/premature/duplicate closes; fully migrate
  test_orthogonal_fixes.py from single- to double-hash anchors.
  Workspace-wide stack-pair scan now passes 6569 code files with 0 problems.
- Relations: normalize legacy predicates USES/CONTAINS/BELONGS_TO to
  canonical DEPENDS_ON/BINDS_TO (28 edits).
- Metadata: normalize @LAYER and [TYPE] enum values to the canonical
  vocabulary (App->Application, lib->Infra, Service/Route/Checklist/
  Declaration/Decorator/Functions -> Module/Function/Block, etc.).
- Config: extend tags.LAYER.enum; fix tools.py prose '#region' phantom that
  broke anchor nesting.
- Remove dead scratch scripts backend/_convert_defs.py, _batch_convert_defs.py.

Index refresh: contract count 9576 -> 10821; schema_unclosed_anchor
1179 -> 729 (remaining 729 are markdown legacy [DEF:]/brace anchors, a
separate migration phase).
2026-09-01 12:24:42 +03:00
7a14a4d947 feat: add MCP authoring workspace foundations 2026-08-28 19:01:42 +03:00
0415a2ed7d chore: accumulate uncommitted workspace changes 2026-08-26 17:03:22 +03:00
4b9619e229 refactor(deploy): standardize enterprise environment file 2026-08-25 15:30:10 +03:00