Files
llm/docs/1c-adapter-api-contract.md
T

124 KiB
Raw Blame History

1C Adapter API Contract

Configuration repository control

The current adapter release is SQL-only. It does not start Designer, call a Windows runner, or inspect repository internals. External 1C execution is a future-version capability and is disabled by default with ONEC_ADAPTER_ENABLE_EXTERNAL_1C=false.

Repository operations are available through repository.status, repository.lock.plan, repository.lock, repository.lock.confirm, repository.lock.verify, repository.unlock, repository.commit.plan, and repository.commit. Configuration is selected only by payload.base_id: the base runtime profile declares repository.backend=direct|karman_bridge, the Designer executable, infobase selector, endpoint, optional extension, users, and environment-variable names containing transient passwords. No repository, bridge, or endpoint name is hard-coded or inferred from naming conventions.

repository.lock_mode=automatic|manual is also selected per base. Automatic mode uses the configured runner. Manual mode requires no Designer or runner: repository.lock.plan returns the exact public development-object names to lock in Configurator, and repository.lock.confirm records the user's explicit confirmation for only that object set. Such a session is marked user_confirmation_only; repository.lock.verify returns manual_confirmation_unverified and never represents it as an automatic repository check.

In the SQL-only release, repository.lock.request persists an adapter-side coordination request with status pending_user_lock and the resolved public object scope. It deliberately does not write a marker into the 1C infobase SQL database: such a marker would not create a native repository lock. repository.lock.request.status exposes the request state, and repository.lock.confirm can consume its request_id; confirmation always uses the immutable object set stored in the request.

Manual requests expire after ONEC_REPOSITORY_REQUEST_TTL_SECONDS (24 hours by default) and may be explicitly cancelled with repository.lock.request.cancel. Manual confirmations expire after ONEC_REPOSITORY_CONFIRMATION_TTL_SECONDS (2 hours by default). After the user releases the objects in Configurator, repository.lock.close closes the confirmation, marks its originating request as closed, and immediately blocks further SQL writes through that session. The adapter keeps a bounded audit trail of request creation, confirmation, cancellation, and closure and exposes it to the administrative requests view.

Both backends invoke standard Designer repository commands. A Karman/Filebox backend is an opaque native TCP transport and does not own credentials, object locks, or repository transactions. For configured bases, saved-state apply is blocked until the caller supplies an active adapter-owned lock_session_id. Commit additionally requires allow_repository_commit=true and a non-empty version comment. Unlock and commit operate only on the object set recorded for that adapter session.

Status: draft, read-only first.

Related work plan: docs/1c-extension-layer-plan.md.

Source Boundaries

  • The live adapter works with 1C through SQL storage only.
  • XML exports and Form.xml files may be used by this project for analysis, fixtures, learning, diffing, and rule discovery, but they are not a live 1C write transport for the adapter.
  • When XML-derived rules are promoted into the adapter, the runtime write path must still resolve to concrete SQL storage targets such as ConfigSave or ConfigCASSave, with explicit gates and readback verification.

User Identity And Access Terminology

An unqualified user request means an infobase user: the platform identity visible in Configurator under administration of infobase users. It does not mean the BSP Catalog.Пользователи record.

The two layers are intentionally separate:

Layer Canonical term Source Authoritative for
Platform infobase_user / Configurator user dbo.v8users and the 1C ПользователиИнформационнойБазы runtime API login identity, authentication flags, platform administrator flag, assigned platform role set and exact platform roles
Application bsp_catalog_user / BSP user BSP catalogs, access groups, profiles and access registers BSP membership, profiles, access groups, RLS/access-key chains and application access diagnostics

Routing rules:

  • ordinary "users", "user roles", "login", "password", and "Configurator users" start with infobase.users.search or infobase.user.get;
  • explicit BSP/group/profile/RLS questions use access.users.search and access.user.explain;
  • a name match between the layers is correlation only and never proves that the records are identical;
  • BSP groups/profiles must never be reported as the exact role assignment of a Configurator user;
  • SQL RolesID proves the assigned platform role-set identity, but exact role names require the supported 1C runtime ПользователиИнформационнойБазы API.

infobase.users.search and infobase.user.get expose only safe v8users fields: platform id, name/full name, change time, login-list visibility, authentication-presence flags, administrator flag, RolesID, and protected payload size. They never expose Data, password hashes, password-policy blobs, material keys, or raw users.usr content. Until a runtime connector is added, responses set role_assignment.exact_role_names_status=runtime_required.

Configurator User Password Operations

Password mutation is available only for the platform infobase_user layer:

  • infobase.user.password.capabilities reports whether the protected path is ready for a concrete base_id;
  • infobase.user.password.status reports empty, set, or standard_authentication_disabled for one exact platform user. It never returns password hashes or Data;
  • infobase.user.password.set changes the password and requires user, the exact 32-hex confirm_user_id, new_password, and allow_password_change=true. It uses the same guarded SQL transaction as clear, storing the Base64-encoded SHA-1 pairs for the UTF-8 password and its Unicode uppercase form;
  • infobase.user.password.clear removes the password and requires user, the exact 32-hex confirm_user_id, and allow_password_clear=true; it rejects a new_password field. This operation uses SQL only: it locks the exact dbo.v8users row, decodes that row's XOR-protected Data container, replaces only the first adjacent current SHA-1/Base64 password pair with the empty password pair, writes with an old-Data concurrency predicate, and verifies readback before commit;
  • a platform administrator additionally requires allow_administrator_password_change=true;
  • normally both mutations are blocked when ONEC_ADAPTER_SERVICE_TOKEN is empty. A disposable isolated test stand may explicitly set ONEC_INFOBASE_USER_ADMIN_ALLOW_UNAUTHENTICATED=true; this also permits an unprotected runtime bridge endpoint and must never be enabled in production.

Both operations select the exact user through infobase.user.get and update only dbo.v8users.Data. The clear-text password for set exists only in memory and is not included in responses or write-history payloads. Neither operation updates Params/users.usr, EAuth, roles, administrator flags, names, or BSP records. Both are rejected when EAuth=0, because changing stored hashes does not enable standard authentication.

The SQL path decodes the row-specific XOR key, patches the first adjacent current-hash pair in the authentication section, reuses the original key and byte layout, and verifies that no other parsed scalar changed. A compare-old Data predicate prevents overwriting a concurrent user edit.

Successful set and clear results are recorded in metadata.write.history with method, operation, target platform id/name, transport, status, and verification result. Request payloads are never written to that history, so new_password is not persisted. The SQL layout with 43 root fields was live-verified on upo during an administrator password clear.

Undecoded Evidence

Public decode/read methods should not drop useful payload evidence when a decoder is incomplete or when only part of the object is understood. Methods that expose decoded object, part, form, or template payloads accept:

{
  "evidence_mode": "none | summary | full | raw"
}

Contract:

  • none: omit undecoded_evidence;
  • summary: return compact role, markers, root signature, string samples, payload size/hash metadata, and safe stream/base64 samples;
  • full: return broader samples and longer text excerpts for agent-side analysis;
  • raw: return the broadest evidence. Low-level storage offsets, block hashes, and physical coordinates are exposed only together with include_storage=true.

evidence_mode is intentionally separate from object view (effective/base/extension): view selects the metadata layer, while evidence_mode selects diagnostic detail.

Current methods using this contract include metadata.object.decode, metadata.object.parts, metadata.object.templates, metadata.object.template.details, metadata.form.decode, and metadata.object.full through its parts_summary section.

Template Content Export

templates.read can return the actual current SQL-stored template content in read-only mode. Content is opt-in and bounded:

{
  "base_id": "upo_test",
  "kind": "Document",
  "name": "АктВыполненныхРабот",
  "template": "ПФ_MXL_УдалитьАкт",
  "view": "full",
  "include_content": true,
  "max_content_bytes": 262144
}

Each part then contains content_export.container: media type, decoded byte size, returned byte size, SHA1, truncation flag, and base64 data. Embedded decodable stream/base64 blocks are also returned in extracted_text, including HTML as text. max_content_bytes is limited to 1 MiB per returned item. The operation never writes to 1C SQL tables; it only reads the configured database and does not perform platform rendering to pixels or PDF.

Managed Form Element Types

SQL form profiles distinguish every element type observed in the reference UPO Form.xml export. This includes containers, pages, command bars, tables and their search additions, input/label fields, checkbox fields, picture fields, radio-button fields, spreadsheet-document fields, label/picture decorations, context menus, and extended tooltips. XML is used only to confirm decoding rules; live metadata.form.decode and metadata.object.form.details responses are produced from SQL payloads. Dynamic table profiles also expose confirmed read-only/skip-on-input and row-set-change flags, height in table rows, footer, row-selection mode, horizontal/vertical line flags, alternating-row color, automatic row insertion, and drag-start/drag flags. The dynamic-table SQL positions for ChangeRowSet, HeightInTableRows, and Footer were confirmed against four distinct tables in the reference UPO form. Rare layout and behavior properties remain best-effort until their SQL positions are confirmed by multiple samples.

The complete offline UPO inventory covers 6,748 Form.xml files, all parsed successfully, with 821,077 named elements, 41 element kinds, and 253 direct property tags. Runtime still does not read XML. SQL section records additionally decode CurrentRowUse and ModifiesSavedData for commands and MainAttribute and SavedData for attributes. The confirmed payload positions are 9/10 for command current-row/saved-data behavior and 10/11 for attribute main/saved-data flags. Table search, view-status, and search-control additions expose a structured AdditionSource derived from their decoded parent-table hierarchy. Its public value contains owner_element and representation; it deliberately does not use the reserved table key, which denotes physical SQL storage in adapter diagnostics. Command-bar buttons also decode ButtonImportance, GroupHorizontalAlign, and GroupVerticalAlign; label/picture decorations decode both group-alignment properties. Input, label, picture, checkbox, radio-button, and chart fields use positions 53/54. Marker-22 containers (ordinary/column groups, command bars, and pages) use the last three and last two entries of their variable-length node (-3/-2). The other confirmed SQL positions are 11/41/42 for command-bar buttons and 32/33 for decorations. The vertical enum is normalized as Top, Center, Bottom, or Auto. These positions were cross-checked against contrasting XML declarations and the matching live SQL payloads; XML remains an offline analysis source only.

Marker-35/37 fields also expose AutoEditMode=true when position 26 is EnterOnInput. In the reference document-form inventory, all 11,817 explicit AutoEditMode declarations are paired with EditMode=EnterOnInput; the live SQL payload stores that pair as the single enum code 2 at position 26. The adapter therefore returns AutoEditMode as a confirmed derived property and does not invent a separate storage position.

Table additions have two confirmed live SQL layouts: marker-5 records embedded directly in the variable tail of a dynamic list/table, and the same records embedded in its auto command bar. Both are normalized to public marker-6 addition items. Validation against 12 UPO forms decoded 39/39 XML-declared search-string, view-status, and search-control additions with a resolved owner and representation.

The variable-length dynamic-table tail is decoded relative to the end of the element after validating the four table-addition records. It exposes SearchStringLocation, ViewStatusLocation, SearchControlLocation, and FileDragMode. The location enum maps were confirmed against eleven live SQL tables covering Default, None, CommandBar, Top, FormCaption, and PullFromTop values present in the reference XML export.

Related-form discovery follows the object descriptor layout for reports (Form section 5), data processors (section 6), exchange plans (section 6), selection criteria (section 3), and settings storages (section 4). Report and data-processor template sections are kept separate from forms.

Live descriptor routes are also confirmed for enum forms (section 3), information-register forms (section 5), accumulation-register forms (section 8), business-process and task forms (section 4), chart-of-characteristic-types and chart-of-calculation-types forms (section 7), chart-of-accounts forms (section 6), and document-journal forms (section 6). Form list and full SQL payload decoding were verified by public object/form names for every listed kind. Template sections for exchange plans and charts of characteristic types remain distinct at section 4.

Template discovery additionally covers enum templates (section 4), information-register templates (section 6), and document-journal templates (section 3). Catalog templates use section 3; section 4 is the catalog command section. Safe bounded templates.read include_content=true export was verified for the newly routed kinds, including MOXCEL content.

Object-command discovery is confirmed for catalogs (section 4), documents (section 6), data processors and document journals (section 5), accumulation registers (section 4), information registers and tasks (section 8), and exchange plans and reports (section 7). When a separate command descriptor is absent, the public command identity falls back to the identity embedded in the owner descriptor. Results are deduplicated by command GUID/name.

Payload Diff

payload.diff is a diagnostic method for comparing two payload snapshots. It accepts before and after sources as either live storage pointers (base_id, table, file_name) or inline payloads (payload_base64, payload_hex, or text). It requires diagnostic=true.

The response includes:

  • byte sizes and SHA1 hashes;
  • decoded envelope metadata;
  • unified text diff;
  • scalar brace-tree changes with paths such as $.1.3.2;
  • changed string sequence entries;
  • compact undecoded_evidence for both sides when include_evidence=true.

Use it after manual Designer/configurator edits to identify which raw payload nodes changed before promoting a rule into a higher-level decoder or writer.

Agent-Facing Addressing

Agent-facing selectors and answers should prefer full semantic 1C paths over GUIDs, SQL names, CAS keys, or bare local names.

Default path shape:

<ObjectKind>.<ObjectName>[.<Section>.<Member>...]

Examples:

Справочник.Контрагенты
Справочник.Контрагенты.Наименование
Документ.РеализацияТоваровУслуг.Товары.Номенклатура
РегистрСведений.ЦеныНоменклатуры.Ресурсы.Цена
Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента.Товары
ОбщийМодуль.ИнтеграцияСCRM.ОтправитьКонтрагента

Short names are allowed as input conveniences, but adapter methods must either normalize them to one canonical_path or return ambiguity candidates. Bare member names such as Наименование are not safe write targets without object, form, module, or routine context.

Metadata path resolution and BSL symbol resolution are separate operations. A code expression such as Номенклатура.ЕдИзмерения.Код starts from a local symbol until the adapter proves that the symbol maps to a metadata path or typed value.

Resolved agent-facing objects should include, where known:

  • canonical_path;
  • context_path when a short path was resolved inside a known context;
  • path_kind, for example metadata_object, metadata_member, form_element, module, routine, or code_symbol;
  • presentation and synonym;
  • ref and GUID/storage evidence for internal follow-up calls.

BSL Symbol Resolution

Command:

python scripts/resolve_1c_bsl_symbol.py
  --metadata <metadata snapshot>
  --modules <bsl module snapshot>
  --expression <BSL expression>
  --module-id <module-id>
  [--object-kind <Kind>]
  [--object-name <Name>]
  [--routine-name <Routine>]

Safe Unicode command shape:

python scripts/resolve_1c_bsl_symbol.py
  --metadata <metadata snapshot>
  --modules <bsl module snapshot>
  --expression-b64 <utf8-base64 BSL expression>

Output schema:

onec_bsl_symbol_resolution.v1

Live adapter RPC:

{
  "method": "code.symbol.resolve",
  "payload": {
    "base_id": "<base-id>",
    "expression": "Номенклатура.ЕдИзмерение.Код",
    "module_ref": "<module-ref-from-code-search>",
    "routine_name": "<routine-name>"
  }
}

Purpose:

  • resolve BSL expressions inside a concrete module/routine/form context before treating them as metadata paths;
  • return metadata_path only for full semantic paths such as Справочник.Номенклатура.Артикул or for members proven by context, for example a current object-module standard attribute;
  • in live adapter mode, read the module through modules.read, use metadata.definition.find for full metadata paths, and use metadata.object.attributes for context-proven owner members;
  • return parameter or local_variable when the first expression segment is declared in the current routine/module, with safe_as_metadata_path=false;
  • return unresolved candidates for short object names such as Номенклатура.ЕдИзмерение.Код instead of silently converting them to Справочник.Номенклатура....

Agent-Facing Code Writes

Normal coding agents should write BSL through code.write, not through SQL, storage rows, payload paths, or metadata.module.write_apply.

code.write accepts 1C names and code text:

{
  "method": "code.write",
  "payload": {
    "base_id": "upo_test",
    "object_type": "CommonForm",
    "object_name": "t_Форма",
    "routine_name": "ЗаменаДомена",
    "routine_text": "Процедура ЗаменаДомена(Команда)\n\t// code\nКонецПроцедуры\n"
  }
}

Contract:

  • default mode is apply, and apply means save to the working ConfigSave/ConfigCASSave layer, not production apply;
  • every code.write response includes write_mode.target=saved_state, write_mode.activation_state=not_activated, and write_mode.production_apply=false;
  • saved-state code.read and code.search responses include current_state.source=saved_state and current_state.activation_state=not_activated;
  • code.read state=working is save-first with active fallback, state=save reads only the saved layer, and state=active skips saved-state lookup. state=both returns side-by-side layers and comparison metadata;
  • SQL/storage gates are set by the adapter for this facade;
  • public responses hide physical storage details unless include_storage=true;
  • full module replacement uses module_text, full_text, or code;
  • routine replacement uses routine_name plus routine_text;
  • fragment replacement uses old plus new. With routine_name or a routine-level canonical_path, old must occur exactly once inside that procedure/function; without routine scope, it must occur exactly once in the current saved module text;
  • if the fragment is missing or repeated, the adapter returns fragment_not_found or ambiguous_fragment and does not write;
  • low-level storage methods remain diagnostic and implementation details.

For embedded form modules the adapter writes only the scalar module token in the saved form payload with path_preserve_format. Whole-form payload canonicalization is forbidden because Designer may reject the form even if the payload decoder can parse it.

Resolve Object

Command:

python scripts/resolve_1c_object.py
  --kind <ConfiguratorKind>
  --name <ConfiguratorName>
  --index <unified object route index>

Output schema:

onec_object_resolution.v1

Purpose:

  • resolve objects by configurator-visible names, synonyms, qualified names, and generated type names such as DocumentRef.ПриходнаяНакладная;
  • return the canonical base object plus extension overlays;
  • keep storage details under storage, so agent-facing code can continue to operate with 1C metadata names.

Object Brief Context

Command:

python scripts/get_1c_object_brief_context.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --view effective|base|extension
  --extension <ExtensionName>
  --max-attributes <N>
  --max-modules <N>
  --max-forms <N>
  --output <json>

Output schema:

onec_object_brief_context.v1

Purpose:

  • provide the default starting context for an agent after a user names a 1C object;
  • keep the response compact: object identity, active extension names, attribute summary, tabular section names, form list, module list, overlay counts, and suggested follow-up tools;
  • use view=effective by default so the agent sees the same working object picture as the user sees in Configurator;
  • avoid loading large BSL modules or full form XML; use the dedicated module and form APIs for detail reads.

Fact Resolution

Command:

python scripts/resolve_1c_fact.py
  --index <unified object route index>
  --path <Kind.Name.Member>
  --view effective|base|extension
  [--extension <ExtensionName>]

Safe Unicode command shape for agents and PowerShell callers:

python scripts/resolve_1c_fact.py
  --index <unified object route index>
  --path-b64 <utf8-base64 Kind.Name.Member>

Output schema:

onec_fact_resolution.v1

Purpose:

  • verify concrete facts about the current configuration before code generation, for example Справочник.Номенклатура.Цвет or Документ.ПриходнаяНакладная.ДатаСоздания;
  • return exists, confidence, area, object identity, matched member, and source provenance;
  • support object, attribute, tabular section, form, module, and snapshot-backed checks through the same agent-facing shape;
  • keep examples and old snapshots out of the current-configuration path unless the caller explicitly passes --snapshot.
  • normalize positive results to a full canonical_path and return ambiguity candidates when a short path is not unique.

Policy:

  • RAG may explain platform behavior, patterns, and documentation.
  • resolve_1c_fact.py or a richer adapter method must confirm concrete object, attribute, form, command, module, and data facts for the selected base.
  • A negative result means the fact is not confirmed in the provided source; the agent should not silently replace it with a fact from examples or generic documentation.

Live Adapter Navigation

The REST adapter exposes metadata and BSL navigation through public selectors. Agents should prefer these selectors over diagnostic storage fields.

Object selectors:

  • Object-scoped methods accept the same public selector shapes: ref, kind + name, guid, or MCP-friendly aliases object_type, object_name, and object_guid.
  • ref can be a public qualified object reference such as Обработка.<Name> or Document.<Name>; the adapter normalizes Russian and English metadata kind names to the canonical internal kind.
  • Public selectors returned by the adapter keep backward-compatible kind/name/guid fields and, when kind + name are known, also include compact ref=<canonical-kind>.<metadata-object-name>.
  • Do not branch on concrete object names in client or MCP code. Normalize the selector once and pass the resulting public selector through adapter methods.
  • If a result contains read_selector.method, call that method with the selector payload as-is. Do not reconstruct the selector from display text or storage diagnostics.
  • help.methods exposes selector_capabilities for object-scoped methods. Agents should use these flags instead of inferring selector behavior only from natural-language descriptions.

Important methods:

  • data.schema, data.list, data.get, data.count, and data.query expose logical 1C data names while reading physical SQL tables. The object is selected by public ref (for example Catalog.<Name>) or by kind + name; a row is selected separately with record_ref. SQL table names and _Fld... columns are internal routes, not caller-facing selectors. Constants are exposed as a typed value; enumeration rows include their public value name, synonym, and value_ref. Business-process storage is resolved through the platform _BPr<N> route internally.
  • data.present returns a compact presentation for one record_ref, and data.movements reads register rows for a recorder_ref.
  • BSP access-key methods use the same object/record separation without overloading their query-area selector. For access.keys.query, kind=object selects the access-key area; it is not a metadata kind. Pass object_ref=Справочники.Номенклатура to select the metadata object and record_ref=<32-hex-ref> to select one application-data record. access.object_keys.resolve and access.object.explain accept the same pair. The adapter resolves object_sql_number and object_id internally. Raw object, object_id, and object_sql_number remain compatibility filters only and should not be generated by new MCP clients.
  • metadata.adapter.audit include_unmapped=true distinguishes configuration metadata from platform storage. Live upo_test DBNames verification showed the former candidate roles Acoustic, Bots, Ecs, LangModel, MobileClientDataExchange, STT*, URLExternalData, and WebSocketClients as singleton platform-system tables, normally carrying the zero GUID. ExtDataSrcPrms is auxiliary external-data-source storage. None of these roles is exposed as an invented public metadata kind.
  • metadata.object.form.details decodes form commands with their explicit Action value from the SQL form payload. command_links resolve that action against the complete form-module routine index; routines_sample is only a compact preview and never limits handler resolution.
  • The same form details expose command CurrentRowUse/ModifiesSavedData, attribute MainAttribute/SavedData, and structured table-addition AdditionSource properties directly from the live SQL payload. Command-bar buttons additionally expose ButtonImportance, GroupHorizontalAlign, and GroupVerticalAlign; decorations expose their horizontal and vertical group alignment.
  • metadata.object.special.details for ScheduledJob returns the complete decoded SQL schedule: date/time windows, completion interval, intraday repeat and pause, weekdays, day/month restrictions, months, and week/day repeat periods, together with use/predefined and restart settings. It also resolves the handler's common module and returns handler.read_selector; pass that selector unchanged to modules.read to read the exact procedure. A non-predefined disabled job may legitimately return schedule.status=not_configured when its separate .0 schedule payload is absent.
  • metadata.object.properties has kind-specific live SQL decoders for EventSubscription, WebService, and HTTPService. Event subscriptions expose their source objects, event and handler. The handler contains a read_selector that can be passed unchanged to modules.read to obtain the exact common-module procedure from the working SQL state. Web services expose namespace, XDTO packages, descriptor/session settings, operations and parameters; HTTP services expose root URL/session settings, URL templates, HTTP methods and handlers. XML exports are used only to establish and test the Config layout, never as a runtime data source.
  • The same property API has SQL decoders for CommonAttribute, SessionParameter, FunctionalOption, and FunctionalOptionsParameter. Common attributes expose their value type, content objects, indexing, full-text/history flags, and data-separation settings and references. Session parameters preserve composite types, including unions of several reference or platform types. Functional options expose their storage location, privileged-get flag, and every affected top-level or nested metadata object; functional-option parameters expose every Use target. XML exports are used only to learn field layout and verify names—the runtime values and references always come from the selected SQL base.
  • CommonCommand, SettingsStorage, and Subsystem also have dedicated SQL-only property decoders. Common commands expose their public command group (including standard platform groups), parameter type, and a ready command-module read selector. Settings storages expose all four default and auxiliary save/load form roles plus every owned form; every physical module stream is classified as a manager module. Subsystems expose use/help/command interface flags, picture, content, child subsystems, and references decoded from the separate command-interface SQL part.
  • A normal metadata.objects.list request validates a kind-specific cache hit against the current configuration-root object count. If a root-discovered kind is only partially represented in the local metadata cache, the adapter ignores that cache hit and returns the authoritative live SQL list. This prevents a partial DBNames cache from hiding root-only objects such as settings storages. The check and fallback are read-only for the 1C database.
  • Language, CommonPicture, Style, and StyleItem are decoded from live SQL as first-class metadata. Languages expose their language code. Common pictures expose choice/appearance flags and a bounded binary summary from their .0 part (format, byte count, and hash) without returning unbounded binary data. Recognized formats include PNG, JPEG, GIF, BMP, ICO, SVG, and zipped 1C picture packages. Styles expose every value from the separate style table; style items decode absolute/web/standard colors, font attributes, and borders. Unknown platform codes remain explicit with status=unknown_code.
  • XDTOPackage reads its live .0 XML payload and returns namespace/form settings, imports, object/value types, nested anonymous type definitions, properties, constraints, and enumeration values. WSReference reads the location and generated manager identifiers from its main payload, then decodes the .0 stream container into WSDL and XSD. The public result links messages, port-type operations, SOAP actions, bindings, services, ports, addresses, schemas, types, elements, restrictions, and enumerations. XML files exported by Configurator are not used at runtime.
  • ExternalDataSource is decoded from the live SQL Config hierarchy. The source returns its tables, cubes, and functions; each table has a public name-based ref, its NameInDataSource, key fields, and the complete field collection with SQL name, 1C value type, ReadOnly, and AllowNull. Primitive number, string, date, boolean, and binary (R) patterns are decoded without consulting the Configurator export. Child payloads are read in one batch. The adapter only describes connection metadata and never opens or changes the external system itself. Live upo_test validation decoded 30 tables, 733/733 typed fields, and 53 key-field links; this base contains no cubes or functions.
  • A top-level CommonTemplate.<Name> is a direct template selector for metadata.object.template.details, templates.read, templates.analyze, and templates.map. It is resolved internally to the Config GUID and its payload parts, while the public response preserves the CommonTemplate name and ref. This is distinct from a template nested under another metadata object and no longer returns an empty template collection.
  • DefinedType.<Name> is decoded completely from its live SQL Config payload. metadata.object.special.details returns the identity, comment, union value type, and every constituent type. Generated platform types are resolved internally to their owning metadata object, including business process object/ref/selection/list/route-point variants and constant value managers. A full upo_test audit read all 612 payloads and resolved all 1,943 unique type GUIDs across 6,241 type references; no unresolved type remained.
  • SelectionCriterion.<Name> returns its value type, standard-command flag, default forms, list presentation, and complete metadata content collection. Content GUIDs are translated to public name-based refs. Live validation decoded all 11 criteria and resolved 862/862 content references.
  • Enum.<Name> returns its identity, comment, standard-command and quick-choice settings, choice mode, and ordered values with public refs. Multilingual and empty-synonym identities are supported. Live validation decoded 1,226 enums and 9,380/9,380 values.
  • metadata.object.modules, modules.read, and code.read support WebService, HTTPService, and IntegrationService. Service Config parts can contain both the complete BSL module and a short repeated fragment; the adapter selects the largest canonical BSL stream and exposes one public module as Модуль Web-сервиса, Модуль HTTP-сервиса, or Модуль сервиса интеграции. Handler names decoded by metadata.object.properties can therefore be followed directly into their live SQL module routines.
  • The same module APIs expose the four configuration-level modules through the public Configuration.<Name> selector: ordinary application, external connection, managed application, and session. Runtime discovery reads the embedded Configuration identity GUID from the current SQL root descriptor and maps its .0, .5, .6, and .7 parts internally. An intentionally empty external-connection module is returned as an empty module instead of being treated as missing. XML is not consulted at runtime.
  • CommonModule.<Name> is a complete public SQL route: root discovery resolves the object by its 1C name, and module APIs read its canonical .0 Config stream. Live upo_test discovery contains 3,400 common modules; sampled modules decoded as BSL with public routine indexes. In public metadata.object.modules, modules.read, and code-search responses, the module name, qualified_name, and display_name are the 1C common-module name; Config GUID/stream coordinates are exposed only with include_storage=true. Common-module writes, when explicitly enabled, remain limited to the saved-state layer.
  • For Role, metadata.object.properties reads the separate SQL part <role-guid>.0 and returns set_for_new_objects, set_for_attributes_by_default, independent_rights_of_child_objects, object and child-object rights, per-right RLS conditions, and full restriction templates. Standard right GUIDs are translated to public 1C names; unrecognized platform GUIDs remain visible with status=unknown_right_guid instead of being silently discarded. Permission targets are resolved to public names even when the target is nested and has no standalone Config file: _Fld/_VT routes are joined through the read-only SQL schema to their parent object, object commands are found in the parent's SQL Config payload, and integration channels are matched to the decoded IntegrationService channel list. The resulting refs use public paths such as Catalog.<Name>.Attribute.<Name>, DataProcessor.<Name>.Command.<Name>, and IntegrationService.<Name>.Channel.<Name>. These decoded identities may be cached only in the adapter's local save index; the live 1C SQL database is never modified.
  • For DocumentJournal, pass include_column_types=true to resolve every public column type through the referenced document attributes. This is a supported deep read, not an undecoded property; prefer adapter.job.start because large journals may require a long metadata scan.
  • data.virtual supports СрезПоследних/СрезПервых for periodic information registers and Остатки/Обороты/ОстаткиИОбороты for accumulation registers. Exact dimension values are passed in filters. At least one dimension filter is required by default; an intentional broad query must set allow_full_scan=true. Accounting-register totals are reported as unsupported_register until account and subconto semantics are resolved for the selected register; raw movements remain readable.
  • All data.* methods publish the same name-first object selector contract in help.methods: callers may pass object_ref, ref, kind/name/guid, or MCP aliases object_type/object_name/object_guid. Prefer object_ref with a 1C code-style name such as Справочники.Номенклатура when a method also needs record_ref or recorder_ref; a record reference is never treated as the metadata object name.
  • metadata.support.decode accepts the same optional public object selectors. When ref or kind/name is supplied, the adapter resolves the metadata GUID internally and returns the effective supplier-support rule for that named object; callers do not need to discover or pass storage identifiers.
  • metadata.code_index.build accepts an optional public object selector for a targeted local-cache refresh. A named base object is resolved through Config, while an extension object with extension_guid uses ConfigCASSave; omitting the selector keeps the bounded global ConfigCAS scan. The index remains a local derivative cache and never writes to the 1C database.
  • metadata.form.owner_index.build keeps the owner selector and form selector separate. Use ref/kind/name for the owning 1C object and form or form_name for the nested form. For example, ref=Обработки.ОбменДанными, form_name=ФормаОбмена searches the owner by ОбменДанными and indexes only the named form; the two names are not substituted for one another.
  • metadata.form.command_button.verify uses the same owner/form separation and publishes command_name, button_name, and handler_name as distinct child selectors. Saved forms with the same name are matched against owner evidence before verification, so a form belonging to another object is not selected merely because its form name matches.
  • metadata.form.command_button.write uses the same disambiguation before it creates any proposal. object_guid identifies the owner and form_guid identifies the nested form; they are never substituted for one another. Name-first selection does not weaken the write workflow: allow_saved_state_write, repository apply checks, allow_sql_saved_state_apply, verification, and rollback guards remain mandatory in their existing execution modes.
  • metadata.form.write_target.resolve and metadata.form.write_target.verify use the same public hierarchy: ref/kind/name select the form owner, form_name/form_guid select the nested form, and element/command/attribute select the child target. object_guid is never treated as a nested form_guid.
  • metadata.form.element.write and metadata.form.element.write_apply pass that hierarchy through unchanged when resolving the concrete saved-state file. An owner object_guid therefore cannot bypass name-first form resolution. Planning remains opt-in and SQL apply still requires the existing explicit apply and repository gates.
  • metadata.form.target.move resolves the owner and nested form before it resolves from_element and to_element; structural moves cannot select a same-named form owned by another object. Its write/apply/rollback gates are unchanged.
  • metadata.form.write_matrix.build and .smoke use the same owner/form hierarchy while resolving the saved-state file. The build operation is read-only; smoke remains restricted to explicit apply-and-rollback.
  • metadata.write_learning.capture_before and .capture_after also accept the public owner ref plus a separate form selector. They write only local learning artifacts; the selected 1C saved-state file is read, not modified.
  • metadata.saved_state.forms.search accepts the same owner scope and filters decoded saved forms by owner evidence before returning them. Its default response contains the public owner ref, form name, qualified name, and name-based selectors for matched elements, commands, and attributes. SQL files, GUID identities, internal brace paths/markers, and low-level writable-property coordinates are returned only with include_storage=true. form_guid remains a separate exact diagnostic selector. The method is read-only.
  • metadata.saved_state.modules.search accepts a public module-owner ref or kind/name/guid, resolves the internal saved-state prefix itself, and keeps file_name/stream_index as opt-in diagnostic selectors. By default its rows contain only the 1C owner, nested form, module role, qualified name, source preview, and a semantic selector. SQL tables/files, GUID identities, hashes, module_ref, and low-level write targets are returned only with include_storage=true. Callers do not need to know an owner GUID for name-first saved-code search.
  • code.write is the public name-first write facade. It accepts the module owner through ref or kind/name/guid, with routine_name as a separate child selector, then resolves the concrete saved-state module internally. metadata.module.write_apply remains the guarded low-level apply operation for an already resolved module_ref.
  • templates.areas.find accepts a public template ref such as Макеты.ПечатнаяФорма. The template selector, named-area selector (area_name/area_query), and low-level direct route are separate MCP fields; normal callers do not need a storage route.
  • metadata.cache.lookup accepts a public object ref in addition to kind/name/guid. Its result is only a local identity-cache hint; operations that require current evidence still verify against live SQL.
  • metadata.module_owner_cache.prune accepts the cached module owner through a public ref or kind/name and resolves owner_guid internally. Generated module_ref values remain valid for narrow follow-up cleanup. The method changes only adapter-local SQLite state, never the 1C SQL database; use dry_run=true to inspect the matching count without deleting cache rows.
  • For backward compatibility, a legacy bare guid without an owner selector may still identify a form. object_guid never gets that legacy treatment.
  • Logical schema results are cached briefly. refresh_cache=true forces a live metadata decode after a configuration change.
  • metadata.objects.list: lists base/effective metadata objects only. It must not be used with extension; extension-scoped queries such as test2 must use extension.objects.find or metadata.definition.find with extension.
  • extension.objects.find: lists extension objects from the current working programming view by default. state=working overlays saved rows from ConfigCASSave over applied extension rows; saved-only objects are returned too. Results carry activation_state: active, saved_override, or saved_only.
  • metadata.definition.find: resolves public names and references such as Обработка.<Name> or Document.<Name>. When exactly one metadata object is found, it is promoted to top-level object; related_selectors lists the next safe calls allowed by the object's capabilities, including card/full reads and scoped code.search/modules.search selectors for module-capable objects. These related selectors include ref when the object kind and name are known.
  • modules.search: searches decoded BSL and returns matches with read_selector.method="modules.read". The selector may contain an opaque module_ref; pass it through unchanged. When the owner is resolved, the same selector also includes the public owner fields such as kind, name, guid, and ref. For extension programming, state=working is the default and searches ConfigCASSave first, including saved-only form/module payloads that are not applied yet. Use state=active only when intentionally checking the applied extension; use full_scan=true only for broad active ConfigCAS fallback scans.
  • modules.read: reads a module by public object selector or opaque module_ref. Public responses include origin layer evidence even when the owner object is not fully recovered: Config means applied configuration, ConfigSave means base saved state, ConfigCASSave means saved state that still needs owner/layer evidence for base-vs-extension choice, and unresolved ConfigCAS means cas_reference with write_surface=requires_owner_resolution.
  • code.search: agent-facing search wrapper. Items contain read_selector.method="code.read" and can be read directly by code.read. If modules.search resolved the owner, code.search preserves the owner selector fields while changing the read method to code.read. Scoped calls may pass module_ordinal together with ref/kind/name/guid; the response must stay a public onec_code_search.v1 object. Items also carry public origin evidence from modules.search, so the agent can see base, saved-state, extension, or unresolved CAS provenance before reading the full code fragment. state is passed through to modules.search; the MCP source_state=working policy maps to this state=working mode.
  • code.read: wraps module/routine reads for agent-facing code analysis. It may set source.kind=code_read, but it must preserve the module origin evidence from modules.read so write planning can still distinguish base, saved state, extension, or unresolved CAS references.
  • metadata.adapter.audit: reports recognized metadata kinds, public kind counts, missing supported kinds, and unmapped DBNames roles. Every missing_supported_kinds item has presence_status=supported_absent_in_selected_base: absence in one infobase is not reported as absence of adapter implementation.
  • Base root discovery includes the configuration object itself, command groups, document numerators, external data sources, and integration services. The root collection UUID map is verified against object UUIDs from the XML export rather than inferred from collection position alone.

Generate a reproducible live coverage matrix without putting adapter or SQL credentials in a file:

python scripts/audit_1c_adapter_coverage.py --base-id upo_test --output reports/1c-adapter-coverage.json

The script reads the adapter bearer token from ONEC_ADAPTER_TOKEN and never reads or prints the SQL password.

Rare-kind regression fixtures for CalculationRegister, Sequence, and the legacy Interface are checked separately:

python scripts/check_1c_metadata_kind_fixtures.py --live

The fixture checker is read-only. It reuses one extension saved-state query for all fixtures on the same layer and does not force the slower active ConfigCAS full scan. It requires an explicit dedicated-base mapping for Interface. The manifest pins the required Designer version and an external structural reference. Use scripts/export_1c_extension_sources.ps1 to export test2 through operating-system integrated authentication; the helper accepts no infobase user or credential parameters and never writes platform SQL.

For a resumable read-only application-data audit, run the full public chain for one object of every data-bearing metadata kind:

python scripts/audit_1c_adapter_coverage.py
  --base-id upo_test
  --sample-data-reads
  --workers 2
  --timeout 90
  --checkpoint reports/1c-adapter-data-checkpoint.json
  --output reports/1c-adapter-coverage-live.json

The checkpoint is replaced atomically after every completed operation and kind. Resume an interrupted run with --resume; add --retry-degraded to rerun only timed-out or failed kinds while retaining successful evidence. Each data check records durations and statuses for data.schema, data.list, data.count, and data.get when the sampled row has a public reference key. Register rows with no reference key report data.get=not_applicable rather than a false failure.

An XML export can be used as an independent property-schema reference. The analyzer keeps the base configuration and each extension as separate layers:

python scripts/analyze_1c_xml_metadata.py --include-artifacts --output reports/1c-xml-metadata-analysis.json

Owner resolution:

  • Search results distinguish module readability from owner resolution. A module can be readable through read_selector even when owner.status=unresolved.
  • Use counts.owner_resolved, counts.owner_unresolved, counts.owner_scan_limit_hit, and diagnostics.owner_resolution to decide whether to narrow the selector or increase owner_scan_limit.
  • Do not request include_storage=true only to read a found module; use the public read_selector first.

Working source state:

  • For programming/designer analysis, agents must query the latest saved working state first. In MCP calls this is source_state=working; the MCP bridge maps it to REST state=working for extension.objects.find, modules.search, code.search, and metadata.resolve_overrides.
  • source_state=applied maps to REST state=active and intentionally ignores saved rows. Use it only when checking what is already applied.
  • source_state=all maps to REST state=both for side-by-side inspection. The response keeps activation_state markers such as saved_only, saved_override, and active, so agents can tell which findings are not applied yet.
  • code.read state=both reads the saved layer and the active layer as two independent views. The response sets current_state.source=both, returns ordered layers entries for saved_state and active, and includes comparison.both_present plus comparison.differs. When include_text=true, top-level text is the effective programming text: saved-state text if it exists, otherwise active text. text_source names the layer used.
  • code.search state=both also returns a mixed view for saved CommonForm code: saved-state matches are listed first, active matches are fetched with an independent state=active pass, and counts.saved_matches / counts.active_matches show layer coverage.
  • If an extension object exists only in ConfigCASSave, it is still part of the working programming surface. Analysis and write planning must not discard it just because activation has not happened yet.

Smoke check:

python scripts/smoke_1c_mcp_selector_chain.py --json

This offline smoke validates generic MCP selector chains such as metadata.definition.find -> related_selectors.code_search -> code.search -> item.read_selector -> code.read. Examples use placeholders only and must not contain concrete configuration object names.

Optional live smoke:

python scripts/smoke_1c_mcp_selector_chain.py
  --live
  --transport rest
  --adapter-url <1c-rest-adapter-url>
  --base-id <base-id-from-project-context>
  --json

To run the same live chain through the MCP proxy instead of direct REST /rpc, use:

python scripts/smoke_1c_mcp_selector_chain.py
  --live
  --transport mcp
  --mcp-url <1c-mcp-proxy-url>
  --base-id <base-id-from-project-context>
  --json

The live mode discovers a module-capable metadata object through metadata.objects.list, verifies metadata.definition.find related selectors, reads the first module through modules.read using the returned selector, then derives a search token from module text or routine metadata and verifies code.search -> item.read_selector -> code.read. It does not hard-code object names or BSL fragments, and it passes object selectors through instead of reconstructing them from display text. MCP transport performs the same calls through initialize, Mcp-Session-Id, and tools/call + onec_request.

Question Routing

Command:

python scripts/route_1c_question.py
  --text <UserQuestionOrTask>
  --index <unified object route index>
  --view effective|base

Safe Unicode command shape:

python scripts/route_1c_question.py
  --text-b64 <utf8-base64 UserQuestionOrTask>
  --index <unified object route index>

Output schema:

onec_question_route.v1

Purpose:

  • classify a user question before tools are selected;
  • route documentation questions to official-docs RAG;
  • route concrete configuration facts to the fact resolver;
  • detect source-risk phrases such as "in the RAG example" and require current configuration confirmation before code generation;
  • extract explicit facts such as Справочник.Номенклатура.Артикул and phrased facts such as "реквизит Артикул у справочника Номенклатура".

Routes:

  • docs_rag: only official documentation context is needed.
  • current_config_fact: current configuration facts are needed before answer or code.
  • mixed_docs_and_current_config: use official docs for platform behavior, but confirm object/member facts through the adapter first.
  • needs_clarification: neither docs nor current-config target was clear.

Contract check:

python scripts/check_1c_question_router.py
  --index <unified object route index>
  --output reports/1c-question-router.json

Agent Intake

Command:

python scripts/build_1c_agent_intake.py
  --text <UserQuestionOrTask>
  --index <unified object route index>
  --view effective|base

Output schema:

onec_agent_intake.v1

Purpose:

  • create the first packet an agent should inspect before answering or writing code;
  • include the question route, source policy, confirmed/unresolved current-base facts, answer/code policy, and next tool commands;
  • make the "example is not current fact" rule machine-readable through source_policy.examples_are_current_facts=false;
  • set answer_policy.code_generation_allowed=false when required current facts are missing or not checked.

HTTP console API:

POST /api/1c/intake
{
  "question": "...",
  "source_path": "reports/1c-sql/upo/unified-object-route-index.json",
  "view": "effective"
}

Saved State Object Compare

Command:

powershell -NoProfile -ExecutionPolicy Bypass -File scripts/compare_1c_saved_state_objects.ps1
  -Server <SqlServer>
  -Database <SqlDatabase>
  -User <SqlUser>
  -Password <SqlPassword>
  -Output <json>

Normal agent command:

powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build_1c_saved_state_object_report.ps1
  -Server <SqlServer>
  -Database <SqlDatabase>
  -User <SqlUser>
  -Password <SqlPassword>
  -OutputDir <directory>
  [-SkipMarkdown]

Repeated observation command:

powershell -NoProfile -ExecutionPolicy Bypass -File scripts/watch_1c_saved_state_once.ps1
  -Server <SqlServer>
  -Database <SqlDatabase>
  -User <SqlUser>
  -Password <SqlPassword>
  -OutputRoot <directory>

python scripts/list_1c_saved_state_watch_runs.py
  --root <directory>
  [--limit <N>]
  [--only-with-delta]
  [--only-changed]
  --output <json>
  [--skip-markdown]
  [--skip-check]

python scripts/check_1c_saved_state_watch_run_list.py
  --list <SavedStateWatchRunListJson>
  --output <json>

python scripts/get_1c_saved_state_latest_watch_run.py
  --root <directory>
  [--require-delta]
  [--require-changed]
  --output <json>
  [--skip-markdown]
  [--skip-check]

python scripts/check_1c_saved_state_latest_watch_run.py
  --latest <SavedStateLatestWatchRunJson>
  --output <json>

python scripts/render_1c_saved_state_latest_watch_run_markdown.py
  --latest <SavedStateLatestWatchRunJson>
  --output <markdown>

python scripts/render_1c_saved_state_watch_run_list_markdown.py
  --list <SavedStateWatchRunListJson>
  --output <markdown>

Markdown rendering:

python scripts/render_1c_saved_state_object_report_markdown.py
  --report <SavedStateObjectReportJson>
  --output <markdown>

Contract check:

python scripts/check_1c_saved_state_object_report.py
  --report <SavedStateObjectReportJson>
  --output <json>

python scripts/check_1c_saved_state_watch_once.py
  --manifest <SavedStateWatchRunJson>
  --output <json>

python scripts/render_1c_saved_state_watch_once_markdown.py
  --manifest <SavedStateWatchRunJson>
  --output <markdown>

Report-to-report delta:

python scripts/compare_1c_saved_state_object_reports.py
  --before <PreviousSavedStateObjectReportJson>
  --after <CurrentSavedStateObjectReportJson>
  --output <json>
  [--skip-markdown]
  [--skip-check]
python scripts/check_1c_saved_state_object_report_delta.py
  --delta <SavedStateObjectReportDeltaJson>
  --output <json>

python scripts/render_1c_saved_state_object_report_delta_markdown.py
  --delta <SavedStateObjectReportDeltaJson>
  --output <markdown>

Object change lookup:

python scripts/list_1c_saved_state_object_changes.py
  --report <SavedStateObjectReportJson>
  [--layer base|extension]
  [--kind <Kind>]
  [--payload-role <PayloadRole>]
  [--active-missing true|false]
  [--text-diff true|false]
  --output <json>
python scripts/get_1c_saved_state_object_change.py
  --report <SavedStateObjectReportJson>
  --name <ConfiguratorObjectName>
  --output <json>

Output schema:

onec_saved_state_object_comparison.v1
onec_saved_state_object_detail.v1
onec_saved_state_object_report.v1
onec_saved_state_object_report_check.v1
onec_saved_state_watch_once.v1
onec_saved_state_watch_once_check.v1
onec_saved_state_watch_run_list.v1
onec_saved_state_watch_run_list_check.v1
onec_saved_state_latest_watch_run.v1
onec_saved_state_latest_watch_run_check.v1
onec_saved_state_object_report_delta.v1
onec_saved_state_object_report_delta_check.v1
onec_saved_state_object_change_list.v1
onec_saved_state_object_change.v1

Purpose:

  • compare saved-but-not-applied SQL state with active state in 1C object terms;
  • provide a single read-only report command that runs comparison, exports the required payload evidence, performs object detail analysis, and writes a Markdown summary by default;
  • provide a one-shot watch command that stores timestamped observations and compares the new observation with the previous one when available; it writes a Markdown watch summary by default unless -SkipMarkdown is used;
  • list timestamped watch observations without reading SQL, including latest run, linked artifacts, check statuses, and delta counts; write Markdown next to the run-list JSON by default and run a contract check when --output is used;
  • return the latest matching watch observation directly, with optional requirements for a delta or actual delta changes; run a contract check by default and write Markdown when --output is used;
  • include agent_summary in onec_saved_state_object_report.v1 so agents can see changed 1C object names, changed payload parts, active-missing part counts, payload roles, and short semantic term hints without parsing Markdown or full detail payloads;
  • compare ConfigSave with Config and ConfigCASSave with ConfigCAS;
  • return object_changes as configurator objects such as ОбщийМодуль.HttpBridgeКлиент or extension forms;
  • keep FileName, byte sizes, and hashes under storage evidence;
  • keep root, versions, and extension configinfo under system_changes.
  • optionally analyze changed object payloads for text deltas, added/removed words, and saved form/module string samples.
  • when extension manifest summary and active ConfigCAS export are provided, detail analysis resolves extension saved parts to active CAS keys before comparing payloads.
  • render the JSON report as compact Markdown for human review while keeping 1C configurator names first and SQL storage names as evidence.
  • classify changed payload parts with roles such as bsl_module_text, form_descriptor, form_body, primary_payload, or metadata_payload;
  • keep raw word diffs in detail evidence, but expose filtered semantic_hints.added_terms and semantic_hints.removed_terms for agent triage.
  • validate each generated report with a final read-only contract check before treating it as reliable agent input.
  • compare two saved-state report observations by 1C object name and stable payload-part fingerprints when the user continues editing between checks; write Markdown and a contract-check JSON next to the delta JSON by default when --output is used.
  • support object-level lookup from a saved-state report by full name, short configurator name, synonym, suffix, or contains match; ambiguous matches must return candidates rather than selecting one silently.
  • support compact changed-object listing and filtering by layer, kind, extension, payload role, text diff presence, and missing active counterpart.

Command:

python scripts/search_1c_object_context.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --text <SearchText>
  --view effective|base|extension
  --extension <ExtensionName>
  --search-code
  --max-form-items <N>
  --limit <N>
  --output <json>

Output schema:

onec_object_context_search.v1

Purpose:

  • search one resolved object by human/configurator terms;
  • search metadata attributes, tabular section names, forms, form items, form attributes, form commands, form events, module names, and optionally BSL code lines;
  • keep origin/effective action evidence so matches from extensions are not confused with base configuration matches;
  • return file paths and line snippets for code hits, allowing the agent to follow up with get_1c_module.py --routine or module snippet reads.

Task Context Plan

Command:

python scripts/plan_1c_task_context.py
  --index <unified object route index>
  --text <TaskText>
  --view effective
  --max-objects <N>
  --max-terms <N>
  --max-matches <N>
  --output <json>

Output schema:

onec_task_context_plan.v1

Purpose:

  • turn a user task into a read-only investigation plan;
  • find likely metadata object candidates by configurator-visible object names and synonyms, using kind hints such as "document" or "catalog";
  • for each candidate, gather brief context and search the object for task terms across metadata, forms, commands, events, modules, and BSL code;
  • produce recommended follow-up reads such as object metadata, form context, and exact module reads;
  • keep write support explicitly blocked by docs/1c-write-path-safety.md.

Task Evidence Bundle

Command:

python scripts/build_1c_task_evidence.py
  --index <unified object route index>
  --text <TaskText>
  --view effective
  --max-objects <N>
  --max-module-chars <N>
  --code-snippet-radius <N>
  --max-code-snippets <N>
  --output <json>

Output schema:

onec_task_evidence_bundle.v1

Purpose:

  • materialize the read-only task plan into a compact evidence bundle for code generation or human review;
  • include full effective metadata summaries, selected form contexts, selected module snippets, and targeted code snippets around search hit lines;
  • preserve base/extension origin, file paths, form XML paths, module paths, and line numbers;
  • keep large files bounded by explicit limits while retaining focused evidence for relevant code found deep inside large modules.

Task Change Proposal

Command:

python scripts/propose_1c_task_changes.py
  --evidence <TaskEvidenceBundleJson>
  --output <json>

Output schema:

onec_task_change_proposal.v1

Purpose:

  • turn a read-only evidence bundle into a structured implementation proposal;
  • infer broad task intents such as form command, attribute, lifecycle, or inspection;
  • separate extension-first write candidates from base/read-only reference files;
  • identify existing form commands/items, metadata attributes, and related code hits before any patch is generated;
  • use full 1C paths as change targets, and keep local names only when they are bound to a concrete object, form, module, routine, or symbol context;
  • keep the proposal under the write safety contract: no SQL/Config writes and no automatic production update/apply.

Markdown rendering:

python scripts/render_1c_task_proposal_markdown.py
  --proposal <TaskChangeProposalJson>
  --output <markdown>

The Markdown report is for human review and should mirror the JSON proposal, not replace it as machine-readable evidence.

Safety check:

python scripts/check_1c_change_proposal_safety.py
  --proposal <TaskChangeProposalJson>
  --output <json>

Output schema:

onec_change_proposal_safety_check.v1

Purpose:

  • gate future patch generation on machine-checkable safety rules;
  • require write candidates to live in the preferred extension origin and path;
  • verify candidate/reference paths exist;
  • reject direct SQL/Config/ConfigSave/ConfigCAS write targets;
  • preserve the required gates that still block real write/apply operations.

Patch Workspace

Command:

python scripts/create_1c_patch_workspace.py
  --proposal <TaskChangeProposalJson>
  --output-root <directory>
  --slug <name>
  --output <json>

Output schemas:

onec_patch_workspace_creation.v1
onec_patch_workspace_manifest.v1

Purpose:

  • create a safe local workspace for future generated edits;
  • run the proposal safety check before copying anything;
  • copy only extension write candidates into original/ and working/;
  • keep proposal.json, safety.json, manifest.json, and README.md beside the copies;
  • require edits to happen only under working/.

Diff command:

python scripts/check_1c_patch_workspace_integrity.py
  --workspace <PatchWorkspaceDir>
  --output <json>

python scripts/check_1c_patch_source_freshness.py
  --workspace <PatchWorkspaceDir>
  --output <json>

python scripts/validate_1c_patch_workspace_semantics.py
  --workspace <PatchWorkspaceDir>
  --output <json>

python scripts/edit_1c_bsl_routine.py
  --workspace <PatchWorkspaceDir>
  --relative-path <ManifestBslModuleRelativePath>
  --operation append|replace|upsert
  --routine-text-b64 <Utf8Base64BslRoutine>
  [--keep-on-failure]
  --output <json>

python scripts/edit_1c_form_command.py
  --workspace <PatchWorkspaceDir>
  --relative-path <ManifestFormXmlRelativePath>
  --operation append|replace|upsert
  --name <CommandName>
  --title <RussianTitle>
  --action <BslHandlerName>
  [--tooltip <RussianTooltip>]
  [--id <CommandId>]
  [--keep-on-failure]
  --output <json>

python scripts/edit_1c_form_button.py
  --workspace <PatchWorkspaceDir>
  --relative-path <ManifestFormXmlRelativePath>
  --operation append|replace|upsert
  --parent-name <ParentFormItemName>
  --name <ButtonName>
  --title <RussianTitle>
  --command-name <ExistingCommandName>
  [--id <ButtonId>]
  [--keep-on-failure]
  --output <json>

python scripts/add_1c_form_button_workflow.py
  --workspace <PatchWorkspaceDir>
  --form-relative-path <ManifestFormXmlRelativePath>
  --bsl-relative-path <ManifestFormModuleRelativePath>
  --operation append|replace|upsert
  --routine-text-b64 <Utf8Base64BslRoutine>
  --command-name <CommandName>
  --command-title <RussianCommandTitle>
  --command-action <BslHandlerName>
  --button-parent-name <ParentFormItemName>
  --button-name <ButtonName>
  --button-title <RussianButtonTitle>
  [--keep-on-failure]
  --output <json>

python scripts/diff_1c_patch_workspace.py
  --workspace <PatchWorkspaceDir>
  --output <json>

python scripts/create_1c_patch_bundle.py
  --workspace <PatchWorkspaceDir>
  --output-root <PatchBundleRoot>
  --slug <BundleSlug>
  --output <json>

python scripts/check_1c_patch_bundle.py
  --bundle-dir <PatchBundleDir>
  [--zip <PatchBundleZip>]
  --output <json>

python scripts/create_1c_extension_staging_from_bundle.py
  --bundle-dir <PatchBundleDir>
  --output-root <ExtensionStagingRoot>
  --slug <StagingSlug>
  --output <json>

python scripts/check_1c_extension_staging.py
  --staging-dir <ExtensionStagingDir>
  --output <json>

python scripts/check_1c_extension_runner_config.py
  --config <ExtensionRunnerConfigJson>
  --output <json>

python scripts/create_1c_extension_validation_plan.py
  --staging-dir <ExtensionStagingDir>
  [--runner-config <SafeRunnerConfigJson>]
  --output <json>
  --markdown-output <markdown>

python scripts/create_1c_extension_validation_evidence.py
  --plan <ExtensionValidationPlanJson>
  [--output-root <EvidenceRoot>]
  --output <json>

python scripts/check_1c_extension_validation_evidence.py
  --plan <ExtensionValidationPlanJson>
  [--evidence-root <EvidenceRoot>]
  --output <json>

python scripts/check_1c_extension_validation_release.py
  --plan <ExtensionValidationPlanJson>
  [--evidence-root <EvidenceRoot>]
  --output <json>

python scripts/render_1c_extension_validation_release_markdown.py
  --release-check <ExtensionValidationReleaseCheckJson>
  --output <markdown>

python scripts/check_1c_patch_preflight.py
  --workspace <PatchWorkspaceDir>
  --output <json>

python scripts/render_1c_patch_preflight_markdown.py
  --preflight <PatchPreflightJson>
  --output <markdown>

Output schema:

onec_patch_workspace_integrity.v1
onec_patch_source_freshness.v1
onec_patch_workspace_semantic_validation.v1
onec_bsl_routine_edit.v1
onec_form_command_edit.v1
onec_form_button_edit.v1
onec_form_button_workflow.v1
onec_patch_workspace_diff.v1
onec_patch_bundle.v1
onec_patch_bundle_creation.v1
onec_patch_bundle_check.v1
onec_extension_staging.v1
onec_extension_staging_creation.v1
onec_extension_staging_check.v1
onec_extension_runner_config_check.v1
onec_extension_validation_plan.v1
onec_extension_validation_evidence_manifest.v1
onec_extension_validation_evidence_check.v1
onec_extension_validation_release_check.v1
onec_patch_preflight.v1

Purpose:

  • verify original/ hashes still match the manifest before any diff/package step;
  • verify source extension files still match the hashes recorded when the patch workspace was created, so stale patches cannot overwrite newer source files;
  • verify every manifest file exists under both original/ and working/;
  • flag unexpected files under original/ as errors and unexpected files under working/ as warnings;
  • validate edited workspace semantics before review: parse Form.xml, parse BSL routines, reject duplicate routines/commands, check basic BSL block balance, and verify form command actions have matching form-module routines when both files are in the workspace;
  • edit one BSL procedure/function under working/ through a manifest-bound operation: append a new routine, replace an existing routine, or upsert one routine; the command validates the full workspace semantics after writing and rolls the file back by default when validation fails;
  • edit one form command under working/ through a manifest-bound operation: append a new <Command>, replace an existing command, or upsert one command; the command chooses a safe numeric id when omitted, validates the full workspace semantics after writing, and rolls the file back by default when validation fails;
  • edit one visible form button under working/ through a manifest-bound operation: append/replace/upsert one <Button> under a named parent form item and bind it to an existing form command; the command validates the full workspace semantics after writing and rolls the file back by default when validation fails;
  • add a complete form button workflow atomically: BSL handler, form command, and visible button. This is the preferred agent operation when a user asks to add a button. It snapshots all working/ manifest files and restores them if any step fails, unless --keep-on-failure is explicitly set;
  • compare original/ and working/ files from a patch workspace;
  • create a review bundle only when preflight status is ready_for_review. The bundle copies modified working/ files, manifest.json, preflight.json, preflight.md, and diff.json into a review directory and zip archive. It self-checks the created bundle and does not apply changes to source extension files or SQL;
  • validate a review bundle independently: check manifest/preflight/diff consistency, copied modified-file hashes, required review files, and zip archive contents;
  • create a disposable extension XML staging copy from a validated review bundle. This copies the source extension directory to staging, overlays bundle files, writes _codex_staging_manifest.json, and still does not modify source extension files or SQL. The creation command validates the staging copy before returning success;
  • validate a disposable extension XML staging copy independently: check staging manifest schema, safety flags, staged file hashes, source extension freshness, and the recorded review bundle;
  • validate runner configuration for disposable 1C validation: require onec_extension_runner_config.v1, reject production-like base references, reject secrets/credentials in the config file, and require disposable_base_confirmed=true;
  • create a disposable-base validation plan for a staged extension. The plan is read-only: it does not launch 1C, does not modify SQL/source files, marks production bases as forbidden, lists required Designer/Enterprise checks, and records the evidence files a future runner must produce. If runner config is provided, it must pass the runner-config check;
  • create pending manual evidence templates from a validation plan. This only creates files to be filled with disposable-base 1C logs and confirmations; it never marks validation as passed;
  • check filled validation evidence: every expected evidence file must exist and no file may still contain the pending template markers. Evidence must state explicit passed, success, or ok status; changed-objects-smoke.json must have passed status for every changed object. Evidence files are also scanned for secret-like key/value text;
  • aggregate final validation gates for human review: validation plan must be ready, staging must still pass, evidence must pass, safety flags must still forbid production/SQL/source writes. The result can only become validated_for_human_review; it never authorizes automatic production apply;
  • render the final validation release check as a human-readable Markdown report that keeps the no-automatic-production-apply safety message visible;
  • return file hashes, status, unified patches, line counts, and hunk counts;
  • aggregate proposal safety, workspace integrity, source freshness, semantic validation, and diff gates into a single preflight status: blocked, ready_for_editing, or ready_for_review;
  • provide the diff evidence needed before any extension packaging or human approval step.

Object Metadata

Command:

python scripts/get_1c_object_metadata.py
  --kind <ConfiguratorKind>
  --name <ConfiguratorName>
  --view effective|base|extension
  --extension <ExtensionName>
  --index <unified object route index>

Output schema:

onec_object_metadata.v1

Purpose:

  • return agent-facing metadata in 1C terms;
  • default to view=effective, the current working metadata picture;
  • support view=base for the main configuration only;
  • support view=extension --extension <name> for one extension's additions and modifications;
  • keep origin.layer, origin.extension, and effective_action in JSON while allowing human-facing answers to stay concise.

Example expectations for Документ.ПриходнаяНакладная:

effective: 66 attributes, includes ДатаСоздания from ДоработкаРарус
base:      65 attributes, excludes ДатаСоздания
extension ДоработкаРарус:
  - ДатаСоздания: added
  - ДокументОснование: modified

Read Object View

Command:

python scripts/read_1c_object_view.py
  --kind <Kind>
  --name <Name>
  --view effective|base|extension
  --extension <ExtensionName>
  --summary <structured metadata DBNames summary>
  --validation <predicted column validation>
  --route-index <unified object route index>
  --output-dir <run output directory>

Unicode-safe shell variant:

--name-b64 <utf8-base64-name>

Output schema:

onec_sql_read_view.v1

Purpose:

  • resolve the visible 1C object name first;
  • locate enriched metadata by kind/name;
  • if the object is absent from the prepared summary, build a metadata card from resolved XML and DBNames evidence;
  • build SQL projection;
  • execute SQL read after live SQL table-column validation;
  • resolve simple references;
  • resolve composite references;
  • resolve composite value branches;
  • attach enum presentations from metadata routes;
  • return an agent-facing object view with raw evidence preserved.

Read views follow the same layer model as metadata:

effective: current working data, including active extension companion tables
base:      base configuration tables only
extension: standard identity fields plus fields added/modified by one extension

Agent-facing metadata should present 1C types in Russian by default, matching how programmers usually write/read 1C code: СправочникСсылка.Номенклатура, ДокументСсылка.ПриходнаяНакладная, ПеречислениеСсылка.ВидОперации, Строка, Число, Булево, Дата. Canonical XML/storage types such as cfg:CatalogRef.* and xs:boolean remain in value_type.types for internal adapter logic and for explicit debug/storage views.

Object metadata is effective metadata, not base-only metadata. Active extension overlays must be applied before returning attributes, tabular sections, forms, modules, or code context. Extension-added attributes are returned alongside base attributes with source metadata; extension-adopted objects keep override evidence in extension_overrides. A base-only answer is a debug/storage view, not the default agent-facing answer.

For SQL reads, active extensions can move effective data into companion tables with Xn suffixes, for example _Document675X1 and _Document675_VT8000X1. The read executor must choose the effective live table by schema coverage and row availability, and record that decision in diagnostics.effective_tables. Agents should see only the metadata object and fields; companion table names remain storage diagnostics.

onec_sql_read_result.v1 may include diagnostics.pruned_missing_columns. These are columns present in the metadata projection but absent from the live SQL table at execution time. The executor removes only those confirmed-missing columns before running SELECT.

Enum Presentation Map

Command:

python scripts/build_1c_enum_presentation_map.py
  --index <unified object route index>
  --output <json>

Output schema:

onec_enum_presentation_map.v1

Purpose:

  • map SQL enum _EnumOrder values to metadata enum value uuid/name/synonym;
  • use exported XML route evidence as the source of enum value order;
  • prefer base configuration enum XML over extension XML when the same enum name exists in both, while keeping extension evidence available in the route index.

This command is an offline analysis aid. Runtime data.list/data.get enum presentation is decoded from SQL metadata and does not require an XML export.

Object Artifacts

Command:

python scripts/get_1c_object_artifacts.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --output <json>

Output schema:

onec_object_artifacts.v1

Purpose:

  • return owner object routes;
  • list related XML top objects under the owner path;
  • list forms, templates, object modules, form modules, and command modules from the exported XML filesystem evidence.

This is currently XML/filesystem backed. The SQL/CAS-backed implementation must preserve the same output shape.

Object Code Context

Command:

python scripts/get_1c_object_code_context.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --view effective|base|extension
  --extension <ExtensionName>
  --output <json>

Output schema:

onec_object_code_context.v1

Purpose:

  • return the module map for an object without loading large BSL contents;
  • keep module names in 1C terms such as МодульОбъекта, МодульМенеджера, МодульФормы.ФормаДокумента, and МодульКоманды.<ИмяКоманды>;
  • for view=effective, return base modules with active extension overlays attached under extension_overlays;
  • for view=base, return only main configuration modules;
  • for view=extension --extension <name>, return only modules from the selected extension.

Module Content

Command:

python scripts/get_1c_module.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --module <ModuleName>
  --view effective|base|extension
  --extension <ExtensionName>
  --routine <ProcedureOrFunctionName>
  --max-chars <N>
  --output <json>

Output schema:

onec_module_content.v1

Purpose:

  • read the requested BSL module or one routine from that module;
  • for view=effective, include the base module and matching active extension overlays, preserving their order and origin evidence;
  • keep full file paths, relative paths, sizes, truncation markers, and line starts so a later write path can target the exact source.

Form Context

Command:

python scripts/get_1c_form_context.py
  --index <unified object route index>
  --kind <Kind>
  --name <Name>
  --form <FormName>
  --view effective|base|extension
  --extension <ExtensionName>
  --max-items <N>
  --output <json>

Output schema:

onec_form_context.v1

Purpose:

  • return common forms by configurator-visible common form name, for example ОбщаяФорма.t_Форма / CommonForm.t_Форма;
  • return object-owned forms by configurator-visible object and form names, for example forms under catalogs, documents, data processors, reports, registers, charts, exchange plans, business processes, tasks, and other form-capable metadata objects;
  • parse Ext/Form.xml into agent-facing form events, items, attributes, and commands without requiring the agent to know XML paths;
  • return both raw item title and computed effective_title with title_resolution, because a form item can inherit its visible title from a bound form command, form attribute, or value-table column when its own title is empty;
  • expose title_resolution.edit_targets.default_change_target and one_off_change_target: default changes should edit the inherited source such as command/attribute title, while one-off form-only changes should edit the form item title;
  • keep runtime form reads SQL-only; XML paths are accepted only by offline analysis scripts and are rejected by the running adapter;
  • for view=effective, return the base form with active extension form overlays attached under extension_overlays;
  • for view=base, return only the main configuration form;
  • for view=extension --extension <name>, return only the selected extension's form structure.

Selector rules:

  • CommonForm / ОбщаяФорма is a top-level metadata object kind, not a child form of an owner object;
  • Form is reserved for child form payloads owned by a metadata object;
  • when a task says "форма " without an owner, search common forms first, then ask for or infer the owner object before falling back to global scans;
  • for live SQL analysis, build metadata.form.owner_index.build before relying on name-only form selectors. The index resolves CommonForm.<name> or object-owned form routes through extension manifests/DBNames and the actual ConfigCAS .0 form payload, storing module_ref and bsl_offset for form module reads;
  • form structural edits such as adding a form command, adding a command bar button, or inserting a new form item are Form.xml node operations. They must not be routed through scalar saved-state property writers that only change an existing decoded target;
  • metadata.form.command_button.write handles the command/button case through SQL saved-state payloads: it clones existing command and command-button nodes from the same form, appends them with the byte-preserving append_child structural edit, increments declared section counts such as {marker,count,record...} when present, and uses the normal proposal/apply/rollback gates. XML may still be used to analyze or train the rule, but live apply remains SQL-only.
  • After form command/button apply or apply_and_verify, the adapter returns semantic_verify with command, button, handler routine, command-handler link, button-command link, decoded command path, and decoded button path. Repeated upsert calls must be idempotent and return idempotency.status=already_exists instead of appending duplicate nodes.
  • metadata.form.command_button.verify is the read-only equivalent for the same workflow. It resolves saved-state form targets from public selectors and returns the command/button/handler/link checks without preparing, proposing, or applying SQL changes.
  • Public command/button write and verify responses use compact saved-state search evidence: counts plus selected_form, not the full candidate list.
  • metadata.form.write_target.verify is a read-only preflight for existing form element/command/attribute writes. It reports writable_now, needs_prepare, a public form_path for the write node, and the metadata.saved_state.prepare payload when the save layer is missing.
  • metadata.write.history lists recent adapter write operations, including code.write, or returns a specific operation_id with status, routed method, target summary, backup ids, and full result for a single operation. It can filter by operation_method, status, routed_method, or backup_id. Pass include_summary=true for aggregate counts by method, status, routed method, and operations with backups.
  • metadata.write.rollback rolls back one saved-state backup selected by operation_id or backup_id. It is an explicit apply operation and requires allow_sql_saved_state_rollback=true.
  • The deployment verification stack includes rollback safety reports: write-rollback-safety-smoke.json for REST and write-rollback-safety-mcp-smoke.json for MCP. These reports must show the method in help.methods, readable write history, and blocked rollback when allow_sql_saved_state_rollback is absent.
  • metadata.saved_state.prepare prepares an object's saved-state working copy. Prefer a public selector (ref or kind/name) together with layer=base_saved_state|extension_saved_state. Its default response reports the selected 1C object, active/saved semantic layers, record counts, and readiness without exposing database/table names, storage files, hashes, or row details. include_storage=true retains the low-level diagnostic response. plan remains the default and performs no write; apply and apply_and_verify still require allow_sql_saved_state_prepare=true.
  • Every public RPC next_resolution/next_call entry uses {method, params}. payload is reserved for the outer RPC request envelope and internal apply-hint bodies; it must not be used as the arguments field of a public follow-up. Saved-state follow-ups use the semantic contract: layer plus a public object ref or kind/name. Internal target_table, source_table, file_name, file_names, module_ref, object GUIDs, and include_storage are not copied into public follow-up payloads. If only an opaque storage target is known, the follow-up reports selector_required instead of exposing that target.
  • metadata.saved_state.diff is the agent-facing read-only comparison between a saved-state module and its active source. Prefer a public 1C selector such as ref=Справочник.Номенклатура or kind/name plus module_ordinal; the adapter resolves the saved-state table and physical file internally. Generated module_ref or table + file_name remain accepted for chained tooling. Name-first responses hide storage coordinates unless include_storage=true, and a missing save layer returns a name-first metadata.saved_state.prepare payload. The method maps ConfigSave -> Config and ConfigCASSave -> ConfigCAS, reads both payloads from live SQL, and returns changed/unchanged, needs_prepare, current hashes, compact text/tree diff, and freshness.status=live_sql_verified. Deployment verification persists REST/MCP smoke reports as saved-state-diff-smoke.json and saved-state-diff-mcp-smoke.json.
  • metadata.saved_state.status is the read-only name-first overview for a whole save layer. Prefer layer=base_saved_state|extension_saved_state; the default response reports semantic aggregate state and object/record counts without exposing SQL tables, database names, files, hashes, or internal diff selectors. include_storage=true enables the diagnostic storage view, which accepts the backward-compatible table=ConfigSave|ConfigCASSave, compares saved rows with their active source by file part, size, and SHA1, and returns per-file changed, unchanged, or saved_only statuses.
  • metadata.saved_state.changes.list is the read-only pending-change overview across the base and extension saved-state layers. Use the semantic layer=base_saved_state|extension_saved_state filter when only one layer is needed; the low-level table filter is retained for compatibility. Its default response is name-first: object/form/module context is resolved automatically, layer names are semantic, and SQL tables/files, GUIDs, hashes, module refs, concrete diff selectors, low-level actions, and SQL-specific freshness vocabulary are hidden. Unresolved changes remain in the counts and are marked context_unresolved. Use include_storage=true for the previous per-file diagnostic view with concrete diff_selector links. include_unchanged=true also includes unchanged entries. The freshness of the pending-change list remains live SQL verified, while context is explanatory metadata. Pass group_by_context=true to also return compact groups keyed by resolved form/module/object context; grouping uses the same best-effort context enrichment and falls back to per-file groups when context cannot be resolved. In diagnostic storage mode each group includes compact selectors: per-file diff selectors, plus module_refs and write_plan_targets when the resolved module context exposes them. Groups also include next_actions, derived from those selectors, for safe follow-up calls such as inspecting a diff, reading a module through code.read state=working, or running read-only metadata.write.preflight. action_summary counts those follow-up calls by kind/method, and recommended_next_action points to the first safe action, preferring diff inspection before module reads and write preflight checks. When group_by_context=true, the root response also includes an aggregated action_summary and root recommended_next_action with the selected group identity plus the action payload.
  • Saved-state form module writes refresh the SQL-derived code index for the embedded module. Cache/vector results remain acceleration only; verified answers still require payload_sha1 and text_sha1 revalidation against current SQL.

Code Index And Vector Candidates

SQL remains the source of truth. Code cache and vector search are acceleration layers only.

Freshness statuses:

  • live_sql_verified: code was read directly from SQL for the answer;
  • cache_hit_verified: cache candidate was rechecked against current SQL payload_sha1 and text_sha1;
  • cache_hit_stale: cache candidate exists, but current SQL no longer matches;
  • vector_candidate_unverified: vector result is only a retrieval candidate.

RPC methods:

{
  "method": "metadata.code_index.build",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigCAS",
    "prefix": "<optional file prefix>",
    "max_items": 500,
    "include_vectors": true
  }
}
  • metadata.code_index.status: reports cache/module/vector chunk counts;
  • metadata.code_index.search: fast lexical search over cached BSL, verifying candidates by default;
  • metadata.code_index.verify: verifies one module_ref against live SQL;
  • metadata.code_index.refresh_changed: verifies search candidates and refreshes stale modules from SQL;
  • metadata.code_vector.search: searches cached module/routine chunks with local hashing embeddings or supplied query_embedding, then revalidates by default.

Operational modes:

  • fast: cache plus SQL hash verification;
  • live: direct SQL search/read, slower but authoritative;
  • background_refresh: intended for long cache warming jobs.

Never apply code changes from cache or vector output alone. Use the returned read_selector after freshness is cache_hit_verified or read live SQL again.

Saved-State Form Search And Write Target Resolve

RPC methods:

{
  "method": "metadata.saved_state.forms.search",
  "payload": {
    "base_id": "<base-id>",
    "tables": ["ConfigCASSave", "ConfigSave"],
    "element": "КомандаПример1",
    "scan_limit": 1000
  }
}
{
  "method": "metadata.form.write_target.resolve",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigCASSave",
    "form": "ТестНастройки",
    "command": "КомандаПример1",
    "property": "Заголовок",
    "value": "ПРОВЕРКА"
  }
}
{
  "method": "metadata.form.write_target.verify",
  "payload": {
    "base_id": "<base-id>",
    "extension": "<extension-name>",
    "form": "ТестНастройки",
    "command": "КомандаПример1",
    "property": "Заголовок"
  }
}

Output schemas:

onec_saved_state_form_search.v1
onec_form_write_target_resolution.v1

Purpose:

  • search saved-state form payloads without running the heavyweight global definition scan;
  • resolve an agent-facing write intent into table, file_name, decoded section (items, commands, attributes, attribute_fields, tables, or command_bars), exact path, current value, and writable properties;
  • prefer selector intent when names overlap: element/element_name search form items first, then commands; command searches commands; attribute searches form attributes and value-table fields. Use element_path/path or element_id/id for strict physical disambiguation;
  • return both the legacy target/effective_target fields and the source-aware display, write_target, and alternatives fields when the visible property is inherited. For example, an empty element caption may be resolved to the linked form command caption;
  • use the form property registry for aliases and verification rules. Current registry covers id, name, title/Заголовок, path_to_data/ ПутьКДанным, visible/Видимость, enabled/Доступность, and read_only/ТолькоПросмотр, plus form layout/button properties such as Использование, Группа, Вид, Отображение, ПоложениеЗаголовка, ПоложениеВКоманднойПанели, УникальностьКоманды, ЦветФона, ЦветТекста, and ЦветРамки;
  • refuse to silently create a local title override when a caption is derived from ПутьКДанным. Pass source=local_override on the edit when a local form-element override is intentional;
  • resolve ПутьКДанным captions by source: if the path points to a form attribute, write the form attribute title; if it points to a tabular form attribute field such as ТЗ.К1, write that field title; if it points to an object/configuration attribute such as Объект.<Реквизит>, write the local form element title instead;
  • return candidate diagnostics when a selector is missing or ambiguous;
  • produce a human-readable semantic diff such as КомандаПример1.Заголовок: Пример1 -> ПРОВЕРКА.

Saved-State Form Write Matrix

RPC methods:

{
  "method": "metadata.form.write_matrix.build",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigCASSave",
    "file_name": "<form-file-name>"
  }
}
{
  "method": "metadata.form.write_matrix.smoke",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigCASSave",
    "file_name": "<form-file-name>",
    "allow_sql_saved_state_apply": true,
    "allow_sql_saved_state_rollback": true,
    "max_candidates": 10,
    "learning_id": "write-matrix-case"
  }
}

Purpose:

  • enumerate all decoded writable scalar form properties that the adapter can read from saved-state form payloads;
  • resolve each property through the same source-aware routing used by metadata.write, including command captions, form attribute captions, and tabular form attribute field captions;
  • classify each entry as can_smoke=true or return a reason such as identity_or_binding_property, enum_values_unknown, or empty_local_string_requires_codec_probe;
  • run can_smoke entries through apply_and_rollback and record verified routes in a write-learning report when learning_id is provided.

Routine Override Resolution

RPC method:

metadata.resolve_overrides

Purpose:

  • build a routine chain for a concrete object and method name across base and extension modules;
  • return public read selectors for every found routine without exposing storage ids by default;
  • expose chain[].extension_action for each routine link. For base configuration links this is operation_class=base_definition;
  • for extension links, normalize known action evidence into insert_before, insert_after, replace, or replace_with_control;
  • when a routine is found in an extension but the action metadata is not yet resolved, return extension_action.status=unknown and operation_class=unknown_extension_action. The agent must not treat this as an ordinary replace;
  • for replace_with_control, carry requires_control_fragment=true; write planning still requires the controlled base fragment, controlled_fragment, or expected_old_contains before apply.
  • return write_plan_evidence, a ready fragment for metadata.write.plan containing target.kind=module, routine_name, object selector fields, and target.extension_action when available;
  • include write_plan_evidence.next_resolution.method and write_plan_evidence.next_resolution.params for metadata.saved_state.modules.search, so the agent has the next safe lookup for the module. The follow-up uses ref or kind/name and the semantic layer=base_saved_state|extension_saved_state; it does not expose owner_guid or SQL table names. The saved-state module search also accepts the object selector aliases and resolves names to storage identities internally. With the explicit diagnostic include_storage=true option, its matching streams return write_plan_target with module_ref, file_name, stream_index, and expected_sha1 for the concrete metadata.write.plan target. This override evidence itself is not a concrete saved-state write route.
  • callers can compose write_plan_evidence.target with a returned streams[].write_plan_target, add the required operation guards, and pass the result to metadata.write.plan; the accepted plan must route to metadata.module.write_apply without inventing storage field names.

This method is read-only evidence for planning. It tells the agent what must be known before calling metadata.write.plan; it does not select a concrete saved state route by itself.

Metadata Write

RPC method:

{
  "method": "metadata.write",
  "payload": {
    "base_id": "<base-id>",
    "target": {
      "kind": "form",
      "table": "ConfigCASSave",
      "form": "ТестНастройки",
      "element": "КомандаПример1"
    },
    "mode": "plan",
    "edits": [
      {"property": "Заголовок", "value": "ПРОВЕРКА"}
    ]
  }
}

Output schema:

onec_metadata_write.v1

Standard object identity properties use the same high-level method and public 1C selector:

{
  "method": "metadata.write",
  "payload": {
    "base_id": "<base-id>",
    "target": {
      "area": "object",
      "kind": "Catalog",
      "name": "Номенклатура",
      "property": "synonym"
    },
    "value": "Номенклатура товаров",
    "expected_old": "Товары",
    "mode": "plan"
  }
}

This route delegates to metadata.object.property.write. It resolves the object GUID and exact saved-state tree path internally, supports only existing synonym locales and scalar comment, and preserves the original payload format. Apply modes retain SHA1/semantic preconditions, backup, readback verification, and rollback. Object rename and structural collection edits are not part of this route.

An existing child metadata identity uses the same method:

{
  "method": "metadata.object.property.write",
  "payload": {
    "base_id": "<base-id>",
    "member_ref": "Catalog.Номенклатура.Attribute.Артикул",
    "property": "comment",
    "value": "Код товара поставщика",
    "allow_saved_state_write": true,
    "execution_mode": "plan"
  }
}

member_kind + member_name is also accepted. If the same child name occurs in several collections, callers must provide the full member_ref; the adapter returns ambiguous instead of choosing a GUID. Supported existing member categories are Attribute, TabularSection, Dimension, and Resource, including Russian aliases.

Adding one requisite uses a separate clone-based method:

{
  "method": "metadata.object.member.add",
  "payload": {
    "base_id": "<base-id>",
    "template_member_ref": "Catalog.Номенклатура.Attribute.Артикул",
    "new_member_name": "КодПоставщика",
    "new_member_synonym": "Код поставщика",
    "allow_saved_state_write": true,
    "execution_mode": "plan"
  }
}

The adapter requires an existing Attribute template from the same collection, generates a deterministic GUID internally, rejects duplicate names, clones the template type/settings, and appends the cloned record to the same declared collection. The proposal verifies both the appended node and updated declared count. Apply/verify/rollback use the normal saved-state gates and backup.

For a tabular-section column, use the complete nested template path:

Document.АвансовыйОтчет.TabularSection.Запасы.Attribute.Номенклатура

Name uniqueness and the deterministic GUID seed are scoped to that tabular section, so identical column names in other table parts do not conflict.

Scheduled-job schedule planning uses the same method and a public 1C reference:

{
  "method": "metadata.write",
  "payload": {
    "base_id": "<base-id>",
    "target": {
      "kind": "schedule",
      "ref": "РегламентныеЗадания.ОбменДанными"
    },
    "schedule": {
      "begin_time": "09:00:00",
      "week_days": [1, 2, 3, 4, 5]
    },
    "allow_saved_state_write": true,
    "mode": "plan"
  }
}

This route returns onec_scheduled_job_schedule_write.v1, resolves the object name to its GUID internally, and targets only <guid>.0 in ConfigSave.

Purpose:

  • provide one agent-facing write entry point;
  • reject write requests that do not resolve to a full 1C path, explicit layer, or concrete saved-state/module reference;
  • use the same planning shape as metadata.write.plan before any apply mode;
  • return a blocked metadata.write.plan result instead of applying when the target is only an effective canonical_path without origin/layer evidence or a concrete saved-state/module reference;
  • include the blocked plan's apply_payload_hint and next_resolution in the metadata.write response when a full form/module path can be parsed, so the agent can resolve the saved-state target without treating the effective view as writable;
  • after the agent provides a concrete saved-state file_name or module_ref for a parsed full path, merge missing selector fields from the same apply_payload_hint into the apply payload, for example form/element or routine_name, while preserving explicit user payload values;
  • preserve the concrete reference field type in write planning and apply hints: module_ref, module_id, file_name, and form_guid must not be collapsed into a generic string or rewritten as another selector field;
  • reject incompatible concrete reference fields for the selected target kind with concrete_reference_kind_mismatch, for example form_guid on target_kind=module or module_ref on target_kind=form;
  • do not call lower-level apply methods when the same read-only metadata.write.plan reports allowed=false; return status=blocked, error=write_plan_blocked, the blocking problems, and the plan instead;
  • require metadata.form.element.write_apply and metadata.module.write_apply to run the same read-only plan gate before SQL apply, even when they are called directly instead of through metadata.write;
  • v1 routes target.kind=form to metadata.form.element.write_apply;
  • v1 routes target.area=object to metadata.object.property.write for synonym and comment;
  • v1 routes target.area=object with operation=add_attribute to metadata.object.member.add;
  • v1 routes target.kind=schedule to the named scheduled-job schedule writer; scalar schedule fields and structural week_days/months resize are supported through a verified full schedule-tree replacement;
  • v1 routes saved-state form payload container module refs without #stream to the embedded form payload writer when routine_name and routine_text identify a single routine edit; this path preserves existing leading BSL directives such as &НаКлиенте if the replacement text omits them;
  • treat saved-state preparation as an adapter concern: when metadata.write receives a current active form/module target from Config or ConfigCAS, plan returns a metadata.saved_state.prepare plan, while apply modes with allow_sql_saved_state_apply=true prepare ConfigSave/ConfigCASSave internally and continue against that save layer;
  • preserve the same gates as the lower-level form runner: plan, apply, apply_and_rollback, explicit SQL apply/rollback flags, sha1 preconditions, backup, and semantic verification;
  • keep remaining writers behind explicit target routing instead of ad-hoc direct SQL methods.

Metadata Write Preflight

RPC method:

{
  "method": "metadata.write.preflight",
  "payload": {
    "base_id": "<base-id>",
    "target": {
      "kind": "module",
      "module_ref": "ConfigCASSave:<file-name>#stream:0"
    },
    "intent": {
      "operation": "replace_with_control",
      "control_fragment": "<current-fragment>",
      "new": "<new-fragment>"
    }
  }
}

Output schema:

onec_metadata_write_preflight.v1

Purpose:

  • provide a read-only check immediately before metadata.write;
  • combine metadata.write.plan with live SQL saved-state verification;
  • return status=ready, needs_prepare, needs_resolution, or blocked;
  • report saved_state.freshness.status=live_sql_verified for concrete saved-state targets verified against SQL;
  • never create or modify ConfigSave/ConfigCASSave;
  • let metadata.write keep saved-state preparation as an adapter concern: agents should not ask the user whether to create save rows.

Metadata Write Plan

RPC method:

{
  "method": "metadata.write.plan",
  "payload": {
    "base_id": "<base-id>",
    "target": {
      "canonical_path": "Справочник.Контрагенты.Наименование"
    },
    "intent": {
      "operation": "property_change",
      "property": "Синоним",
      "value": "Контрагент"
    },
    "preferred_layer": "auto"
  }
}

Output schema:

onec_metadata_write_plan.v1

Purpose:

  • resolve the requested change target to a full 1C path or return ambiguity candidates;
  • infer target_kind from full path sections when it is not explicit, for example ...Форма.<FormName>.<Member> routes as form and ОбщийМодуль.<Name>.<Routine> routes as module;
  • read effective and origin evidence before selecting a write route;
  • use metadata.definition.find for read-only origin lookup when a canonical_path is provided, returning compact matches, origin, read_selector, and related_selectors under origin_lookup;
  • accept public target.origin or top-level origin from prior code.search, code.read, modules.search, or modules.read results and normalize it into origin_lookup.method=provided_origin_evidence for layer recommendation without repeating the lookup;
  • accept public target.extension_action, top-level extension_action, or a single-item extension_actions list from metadata.resolve_overrides. If the write intent has no explicit operation, known action evidence may infer route.operation_class; unknown action evidence blocks planning with extension_action_unknown;
  • block multi-item extension_actions with extension_action_ambiguous until the caller narrows the extension/module/routine context to one concrete action;
  • reject mismatches between explicit module-code operation and extension action evidence with extension_action_operation_mismatch, because extension code changes must preserve insert_before, insert_after, replace, or replace_with_control semantics;
  • return ambiguous_origin_matches when origin lookup finds more than one matching definition, even if all matches are in the same layer; callers must narrow object/form/module/routine context before apply;
  • classify the current owner as base configuration, extension, saved-state working copy, generated extension source, or read-only reference evidence;
  • return route.recommended_write.write_surface from origin evidence: base_saved_state for configuration origin, extension_saved_state for a resolved extension origin, saved_state for an already concrete saved-state origin, blocked_unknown for unresolved owners, or blocked_conflict when multiple layers match the target;
  • normalize preferred_layer (auto, base, extension, generated_extension_source, including Russian aliases) and return preferred_layer_conflict when it disagrees with origin-derived recommended_write;
  • accept preferred_extension as an optional extension name/GUID and return preferred_extension_conflict when it disagrees with the resolved extension owner;
  • select the smallest allowed operation such as add, property_change, insert_before, insert_after, replace, replace_with_control, append_routine, upsert_routine, or move_form_item;
  • normalize natural operation names into route.operation_class, including Russian phrases such as вставить до, вставить после, вместо, and вместо с контролем;
  • return route.apply_payload_hint for concrete saved-state module/form routes, mapping normalized operations and guard fields into the next safe planner/apply method payload such as metadata.module.write_apply;
  • include target.concrete_reference_field and target.concrete_reference_source when a concrete selector was provided, so the agent can distinguish module_ref, module file_name, form file_name, and form_guid;
  • include selector fields derived from canonical_path in route.apply_payload_hint, for example object kind/name, form, element, and routine_name;
  • mark route.apply_payload_hint.ready_for_apply_method=true only when the hint already has a concrete saved-state/module reference; selector-derived hints must use ready_for_apply_method=false and include next_resolution, for example metadata.saved_state.modules.search for modules or metadata.form.write_target.resolve for forms;
  • report required guards: current sha1, expected old text, controlled fragment, extension order, conflict scan, BSL validation, and semantic readback;
  • for module operations, block replace_with_control unless control_fragment, controlled_fragment, or expected_old_contains is present. Plain old is still useful replacement evidence, but it is not a controlled base fragment;
  • when optional current-source evidence such as current_text or source_text is provided for replace_with_control, block stale plans with control_fragment_drift if the controlled fragment no longer matches that source;
  • for module replace/replace_with_control, require old-code evidence (old, control_fragment, expected_old_contains, expected_old_sha1, expected_contains, or expected_sha1) and new code (new, text, or routine_text);
  • for module insert_before/insert_after, require an anchor through anchor, before, after, or expected_contains;
  • return allowed=false when the target is effective-only, ambiguous, active-applied, or missing required extension/control evidence.

The planner is read-only. Apply methods may consume the accepted plan, but must still enforce the explicit saved-state or extension-source gates.

Metadata Write Learning

RPC methods:

metadata.write_learning.capture_before
metadata.write_learning.capture_after
metadata.write_learning.diff
metadata.write_learning.infer_rule

Purpose:

  • support the manual learning loop: capture a saved-state form before a Designer edit, capture it after the edit, compare decoded writable properties, and infer a repeatable metadata.write payload;
  • store learning artifacts under ONEC_ADAPTER_WRITE_LEARNING_DIR or /data/adapter-write-learning;
  • store decoded targets, writable properties, storage sha1 and byte counts; raw payload hex is not stored in learning captures;
  • keep learning scoped to saved-state form payloads in ConfigSave and ConfigCASSave.

Example:

{
  "method": "metadata.write_learning.capture_before",
  "payload": {
    "base_id": "<base-id>",
    "learning_id": "case-command-title",
    "table": "ConfigCASSave",
    "form": "ТестНастройки",
    "command": "КомандаПример1"
  }
}

After a manual Designer edit:

{"method": "metadata.write_learning.capture_after", "payload": {"base_id": "<base-id>", "learning_id": "case-command-title", "table": "ConfigCASSave", "form": "ТестНастройки", "command": "КомандаПример1"}}

Then:

{"method": "metadata.write_learning.diff", "payload": {"learning_id": "case-command-title"}}
{"method": "metadata.write_learning.infer_rule", "payload": {"learning_id": "case-command-title"}}

Saved-State Form Element Write Planner

RPC method:

{
  "method": "metadata.form.element.write",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigSave",
    "form_guid": "<form-guid>",
    "element": "<form-element-name>",
    "allow_saved_state_write": true,
    "include_payload": true,
    "edits": [
      {"property": "title", "value": "Новый заголовок"},
      {"property": "Видимость", "value": true},
      {"property": "Заголовок", "value": "Локальный заголовок", "source": "local_override"}
    ]
  }
}

Output schema:

onec_change_proposal.v1

Purpose:

  • resolve an agent-facing decoded form element (element, element_id, or diagnostic element_path) into exact form payload paths;
  • build a changes.propose review payload for saved-state tables only: ConfigSave or ConfigCASSave;
  • build form proposals in preserve-format mode: only the selected scalar token span is patched in the original brace text;
  • redirect empty inherited captions to their real display source when known, such as a linked form command title;
  • block non-explicit local caption overrides when the display caption appears to come from ПутьКДанным;
  • auto-resolve file_name through metadata.form.write_target.resolve when a direct form file selector is not provided;
  • include semantic_diff and candidate diagnostics for agent review;
  • verify semantic readback through the same property registry aliases, so an edit like command_bar_location is checked against ПоложениеВКоманднойПанели;
  • require explicit allow_saved_state_write=true so write intent is visible in logs and prompts;
  • keep direct SQL updates blocked: write_mode.sql_write_performed=false.

Saved-State Form Element Write Runner

RPC method:

{
  "method": "metadata.form.element.write_apply",
  "payload": {
    "base_id": "<base-id>",
    "execution_mode": "apply_and_rollback",
    "table": "ConfigSave",
    "form_guid": "<form-guid>",
    "element": "<form-element-name>",
    "allow_sql_saved_state_apply": true,
    "allow_sql_saved_state_rollback": true,
    "edits": [
      {"property": "title", "value": "Новый заголовок"}
    ]
  }
}

Output schema:

onec_form_element_write_apply.v1

Purpose:

  • orchestrate the planner, saved-state apply, semantic verification, and optional rollback in one adapter call;
  • support execution_mode=plan, apply, apply_and_verify, and apply_and_rollback;
  • force include_payload=true internally for apply modes;
  • require explicit SQL apply and rollback gates before touching saved-state rows.

Saved-State Apply

RPC method:

{
  "method": "storage.saved_state.apply_proposal",
  "payload": {
    "base_id": "<base-id>",
    "allow_sql_saved_state_apply": true,
    "proposal": "<full proposal from metadata.form.element.write or changes.propose>"
  }
}

Output schema:

onec_storage_saved_state_apply.v1

Purpose:

  • apply a reviewed proposal to ConfigSave or ConfigCASSave;
  • require proposal.encoded.payload_hex, so the proposal must be created with include_payload=true;
  • verify proposal.original.sha1 against the current saved-state payload before writing;
  • write backup evidence with rollback payload under ONEC_ADAPTER_BACKUP_DIR or /data/adapter-apply-backups;
  • run the SQL update inside a transaction and verify readback sha1 after commit;
  • when the proposal comes from metadata.form.element.write, re-read the form and verify the edited element property through metadata.form.decode;
  • v1 only updates payloads stored as one SQL part. Multi-part payloads return unsupported_part_layout until a schema-aware multi-part writer is added.

Saved-State Rollback

RPC method:

{
  "method": "storage.saved_state.rollback",
  "payload": {
    "base_id": "<base-id>",
    "allow_sql_saved_state_rollback": true,
    "backup_id": "<backup-id-from-apply>"
  }
}

Output schema:

onec_storage_saved_state_rollback.v1

Purpose:

  • load backup evidence by backup_id or backup_path;
  • apply the embedded rollback proposal through the same saved-state apply gate;
  • return the nested apply result, including readback and semantic verification when available.

Saved-State Backups List

RPC method:

{
  "method": "storage.saved_state.backups.list",
  "payload": {
    "base_id": "<base-id>",
    "table": "ConfigCASSave",
    "file_name": "<saved-state-form-file>",
    "limit": 10,
    "diagnostic": true
  }
}

Output schema:

onec_saved_state_backups.v1

Purpose:

  • list local apply backups from ONEC_ADAPTER_BACKUP_DIR or /data/adapter-apply-backups;
  • filter by base, table, and file name;
  • return backup ids, source metadata, sha1 and byte counts without returning rollback payload hex.

Kind Smoke

Command:

python scripts/smoke_1c_read_view_kinds.py
  --kind InformationRegister
  --kind AccumulationRegister
  --kind AccountingRegister
  ...

Output schema:

onec_read_view_kind_smoke.v1

Purpose:

  • select first routed object of each kind from the enriched metadata summary;
  • run the full read object view pipeline;
  • record success/failure and command tails for regression tracking.

Current Implemented Schemas

onec_sql_read_projection.v1
onec_sql_read_result.v1
onec_sql_reference_resolution.v1
onec_sql_composite_reference_resolution.v1
onec_sql_composite_value_resolution.v1
onec_bsl_symbol_resolution.v1
onec_enum_presentation_map.v1
onec_object_resolution.v1
onec_object_brief_context.v1
onec_object_context_search.v1
onec_saved_state_object_comparison.v1
onec_saved_state_object_detail.v1
onec_saved_state_object_report.v1
onec_saved_state_object_report_check.v1
onec_saved_state_watch_once.v1
onec_saved_state_watch_once_check.v1
onec_saved_state_watch_run_list.v1
onec_saved_state_watch_run_list_check.v1
onec_saved_state_latest_watch_run.v1
onec_saved_state_latest_watch_run_check.v1
onec_saved_state_object_report_delta.v1
onec_saved_state_object_report_delta_check.v1
onec_saved_state_object_change_list.v1
onec_saved_state_object_change.v1
onec_task_context_plan.v1
onec_task_evidence_bundle.v1
onec_task_change_proposal.v1
onec_change_proposal_safety_check.v1
onec_patch_workspace_creation.v1
onec_patch_workspace_manifest.v1
onec_patch_workspace_integrity.v1
onec_patch_source_freshness.v1
onec_patch_workspace_semantic_validation.v1
onec_bsl_routine_edit.v1
onec_form_command_edit.v1
onec_form_button_edit.v1
onec_form_button_workflow.v1
onec_patch_workspace_diff.v1
onec_patch_bundle.v1
onec_patch_bundle_creation.v1
onec_patch_bundle_check.v1
onec_extension_staging.v1
onec_extension_staging_creation.v1
onec_extension_staging_check.v1
onec_extension_runner_config_check.v1
onec_extension_validation_plan.v1
onec_extension_validation_evidence_manifest.v1
onec_extension_validation_evidence_check.v1
onec_extension_validation_release_check.v1
onec_patch_preflight.v1
onec_structured_metadata_from_resolved_xml.v1
onec_sql_read_view.v1
onec_object_artifacts.v1
onec_object_code_context.v1
onec_module_content.v1
onec_form_context.v1
onec_metadata_write_plan.v1
onec_read_view_kind_smoke.v1

Extension Evidence

Declared metadata targets and physical SQL hits must remain separate.

Example:

declared target: cfg:CatalogRef.Пользователи -> _Reference348
physical hit:    _Reference348X1

The adapter may select an alternate presentation for convenience, but it must keep declared target, alternate_hits, and selected presentation as separate fields.