# Layout editor Runtime integration and product UI acceptance

Current checkpoint: Core #4774 is merged and #829 is Ready for review. The
new-layout route and return-after-completion defects are fixed and verified in
the complete product UI at `ae71fd27ddb797432277b329801507d35d6d67e7`;
the alleged signed-source mismatch and opaque-section loss blockers were
independently disproved. See the final sections for evidence. Earlier Draft and
sequencing statements below describe historical checkpoints, not current status.

The delivery is one reliable Layout edit: save the document and ordered list
fields atomically, read back the exact published result before reporting success,
and retain the original command identity through an uncertain response. SFCRM
exposes workspace/stored/submit/status; Runtime owns authorization, durable
execution and publication. The frontend does not write Layout records directly.

## Ownership and the confirmed fixes

- API Host #112 removes an exactly rejected cached SECURITY_EPOCH delegation.
  The next request acquires a fresh credential; the client does not replay writes.
- Controlplane #441 reads the activated App operation's existing immutable
  metadata selection. Direct producers must commit it before serving advances,
  and activation rechecks it. Existing omissions use the existing same-release
  refresh, with preflight and recovery documented by that owner.
- Core #4770 supplies the already-open snapshot store and selects these owner
  dependencies. It is based on main after #4769 and #4771.
- App-packs #829 owns the neutral document codec and Setup/Studio/Manager UI.
  No new serving mode, global publication pointer, history index or full Layout
  graph co-publication is needed.

A logical editor owns its draft, modal and save-result state. Setup, Studio and
Manager create a keyed component instance for each object/layout context; an old
callback can update only its original page and captured query key. Explicit
reload/save completion resets the complete draft even when the query cache keeps
an unchanged document reference, including separately changed list columns.

A signed-in CRM session owns each logical editor's browser command attempt through
`layoutCommandSession`. All three surfaces use this owner instead of component
refs. Navigation preserves unresolved command identity; concurrent checks share
one active promise through exact readback. Session clearing aborts further work
and removes the attempts. Runtime remains the only durable journal. These attempts
are not persisted across browser reloads; the unload warning also covers a pending
operation after navigating away from its editor.

## Earlier verification on 2026-09-03

Final local code gate: the exact unmodified CI source-test command passed all
117 files / 1,068 tests in 34.56 seconds. The independent package compiler and
its self-test also passed. Product frontend build and final recovery browser
checks passed at `0cf0eb6`; subsequent edits affect only declarations and docs.

- API Host #112 and Controlplane #441 are merged and released as `v0.38.15`
  and `v0.2.110`. Core #4770 merged as `9acfecf20631f89d1d8b62bdaeaa5d7a3f7e5a33`.
- The full frontend source suite passed: 117 files, 1,067 tests in 53.36 seconds
  at `76c1e62ad39da08a1c4b35a6f59371230e24ba28`, with `--testTimeout=10000
  --maxWorkers=2`. An earlier concurrent-build run timed out in two unrelated
  dynamic-import tests; both passed with the same timeout after the build ended
  (2 files / 6 tests, 5.88s). No test assertion or timeout was weakened.
- A subsequent error-feedback cleanup passed the relevant complete batch:
  command runner, actual Query/Router editor lifecycle and Manager tests,
  3 files / 18 tests in 4.99 seconds at `0cf0eb6`. The new regression verifies
  an assigned-layout delete failure followed by a successful assignment
  correction clears the old error and leaves deletion available.
- The actual Core `scripts/test-layout-runtime.sh` passed in 123.60 seconds at
  `479945bd18e8bdd3a343a3be3549ba8b1f6f4baf`, using published owner tags,
  `GOWORK=off -mod=readonly`, separate SFCRM, real TLS and isolated local TiDB.
  Nine successful publications reached revision 10, with business failures,
  exact readback/replay, AppMetadataV3 and unchanged-config SFCRM restart.
  Core #4772 carries the message-only follow-up rebased onto merged #4770;
  its complete Git tree is byte-identical to that tested candidate.
- Lifecycle regressions use actual React Query and Router. They cover explicit
  reload with structural sharing, list-only changes, coalesced checks, route
  unmount/remount with exact command reuse, session cancellation and late A
  results while the real Studio component edits B.

## Product UI acceptance

The real Core production frontend runs at local port 5223 with its standard
entry, Router, original L1 CRM shell/components and CSS. Browser login uses the
normal password grant and identity verification. Backend calls go through real
SFCRM HTTP → Runtime TLS → durable workers → TiDB/Catalog. Temporary test
provisioning supplies minimal Layout objects, Connected App, AppConfig and
normal permissions. There are no API doubles or replacement UI shells.

Observed in that full product frontend:
- Setup save, publishing state, successful exact readback and persistence after
  full reload and in a second browser tab.
- Two-window stale save rejection preserves the competing draft; explicit
  reload loads the winner. Document and ordered list columns save together.
- Studio save of object A completes after navigating to B; B's unsaved draft
  stays intact. Reopening A reads its stored section label.
- Layout Manager clone, profile assignment, default switch and restore,
  protected deletion, assignment removal and subsequent successful deletion.
- SFCRM process restart with unchanged configuration preserves normal reads.

The browser found two related presentation defects: every conflict was being
rewritten as a stale-version message, and a successful assignment correction
left the previous deletion error visible. The frontend now preserves the owner
reason and clears resolved action errors. Core #4772 supplies actionable owner
messages for version/default/assignment conflicts with the existing error type.
No permission, publication or deletion guard was removed.

Fixture findings are not product defects: a generic test App ID cannot bootstrap
CRM navigation; Profile's private sharing needs the administrator's normal
ViewAllRecords grant; an inactive selector profile is still resolvable by the
explicit current contract (an inactive actor cannot administer). The normal
production build works; a separate development-preview auth-registration issue
was observed and remains outside this Layout acceptance.

This is Layout-focused acceptance in the complete product frontend with minimal
isolated metadata. It is not acceptance of all CRM features, production tenant
metadata, OCI publication or a tenant deployment. Old component-only port 5221
is not this product environment.

## Merge order and release boundary

Core #4772 has also merged. The subsequent create-context review found the
additional prerequisites described below; #829 remains Draft until those land.
The complete product browser recovery recheck passed at frontend `0cf0eb6`: the
assigned-delete message appears, correcting the assignment clears it, and deletion
then succeeds. The former draft-only review gate was sequencing, not a runtime
failure. No PR was merged by this agent.

The independent package compiler initially rejected the new error reset calls
because its handwritten React Query declaration omitted the real dependency’s
`isError` and `reset` members. Those declaration members now match the installed
dependency; the isolated build and its self-test both pass. Product runtime code
and the already completed browser evidence are unchanged by that declaration fix.

The checked-in 0.69.0 AppPackage metadata closure was built from `e65510f`, with
seal `sha256:9b9d3d1e7148df2b1df406829f4b196063e358cff9faf6fe8891ee7a79dbe8f3`.
That seal does not establish publication of a frontend image of these fixes.

## Reproduce the service slice

Build `appservices/sfcrm/cmd/sfcrm-appservice` with
`GOWORK=off go build -mod=readonly -o <absolute-sfcrm-binary> ./cmd/sfcrm-appservice`.
In Core, set isolated local `TIDB_HOST`, `TIDB_PORT`, `TIDB_USER`, and
`NEXUSCRM_LAYOUT_SFCRM_BINARY=<absolute-sfcrm-binary>`, then run
`scripts/test-layout-runtime.sh`. Without the SFCRM binary input, this runner's
Runtime-only topology is not evidence for the application HTTP path.

## Create-context root fix

The review after the earlier UI pass found two missed checks. The release builder
still asserted the pre-Layout capability lists in three places. More materially,
the StoredLayout migration dropped the server-owned `createRequiredFields` used
by both preview buttons and required-field guidance. Saving succeeded, but initial
and post-save reads could never enable the previews. The earlier browser journeys
had not exercised those buttons.

The fix keeps one Records-owned static create-input predicate. Catalog applies the
same AutoNumberRule-derived defaults as the actual mutation view before computing
requirements. Its immutable authoring view carries read-only create context outside
the writable Layout document and all Layout resource/aggregate/workspace versions.
The existing AppMetadataV3 producer gets the same requirements from its compiled
effective source. SFCRM projects them into both the StoredLayout DTO and actual
Create layout handling. The frontend uses one mapper for initial, post-save and
uncertain-response readback; it neither derives rules nor writes the context back.

This matters for a required string field with an AutoNumberRule: raw schema reads
do not contain its server-derived default bit. Sharing a predicate without sharing
that effective stage would still falsely ask the user for input. Read-only Catalog
publications therefore also read the authoritative rules in their existing source
transaction, without loading unrelated mutation metadata or adding request-time
queries. No cache, RPC, history index or serving mode is introduced.

Unknown old context stays absent; a known empty set is explicitly `[]`. Historical
Catalog/View bytes remain supported. New object-search format 6 carries the list;
old format 5 remains readable for View/Edit, while new Create/defaults/clone needs
format 6. Old SFCRM does not accept format 6, so producer and consumer must be
promoted as a selected compatible release tuple. Neither side alone is a completed
rollout. Contract PR214 is the first prerequisite, followed by the Core/Controlplane
producer work (Core #4774 and Controlplane #443) and this L1 consumer PR.

The actual form does not inject omitted required fields. Earlier guidance that
claimed automatic insertion was removed; the editor identifies missing requirements.
The actual Create projection retains its existing rule that a caller-required field
already in the layout cannot be hidden, while server-defaulted fields may remain
hidden. No new field injection behavior is claimed.

The new frontend regressions cover known, empty and absent context on initial load,
post-save readback and uncertain-response recovery. The exact CI source-test command
passed 118 files / 1,076 tests, without timeout or worker overrides. The full release
builder passed with all three stale assertions corrected. Contract validation now
uses the existing 3 MiB response budget for a whole-object list; a section's 1,000
field limit is not reused as an object limit. The full contract gate, 1,100-field
protobuf roundtrip and 1,001-field Catalog regression passed. The new SFCRM module
suite and complete product frontend build passed using the published contract pair.

The final candidate used Core `ee2f7a056`, Controlplane `04a307d30709`, contract
root `38246b90d937` / wire `ceacbf47cfc5`, and L1 service/frontend `94c0e215f0fe`.
All module builds used `GOWORK=off -mod=readonly`; no temporary workspace replacements
were used for the final services. The Core committed test ran through real entrypoints
with a temporary browser overlay that adds normal login/navigation fixture metadata
and holds only after every formal HTTP and restart assertion has passed.

Final real-service result: `TestLayoutRuntimeProductionTransportRealTiDB` passed
in 303.50 seconds including the browser hold. Nine formal publications reached
revision 10; exact readback/retry, business failures, initial/current AppMetadataV3,
and an unchanged-config SFCRM restart passed. The actual Create endpoint showed
required `Name`, kept required-with-default `Defaulted` and autonumbered-string
`Numbered` hidden, and preserved the authored Edit hiding. StoredLayout and
AppMetadataV3 both reported exactly `Name` as initial user input.

The full product browser then verified normal login; enabled Create/Edit previews;
`Name` marked required in Create, with defaulted/numbered fields hidden; all three
fields hidden in Edit as authored; a real layout-name change through publishing and
successful exact readback; unchanged previews after save and full reload; and a
second unchanged-config service restart followed by successful UI reload. A second
object with an explicitly empty requirement list also allowed both preview modes.
Screenshots and DOM records accompany the local candidate evidence. These new checks,
not the earlier browser pass, prove the create-context correction.

Contract #214 merged at `b649e8d1332b43ba21035190d549d3942eaab847` and is
published as root `v0.6.4` and `wire-go/v0.3.3`. Its merge tree is identical to
the verified PR head. Core and SFCRM now select those formal versions; Controlplane
selects root `v0.6.4`. With `GOWORK=off -mod=readonly`, the full Catalog snapshot
package, Runtime Layout tests and entire SFCRM module passed again. Controlplane's
three Catalog owner packages also passed after merging current main and retaining
its connector dependency update (0.572s / 0.869s / 1.085s).

Controlplane #443 merged at `a6bbd96062779a540ba24cdeb751810eb49e8bec` and
is published as `v0.2.112`, from the same tree as its reviewed head. Core backend
and distributions now consume this formal version alongside contract `v0.6.4`
and wire `v0.3.3`, retaining current main's connector `v0.2.20`. Both release-pin
and standalone-workspace pin guards pass. Four internal module declarations were
also synchronized with their actual selected contract version; independent
compilation passed in analytics, automation, files, records and distributions.
Runtime Layout tests passed again (API 0.665s / worker 0.915s).

The plain committed runner exposed a fixture omission: its generic test
application was installed while SFCRM was launched. The earlier browser setup
script selected the CRM application, so that pass had not proved the standalone
runner's setup. The shared fixture now accepts an explicit application ID, and
the SFCRM topology selects its real application and derives capability IDs from
it. The Runtime-only default remains generic. No application identity validation
or product error mapping was changed.

At Core `2a4f53732`, `scripts/test-layout-runtime.sh` passed in 98.49 seconds
using the unchanged SFCRM binary from `f0e542b02` and the formal module versions,
without a Go overlay or browser preparation. Nine publications reached revision
10; exact readback/retry, actual Create/Edit requirements/defaults/autonumber
behavior and unchanged-config SFCRM restart passed. Core #4774 is next for review
and merge; this L1 PR stays Draft behind it. This is local real-service proof,
not a new browser acceptance run, tenant deployment or OCI publication.

### Write-protection compiler consistency

Core review identified an accepted raw-input case missed by the earlier matrix:
a required field could declare `Createable=true` while its write-protection policy
made it unavailable to callers. Mutation narrowed that capability, but Catalog's
new create-input derivation did not. The current production database reader already
performs this narrowing, so the finding establishes a compiler consistency defect,
not a reproduced current UI failure.

Core `a9e666e6bd0967da7e8a398750653f0dc888df35` applies the existing write-protection
policy to copied fields in the same effective preparation that derives autonumber
defaults. StoredLayout context, source validation and the effective component used
by AppMetadata now agree with mutation for raw as well as normalized input. This
adds no live query or separate source of truth and preserves authored Layout bytes
and all Layout write versions.

The complete Catalog package passed in 1.346s, including 42 combinations of policy,
declared capability and default source, plus policy changes across revisions. Runtime
Layout tests passed (API 0.515s / worker 0.711s). The committed real TiDB/TLS/SFCRM
runner passed in 98.21s without an overlay, using App-packs `e90d62a9c3015db5b7a6ab314a32e2d486cdb86a`
and the formal dependency versions above. Its database fixture now includes required
trusted-only and authority-only fields. Nine publications reached revision 10;
exact readback/retry, initial/current context, actual Create/Edit behavior and
unchanged-config service restart passed. Only caller-supplied `Name` was reported
required; defaulted, numbered and protected fields remained hidden in Create.

Valid historical artifacts remain readable. The earlier artifact probe also showed
that corrected source validation rejects a pre-fix source artifact containing raw
protected `Createable=true` and contradictory required context. Standalone historical
Runtime views remain readable; no current production source path was found to emit
the contradictory source artifact. The published standalone Controlplane `v0.2.112`
does not contain this new compiler patch; its current database reader already
normalizes write policies. Core uses the corrected local metadata implementation.
Core #4774 remains Ready for review, and this L1 PR remains Draft behind it. This
verification adds service coverage and does not claim a new browser or deployed UI
acceptance run.

### Core merged; L1 ready for review

Core #4774 merged as `7ea22feea33a6de56a20f73aa9694f4a34b8d988`. Its tree is
identical to the locally verified `b30686d016b8f00f1060b67391d280bcd895a1f8`, and
both PR checks passed. Core's main build/release pipeline is separate from merge
acceptance and was still running at this checkpoint.

App-packs candidate `a365d32b6d600ec559e274504cf0b1127546b8eb` merges main
`64216bc` (#822 and #833). Two SFCRM dependency-file conflicts were resolved by
retaining main's contract root `v0.6.5` and this PR's wire `v0.3.3`. The activity
feed and permission-editor changes from main are retained. These module pins are
client build inputs, not a requirement that L0 and L1 services share a source SHA.

The complete SFCRM module passed (service 1.681s / command 0.610s); the complete
release-builder package passed in 164.810s. Frontend source-manifest validation,
independent package compilation and its self-test passed. The unmodified complete
frontend test command finished with 119/120 files and 1,097/1,098 tests passing.
The remaining failure is the existing search-object-icons first-import test's
5-second timeout. Its test and production source are unchanged from main, and an
isolated checkout of exact main `64216bc` reproduced that same timeout using the
same installed test dependencies. The other initial timeout, app-launcher navigation,
passed in isolation and on the final complete run. No test timeout or worker setting
was changed. All Layout cases passed. This is a recorded baseline test-stability
follow-up, not a claim that the latest complete frontend suite passed.

The committed real-service runner then used exact merged Core `7ea22feea` and a
newly built SFCRM binary from `a365d32`. It passed in 116.40s: nine publications to
revision 10, exact readback/retry, current AppMetadata/StoredLayout, required/default/
autonumber/protected-field Create/Edit behavior and unchanged-config service restart.
No Go overlay was used. Candidate identities, binary hashes, baseline comparisons
and complete logs were recorded locally under `/tmp/layout-root-fix/app-ready`.

The previous review's release-capability assertion and lost-create-context findings
are corrected in the current tree. #829 is now submitted as Ready for review; the
old verdict was on `8df5262` and is not approval or rejection of this candidate.
CI/review still determine merge readiness. After merge, select compatible published
L0/L1 artifacts through the L2 delivery workflow and verify the deployed UI. No
tenant deployment or new browser acceptance is claimed by this checkpoint.

## Reopened evidence: new-layout identity after publication

Review [5527427438](https://github.com/pingcap-inc/nexuscrm-app-packs/pull/829#issuecomment-5527427438)
raised two distinct claims against `9ae95b2`. They have different dispositions:

- The signed metadata release mismatch is not reproduced. The existing current
  release/source-tree test and attested `0.69.0` rebuild both pass. The release CLI
  rebuild produces exactly the committed 378,346 bytes, and signature verification
  passes. Current and attested source inputs both hash to
  `sha256:d924b26e29729b07a55c8ce60610ba7ba02f2ccae0b6fcf7d58e47e2d6ecc409`;
  the artifact remains
  `sha256:9b9d3d1e7148df2b1df406829f4b196063e358cff9faf6fe8891ee7a79dbe8f3`.
  The builder owns the hash of 78 declared pack/metadata/command inputs, excluding
  frontend sources. The review's `38d223...` value could not be reproduced with
  that algorithm. Its calculation is unknown; no replacement signing, publication
  mechanism or same-source-SHA gate is justified. This frontend-only fix changes
  none of those inputs or the signed artifact.
- The new-layout route defect is real and blocks a reliable new-layout editor.
  Successful publication updated the hook's data, but left the route at `new`.
  Reload/remount therefore initialized another draft; a later save could create
  another layout. The first saved layout was not deleted. The earlier browser
  acceptance covered existing-layout edits but missed this new-to-stored transition.

The root owner is the L1 editor route lifecycle. The existing shared completion
path now exposes the exact published layout ID as mount-local state. The currently
mounted keyed Setup editor replaces its `new` route with that ID after readback.
Both Save and Check pending save use this path. An old cached new-page result
cannot trigger navigation, and completion after leaving the editor cannot redirect
another page. Back does not return to the completed new draft. Studio and Manager
retain their existing navigation; no backend, command-journal, cache-key or read
protocol changes are needed. The normal stored route uses its existing read path;
there is no new polling, database query mechanism or persistent identity registry.

Evidence for code commit `7288986e48e5904de9eab45b9a165c45cf57cd81`:

- A new actual-LayoutEditor/React Query/Router regression first failed on the old
  implementation: the expected stored-ID route remained `new`. This changes the
  observation boundary from the previous hook-only reproduction to the real page.
- The owner batch passed all 22 cases across create-route, editor-session and
  create-context tests. Six new cases cover create/reload/update/remount, history
  replacement, uncertain-response recovery, delayed exact readback, unmount during
  readback, and old-cache/rejected-create isolation. They assert the single stored
  identity and command reuse, not merely the presence of a navigation call.
- Source-manifest validation, isolated package build/self-test and the full Core
  production frontend build all pass. The unmodified full frontend test command
  passed 120/121 files and 1,103/1,104 tests. The sole failure is the same existing
  5-second search-object-icons first-import timeout already reproduced on exact
  main `64216bc`; no assertion, timeout or worker setting was weakened.
- The current Core real TiDB/TLS/Runtime/worker/SFCRM integration test passed in
  426.63 seconds including the browser hold. Its temporary test-only overlay adds
  ordinary browser login/navigation metadata and holds after all current formal
  HTTP/publication/retry/create-context/restart assertions. It does not replace
  application calls or drop the protected-field cases. Core was merged `7ea22feea`;
  the unchanged SFCRM service binary was built from `a365d32`.
- The production frontend was built with explicit L1 revision `7288986e48e5904de9eab45b9a165c45cf57cd81`
  and tested through normal login at local port 5225. New-layout Save showed
  Publishing, then changed `/setup/objects/LayoutUpdate/layout/new` to the created
  ID. A full browser reload retained the name; a second edit reported successful
  publication under the same ID. A fresh browser tab read the updated name under
  that same ID. Screenshots and DOM records capture the created and remounted pages.

Local logs and screenshots are in `/tmp/layout-root-fix/new-route-fix`; the
independent release proof is in `/tmp/layout-root-fix/review-829-latest`. The
browser/service fixture was released after acceptance and the preview stopped.
This is local Layout acceptance in the complete product UI with isolated metadata,
not a tenant deployment or a claim that the entire frontend suite is green.

Reproduce the focused frontend batch from this repository:

```sh
npm --prefix frontend run check:frontend-app-package-source-tests -- \
  ../salesforce-crm-standard/frontend/source-tests/layout-editor-create-route.test.tsx \
  ../salesforce-crm-standard/frontend/source-tests/layout-editor-session.test.tsx \
  ../salesforce-crm-standard/frontend/source-tests/layout-authoring-create-context.test.tsx
npm --prefix frontend run check:frontend-app-package-build
npm --prefix frontend run check:frontend-app-package-build:self-test
```

Reproduce the signed-release checks from `tools/crm-app-release`:

```sh
GOWORK=off go test -mod=readonly . -run '^TestCurrentCRMReleaseMatchesCommittedArtifactAndSourceTree$' -count=1
GOWORK=off go test -mod=readonly . -run '^TestPublishedCRMReleasesRebuildFromAttestedSource$/^0.69.0$' -count=1
```

## Reopened evidence: returning after create readback

Adversarial review [5528986138](https://github.com/pingcap-inc/nexuscrm-app-packs/pull/829#issuecomment-5528986138)
identified one new lifecycle window and repeated the opaque-section claim.

The lifecycle finding is valid. If an admin started a new-layout save, navigated
away during exact readback, waited for completion and used Back, the original
component's `savedLayoutId` no longer existed. The session runner had also cleared
the completed command. The returned `new` route therefore synthesized a fresh
draft and could submit a second create. The earlier regression correctly proved
that an unmounted editor cannot redirect the current page, but stopped before
returning to that same history entry.

The fix gives each `/layout/new` browser history entry its existing Router
`location.key` as its logical editor identity. The current browser command runner
can retain a successful, exactly read-back result until that same entry consumes
and acknowledges it. While unconsumed, the editor remains read-only. Returning to
the entry hydrates the normal Query data and replaces `new` with the stored layout
ID. A separate deliberate `/new` navigation has a different entry key and therefore
receives a new runner and draft. Runtime remains the durable journal; this is the
existing browser-session attempt state, not metadata authority. Nothing is added
to a database, service protocol, global recent-layout map or request-time read path.
Full browser reload recovery remains outside the explicitly session-only attempt
contract.

The old implementation was reproduced at the actual LayoutEditor/React Query/
Router boundary: returning stayed on `/new`, and another Save issued a second
create with a different ID. After the fix, the relevant three-file owner batch
passed 25/25 tests in 4.15 seconds. The three new regressions prove same-entry
recovery, that a deliberate second new history entry stays independent, and that
direct navigation between two `/new` entries resets the entire editor session.
Source-manifest validation, isolated package build/self-test and the full product
frontend build pass. The unmodified full frontend suite passed 120/121 files and
1,105/1,106 tests; its sole failure is the already reproduced exact-main 5-second
first icon import timeout. All Layout tests pass without timeout or worker changes.

The complete product UI was built from `ae71fd27ddb797432277b329801507d35d6d67e7`
and tested through normal login and real SFCRM → Runtime → worker → TiDB calls.
During a new LayoutCreate publication, the browser navigated to Setup before
readback completed. After completion, browser Back landed on
`/setup/objects/LayoutCreate/layout/5e8aae5a-e552-49a1-83e2-5fc9d057a5a0`
with the saved name, rather than a blank `new` draft. A subsequent name change
published successfully under that same ID. Independent review then found that
two direct `/new` history entries also needed to remount the whole editor, and
that completion consumption needed to be atomic. Both refinements are in
`57cb056e4b117fe7096ade40b25dfe487735259e`; the 25 owner tests and complete
product build pass at that exact candidate. Screenshots and DOM records are in
`/tmp/layout-root-fix/review-829-return-after-create`.

The current formal real-service runner also passed in 210.62 seconds including
the browser hold. All nine existing publications reached revision 10; exact
readback/retry, Create/Edit requirements and unchanged-config restart assertions
ran before browser acceptance. Its overlay only supplies isolated login/navigation
metadata and the hold; production frontend and service calls are unchanged.

The repeated section claim remains outside current truth. Contract v0.6.5 has
eleven typed LayoutSection JSON fields and the codec maps all eleven. Real SFCRM
HTTP create/update probes accepted supported fields and opaque configuration with
202 and one Runtime call; an invented section property was rejected with 400 and
zero Runtime calls. Current producer documents preserve all fields and app-owned
configuration through edits. An arbitrary TypeScript index signature is not a
promise that the typed semantic, wire and HTTP contract admits future structural
properties. No production change was made for that hypothetical case.
