Commit Graph

1094 Commits

Author SHA1 Message Date
5758ae4a83 fix(database): object-level reset and optional DB_SCHEMA isolation
Safe one-shot reset, fail-fast on unknown revisions, object-level drops for non-owner corporate PG, rollback before advisory unlock, configurable DB_SCHEMA via search_path, e2e migration matrix tests.
2026-09-11 16:17:11 +03:00
e334863771 build(backend): declare python-dotenv explicitly (review nit — direct import) 2026-09-11 15:10:24 +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
1d48625b10 test(maintenance): fix 5s first-test timeout flake — static import + vi.hoisted mocks
Module load of maintenance.svelte.js happened inside the first test via
dynamic import and exceeded the 5000ms testTimeout under full-suite
parallel load. Move to a single hoisted static import (mock factories
now resolve vi.fn()s created via vi.hoisted) and drop a dead no-op
placeholder test. 39/39 in isolation, 3563/3563 full suite.
2026-09-11 09:49:52 +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
792bb1251d feat(scenario): live eval trust — MIME sniffing, multimodal evidence, baseline pin stamping, binding admin surface 2026-09-11 08:40:19 +03:00
bac002bcbc feat(settings): derive project-sections toggles from sidebar nav registry
- sidebarNavigation.ts: static SIDEBAR_SECTIONS registry (i18n labelKey) + getTogglableFeatureNodes() with per-flag dedup
- projectSections.json: shared feature-id manifest; vitest guard pins nav ids to it, pytest guard pins it to FeaturesConfig fields
- FeaturesSettings: toggles derived and grouped by sidebar section/category, extra block for non-nav flags
- features.svelte.ts: reactive flags store; sidebar rebuilds live after settings save, untracked health polling
2026-09-11 07:35:26 +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
2532702478 feat(migration): localized risk messages, advanced options collapse, names over UUIDs
Iteration 2 of the migration UX plan:

Risk message localization (params + frontend templates):
- MigrationRiskItem.params (additive) populated at all 13 emission sites
  (orchestrator, dashboard_outcomes, risk_assessor); English message kept
  for assistant/logs backward compatibility
- migration.riskMessages.ts renders risk_msg_* en/ru templates with
  drift details (schema: «marts» → «public») and graceful fallback

Names over UUIDs:
- _read_target_databases caches uuid->name map; drift/missing-datasource
  messages and params carry dataset titles (table_name) and DB names
- compare_dataset_contracts: live None = no evidence, never drift
  (fixes false positives where target LIST omits database_uuid)
- UUID rendered as ds:{8-char} chip with full UUID in title tooltip

Step 2 UX:
- sed rule, composite keys (+mutation server), rescan IDs moved into
  collapsed Advanced options; selected-count chip near Dry Run CTA;
  target-mutation hint + SOURCE-mutation warning

P0 hygiene:
- task view Cancel -> Close view + background-continues hint; own i18n
  keys for Dry Run/step labels; dead Quick Actions block removed;
  PasswordPrompt alert() -> inline validationError

Decomposition (no behavior change):
- run() 330 -> ~55 lines via _process_dashboard/_resolve_effective_
  mapping/_transform_with_fallback/_assemble_report
- MigrationReviewPanel 303 -> 151 lines via MigrationOutcomeList +
  MigrationRiskAssessment

Tests: params assertions + None-skip case (backend), 5 riskMessages
cases (frontend). 116 pytest + 270 vitest passed, lint/build clean.
2026-09-10 20:13:45 +03:00
3458343d89 fix(scenario): live agent-evaluation chain — manifest byte-lengths, response normalization, prompt contract 2026-09-10 20:02:09 +03:00
bbbd4ccfa6 feat(scenario): published-catalog source fallback + server-side live binding resolution at start 2026-09-10 18:59:15 +03:00
043a14558f docs(specs): record live provider canary evidence in quickstart statuses 2026-09-10 18:32:25 +03:00
fe11a636f1 docs(scenario): live provider canary trace (T7/T8 passed) + two production defects closed 2026-09-10 18:27:46 +03:00
ba2f1f45b2 fix(scenario): browser preflight probe deadlocked lifespan loop thread (300s startup hang) 2026-09-10 18:12:59 +03:00
3e5cc942dd refactor(scenario): wrap naked helpers in GRACE regions (INV_1) 2026-09-10 16:35:13 +03:00
befa03e34f feat(migration): dashboard-first dry-run review, compact logs, second timestamps
Backend:
- dashboard_outcomes module: per-dashboard new/overwrite/identical outcome,
  composite-key drift prediction with desired-vs-live values, read-only
- dry-run: single cached live dataset-contract fetch (was O(dashboards)),
  literal_find/literal_replace reach every transform_zip call
- catalog read failures degrade to warnings (target_database/dataset_catalog_
  unavailable, risk_analysis_unavailable) instead of fabricated blockers
- MigrationDryRunResult + dashboards[]; MigrationRiskItem + dataset_uuid

Frontend:
- MigrationReviewPanel: sorted outcomes (blocked -> overwrite -> new ->
  identical), show-all toggle, risk assessment separated from technical
  details, full en/ru localization
- execute failure preserves dry-run and returns to step 3; submit guard
  hides Back while POST is in flight; confirm dialog before migration start
- task logs: dense one-line rows with expand chevron, compact toolbar
  (filters/debug/errors/autoscroll/count in one row)
- migration dashboard grid timestamps truncated to seconds via
  formatDateTimeSeconds

Tests: +6 backend regression (literal kwargs, outcomes, drift severity,
missing-db blocker, catalog degradation, single live fetch), +4 frontend
(sorting, legacy fallback, execute recovery). 116 pytest + 261 vitest passed.
2026-09-10 16:34:02 +03:00
1b79597536 test(mcp): adapt initial-scenario e2e to fail-closed baseline resolver (Front 5-R) 2026-09-10 16:31:01 +03:00
a21481ea6d refactor(scenario): INV_7 split runner into walker/start/dispatch/crash-recovery facade 2026-09-10 16:13:44 +03:00
8f057f3043 refactor(scenario): INV_7 split executors + lifecycle, repair orphan relations, fix serializer fixture 2026-09-10 15:40:17 +03:00
b024e60884 fix(scenario): commit missing Slice G router + eligibility service 2026-09-10 15:38:59 +03:00
83727aa7f9 feat(scenario): complete offline agentic runtime chain 2026-09-10 14:14:40 +03:00
fc8a9bf45d feat(maintenance): support insecure TLS mode 2026-09-10 13:46:11 +03:00
9d2e856e3f fix(maintenance): make example scripts ASCII-only 2026-09-10 12:29:30 +03:00
e1dcf7cf90 fix(maintenance): INV_7 routes decomposition, UX contract-drift repair, RBAC/L2 test gaps closed
- decompose _routes.py (947 lines) into a 27-line facade + 5 handler modules (events/preview/start/end/settings), all <=400; extract _chart_layout from _chart_manager (441->381+78); contract IDs preserved verbatim, 9 routes registered in original order
- close RBAC FR-015 invariant gap: tests/api/test_maintenance_routes_rbac.py — 403 denied + 401 unauth on all 9 endpoints with exact guards (root cause of the blind spot: conftest MaintenanceRouteEnv overrode permission closures with lambda: None)
- repair 4 UX contract drifts: EventsTable empty-state + expandedEventIds invariant aligned to implementation (backend terminal-events expansion is intended per MaintenanceEventStateStatuses @POST); Badge phantom loading state removed (INV_9); SettingsPanel fields disabled during Saving implemented per contract
- add 34 L2 component tests (EventsTable/Badge/SettingsPanel) covering declared @UX_STATE/@UX_TEST/@UX_RECOVERY
- split oversized test files (709/686/624 -> all <=520, collected counts identical)
- test hygiene: RootTransaction is_active guard removes SAWarning in shared postgres fixture; AsyncMock create_task coroutine leak fixed in scheduler tests (zero RuntimeWarnings)
- examples/maintenance actualized against current API: optional environment_id with PROD fan-out (batch response), 422 no-PROD-target, GET events/{id}/dashboards, settings field list

Verified: isolated worktree (HEAD + this diff) 729 backend tests passed; frontend 109 passed; ruff clean; anchors balanced; index rebuilt (0 warnings)
2026-09-10 10:57:18 +03:00
1b9cb2b352 fix(migration): compare only obtainable fields in dry-run diff + archive key mapping
- archive_parser: canonical compare-field specs (position->position_json), presence-checked `fields`, shared normalization; keep backward-compat signature
- dry_run_orchestrator: intersection-based object diff — no false "update" on 6.x LIST exposure; 4.1.2 create-only limitation documented and pinned
- translate: unshadow fastapi.status in job list route (ValueError now 400) + unskip regression test
- tests: real-container migration plugin PARTIAL_SUCCESS/dry-run e2e, Superset LIST column-exposure characterization, translate malformed-LLM e2e + pg_e2e split (<800-line cap), dict_snapshot_hash DATABASE_URL poisoning fix, dead BINDS_TO/edge repairs
2026-09-08 06:09:25 +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
3d78569235 fix(logging): enforce single JSON protocol on console — uvicorn takeover + library noise demotion
uvicorn/uvicorn.error adopt the shared CotJsonFormatter handlers (own plain-text handlers replaced, propagate=False); uvicorn.access silenced by default — middleware JSON framing already narrates every non-polling request, and the plain 'INFO: host - GET ...' access lines were the duplicate-console-format source under run.sh. LoggingConfig.uvicorn_access_log=True restores access output as JSON, never plain text.

Unmarked library records map deterministically in CotJsonFormatter: ERROR+ -> EXPLORE with exc_info traceback captured into the error field (<=1000 chars), below -> REASON. Explicit marker always wins.

httpx/httpcore demoted to WARNING via LoggingConfig.http_client_log_level ('HTTP Request: ...' per outbound Superset call is polling-amplified noise; our CoT layer narrates those requests). Git NO_REPO branch: 10 interpolated REASON lines per batch poll -> one invariant-intent DEBUG line with payload{dashboard_id,result} (ADR-0021 intent-invariance).

Tests: uvicorn takeover x3, httpx demotion x2, formatter marker mapping x3 — logger/formatter suites green (42), ruff clean. NOT included (entangled with a parallel session's WIP in the same files, stays in working tree): app.py POST-batch framing suppression + its middleware test, and the Run Center runaway-fetch-loop fix + regression test.
2026-09-05 10:09:49 +03:00
65121cac6b feat(logging): self-diagnosing EXPLORE + shared/ absorption + belief analytics (ADR-0021/0022)
T0: absorb shared/ into backend — cot_logger→src/core, CotJsonFormatter→src/core/cot_formatter.py, _llm_http/_llm_health/ssl→src/core/utils; imports rewritten (26 prod + tests, patch targets); run.sh/backend.Dockerfile/requirements/.axiom source_dirs/semantic_health/AGENTS/INSTALL cleaned; ADR-0022 supersedes ADR-0015; fixed latent CI defects (ss_tools ImportError, record.message in logger tests, same-name test-module collision).

ADR-0021 wire enrichment (additive): contract_id/claim/error_code/loc fields; _contract_id ContextVar + resolve_contract_id (explicit > belief_scope > declared-src mirror, derived src never mirrors); EXPLORE auto-loc via single frame walk; facade error auto-fill; 2KB payload cap with payload_truncated/payload_bytes markers; migrated 85 error="CODE" sites to error_code= (12 files); pilot editor/load.py; superset preview payload-bomb inlined bodies removed.

Analytics SSOT src/core/log_stats.py (bond transition matrix, orphan-EXPLORE ratio, REFLECT pairing, intent families, coverage, insufficient-sample flag); pretty_cot.py --stats/--digest/--trajectory/--story over one engine; log_gap_service three-tier ground-truth triangulation (FAILED w/o EXPLORE etc.) + GET /api/reports/log-stats|task-log-gaps (polling-suppressed); scripts/cot_audit.py CLI; enriched fields persisted into task_logs.payload for tier queries.

Frontend: ReportsAnalyticsModel + AnalyticsStatsPanel (Logs tab) + TaskGapPanel and per-row T1/T2/T3 gap badges (Tasks tab); cot-logger.ts ADR-0021 opts; i18n en/ru. Scheduler console spam fixed: apscheduler logger demoted to WARNING via LoggingConfig.scheduler_log_level. .axiom belief patterns -> $OBJ.* (alias undercount). molecular-cot-logging skill updated (fields, decision rules, tie-break, CLI) and synced.

Reviewed orthogonally: F1 cot_span contract pollution, F2 cap boundary accounting, F3 digest over-dedup, F4 trace-state bound, F5 tier metadata — fixed with regression tests. Validation: backend 11287 passed + ruff + compileall; frontend 3446 passed + lint + build; CLI smoke on live app.log.
2026-09-04 20:56:41 +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
96f6965845 feat(agents): inject semantic nav map (root.map) into agent context
- .kilo/kilo.jsonc: instructions=["docs/api/nav/root.map"] — the
  semantic module digest (doc-gen --nav) is auto-injected into the
  starting context of every agent session (~14 KB: areas, per-module
  purpose/kw/deps, collapsed tests).
- AGENTS.md: documented the L0->L3 navigation protocol (root.map ->
  <Name>.map -> nodes/<Contract>.md -> source via FILE:line), nav_id.map
  fallback, and the re-read/regenerate freshness rule (the injected map
  is a session-start snapshot).
- .kilo/setup-script: generate docs/api/nav for fresh Agent Manager
  worktrees (gitignored artifact; uses $REPO_PATH/../axiom-mcp binary,
  cold index build ~60s, graceful skip when the binary is missing).

Requires ../axiom-mcp doc-gen with the semantic root (see axiom-mcp
"feat(docs): semantic module digest root.map" commit); regenerate via
`make docs-nav`.
2026-09-04 17:39:31 +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
ddbfe00fc5 fix(semantics): round 3 — zero parse warnings via relation/canonical fixes, MCP parser patches
- All schema parse warnings NOW ZERO (unclosed, def_deprecated, invalid_enum,
  unknown_tag, invalid_predicate, invalid_tier: 0).
- Redirect 42 dead @RELATION targets to existing contracts (Core.Database.*→
  DatabaseModule, User→Models.Auth.User, create_task→Core.Manager.TaskManager,
  AuthMiddleware→Dependencies.AppDependencies, AuthRepository→Core.Repository.*,
  _handle_deploy_helpers→Api.RepoLifecycleRoutes, etc.).
- Config: add NAMESPACE/SEE (Doxygen-native), TYPE empty-enum (suppress JSDoc
  @type false positives), remove *.html exclude (prototype contracts now
  indexable), extend LAYER enum.
- Plan doc: record round-3 results (2066→1171, -43%).

MCP parser fixes (axiom-mcp sibling repo):
- comments.rs: detect block-comment terminator BEFORE stripping leading '*'
  (bare '*/' close line no longer stays open → 20 Svelte __unclosed__ cleared).
- parser.rs line 249: only comment-normalized lines carry GRACE anchors
  (payload.unwrap_or('') instead of .unwrap_or(raw_line)) → string-literal
  '#region' misreads + prose [DEF:] false positives cleared.
2026-09-03 09:09:21 +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
e14524d22a fix: resolve test and lint gate failures 2026-08-26 18:56:57 +03:00
0415a2ed7d chore: accumulate uncommitted workspace changes 2026-08-26 17:03:22 +03:00
c4ccfcc9fd fix(migration): dual-mode recovery logging + regression tests for PR-0160 incident
The composite-key recovery branch crashed with TypeError depending on execution
mode: TaskLogger requires metadata=, app CoT logger requires extra=. The earlier
metadata= fix repaired task-context runs but broke context-less runs (6 existing
tests confirmed).

- add _emit_task_log: inspect-based kwarg selection per logger backend
  (@REJECTED TypeError-catch: masks genuine logging failures)
- add test_migration_recovery_regression.py with a REAL TaskLogger (mocks
  silently accepted the wrong kwarg, which is why the prod bug was never
  caught): recovery success phases started/sync/retry_import/completed,
  context-less mode, invalid mutation-server coercion to target,
  retry-failure entry fields, NO_MATCHES short-circuit
2026-08-26 13:37:27 +03:00
e3754b0931 sync skills 2026-08-26 13:13:02 +03:00
6cfd9135bb fix: resolve production log errors — profile, datasets, migration recovery, mapper validation, reencrypt
- AuthRepository: add missing save_user_dashboard_preference (PATCH
  /api/profile/preferences returned 500)
- DatasetItem.schema_name nullable — GET /api/datasets no longer 503s on
  Superset datasets with null schema
- migration: TaskLogger calls used extra= kwarg which raised TypeError and
  killed the composite-key recovery branch, leaving the target server
  unrepaired after failed dashboard imports (e.g. PR-0160); switched to
  metadata=
- maintenance settings: lazy-create singleton with IntegrityError race guard
  instead of permanent 404
- mapper upload-xlsx: structured 400 detail (expected vs actual columns);
  MapperTool shows inline error panel instead of toast; i18n ru/en
- connection_service: eager re-encryption of legacy plaintext passwords in
  get_connection; returns a copy so live config never holds plaintext
- check_target_schema: log exception type/repr/traceback (was empty error)
- scheduler/maintenance auto-end: skip empty-tick INFO logs; suppress HTTP
  framing for GET polling endpoints
- reencrypt script: repair broken merge artifact, JSON-serialize payload on
  save, fix failed-count arithmetic
2026-08-26 12:50:03 +03:00
8a3bba139e fix(database): auto-reset orphaned Alembic revisions 2026-08-25 16:06:14 +03:00
4b9619e229 refactor(deploy): standardize enterprise environment file 2026-08-25 15:30:10 +03:00
a2ede492b7 fix(database): reset any legacy Alembic revision 2026-08-25 15:21:42 +03:00