1058 Commits

Author SHA1 Message Date
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
e80c954b37 fix(build): defer bundle secrets to deployment 2026-08-25 12:24:51 +03:00
5bc1b62bd0 refactor: unify initialization and reset migration baseline 2026-08-25 11:42:31 +03:00
cfb13d9a69 chore(agents): migrate command definitions 2026-08-24 17:02:22 +03:00
9fb37a7e9d fix(settings): normalize empty validation policy lists 2026-08-24 17:02:15 +03:00
c1222eb906 feat(scenarios): add SQL evidence and bounded transforms 2026-08-24 17:02:06 +03:00
0c895cf416 feat(logging): unify canonical task CoT events 2026-08-24 17:00:17 +03:00
511219e3e0 fix(git): remove guided tour 2026-08-24 16:01:03 +03:00
fa4a75ce1e feat(frontend): unify Superset Tools visual system 2026-08-24 14:16:35 +03:00
2043f25d3a docs(scenarios): define production provider contracts 2026-08-24 12:34:02 +03:00
1a5c14739e feat(auth): refresh login experience 2026-08-21 16:17:23 +03:00
ffa4d6a85b feat(scenarios): implement execution engine contracts 2026-08-21 16:15:40 +03:00
adbea9db18 fix(translate): fail-closed source handling, double insert, retry recount, scheduler races, LLM parse safety, and improved BI-analyst error UX 2026-08-20 17:34:39 +03:00
63a839e3b0 fix(translate): fail closed on missing source and silent run success
Stop preview/env fallbacks when a configured datasource is gone, skip the
duplicate final insert after streaming, and surface retry/scheduler/LLM
edge cases as FAILED instead of COMPLETED.
2026-08-20 15:37:16 +03:00
585a00c537 semantic-curation: fix anchors, metadata, and relations across backend + specs
- Replace legacy @PURPOSE with @BRIEF across 241 files
- Add missing [C:N] complexity tiers to function contracts in core modules
- Fix tombstone contracts: add @STATUS DEPRECATED to 5 deprecated anchors
- Resolve 7 unresolved @RELATION edges in executor.py (DictionaryManager, TranslationPreview, etc.)
- Fix flat hierarchical IDs in 4 test files (22 test functions)
- Fix invalid tags/relations in logger.py (@ADR, @CONSEQUENCES, DISABLED_BY)
- Rebuild semantic index: 9,576 contracts, 4,742 edges, 0 parse warnings
2026-08-20 11:45:15 +03:00
82a519a347 feat(scenarios): complete editor execution and analytics 2026-08-20 11:32:26 +03:00
455a56856f fix(agent): report THREAD_REPAIRED as lifecycle error code
The send-path repair branch set _request_result but not
_request_error_code, so the AGENT_REQUEST_FAILED lifecycle event fell back
to the misleading 'agent lifecycle failure'. Set THREAD_REPAIRED so logs
and middleware show the real outcome.
2026-08-19 20:14:50 +03:00
a619c0afb2 fix(agent): use async aupdate_state for checkpoint repair
The repair paths (send-path _repair_pending_tool_calls and resume fallback)
called graph.update_state — the SYNC method — which internally invokes
AsyncPostgresSaver.get_tuple() and raises InvalidStateError ('Synchronous
calls to AsyncPostgresSaver are only allowed from a different thread').
The repair therefore always failed (surfacing as 'Event loop is closed' +
a dangling aget_tuple coroutine) and broken threads stayed broken.

Switch both repair sites to agent.aupdate_state (async checkpointer
interface) and align the mocked agent in tests. Verified live: aupdate_state
repaired the broken checkpoint of conversation 69651ca1 (pending calls → 0).
2026-08-19 20:08:52 +03:00
7cc3297f1e fix(agent): recover broken threads and lazily create scenario runs
Two recurring failures from live logs (conversations 69651ca1 / a8c0dff8):

1. A checkpoint whose AI messages carry tool_calls without ToolMessages
   (run crashed after the LLM emitted a call) makes every send raise
   INVALID_CHAT_HISTORY with no recovery. The send path now repairs the
   thread via _repair_pending_tool_calls: pending calls are answered with
   synthetic error ToolMessages (THREAD_REPAIRED) so the user can retry.

2. Scenario tools scheduled from plain chat (no build_dashboard_test_scenario
   UI intent) had no durable AgentRun, so the resume fallback refused with
   SCENARIO_RUN_REQUIRED. _ensure_scenario_run now lazily creates the run
   from the tool args (dashboard_context from scenario_json for
   validate/resolve), mirroring the UIContextV2 scenario contract.
2026-08-19 20:02:12 +03:00
614f675f64 fix(agent): detect truncated scenario JSON for clear retry feedback
Observed in a live checkpoint: the pending scenario_validate tool call
carried a scenario_json that the LLM stream cut mid-document (ended
inside the unclosed outer object, len 3837). _parse_json_value failed
with a generic 'Could not extract JSON value' that neither the operator
nor the LLM could act on. Add _looks_truncated (unbalanced structure /
unterminated string at end) and report 'truncated/incomplete JSON' with
input length, so the model regenerates the full document.
2026-08-19 19:52:16 +03:00
9b0350b3b0 fix(agent): send search param instead of ignored q to /api/dashboards
The backend route binds the search query to `search`; a bare `q` param is
not bound, so search_dashboards and prefetch_dashboards silently returned
the unfiltered catalog (e.g. query 'Sales' listed all 11 dashboards).
Switch both to `search` and update the URL-contract test.
2026-08-19 19:31:32 +03:00
e291ba757f fix(agent): full-catalog dashboard search and working LLM retry
- search_dashboards: call /api/dashboards with page_context=other and
  page_size=100 so the profile 'My Dashboards Only' filter can no longer
  hide the whole catalog; parse available_total/effective_profile_filter
  and report hidden-by-filter instead of a false 'no dashboards' answer
- prefetch_dashboards: same full-catalog context; fix dead code where
  data=resp.json() sat after return '' inside the error branch, making
  every 200 response raise NameError and the prefetch always return ''
- llm-status: ?force=1 bypasses the 30s health cache so the 'Retry now'
  button performs a fresh probe instead of re-reading the stale status;
  frontend keeps a single retry interval (previously stacked intervals
  decayed the countdown faster than 1/s and fired duplicate probes)
- tests: agent tool/prefetch, backend route bypass + force param,
  frontend retry/force coverage
2026-08-19 19:21:00 +03:00
615f3ccd25 fix: graceful fallback when Superset rejects changed_on_dttm filter during incremental sync 2026-08-19 17:38:35 +03:00
488a8f349b test(backend): raise coverage to 95%+ statements and branches (97.8%/95.0%)
- ~60 new/extended test files across api, core, plugins, services, schemas:
  routes, superset clients, task_manager, lineage, git, translate,
  dashboard-testing, load-testing, migration, llm_analysis, scheduler, ssl
- .coveragerc: enable branch coverage; exclude src/__tests__ (test files)
  and src/scripts (CLI/ops tools) from the denominator
- bug fixes found while testing:
  * settings: PUT /settings/reports registered under duplicated prefix
  * schemas/lineage: FleetReportDTO missing run_status (route always 500)
  * dashboard_testing/baseline_inheritance: visual entry read wrong field
  * superset_client/_databases: logger extra name shadowed LogRecord attr
  * routes/datasets: _yaml_string_paths recursion without yield from
  * translate/sql_generator: restore explicit-type timestamp contract
  * baseline_catalog: remove unreachable dashboard_id fallback
- conftest fixes: pytest_plugins to rootdir conftest (pytest 9), test
  filename collision, TMPDIR-safe integration fixtures
2026-08-19 17:14:32 +03:00
dd9df0fc5e feat(env-widget): dashboard stats widget with per-env counts, health probe and profile-filter reference info
- Replace the global env <select> in TopNavbar with an expandable
  EnvironmentStatsWidget showing per-env total/mine/published/drafts
  and health status (latency, unreachable), preserving env switching.
- Add GET /api/environments/stats: per-env counts (profile-actor matched)
  + lightweight health probe, gathered concurrently with an 8s probe
  timeout and a process-local TTL cache (30s, coalescing) so the full
  Superset dashboard catalog is not re-fetched on every dropdown open.
- Add available_total to GET /api/dashboards so grids can show how many
  dashboards exist when the profile-default filter hides everything.
- Share ProfileFilterBanner across the dashboards hub and validation
  task form: 'showing X of Y' reference info + explicit Show all /
  Restore filter actions.
- Russian plural forms for dashboard counts (pluralRu helper) and
  compact 'Опубл.' label; i18n keys en/ru.
- Ignore :memory:test_* SQLite test artifacts and drop them from the index.
- Tests: env stats endpoint (incl. caching), widget, model fallback,
  plural helper, api client, integration.
2026-08-19 14:40:14 +03:00
a571ff8175 fix(search): global search queries with envId and bypasses profile filter
- handleSearchInput now receives the selected envId, so the debounced
  search actually fires API requests instead of hitting the !envId guard
  and clearing results immediately.
- The dashboard section of the global search sends page_context=other,
  apply_profile_default=false, override_show_all=true (same pattern as
  DashboardHubModel.loadDashboardSearchOptions), so the "show only my
  dashboards" profile filter no longer zeroes out dashboards that lack
  owner metadata.
- Updated unit tests: debounce now asserts API calls + profile-off flags.
2026-08-19 11:00:33 +03:00
81ba94684f feat: sed-мутации датасетов, правки миграции и фиксы
- Dataset viewer: sed-замена (find→replace) по всем/выбранным/текущим датасетам
  с обязательным визуальным предпросмотром и целями (sql/metrics/yaml); сохранение
  и выбор именованных правил (sedRules store + SedRuleEditor).
- Migration: literal-замена в dataset YAML при переносе; рескан ID чартов/датасетов
  перед миграцией + метрика средней длительности синка (GET /migration/sync-stats);
  логическая группировка опций (маппинги БД, сервер изменений, rescan) под галочками.
- Fix: дашборды хаба скрывались дефолтным профиль-фильтром show_only_slug_dashboards=true
  (теперь false); мастер миграции не грузил дашборды предзаполненного источника;
  потеря терминального task_status из-за утечки pending-корутин в /ws/logs (панель
  результата не появлялась); горизонтальный скролл в MappingTable; чистая per-env
  ошибка в mapping coverage.
- Backend: record_sync_duration + alembic-миграция sync-duration; literal_replace модуль.
2026-08-19 10:29:28 +03:00
a5764eb008 fix(orchestration): make KV-cache rules explicit; workers long-lived everywhere
- skill §11 rewritten: one invariant (byte-identical prefix) + explicit
  preserve/invalidate lists + discipline (load self-orchestration once;
  persona/toolFilter/model fixed for a worker's whole life)
- worker skills: "disposable context" -> "long-lived context"; role lines
  now say "leaf, long-lived, refined in place via send_message"
2026-08-18 16:24:19 +03:00
e3de06832a feat(orchestration): long-lived workers across all roles + KV-cache economics
- contracts: Self.Worker.Verify/Curate now carry the long-lived invariant
  and "refined in place" brief (matching Implement)
- skill §9: cycle says "read freely" + "spawn long-lived worker, refine"
- skill §11 (new): token & KV-cache economics — long-lived send_message
  keeps the prefix byte-identical (warm cache), fork invalidates it,
  spawn starts cold; merge envelopes; keep surface lean
2026-08-18 16:15:23 +03:00
b232c347fd feat(orchestration): make workers long-lived, not disposable
Workers are continuable long-lived children: spawn once, refine in place
via send_message as the feature evolves; a worker's own session persists
and compacts independently. Re-spawn only when the context is poisoned.

- skill §3: delegation tree rewritten — "refine, don't re-spawn"
- skill §5: "refine, don't re-spawn" coordination rule
- skill §7: stalled worker → send_message (keep context), fresh spawn
  only for poisoned context
- contracts: Self.Worker.Implement is "long-lived, refined in place";
  add long-lived invariant
2026-08-18 16:11:07 +03:00
8a2a12964c fix(orchestration): architect reads freely; delegate execution, not reading
Drop the "never read raw files" rule — it was a false economy. The
architect's context is large and auto-compacting, so reading is cheap and
necessary for decomposition and verification. The real boundary is
EXECUTION (edits/builds/tests) stays with workers, not READING.

- skill §1/§6/§10: "read freely" replaces "never read raw files";
  prefer read_outline/search_contracts to locate, read/grep/glob to understand
- @RATIONALE reframed: reading is cheap; only DECISIONS must not live
  solely in context (they go to files)
- contract: invariant becomes "reads freely for decisions, delegates execution"
2026-08-18 15:52:06 +03:00
ca1761f490 fix(orchestration): harden thin-context protocol against observed drift
Session-log review found the orchestrator diverging from its own design.
Encode every divergence as a rule + invariant:

- no polling: get_goal/list_agents are state tools, not completion checks
  (settlement/report are the signals) — was 101 get_goal + 98 list_agents
- no raw reads: structure via read_outline/search_contracts; file CONTENT
  is delegated (was 77 read vs 1 read_outline)
- <RESULT> enforcement: a worker result with no envelope is blocked
  (was 4/19 envelopes)
- closed role taxonomy: only Implement/Verify/Curate (was ad-hoc
  "code reviewer"/"auditor"/"adversarial")
- fork semantics: fork inherits MY context, not a stalled worker's;
  no "takeover" via fork
- interrupt only to redirect; let workers finish (was 7 interrupts)
- decision memory written by me to files (was zero file writes)
- skill hygiene: load self-orchestration once; never load worker skills
- cross-workspace: point Axiom at the target or delegate all reading
2026-08-18 14:51:50 +03:00
f1ee96fda8 fix(orchestration): stop workers from inheriting the orchestrator role
Child subagents join the parent's preset composition, so by default they
inherited the orchestrator persona AND the delegation tools — and drifted
into orchestrating instead of working (observed: a "worker" called
list_agents/get_goal/send_message and spawned its own grandchildren).

Fixes:
- preset: subagent/subagent_fork now carry a role-agnostic worker `persona`,
  `toolFilter.deny` for all delegation/coordination tools, and `maxDepth: 1`
  (children cannot spawn grandchildren) — hard enforcement at the boundary
- skill: every worker prompt opens with a mandatory role-reset block
- contracts: Self.Worker.Implement/Verify gain a LEAF invariant (no subagents,
  no delegation tools)
2026-08-18 14:41:37 +03:00
dff97e58da chore: gitignore generated semantic-index and bundle artifacts 2026-08-18 12:45:06 +03:00
2a0f334717 chore: remove hardcoded Fernet key and client cert
- ENCRYPTION_KEY: smoke test generates a fresh key inline; templates use a placeholder
- drop RUSAL_ROOT.cer (client-specific public cert) + gitignore it
2026-08-18 12:32:06 +03:00
a995e6f269 chore: remove tracked junk and add gitignore rules
Drop service/debug files accidentally tracked in the previous checkpoint:
- session.jsonl (agent transcript)
- artifacts/ (integration-test debug logs)
- research/paper.pdf (binary blob)
- .npmrc (machine-local config)

Add .gitignore rules for session.jsonl, artifacts/, .npmrc, *.pdf
so they cannot be re-committed.
2026-08-18 12:27:03 +03:00
977f3d6d75 chore: checkpoint working tree onto master
Carried over from 042-dashboard-scenario-registry:
- dashboard/migration backend changes + tests (dataset_key_sync)
- specs updates; drop generated doxygen artifacts
- research notes, integration artifacts, session log
2026-08-18 12:20:42 +03:00