rastrillo / native Public

Prefer native platform behaviour in companion apps

Shared logic should not flatten the menus, links, contextual actions and navigation people expect. Explain a native-first approach, selective hybrid surfaces and shared app semantics without implying that a dual-target compiler already exists.
Paul Campbell pushed by paul@keymail.dev e6520f10a71d60220cddc706d533b550dcede3a7 parent f8b282f
3 files changed, +95 −2
  • README.md +6 −2
  • SKILL.md +29 −0
  • docs/app-architecture.md +60 −0

CI passed — run details

diff --git a/README.md b/README.md
index 4bdebe9..7eaf6e6 100644
--- a/README.md
+++ b/README.md
@@ -44,8 +44,12 @@ bundle identifiers, and add your app's screens. Run `xcodegen generate` in
the copied directory and open `Companion.xcodeproj`. Sign with your own team
for physical devices or distribution.
-Use native platform views for navigation and controls. A webview can reuse
-an existing web screen where that suits the app. Bind shared Go logic only
+Prefer fully native UI so navigation, menus, contextual actions, links and
+accessibility meet the platform's expectations. For a complex app, keep a
+native shell around selected webview screens. A shared app manifest can
+describe destinations and commands for separate web and native renderers;
+that is a possible architecture, not a compiler supplied by this kit. See
+[docs/app-architecture.md](docs/app-architecture.md). Bind shared Go logic only
when it removes duplication: see [docs/go-mobile.md](docs/go-mobile.md).
## Validate
diff --git a/SKILL.md b/SKILL.md
index c5c145e..e0855ce 100644
--- a/SKILL.md
+++ b/SKILL.md
@@ -17,6 +17,35 @@ and revision, set app-owned bundle IDs, run `xcodegen generate`. The example
checks `/api/version` only; it supplies no authenticated session. The app
owns linking, navigation, storage, signing and release policy.
+## Prefer native UI
+
+Aim for a fully native interface wherever practical. Meeting the platform's
+expectations can substantially improve daily use: navigation, selection,
+menus, context menus/right-click, keyboard shortcuts, accessibility, links,
+windows and system sharing should behave as people already expect. Treat
+those behaviours as part of the feature, not final polish. Share logic and
+contracts freely; let each platform own how the feature is presented.
+
+For a complex app, a native navigation layer around selected webview screens
+can avoid duplicating a large working surface. Use that as a deliberate
+boundary: keep app navigation, menus, contextual actions and link routing
+native, and expose typed actions from the embedded screen. Route internal
+links to native destinations and ordinary external links through the
+platform's normal browser behaviour. Do not intercept text editing or
+replace useful web behaviour with a less capable native imitation.
+
+If both clients would otherwise duplicate navigation and action definitions,
+consider a shared app manifest compiled into separate web and native
+presentations. Share destination IDs, available commands, capabilities and
+link intent; each renderer chooses platform-appropriate controls. A command
+may appear in a web toolbar, a Mac menu/context menu, or an iPhone action
+menu. Avoid encoding DOM trees, pixel layout or one platform's navigation
+model as the common schema. See [docs/app-architecture.md](docs/app-architecture.md).
+This is architectural guidance, not an existing dual-target generator;
+Rastrillo's current resource manifests generate web CRUD only.
+
+## Shared components
+
`@MainActor CoalescedRunner.run` serializes one refresh operation. A burst
during a pass queues one trailing pass; callers await its completion.
Trailing passes reuse the first caller's closure. Keep one runner per
diff --git a/docs/app-architecture.md b/docs/app-architecture.md
new file mode 100644
index 0000000..58b5f52
--- /dev/null
+++ b/docs/app-architecture.md
@@ -0,0 +1,60 @@
+# Build for the platform
+
+Prefer fully native UI when practical. The gain is in everyday behaviour:
+the app responds to the menus, keyboard, selection, accessibility and
+navigation habits a person brings from the rest of their device. A familiar
+appearance alone does not deliver that improvement.
+
+Use platform controls and conventions for navigation, menus, contextual
+actions, links, windows, drag/drop, sharing and keyboard interaction.
+Desktop right-click should expose the relevant context menu. Link actions
+should support the platform's expectations for opening, copying and sharing
+destinations; do not reduce every link to a JavaScript click handler.
+Accessibility semantics and focus behaviour belong in the first implementation.
+
+## When a hybrid app is appropriate
+
+A complex editor, feed or established interactive screen can justify reuse
+through a webview. Keep the app shell and navigation native and choose
+individual embedded surfaces deliberately. Give the embedded content a
+narrow, typed bridge for app commands and navigation intents. The native
+host resolves those intents to native screens, contextual actions and
+system services. It should not need to inspect DOM text to discover meaning.
+
+Internal app destinations open through native navigation. External web
+destinations follow the platform's browser conventions, including the
+person's choice where applicable. Preserve useful editing, selection and
+accessibility behaviour inside the web surface. Avoid replacing a capable
+web editor merely to increase the percentage of native code.
+
+For encrypted content, bridge capabilities stay narrow. Pass only what the
+embedded surface needs; a webview that displays one conversation need not
+receive the account's private key or another conversation's keys.
+
+## A shared app manifest
+
+When navigation and commands are repeated across clients, consider a
+manifest of app meaning with separate web and native compilers/renderers.
+It can describe stable destination IDs, route parameters, commands,
+capabilities, labels/localisation keys and link intent. The app's server
+still enforces permissions; hiding a command is not authorisation.
+
+For example, the common definition can say a document supports `open`,
+`rename`, `share` and `delete`, and identify their handlers. The web renderer
+can use routes, anchors, forms and a toolbar; the Mac renderer can use
+windows, menu commands and right-click actions; the iPhone renderer can use
+navigation stacks, toolbars and action menus. Destructive confirmation and
+disabled/unavailable actions need explicit meaning in that contract.
+
+Keep DOM structure, coordinates and platform-specific navigation stacks out
+of the common schema. Provide platform overrides for presentation and
+capabilities rather than forcing the least capable shared layout everywhere.
+Share business rules, API contracts and test vectors below the renderers.
+
+The first proof should be a real feature rendered for web and native, with
+tests for destinations and action semantics plus platform UI tests. Extract
+the manifest schema after that proof, rather than designing a universal
+compiler before either client works.
+
+No such compiler ships in the initial kit. Rastrillo's existing resource
+manifests generate server-rendered web CRUD; they are a separate mechanism.