# Application authoring

The same maintained guide available through berry guide applications.

Source: cd46e0e78d73497aec99e3e8d33c1fef632f36f9
URL: /reference/applications

Use gen_ui to load installed interface guidance when needed. Conversation and
graphical UI are independent optional interfaces. Ordinary rendering requires
no inference. The common WorkArea owns title and window actions; do not repeat
them in the page. Declare an interface offer; scope:session explicitly binds
session authority. A source export alone does not attach an interface.

Ordinary HTTP servers run as process services. Use runtime.service.start for continuing
processes, exec for finite commands and temporary checks. A service is kept
running through failures and restarts until runtime.service.stop and uses its
own recipient:{root,entry,limits}. A separate runtime.service.connect is scoped to
its execution, not durable ownership. Copy the exact prepared root.
For portable process code, capture the complete program directory with the
computer.retain_directory operation when granted. Pass its root reference unchanged
to runtime.service.start.program: {root, entry}. For a composition import, use the
receipt's root.$ref as the import address without an export field. Reference the
import with !ref, read it through load and pass the returned address reference as
program.root. A literal hash alone grants no read access. command supplies an
interpreter when needed; the captured entry becomes its first argument. Dependencies
must already be in the snapshot. cwd is separate mutable working data. The runtime
materializes the exact retained files for each launch without dependency downloads.
Program-content retention is not source-review evidence by itself. Include every
program file in the independent verification obligation, with exact snapshot
identity and recorded observations; block if the offered readers cannot inspect it.
For static HTML, package resources and use serve or an interface offer.
Use relative asset and API URLs (for example ./styles.css, not /styles.css):
the host mounts retained sites below a scoped path. Copy the complete current URL
from runtime.service.inspect, including its path and trailing slash. After replacement
or a host restart, read that observation again; an earlier port may be closed.
Ordinary local sites served with serve can load external fonts, styles, scripts,
images and APIs under normal browser rules. Do not remove a chosen dependency
merely because it is external. Restricted generated-UI publication profiles have
their own contracts. Diagnose the actual failing request and current page.
Mutable workspace commands remain useful for experiments but do not freeze code.

JSONL stdout frames contain exactly id and content. id is a nonempty string;
content is the actual JSON input, not a string containing JSON. Serialize the
whole frame once and append a newline. One connection selects one recipient.
Route an action field inside content when several operations are needed;
top-level method/entry fields cannot select another export.
stdin first reports accepted:{executionId}, then output or a terminal
{id,executionId,outcome}. Register HTTP waiters before sending stdout. Keep the
response open until outcome or expose receipt/outcome polling. Never invent
execution IDs or embed the owner bearer token in a process or browser.
Finite recipients create fresh invocations; execution recipients address a
retained input port. Code uses context.receive() and context.emit(value).
Resident waiting needs no inference.

Object fields named base64 are not automatically model media. Preserve real
uploaded bytes and MIME types, sending native media parts to capable models.
Keep large media in durable files and bounded records, not an ever-growing
base64 array in one State value. localStorage alone does not establish
runtime-owned persistence across clients.

For editable data, use one application mutation boundary for human input, model
results, imports and background updates. Each accepted change identifies the
record and revision it read, preserves unrelated fields and commits the new data
and any required undo history together. Determine the editable fields from the
user's operation before generating their values. A model may interpret an
ambiguous request, but its generated replacement must not grant itself more
fields to change. Use a patch restricted to that scope, not a regenerated whole
record. Keep exact supplied values outside generation; an omitted field retains
its original bytes, including manual text, empty values and formatting. Reject
out-of-scope fields before saving. The checked `scoped_edit` example in
`native_examples` demonstrates this admission in ordinary application code.
An asynchronous result cannot silently overwrite newer edits or a different
selected record. Revision comparison and persistence form one atomic operation:
two writes based on the same revision cannot both succeed. Reuse State's versioned
write when it owns the data. A file-backed application's existing store must
serialize the read, revision check, mutation and durable write for each record;
locking only the final rename is too late. An atomic file replacement prevents a
partial file, not a lost update. Missing or invalid expected revisions must not
disable this check. If the operation permits retrying a version conflict, read
current state and re-evaluate its business conditions before committing. Merely
updating the version or merging data does not validate the earlier decision:
another writer may already have completed the claimed action. Keep the last accepted
document on failure. Undo/redo, when required, follows accepted changes from every
producer, not just input-field events; replay uses the same save/version rules.
Stage the next document and its history without modifying the live record;
publish both only after the write succeeds. A failed write must leave the live
document, revision and history cursor unchanged. Do not replace unreadable saved
data with an empty document and then autosave over it; report the read failure.
Observe a mixed human -> model -> undo -> redo sequence with exact before/after
values. For asynchronous mutations, submit two changes from the same revision
concurrently and verify that at most one commits; a conflict retains the accepted
data and history. Test record switching while a save is queued when concurrent
editing is part of the contract. These are application responsibilities over ordinary storage
and process operations, not additional runtime execution types.

A value the user marks as exact never passes through a model. Extract it in
code before any inference with the checked `exact_values` example of
`native_examples`: a quoted string, or the text after "exactly:" up to the end
of its sentence without the sentence's final period, applied verbatim; let the
model produce only the rest. A delivered application honored "to exactly: A
better launch plan." once and then wrote "Ready after restart." with the
period, failing an explicit exactness requirement.

Show progress and errors in empty, loading and populated states. Use accessible
labels and revalidate assets or use immutable URLs during iteration. Keep the
native role of every interactive element: a button given another role, such as
listitem or tab, stops being a button to assistive technology and automation.
Put list or grouping semantics on a wrapper element instead.
Verify edits with before/after data, undo with restored values, and exports
with actual downloaded bytes. Successful clicks and HTTP status are insufficient.
Verify a page journey with one browser.run_code script run whole; it accepts
dialogs and uploads workspace files through setInputFiles. Automated checks must
not require the user to dismiss dialogs. Inspect actual
pixels after the final revision for visual requirements. A capture limitation
does not authorize taking user focus or pretending that the screenshot exists.

## Embedded presentation is part of the application contract [#embedded-presentation-is-part-of-the-application-contract]

Berry displays a process's HTTP UI in an isolated iframe on another local origin.
A server header Content-Security-Policy: frame-ancestors 'self' or X-Frame-Options:
SAMEORIGIN/DENY blocks that UI even when standalone navigation and HTTP requests
work. For a local application use an explicit frame-ancestors allowlist covering
its Berry client, such as http://127.0.0.1:* http://localhost:*. Keep the other CSP
restrictions appropriate to the application's own assets; do not remove security
headers wholesale or grant the embedded page owner credentials. Scope this to
local presentation; remote deployment requires its actual client origins.
Check the response headers and test a real cross-origin embedded page before
claiming that the UI works in Berry. Standalone browser.navigate is insufficient
for frame policy. Observe console/network errors and pixels, not only DOM text.
An application can show useful empty/loading/error states before inference returns.
The embedded work area is often narrower than a standalone browser window: its
width can be well under 1100 CSS pixels beside the client's own navigation. Keep
the primary panes of a multi-pane application usable side by side at about 900
CSS pixels, and collapse to a single column only below that. A layout whose
editor and chat fall far below the fold in the embedded view does not satisfy a
request to work with them beside each other. Panes must never overlap at any
width: lay them out with grid or flex, give every pane `min-width: 0` and its
own scrolling, and position nothing absolutely over a neighbouring pane. A
control that another element covers cannot be clicked, even when it looks
enabled; a disabled field lying over the Send button failed an otherwise
working application at the embedded width.

The app must be operable at the current stage of development. Leave its exact
candidate service running for independent verification. Stop obsolete services
only; do not clean away test evidence or the only running candidate. Report its
exact service ID and URL. Starting a routine does not start its process or attach
an HTTP interface. A JSON manifest packaged as a resource is inert data unless
some declared executable path actually consumes it.
Service desired state controls recovery: runtime.service.stop records desired: stopped,
and nothing restarts a stopped service. Retained stopped records are history,
not competing running applications.

Before starting a continuing resource, decide its purpose and end condition:
delivery, temporary verification, a separate user-requested copy, or replacement
of an exact earlier service. Keep service IDs and finite exec session IDs with
their purpose in your work notes and checkpoint report. A name, port, executable
or program root alone never proves that two runs have the same purpose or data.

Use runtime.service.replace with the exact old id and complete new start configuration
when revising that same application and a brief interruption is acceptable.
The owner validates, stops and joins the old resource, then starts the new one;
the receipt identifies the successor. Invalid configuration leaves the old run
alone. Failed startup after a confirmed stop does not roll back automatically.
Inspect the recorded result. For uninterrupted comparison, start a separate copy
with its own port and data, verify it, then stop the exact superseded service.
Use ordinary serve/runtime.service.start for an independent copy; never replace another
task's service because it runs the same code. If runtime.service.replace is unavailable,
perform that explicit stop/start sequence with the available Tools.

Run a temporary verification server as an exec session with its own port, data
location and timeout, not as a service, which would be kept running. Terminate
it as soon as that check finishes, including failed checks, and confirm it
exited before deleting its disposable data. A finite exec session is
continued through computer.write_stdin; terminate:true stops it when no further step needs
it. A yielded Tool call, closed view, or completed builder round does not stop
an independent resource. At every report/checkpoint inspect your own receipts:
stop probes that have served their purpose, retain the candidate and requested
background work, and record why any still-running temporary resource is needed.
Unconfirmed termination remains a limitation to resolve, never a successful
cleanup. Preserve original History evidence and unrelated resources.

## Complete process bridge example [#complete-process-bridge-example]

The server uses ordinary Node IO. Reserve stdout for frames, stderr for diagnostics.
Register the pending request before writing; one id identifies one request. The
accepted frame is not an HTTP success payload. Handle rejection, failure and
unknown terminal outcomes. The application owns durable request records and
recovery; restarting a process does not replay lost in-memory Promises safely.
Retain the admitted executionId beside the application's own request identity
and terminal result. Make that correlation inspectable through the application's
ordinary diagnostic/data interface without exposing credentials. A request can
then be investigated without rerunning it; runtime.thread.read and runtime.execution.observe
provide the corresponding permitted runtime observations.

```javascript
import {createInterface} from 'node:readline';
import {randomUUID} from 'node:crypto';
const pending = new Map();
const lines = createInterface({input: process.stdin});
lines.on('line', line => {
  let message;
  try { message = JSON.parse(line); }
  catch { console.error('Invalid runtime reply'); return; }
  const request = pending.get(message.id);
  if (!request) return;
  if (message.accepted) {
    request.executionId = message.accepted.executionId;
    return;
  }
  if (!message.error && !message.outcome) return;
  pending.delete(message.id);
  request.resolve(message);
});
export function invoke(content) {
  const id = randomUUID();
  return new Promise((resolve, reject) => {
    pending.set(id, {resolve, reject});
    process.stdout.write(JSON.stringify({id, content}) + '\n', error => {
      if (error) { pending.delete(id); reject(error); }
    });
  });
}
```

invoke returns the whole terminal frame, including a refusal or a non-completed
outcome. The HTTP handler must persist that frame with its application request,
check error and outcome.status, and only then use outcome.content as a successful
application value. Keep executionId in the diagnostic record; do not discard it
while translating the reply into UI data.

This finite snippet explains correlation; a production server must also resolve
outstanding waiters on stdin closure and implement the requested persistence and
cancellation policy. Do not resend an uncertain request under a new identity.

## Packaged interfaces and HTTP sites [#packaged-interfaces-and-http-sites]

The manifest interfaces field follows the shared InterfaceOffer contract. The index names a retained
resource URI. The associated entry and action entries must be public callable
exports. scope: session requires entry and attaches to that exact session;
otherwise the offer is standalone. Export association alone is not attachment.
Actions name finite handlers with explicit uses and limits. Session state and thread input
or publication updates require the corresponding access declaration and granted
Tools. Conversation plus a declared interface uses the common auxiliary dock;
a UI-only application uses the main region. No second title/header is needed.
Use gen_ui for the installed renderer's bridge contract before writing an offer.
To attach an HTTP service view, the application's own invocation calls serve or
runtime.service.start with scope: session. The runtime resolves that admitted call's
stable session; input never supplies an arbitrary session ID. Conversation uses
the auxiliary dock and a graphical-only session uses the whole workspace. Omit
scope for independent services, including builder-owned tests. Attachment grants
no new capabilities and does not couple stopping the service to closing its view.

serve uses packaged resources and exposes declared exports through its scoped
HTTP API. runtime.service.start runs a real executable and can connect stdout/stdin to a
finite prepared export. Use the path requested by the user; do not replace a
required process chain with a mock, direct provider call or static fake response.
A prepared root binds authority and models; a service ID identifies lifecycle;
an executionId identifies one request. Keep these values separate and exact.
