@aarwitz/tapp 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/AGENTS.md +123 -0
  2. package/Harness/OCQAHarness/AppDelegate.swift +21 -0
  3. package/Harness/OCQAHarness/Info.plist +26 -0
  4. package/Harness/OCQAHarness.xcodeproj/project.pbxproj +199 -0
  5. package/Harness/OCQAHarness.xcodeproj/xcshareddata/xcschemes/OCQAHarnessUITests.xcscheme +22 -0
  6. package/Harness/OCQAHarnessUITests/ExplorerTests.swift +4526 -0
  7. package/Harness/OCQAHarnessUITests/Info.plist +22 -0
  8. package/Harness/generate-harness-xcodeproj.rb +254 -0
  9. package/LICENSE +21 -0
  10. package/README.md +374 -0
  11. package/bin/tapp.js +1382 -0
  12. package/browser/app.css +227 -0
  13. package/browser/app.js +675 -0
  14. package/browser/index.html +195 -0
  15. package/browser/product-contract.js +25 -0
  16. package/browser/view-model.js +16 -0
  17. package/docs/BROWSER-PRODUCT.md +72 -0
  18. package/docs/PRODUCT-ENGINE.md +102 -0
  19. package/docs/application-model.md +276 -0
  20. package/docs/scenarios.md +95 -0
  21. package/mcp-server/src/android-driver.js +287 -0
  22. package/mcp-server/src/android-explorer.js +197 -0
  23. package/mcp-server/src/android-flow.js +89 -0
  24. package/mcp-server/src/application-model.js +1597 -0
  25. package/mcp-server/src/browser-product.js +659 -0
  26. package/mcp-server/src/browser-workspaces.js +234 -0
  27. package/mcp-server/src/ci-report.js +557 -0
  28. package/mcp-server/src/ci-setup.js +359 -0
  29. package/mcp-server/src/contract-authoring.js +10 -0
  30. package/mcp-server/src/enrich.js +57 -0
  31. package/mcp-server/src/flow-runtime.js +127 -0
  32. package/mcp-server/src/html-report.js +124 -0
  33. package/mcp-server/src/index.js +3775 -0
  34. package/mcp-server/src/maintenance-proposal.js +178 -0
  35. package/mcp-server/src/managed-operation.js +61 -0
  36. package/mcp-server/src/pr-selection.js +841 -0
  37. package/mcp-server/src/product-execution.js +155 -0
  38. package/mcp-server/src/product-operations.js +526 -0
  39. package/mcp-server/src/project-config.js +101 -0
  40. package/mcp-server/src/release-contract.d.ts +81 -0
  41. package/mcp-server/src/release-contract.js +226 -0
  42. package/mcp-server/src/report.js +363 -0
  43. package/mcp-server/src/scenario-runtime.js +139 -0
  44. package/mcp-server/src/static-server.js +44 -0
  45. package/mcp-server/src/task-runtime.js +266 -0
  46. package/mcp-server/src/ui-map.js +661 -0
  47. package/mcp-server/src/web-explorer.js +493 -0
  48. package/mcp-server/src/web-flow.js +238 -0
  49. package/package.json +82 -0
  50. package/scripts/android-corpus-e2e.sh +30 -0
  51. package/scripts/ci-gate.sh +323 -0
  52. package/scripts/cleanup-xcode.sh +157 -0
  53. package/scripts/compile-contract.js +27 -0
  54. package/scripts/compile-flow.js +18 -0
  55. package/scripts/corpus-apps.txt +9 -0
  56. package/scripts/corpus-sweep.sh +121 -0
  57. package/scripts/coverage-eval.sh +92 -0
  58. package/scripts/coverage_eval_parse.py +95 -0
  59. package/scripts/deploy-and-build.sh +99 -0
  60. package/scripts/flow-platform.js +18 -0
  61. package/scripts/flow_ai_judge.py +102 -0
  62. package/scripts/flow_lib.py +154 -0
  63. package/scripts/mutation-recall-desktop.sh +186 -0
  64. package/scripts/mutation-recall.sh +121 -0
  65. package/scripts/mutation_lib.py +128 -0
  66. package/scripts/mutation_operators.py +144 -0
  67. package/scripts/platform-gate.js +186 -0
  68. package/scripts/pr-plan.js +68 -0
  69. package/scripts/quick-capture.sh +419 -0
  70. package/scripts/run-android-flow.js +27 -0
  71. package/scripts/run-flow.sh +90 -0
  72. package/scripts/run-web-flow.js +28 -0
  73. package/scripts/run-web-scenario.js +23 -0
  74. package/scripts/validation-matrix.sh +146 -0
  75. package/scripts/vision-fp-eval.sh +206 -0
  76. package/scripts/vision_escalation_responder.py +147 -0
  77. package/scripts/vision_fp_probe.py +221 -0
@@ -0,0 +1,195 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="description" content="Tapp turns repositories into UI maps, deterministic release contracts, and evidence-backed merge decisions across iOS, Android, and web.">
7
+ <meta name="tapp-api-base" content="">
8
+ <meta name="tapp-login-url" content="">
9
+ <title>Tapp</title>
10
+ <link rel="stylesheet" href="./assets/app.css">
11
+ </head>
12
+ <body>
13
+ <header class="topbar">
14
+ <button class="brand" id="brand-home" aria-label="Tapp overview"><span class="brand-mark">&#9757;&#65038;</span><span>tapp</span><small>release confidence</small></button>
15
+ <div class="top-actions">
16
+ <span class="mode-pill" id="mode-pill">Local engine</span>
17
+ <select id="repository-switcher" class="repository-switcher hidden" aria-label="Current repository"></select>
18
+ <button class="quiet hidden" id="refresh-project">Refresh</button>
19
+ </div>
20
+ </header>
21
+
22
+ <main class="source-onboarding hidden" id="source-onboarding">
23
+ <section class="welcome-copy">
24
+ <p class="eyebrow">RELEASE CONTRACTS FOR REAL APPLICATIONS</p>
25
+ <h1>Bring the product.<br>Tapp builds the proof.</h1>
26
+ <p>Connect a repository once. Tapp detects its targets, builds and explores the real application, maps what users can do, proposes the business journeys worth protecting, and installs deterministic release gates.</p>
27
+ <div class="platform-row" aria-label="Supported target platforms">
28
+ <span>iOS</span><span>Android</span><span>Web</span>
29
+ </div>
30
+ </section>
31
+
32
+ <section class="source-choices" aria-label="Connect a repository">
33
+ <article class="source-card local-runner-card">
34
+ <div class="source-icon">⌘</div>
35
+ <p class="eyebrow">THIS MAC</p>
36
+ <h2>Run from your checkout</h2>
37
+ <p>Your source never uploads. Tapp builds with local Xcode and drives your local simulator, while the web app shows progress and evidence.</p>
38
+ <div id="local-repositories"><small>Looking for connected Mac repositories…</small></div>
39
+ </article>
40
+ <article class="source-card drop-zone" id="repository-drop-zone" tabindex="0">
41
+ <div class="source-icon">↥</div>
42
+ <p class="eyebrow">CLOUD COPY</p>
43
+ <h2>Upload a project folder</h2>
44
+ <p>Upload an isolated working copy from this computer. Committed hidden config (like <code>.autotap/</code>) is included; dependency and build output folders are skipped.</p>
45
+ <button class="primary" id="browse-folder">Browse folder</button>
46
+ <input id="folder-input" type="file" webkitdirectory multiple hidden>
47
+ <small>For direct edits to an existing checkout, start with <code>tapp app /path/to/repo</code>.</small>
48
+ </article>
49
+ <article class="source-card github-card">
50
+ <div class="source-icon github-icon">⌘</div>
51
+ <p class="eyebrow">GITHUB</p>
52
+ <h2>Connect to GitHub</h2>
53
+ <p id="github-source-copy">Select one of the repositories authorized by your local GitHub session. Tapp clones an isolated checkout and never pushes silently.</p>
54
+ <button class="secondary" id="connect-github">Choose repository</button>
55
+ <small id="github-source-note">Local preview uses <code>gh auth</code>. Hosted Tapp will use repository-scoped GitHub App authorization.</small>
56
+ </article>
57
+ </section>
58
+
59
+ <div class="privacy-note"><strong id="privacy-note-title">Your code stays on this machine in local mode.</strong><span id="privacy-note-detail">Ordinary exploration, replay, and merge decisions are deterministic and require no API key.</span></div>
60
+ </main>
61
+
62
+ <div class="product-shell hidden" id="product-shell">
63
+ <aside class="sidebar">
64
+ <div class="project-identity">
65
+ <span class="project-avatar" id="project-avatar">A</span>
66
+ <div><strong id="sidebar-project-name">Product</strong><small id="sidebar-project-source">Repository</small></div>
67
+ </div>
68
+ <nav class="primary-nav" aria-label="Product navigation">
69
+ <button data-view="overview" class="active"><span>⌂</span>Overview</button>
70
+ <button data-view="runs"><span>▶</span>Runs <i id="run-count">0</i></button>
71
+ <button data-view="findings"><span>◇</span>Findings <i id="finding-count">0</i></button>
72
+ <button data-view="coverage"><span>⌘</span>Coverage</button>
73
+ <button data-view="contracts"><span>✓</span>Contracts <i id="contract-count">0</i></button>
74
+ <button data-view="settings"><span>⚙</span>Settings</button>
75
+ </nav>
76
+ <div class="sidebar-context">
77
+ <p class="eyebrow">SELECTED TARGET</p>
78
+ <strong id="sidebar-target">Select a target</strong>
79
+ <small id="sidebar-runner">Runner not checked</small>
80
+ </div>
81
+ <button class="sidebar-source" id="change-source">+ Add another repository</button>
82
+ <div class="keyless-note"><span>●</span><div><strong>Keyless replay</strong><small>AI is outside the ordinary gate loop.</small></div></div>
83
+ </aside>
84
+
85
+ <main class="workspace">
86
+ <section class="workspace-view active" data-view-panel="overview" id="overview">
87
+ <div class="view-heading">
88
+ <div><p class="eyebrow">OVERVIEW</p><h1 id="app-name">Your release workspace</h1><p id="app-summary">Inspect the repository to discover product targets and release intent.</p></div>
89
+ <div class="decision-card neutral" id="decision-card"><span class="decision-label">CURRENT DECISION</span><strong id="decision-title">Not evaluated</strong><span id="decision-detail">Run a conclusive release gate to establish evidence.</span></div>
90
+ </div>
91
+
92
+ <nav class="journey" aria-label="Release setup progress">
93
+ <button data-jump="connect"><span>1</span><b>Connect</b><small>Repository</small></button>
94
+ <button data-jump="target-stage"><span>2</span><b>Target</b><small>Build & runtime</small></button>
95
+ <button data-jump="map"><span>3</span><b>Map</b><small>Observed product</small></button>
96
+ <button data-jump="contracts"><span>4</span><b>Contracts</b><small>Review intent</small></button>
97
+ <button data-jump="validate"><span>5</span><b>Validate</b><small>Keyless replay</small></button>
98
+ <button data-jump="evidence"><span>6</span><b>Gate</b><small>Decision & CI</small></button>
99
+ </nav>
100
+
101
+ <section class="panel section" id="connect">
102
+ <div class="section-heading"><div><p class="eyebrow">CONNECTED REPOSITORY</p><h2 id="repository-title">Repository</h2><p id="repository-detail">Tapp reads canonical repository artifacts and writes only explicit, reviewable changes.</p></div><span class="status-chip" id="connect-status">Not inspected</span></div>
103
+ <div class="button-row"><button class="secondary" id="inspect">Inspect repository</button><button class="quiet" data-view="settings">Repository settings</button></div>
104
+ </section>
105
+
106
+ <section class="panel section" id="target-stage">
107
+ <div class="section-heading"><div><p class="eyebrow">BUILD & RUN</p><h2>Choose the product target</h2><p>Tapp detected these targets from source. Multiple targets require an explicit choice; build results validate—not replace—the model.</p></div><span class="status-chip" id="target-status">No target selected</span></div>
108
+ <div class="target-choice-callout hidden" id="target-choice-callout"><span>1</span><div><strong>Choose what Tapp should test</strong><small>Nothing will build until you select a target. Tapp never guesses when a repository contains multiple applications.</small></div></div>
109
+ <div id="targets" class="target-grid"><div class="empty">Inspect the repository to detect iOS, Android, and web targets.</div></div>
110
+ <div class="runtime-row hidden" id="runtime-row">
111
+ <label class="field android-runtime hidden" id="serial-field"><span>Android device serial <i>optional</i></span><input id="android-serial" placeholder="emulator-5554"><small>Leave blank to use the first connected and authorized device.</small></label>
112
+ <div class="run-cta"><div class="button-row"><button class="primary" id="explore">Build, launch & explore</button><button class="secondary" id="start-session">Open live app</button></div><small id="explore-help">Select one target to continue.</small></div>
113
+ </div>
114
+ <div id="requirements"></div>
115
+ </section>
116
+
117
+ <section class="panel section live-session-panel hidden" id="live-session-panel">
118
+ <div class="section-heading"><div><p class="eyebrow">LIVE APPLICATION</p><h2 id="live-screen-title">Running target</h2><p>See and drive the same real application surface used by Tapp's deterministic engine. Semantic controls refresh after every action.</p></div><div class="button-row"><button class="quiet" id="refresh-live-session">Refresh</button><button class="secondary" id="end-session">End session</button></div></div>
119
+ <div class="live-layout">
120
+ <div class="live-frame-shell"><div class="live-frame-head"><span id="live-platform">Target</span><span id="live-recorded-steps">0 recorded steps</span></div><div class="live-frame"><img id="live-frame-image" alt="Current application screen"><div id="live-frame-loading">Capturing live application…</div></div><div class="flow-recorder"><div><strong>Keep this journey as a deterministic Flow</strong><small>Successful actions are recorded with semantic selectors. Existing files are preserved.</small></div><label><span>Flow name</span><input id="live-flow-name" placeholder="Checkout smoke"></label><button class="primary" id="save-live-flow">Save Flow</button></div></div>
121
+ <aside class="live-controls"><div class="live-controls-heading"><div><strong>Semantic controls</strong><small id="live-control-count">0 available</small></div></div><div id="live-control-list"><div class="empty">Controls appear when the session starts.</div></div><div class="manual-action"><label><span>Target or field</span><input id="live-action-target" placeholder="Accessibility id or visible label"></label><label><span>Text <i>for type/wait</i></span><input id="live-action-text" autocomplete="off"></label><div class="button-row"><button class="secondary" id="live-tap">Tap</button><button class="secondary" id="live-type">Type</button><button class="quiet" id="live-back">Back</button><button class="quiet" id="live-swipe">Swipe up</button></div></div></aside>
122
+ </div>
123
+ </section>
124
+
125
+ <section class="overview-grid">
126
+ <article class="panel summary-panel"><div class="section-heading compact"><div><p class="eyebrow">LATEST EVIDENCE</p><h2>What changed?</h2></div><button class="quiet" data-view="runs">All runs</button></div><div id="overview-evidence"><div class="empty">No release run yet.</div></div></article>
127
+ <article class="panel summary-panel"><div class="section-heading compact"><div><p class="eyebrow">COVERAGE</p><h2>Observed surface</h2></div><button class="quiet" data-view="coverage">Open map</button></div><div id="overview-coverage" class="metric-grid"></div></article>
128
+ </section>
129
+ </section>
130
+
131
+ <section class="workspace-view" data-view-panel="runs">
132
+ <div class="view-heading simple"><div><p class="eyebrow">RUNS</p><h1>Release history</h1><p>Every autonomous sweep, deterministic replay, finding, and decision stays inspectable.</p></div><button class="primary" id="run-gate">Run release gate</button></div>
133
+ <div class="split-view">
134
+ <section class="panel list-panel" id="runs-list"><div class="empty">No runs yet.</div></section>
135
+ <section class="panel detail-panel" id="run-detail"><div class="empty">Select a run to inspect its decision, checks, findings, and artifacts.</div></section>
136
+ </div>
137
+ </section>
138
+
139
+ <section class="workspace-view" data-view-panel="findings">
140
+ <div class="view-heading simple"><div><p class="eyebrow">FINDINGS</p><h1>What needs attention</h1><p>Findings preserve their severity and regression state. A failed contract is never silently healed.</p></div><select id="finding-filter"><option value="all">All severities</option><option value="critical">Critical</option><option value="high">High</option><option value="medium">Medium</option><option value="low">Low</option></select></div>
141
+ <div class="split-view findings-layout"><section class="panel list-panel" id="findings-list"><div class="empty">No findings yet.</div></section><section class="panel detail-panel" id="finding-detail"><div class="empty">Select a finding to inspect its evidence.</div></section></div>
142
+ </section>
143
+
144
+ <section class="workspace-view" data-view-panel="coverage" id="map">
145
+ <div class="view-heading simple"><div><p class="eyebrow">COVERAGE</p><h1>The product Tapp understands</h1><p>One platform-neutral Application Model and UI Map power exploration, planning, maintenance, CLI, MCP, and CI.</p></div><span class="metric" id="map-metric">0 states</span></div>
146
+ <div class="subnav"><button data-coverage-tab="map" class="active">Flow Map</button><button data-coverage-tab="screens">Screens</button><button data-coverage-tab="application">Application</button><button data-coverage-tab="plan">Release Plan</button></div>
147
+ <section class="coverage-panel active" data-coverage-panel="map"><div class="map-layout"><div class="map-canvas" id="map-canvas"><div class="empty">Explore the real product to build its map.</div></div><aside id="coverage-summary" class="coverage-summary"></aside></div><div id="transition-list" class="transition-list"></div></section>
148
+ <section class="coverage-panel" data-coverage-panel="screens"><div class="panel table-panel" id="screen-list"><div class="empty">No observed screens yet.</div></div></section>
149
+ <section class="coverage-panel" data-coverage-panel="application"><div class="application-grid" id="application-model"><div class="empty">Inspect the repository to build its Application Model.</div></div></section>
150
+ <section class="coverage-panel" data-coverage-panel="plan"><div id="coverage-plan-list" class="plan-list"><div class="empty">No release plan yet.</div></div></section>
151
+ </section>
152
+
153
+ <section class="workspace-view" data-view-panel="contracts" id="contracts">
154
+ <div class="view-heading simple"><div><p class="eyebrow">RELEASE CONTRACTS</p><h1>Review business guarantees</h1><p>Approve a compact set of important outcomes. Tapp composes reusable Tasks instead of generating one script for every situation.</p></div><span class="status-chip" id="plan-status">No plan</span></div>
155
+ <section class="panel section">
156
+ <div class="plan-toolbar"><button class="quiet" id="approve-high">Approve high & critical</button><button class="quiet" id="defer-rest">Defer undecided</button><span class="spacer"></span><button class="primary" id="save-review">Save review</button></div>
157
+ <div id="plan-list" class="plan-list"><div class="empty">Inspect and explore to create a grounded release plan.</div></div>
158
+ </section>
159
+ <section class="panel section" id="validate">
160
+ <div class="section-heading"><div><p class="eyebrow">DETERMINISTIC SUITE</p><h2>Generate, replay, then promote</h2><p>Draft Tasks and contracts remain untrusted until they pass without AI against the selected real target. Promotion is explicit.</p></div><span class="status-chip" id="validation-status">Not generated</span></div>
161
+ <div class="pipeline"><article><span>01</span><h3>Generate drafts</h3><p>Compose reusable Tasks and TypeScript contracts from approved, grounded intent.</p><button class="secondary" id="generate">Generate</button></article><article><span>02</span><h3>Replay without AI</h3><p>Execute exact assertions and bounded waits on the actual selected platform.</p><button class="secondary" id="validate-drafts">Validate</button></article><article><span>03</span><h3>Promote reviewed proof</h3><p>Move only validated drafts into the committed suite and update map coverage.</p><button class="secondary" id="promote">Promote</button></article></div>
162
+ <div id="artifact-list" class="artifact-list"></div>
163
+ </section>
164
+ </section>
165
+
166
+ <section class="workspace-view" data-view-panel="settings">
167
+ <div class="view-heading simple"><div><p class="eyebrow">SETTINGS</p><h1>Project and execution</h1><p>Only unavoidable target, environment, actor, and credential inputs belong here.</p></div></div>
168
+ <div class="settings-grid">
169
+ <section class="panel settings-section"><p class="eyebrow">REPOSITORY</p><h2>Source</h2><div id="settings-repository"></div><button class="secondary" id="settings-add-repository">Add repository</button></section>
170
+ <section class="panel settings-section"><p class="eyebrow">RUNNERS</p><h2>Execution surfaces</h2><div id="runner-list"></div></section>
171
+ <section class="panel settings-section"><p class="eyebrow">ACTORS & CREDENTIALS</p><h2>Runtime-only values</h2><p>Values stay in this browser session and process environment; they are never written into repository artifacts or job results.</p><label class="field"><span>Test email</span><input id="test-email" autocomplete="off"></label><label class="field"><span>Test password</span><input id="test-password" type="password" autocomplete="new-password"></label><div id="actor-list" class="actor-list"></div></section>
172
+ <section class="panel settings-section"><p class="eyebrow">AI & DATA</p><h2>Optional orchestration</h2><div class="setting-row"><div><strong>Remote AI</strong><small>Planning and maintenance only. Deterministic execution does not need it.</small></div><span class="status-chip">Off</span></div><p class="honesty">Remote AI consent and provider controls are not yet exposed in this local browser build. Tapp will not opt you in implicitly.</p></section>
173
+ </div>
174
+ <section class="panel section" id="evidence">
175
+ <div class="section-heading"><div><p class="eyebrow">RELEASE EVIDENCE & CI</p><h2>Install the same decision in GitHub</h2><p>Preview the target-aware workflow, required secrets, unresolved configuration, and exact policy before writing anything.</p></div><div class="button-row"><button class="secondary" id="create-baseline" disabled>Establish baseline</button><button class="secondary" id="preview-ci">Preview CI</button><button class="primary" id="install-ci">Write reviewable patch</button></div></div>
176
+ <div id="latest-evidence" class="evidence-grid"><div class="empty">No release run yet.</div></div>
177
+ <pre id="ci-preview" class="code-preview hidden"></pre>
178
+ </section>
179
+ </section>
180
+ </main>
181
+ </div>
182
+
183
+ <dialog id="github-dialog">
184
+ <form method="dialog" class="dialog-shell">
185
+ <div class="dialog-heading"><div><p class="eyebrow">CONNECT TO GITHUB</p><h2>Select a repository</h2><p>Tapp only displays repositories available to your authenticated local GitHub session.</p></div><button class="quiet" value="cancel" aria-label="Close">Close</button></div>
186
+ <input class="search-input" id="github-search" placeholder="Search repositories…" autocomplete="off">
187
+ <div id="github-repositories" class="github-repositories"><div class="empty">Loading authorized repositories…</div></div>
188
+ </form>
189
+ </dialog>
190
+
191
+ <div class="operation-drawer hidden" id="operation-drawer" role="status" aria-live="polite"><div class="spinner"></div><div class="operation-copy"><strong id="operation-title">Working…</strong><p id="operation-progress">Starting operation</p><div class="progress-track"><span id="operation-progress-bar"></span></div></div></div>
192
+ <div class="toast hidden" id="toast"></div>
193
+ <script type="module" src="./assets/app.js"></script>
194
+ </body>
195
+ </html>
@@ -0,0 +1,25 @@
1
+ // Executable parity contract for Tapp's one customer-facing browser product.
2
+ // Both the local adapter and hosted adapter must serve this same application.
3
+ export const customerProductContract = Object.freeze({
4
+ schemaVersion: 1,
5
+ product: "Tapp",
6
+ interface: "customer-browser",
7
+ targetPlatforms: ["ios", "android", "web"],
8
+ repositorySources: ["local-folder", "github"],
9
+ views: [
10
+ { id: "overview", label: "Overview", capabilities: ["release-decision", "onboarding-progress", "current-operation", "latest-evidence"] },
11
+ { id: "runs", label: "Runs", capabilities: ["run-history", "run-detail", "timeline", "screenshots", "recordings", "logs", "artifacts"] },
12
+ { id: "findings", label: "Findings", capabilities: ["finding-list", "severity-filter", "regression-state", "evidence"] },
13
+ { id: "coverage", label: "Coverage", capabilities: ["application-model", "ui-map", "screens", "transitions", "controls", "task-coverage", "contract-coverage"] },
14
+ { id: "contracts", label: "Contracts", capabilities: ["release-plan-review", "task-generation", "contract-generation", "deterministic-validation", "explicit-promotion"] },
15
+ { id: "settings", label: "Settings", capabilities: ["target-selection", "runner-status", "runtime-inputs", "actors", "credentials", "ai-consent", "ci-installation"] },
16
+ ],
17
+ operations: ["initialize", "session-start", "session-act", "session-save-flow", "session-end", "review", "generate", "validate", "promote", "gate", "baseline", "ci-preview", "ci-install"],
18
+ invariants: [
19
+ "Browser is the Tapp customer interface; web is one target platform.",
20
+ "Repository paths are selected by the server or imported into isolated workspaces.",
21
+ "AI is optional for planning; deterministic replay and ordinary merge decisions are keyless.",
22
+ "Generated Tasks and contracts remain untrusted until real replay passes and promotion is explicit.",
23
+ "The internal fleet console is not a customer product surface.",
24
+ ],
25
+ });
@@ -0,0 +1,16 @@
1
+ export function productJourneyFlags({ status = {}, hasTarget = false, hasEvidence = false } = {}) {
2
+ return [
3
+ true,
4
+ hasTarget,
5
+ status.explored === true,
6
+ status.reviewComplete === true,
7
+ // A committed or promoted contract is not proof that it replayed on the
8
+ // current revision. Only current validation evidence completes this step.
9
+ status.validated === true,
10
+ hasEvidence,
11
+ ];
12
+ }
13
+
14
+ export function operationIsPending(status) {
15
+ return ["queued", "claimed", "running"].includes(String(status || ""));
16
+ }
@@ -0,0 +1,72 @@
1
+ # Browser Release Studio
2
+
3
+ Status: current local-product contract as of 2026-08-08.
4
+
5
+ The browser is Tapp's primary customer workflow. Web is also one application target beside iOS and
6
+ Android; it is not a separate QA product. CLI, MCP, VS Code, the Action, desktop, and future managed
7
+ SaaS adapt the shared product operations described in [`PRODUCT-ENGINE.md`](PRODUCT-ENGINE.md).
8
+
9
+ ## Start locally
10
+
11
+ ```bash
12
+ npx -y @aarwitz/tapp app
13
+ ```
14
+
15
+ Tapp prints an authenticated one-time launch URL and opens it in the default browser. Use
16
+ `--no-open` when copying the URL manually and `--port 4317` only when a fixed loopback port is
17
+ needed. Drag/drop or Browse Folder copies source into a Tapp-owned workspace. Connect GitHub lists
18
+ repositories authorized to the local `gh` session and makes a shallow isolated clone.
19
+ `tapp app /path/to/repo` intentionally works directly in that checkout.
20
+
21
+ The local server binds to `127.0.0.1`. It owns workspace paths; browser requests cannot submit an
22
+ arbitrary server path. Mutations require an `HttpOnly` same-site session cookie, the exact local
23
+ Origin, and an in-memory CSRF token. Application runtimes, repository credentials, and evidence stay
24
+ in the local process/filesystem. This is a local trust boundary, not hosted multi-tenancy.
25
+
26
+ ## Product journey
27
+
28
+ 1. **Connect** a copied folder, an explicit checkout, or a repository authorized by local `gh`.
29
+ 2. **Detect and choose** an iOS, Android, or web target. Continue automatically only when the target
30
+ and configuration are conclusive.
31
+ 3. **Build, launch, and explore** the real simulator, emulator/device, or browser surface.
32
+ 4. **Understand the UI Map** through observed states, transitions, controls, provenance, and gaps.
33
+ 5. **Review intent** by approving, rejecting, deferring, or constraining a compact release plan.
34
+ 6. **Generate drafts** of Tasks and contracts. Drafts remain visibly untrusted.
35
+ 7. **Validate** approved drafts deterministically against the real target.
36
+ 8. **Promote** only validated artifacts into the canonical suite and refreshed Application Model.
37
+ 9. **Gate** with autonomous evidence plus the promoted deterministic suite.
38
+ 10. **Baseline** only a passing, conclusive, target-scoped gate.
39
+ 11. **Install CI** by previewing and writing a reviewable repository patch. Tapp does not commit,
40
+ push, create GitHub secrets, or enable branch protection.
41
+
42
+ Successful semantic actions can be saved in `.autotap/flows/`; credential values are templated to
43
+ environment references. Long-lived repository artifacts store binding names, not resolved secret
44
+ values.
45
+
46
+ ## Verified reference journey
47
+
48
+ `tests/browser-journey.test.js` drives the visible local browser against a fresh CommerceDemo copy.
49
+ It exercises startup, a real live web surface and semantic action, UI Map creation, Flow recording
50
+ and replay, proposal review, generation, deterministic validation, promotion, a first gate,
51
+ baseline-aware rerun, and CI preview.
52
+
53
+ The opt-in `tests/browser-native-journey.test.js` passed on 2026-08-06 against a booted iOS
54
+ simulator: the browser built and installed a disposable DemoApp checkout, ran shared target
55
+ preparation and exploration, rendered an observed UI Map, drove the live surface, and saved a
56
+ repository-native iOS Flow. The equivalent Android browser journey was not verified in that audit
57
+ because no emulator/device was connected.
58
+
59
+ This evidence proves representative local journeys. It does not prove arbitrary frameworks,
60
+ production credentials, third-party services, hosted execution, or complete inference of business
61
+ intent.
62
+
63
+ ## Hosted relationship
64
+
65
+ `app.runtapp.com` will present the same product journey through a different adapter: application
66
+ accounts/organizations, GitHub App repository authorization, private storage, a durable queue, and
67
+ isolated managed workers. It cannot reuse the loopback session, local `gh` authority, filesystem
68
+ boundary, or in-memory ownership assumptions.
69
+
70
+ The old hosted preview and `cloud/` prototype do not satisfy this boundary. Follow
71
+ [`SAAS-ARCHITECTURE.md`](SAAS-ARCHITECTURE.md) and do not market or accept private repositories until
72
+ [`SAAS-READINESS.md`](SAAS-READINESS.md) passes.
@@ -0,0 +1,102 @@
1
+ # One Tapp product engine
2
+
3
+ Status: current product-engine contract as of 2026-08-08.
4
+
5
+ Tapp has several interfaces, not several products. The source of truth for customer-critical
6
+ operations is [`mcp-server/src/product-operations.js`](../mcp-server/src/product-operations.js).
7
+ An interface may validate its transport and render a result; it must not redefine onboarding,
8
+ review, trust, baseline, or gate semantics.
9
+
10
+ ## Product operation contract
11
+
12
+ The shared engine owns these operations:
13
+
14
+ | Operation | Authoritative result |
15
+ |---|---|
16
+ | `initializeProductProject` | detected targets, real exploration, Application Model, UI Map, release plan |
17
+ | `readProductProject` | one current, read-only product snapshot for any interface |
18
+ | `reviewProductPlan` | explicit approve/reject/defer decisions |
19
+ | `generateProductPlan` | compile-checked but untrusted Task/contract drafts |
20
+ | `validateProductPlan` | real-target, deterministic replay evidence |
21
+ | `promoteProductPlan` | canonical Tasks/contracts, refreshed model/plan, updated map coverage |
22
+ | `prepareProductCi` / `installProductCi` | target-aware workflow and machine-readable CI manifest |
23
+ | `runProductGate` | autonomous evidence plus the committed deterministic suite and one gate decision |
24
+ | `createProductBaseline` | conclusive, platform-and-target-specific comparison state |
25
+
26
+ Deterministic contract execution is in
27
+ [`mcp-server/src/product-execution.js`](../mcp-server/src/product-execution.js). It invokes platform
28
+ executors directly; MCP does not shell through the CLI, and the browser does not shell through MCP.
29
+
30
+ ## Interfaces
31
+
32
+ ```text
33
+ Browser Release Studio ─┐
34
+ CLI ├── product-operations ── application model / UI Map / Tasks / contracts
35
+ MCP ┘ │
36
+ └── deterministic executors / portable gate / evidence
37
+
38
+ VS Code ── MCP client
39
+ Desktop ── canonical artifact reader (migration to operation client remains)
40
+ Action ── portable gate adapter
41
+ Hosted ── tenant-aware SaaS adapter + queued isolated shared-operation workers (not built)
42
+ ```
43
+
44
+ Current convergence:
45
+
46
+ - the browser calls only shared product operations;
47
+ - CLI initialization, plan lifecycle, deterministic draft validation, promotion, gate/baseline
48
+ lifecycle, and CI installation call the same operations. Native build preparation remains at the
49
+ adapter boundary and passes a resolved `.app` or APK into the shared gate;
50
+ - MCP initialization, plan lifecycle, deterministic draft validation, promotion, baseline, and CI
51
+ installation call the same operations;
52
+ - the GitHub Action and `runProductGate` call the same portable gate and evidence protocol;
53
+ - VS Code remains a thin MCP client;
54
+ - desktop reads the same `.autotap` artifacts but still has legacy import/build orchestration. It is
55
+ retained, not the launch UX, until that orchestration is removed;
56
+ - `cloud/runner` is retained prototype evidence for exact checkout, versioned operation envelopes,
57
+ leases, and cleanup. It is not the production hosted adapter or an adequate arbitrary-customer
58
+ isolation boundary. The new SaaS must call these shared operations only through the tenant-aware,
59
+ queued worker contract in [`SAAS-ARCHITECTURE.md`](SAAS-ARCHITECTURE.md).
60
+
61
+ ## Canonical repository protocol
62
+
63
+ New product behavior writes only `.autotap/`:
64
+
65
+ ```text
66
+ .autotap/
67
+ project.json # actors, env binding names, controlled lifecycle; never secret values
68
+ application-model.json # detected/observed/declared product facts
69
+ ui-map.json # grounded screen/action/transition graph
70
+ release-plan.json # proposals and explicit human decisions
71
+ tasks/ # reusable deterministic semantic operations
72
+ contracts/ # reviewed business guarantees
73
+ baselines/<platform>/ # conclusive target-specific comparison state
74
+ ci.json # generated CI installation manifest
75
+ ```
76
+
77
+ `.autotap.yml` and `.tapp.yml` are legacy compatibility inputs, not parallel sources of product
78
+ truth. Do not add a fourth configuration format. Migration readers may normalize old input into the
79
+ canonical model; only an explicit reviewed operation may write new repository artifacts.
80
+
81
+ ## Anti-duplication rules
82
+
83
+ 1. Trust states (`pending`, `approved`, `validated-draft`, `promoted`) are computed by the engine.
84
+ 2. Interfaces render `readProductProject`; they do not infer readiness from file existence.
85
+ 3. Re-exploration refreshes evidence while preserving reviewed decisions everywhere.
86
+ 4. Promotion refreshes the Application Model immediately; no interface may show stale pre-promotion
87
+ requirements.
88
+ 5. Baselines are identified by platform and stable target id everywhere.
89
+ 6. An adapter-specific feature is not complete until its engine operation is useful without that
90
+ adapter.
91
+ 7. Equivalence tests should assert artifacts and structured results, not merely matching copy.
92
+
93
+ ## Remaining migration
94
+
95
+ The next safe convergence work is deliberately narrow:
96
+
97
+ 1. replace desktop import/build orchestration with a local product-operation client;
98
+ 2. delete the two desktop detection/scaffolding paths only after equivalence fixtures pass;
99
+ 3. implement managed account, organization, and tenant authorization before connecting repositories;
100
+ 4. implement scoped GitHub authorization, private evidence, and disposable per-job
101
+ identity/simulator/credential isolation before accepting customer code;
102
+ 5. preserve CLI/MCP/VS Code/Action as adapters—do not rebuild their product logic.