# 1C Form Discovery And Editing

The semantic object/form boundary for agent responses is defined in
[`1c-metadata-structure.md`](1c-metadata-structure.md). In particular, an
owner returns references to forms; form parameters, attributes, commands,
elements, and form-module facts are read through the form's own public
selector. Do not duplicate a decoded form as an invented subtree of its owner.

This runbook adapts the MOXCEL discovery loop to managed forms. The goal is a
full SQL-side form decoder and safe saved-state editing through the test
extension, with XML exports used only as evidence fixtures.

## Current Baseline

- Default base: `upo_test`.
- Default adapter endpoint: `http://docker.cin.su:8011`.
- Primary test extension/object fixture:
  `фс_ДоработкиОбщее` /
  `DataProcessor.фс_НастройкаУсловногоОформления`.
- Primary form fixture: `ТестНастройки`.
- Existing form context evidence:
  `reports/1c-sql/upo/form-context-test-nastroiki-title-resolution.json`.
- Existing saved-state smoke selectors:
  `А`, `ТЗК1`, and `КомандаПример1`.

If `ConfigSave` or `ConfigCASSave` is empty, prepare the working saved-state
row through the reviewed saved-state copy flow in
`docs/1c-write-path-safety.md` before running write smokes.

## Current UPO Test Status

- Active form discovery object:
  `Catalog.ЗадачиАссистентаУправления`.
- Working saved-state table: `ConfigSave`.
- Working form payloads:
  `fa447250-c2a0-439d-8ba7-422923f57200.0` (`ФормаЭлемента`) and
  `91ce61c5-6f4b-484a-9021-59f18be88550.0` (`ФормаСписка`).
- The saved-state copy planner now includes form payload rows (`*.0`) with
  `role=form_payload`; descriptor-only copies are not enough for
  `metadata.form.decode`.
- Latest decoder profile after container/dynamic-list baseline mapping:
  `reports/1c-sql/upo_test/form-profile-zadachi-assistenta-configsave-after-map-live.md`.
  Coverage is `484/2083` mapped, up from `252/2083`.
- Latest SQL/XML oracle comparison for `ФормаСписка`:
  `reports/1c-sql/upo_test/form-sql-xml-compare-zadachi-assistenta-list-xmlmap.md`.
  It currently shows `17` matched items, `44` matched properties, `41`
  XML-only properties, and `12` mismatches after mapping SQL type code `8`
  to `Контекстное меню`.
- `ТестНастройки` XML context is available at
  `reports/1c-sql/upo_test/form-context-test-nastroiki-effective-refresh.json`,
  and the live SQL saved-state rows are prepared in `ConfigCASSave` from local
  CAS blobs:
  `f96a0c45-3eff-11f1-8287-005056b0d483__25c39fbf-35a4-4b43-8e3f-cd1f91082c88`
  plus `.0`.
- Latest `ТестНастройки` direct SQL decoder profile:
  `reports/1c-sql/upo_test/form-profile-test-nastroiki-direct.md`.
  Coverage is `552/2891` mapped after decoding `ExtendedTooltip` form
  items from marker `12`, table additions from marker `6`, buttons from
  marker `34`, form/element events, field layout details, group/table layout
  properties, derived child item references, and section-level command/action
  semantics.
- Latest `ТестНастройки` SQL/XML oracle comparison:
  `reports/1c-sql/upo_test/form-sql-xml-compare-test-nastroiki-direct.md`.
  It currently shows `68` matched items, `292` matched properties, `2`
  XML-only properties, no missing SQL items, and no remaining value
  mismatches after `ExtendedTooltip` decoding, form event decoding from
  section `1.19`, marker `6`/`34` decoding, element event matching, derived
  reference semantics, field/group/table layout semantics, plus section-aware
  XML matching for dynamic-list columns and command-backed buttons. The only
  remaining XML-only properties are command binding cases:
  `ТЗИзменитьФорму -> Form.StandardCommand.CustomizeForm` and
  `ФормаКомандаОбновить -> Form.Command.КомандаПрименить`.
- Latest `ТестНастройки` write matrix smoke:
  `reports/1c-sql/upo_test/form-write-matrix-smoke-test-nastroiki-layout-table-100.json`.
  It verified 100 candidates with zero failures. The current matrix has
  `2912` entries, `1339` safe smoke candidates, and no not-writable entries.
  A direct `metadata.write` smoke for `А.Заголовок` also completed as
  `verified_and_rolled_back`.
- Latest write matrix smokes:
  `reports/1c-sql/upo_test/form-write-matrix-smoke-element-50.json` and
  `reports/1c-sql/upo_test/form-write-matrix-smoke-list-50.json`.
  Both verified 50 candidates with zero failures.
- Latest direct `metadata.write` smoke changed `Список.Заголовок` through
  `apply_and_rollback`; semantic readback verified the change and rollback
  restored the original SHA1.

## Discovery Loop

Use the same shape as the MOXCEL work:

1. Create or update one controlled form fixture in the test extension.
2. Change exactly one visible form property in Designer.
3. Capture the SQL saved-state form payload before and after.
4. Compare the decoded SQL payload with exported `Ext/Form.xml` as an oracle.
5. Promote read rules only when SQL bytes reproduce XML-visible facts.
6. Promote write rules only after `apply_and_rollback` proves semantic readback
   and rollback.

The adapter runtime remains SQL-only. Exported form XML is a labeling and
verification fixture, not a runtime input for adapter answers.

## Decoder Scope

The full decoder should expose these public form sections:

- form common properties and events;
- form items with stable `id`, `name`, parent/group, type, title, data path,
  visibility, enabled/read-only flags, layout properties, and color/font
  properties when decoded;
- form attributes, including value-table fields and dynamic-list fields;
- form commands, command bars, command-button bindings, and command handlers;
- table columns, pages, groups, decorations, input fields, labels, buttons,
  extended tooltips, context menus, and dynamic lists;
- form module summary and routine/event/command link validation;
- source-aware display resolution for inherited captions:
  command title, form attribute title, value-table field title, and local
  form item override.

Every decoded scalar must carry enough evidence for future writes:
section, element identity, physical payload path, semantic group/name, current
value, value type, source, and verification rule.

## Test Extension Fixture Plan

Keep fixtures small and intentionally boring. Add form elements in
`ТестНастройки` or a sibling test form so each save isolates one concept:

- command button bound to `КомандаПример1`;
- local-only button title;
- element title inherited from a form command;
- element title inherited from a form attribute `А`;
- element title inherited from a value-table field `ТЗ.К1`;
- input field with visibility, availability, read-only, title location, choice
  buttons, quick choice, and text editing flags;
- group/page/table layout properties: parent group, order, stretch, width,
  height, command-bar location, and default item;
- color/font properties for label/button/input field;
- dynamic list with main table, custom query flag, query text, and columns;
- form events and element events with matching and missing BSL handlers;
- structural move/reorder cases inside one parent container.

Prefer one-property saves. Do not combine property, handler, and structural
changes in the same learning capture.

## Read-Side Commands

Decode a concrete saved-state form payload:

```powershell
python scripts/smoke_1c_write_matrix.py `
  --base-url http://docker.cin.su:8011 `
  --base-id upo_test `
  --table ConfigCASSave `
  --file-name <form-file-name> `
  --build-only `
  --report reports/1c-sql/upo_test/form-write-matrix-build.json
```

Read XML-backed form context for the test fixture:

```powershell
python scripts/get_1c_form_context.py `
  --index reports/1c-sql/upo/unified-object-route-index.json `
  --kind DataProcessor `
  --name фс_НастройкаУсловногоОформления `
  --form ТестНастройки `
  --view effective `
  --max-items 500 `
  --output reports/1c-sql/upo_test/form-context-test-nastroiki-effective.json
```

Adapter RPC equivalents:

```json
{"method":"metadata.form.decode","payload":{"base_id":"upo_test","table":"ConfigCASSave","file_name":"<form-file-name>","include_parameters":true,"max_items":5000,"max_parameters":500}}
```

```json
{"method":"metadata.form.write_matrix.build","payload":{"base_id":"upo_test","table":"ConfigCASSave","file_name":"<form-file-name>"}}
```

Build a decoder coverage and gap profile for an object form:

```powershell
python scripts/profile_1c_forms.py `
  --adapter-url http://docker.cin.su:8011 `
  --base-id upo_test `
  --kind Catalog `
  --name ЗадачиАссистентаУправления `
  --table Config `
  --raw-output-json reports/1c-sql/upo_test/form-profile-zadachi-assistenta-details.json `
  --output-json reports/1c-sql/upo_test/form-profile-zadachi-assistenta.json `
  --output-markdown reports/1c-sql/upo_test/form-profile-zadachi-assistenta.md
```

Compare decoded SQL form semantics with exported `Form.xml` semantics:

```powershell
python scripts/compare_1c_form_sql_xml.py `
  --sql-details reports/1c-sql/upo_test/form-profile-zadachi-assistenta-configsave-xmlmap-details.json `
  --xml-context reports/1c-sql/upo_test/form-context-zadachi-assistenta-list-effective.json `
  --output-json reports/1c-sql/upo_test/form-sql-xml-compare-zadachi-assistenta-list-xmlmap.json `
  --output-markdown reports/1c-sql/upo_test/form-sql-xml-compare-zadachi-assistenta-list-xmlmap.md
```

## Write Learning

For a manual one-property Designer change:

```json
{"method":"metadata.write_learning.capture_before","payload":{"base_id":"upo_test","learning_id":"form-visible-case","table":"ConfigCASSave","form":"ТестНастройки","element":"<element-name>"}}
```

After the Designer save:

```json
{"method":"metadata.write_learning.capture_after","payload":{"base_id":"upo_test","learning_id":"form-visible-case","table":"ConfigCASSave","form":"ТестНастройки","element":"<element-name>"}}
{"method":"metadata.write_learning.diff","payload":{"learning_id":"form-visible-case"}}
{"method":"metadata.write_learning.infer_rule","payload":{"learning_id":"form-visible-case"}}
```

Promote a rule only when the diff changes exactly one intended semantic value
or one intended structural relation. Composite/list rewrites need a dedicated
source-specific rule, not a generic scalar writer.

## Write Verification

Run the existing source-aware route smoke:

```powershell
python scripts/smoke_1c_saved_state_write_routes.py `
  --base-url http://docker.cin.su:8011 `
  --base-id upo_test `
  --table ConfigCASSave `
  --file-name <form-file-name> `
  --report reports/1c-sql/upo_test/saved-state-write-routes-smoke.json
```

Then run the matrix smoke:

```powershell
python scripts/smoke_1c_write_matrix.py `
  --base-url http://docker.cin.su:8011 `
  --base-id upo_test `
  --table ConfigCASSave `
  --file-name <form-file-name> `
  --max-candidates 50 `
  --learning-id upo-test-form-write-matrix `
  --report reports/1c-sql/upo_test/form-write-matrix-smoke-50.json
```

Successful writes must use `apply_and_rollback`, explicit SQL apply and
rollback gates, sha1 preconditions, backup evidence, semantic readback through
`metadata.form.decode`, and rollback verification.

## Promotion Gates

Read rule promotion requires:

- SQL-only decoder output with stable semantic name and value type;
- XML fixture agreement for the same form element/property;
- no dependency on display strings when a stable id/path exists;
- regression coverage on the test form and at least one real extension form.

Write rule promotion requires:

- exact physical payload path or structural span evidence;
- source-aware routing for inherited display values;
- `metadata.form.write_target.resolve` success with a deterministic target;
- `metadata.form.element.write_apply` or `metadata.write` success in
  `apply_and_rollback`;
- semantic verification and rollback readback success;
- registration in the scalar/enum/verified write matrix reports.

## Immediate Work Queue

1. Refresh the test form saved-state row for `upo_test` if
   `ConfigCASSave`/`ConfigSave` is empty.
2. Capture a fresh `metadata.form.decode` baseline for `ТестНастройки`.
3. Build a form property gap report: decoded SQL semantics versus `Ext/Form.xml`
   semantics from the test extension.
4. Learn the two remaining command binding cases with a one-property
   before/after capture: standard command button binding and local button to
   form command binding. Do not hard-code these from display names. Current
   captures and exact after-capture commands are in
   `docs/runbooks/1c-form-command-binding-learning.md`.
5. Expand `parser/form_payload.py` for the next write-relevant properties:
   availability, read-only, title location, command-bar location, colors, font,
   and dynamic-list query settings.
5. Rebuild the write matrix and split entries into verified scalar, enum,
   composite-needs-rule, identity/binding, and structural queues.
6. Learn one property at a time through
   `metadata.write_learning.capture_before/capture_after/diff/infer_rule`.
7. Promote safe scalar/enum routes into smoke coverage.
8. Add a structural movement scorecard for sibling reorder and parent/group
   movement, then extend `metadata.form.target.move` beyond sibling swaps only
   after controlled round-trip proof.
