@amityco/social-plus-vise 1.4.6 → 1.5.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.
package/CHANGELOG.md CHANGED
@@ -4,14 +4,30 @@ All notable changes to `@amityco/social-plus-vise` are documented in this file.
4
4
 
5
5
  The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## Unreleased
7
+ ## 1.5.0 — 2026-07-05
8
8
 
9
- No changes yet.
9
+ ### Added
10
+ - **`no-platform` check status (exit 8).** A repo with no detected mobile/web platform no longer resolves to a vacuous green — `vise check` reports `no-platform` so a platform-less/static project can't pass by having zero applicable rules.
11
+ - **Runtime `proof-waived` terminal.** `vise smoke waive --reason <why> --mode declined|deviceless` records an auditable, under-claiming waiver; `vise check` then reports `runtime-proof-waived` (exit 9; `--allow-proof-waiver` → exit 0), and `vise workplan complete` accepts it. Genuine passing runtime-smoke evidence always overrides a waiver; a waiver never reads as "proven".
12
+ - **Evidence-inferred workplan completion.** `vise workplan status`/`next` now auto-records a surface whose live check is green (completable) for the in-scope surface, reusing the same snapshot/integrity-manifest machinery as `vise workplan complete` — so a working, check-green surface isn't left uncredited when the separate `complete` step is skipped. Reports an `autoCompleted` field; fires only for the in-scope surface.
13
+ - **Native data-seeding guidance (SKILL).** New "Seeding Data When Empty (read-after-write lag)" guidance: a freshly created community/channel/post may not reappear in an immediate list re-query — merge the create-response into the rendered list, persist created IDs, and bound-retry on a transient 401/stall.
14
+
15
+ ### Changed
16
+ - **State-based resume.** A reworded "continue" request re-attaches to an in-progress signed flow via companion outcomes (comments↔feed, community→feed/comments); unrelated requests stay separate but get a resume hint.
17
+ - **Sharper day-2 debug scope.** Session-state symptoms (`notLoggedIn`, "session not established") correlate to the requery rules; a bare backend 401/500 now needs SDK context so it doesn't mis-correlate.
18
+
19
+ ### Fixed
20
+ - **iOS sensor precision (false-positives).** Recognize valid SDK idioms — `post.postData` / `post.data?["text"]` for post body, Combine `AmityObject.$snapshot.sink` for follow subscription — bound the unread manual-count regex to a single line (it spanned to EOF in semicolon-free Swift), and skip non-rendering `ViewModel`/`Gateway` layers for the ban-state/role-gated guards (the View/Activity that renders the action is still checked). Also fixed a latent bug: the non-UI-file skip didn't account for `.java`/`.kts` extensions, so it never applied to Android Java files.
21
+ - **Forgeable cross-file `// vise:` assertions.** A `// vise: … at <File>` guard assertion is now trusted only when the named file actually carries a real (non-comment) guard; a bare comment naming no file stays the documented opt-out.
22
+ - **Malformed `design-profile.json`.** Now surfaces `brandGrounding: invalid` with a "fix, don't re-author" diagnostic instead of silently reading as absent.
23
+
24
+ ### Compatibility
25
+ - **Additive exit codes.** `vise check` gains `no-platform` (exit 8) and `runtime-proof-waived` (exit 9; `--allow-proof-waiver` → 0). The existing 0–6 exit surface and its precedence are unchanged, so a pipeline that gates on `exitCode === 0` (or `--ci`) is unaffected. One intentional behavior change: a platform-less repo that previously exited green now reports `no-platform` (exit 8) — a repo with zero applicable rules was never a real pass. The rule corpus and contract digest are unchanged, so existing attestations are not invalidated.
10
26
 
11
27
  ## 1.4.6 — 2026-07-02
12
28
 
13
29
  ### Added
14
- - **Marketing capability explainer.** Added a shipped `docs/vise-how-it-helps.html` page for marketing and sales enablement that explains Vise's agentic workflow, three validation layers, current real-E2E scorecard methodology, and realistic brownfield-style Social+ integration outputs in a light themed gallery.
30
+ - **Capability explainer page.** Added a shipped `docs/vise-how-it-helps.html` page that explains Vise's agentic workflow, three validation layers, real-E2E scorecard methodology, and realistic brownfield-style social.plus integration outputs in a light-themed gallery.
15
31
 
16
32
  ### Changed
17
33
  - **Preview status is explicit in the public README.** The npm README now marks Vise as a preview release and sets the expected boundary for API stability, benchmark methodology, advisory intelligence, code review, QA, and runtime verification.
@@ -32,7 +48,7 @@ No changes yet.
32
48
  ## 1.4.3 — 2026-07-02
33
49
 
34
50
  ### Changed
35
- - **Current scorecard now has React Native and Flutter controls.** The retained real-E2E summary and npm README now include fresh no-Vise controls for React Native and Flutter beside the current Vise rows, bringing the cross-platform head-to-head average to **91.8 vs 48.0** (+43.8 points).
51
+ - **Current scorecard now has React Native and Flutter controls.** The retained real-E2E summary and npm README now include fresh no-Vise controls for React Native and Flutter beside the current Vise rows.
36
52
  - **Scoring methodology is now documented.** Added the real-E2E scoring methodology, including dimensions, weights, caps, aggregation rules, and the claim boundary for current-loop vs formal public benchmark results.
37
53
 
38
54
  ### Fixed
@@ -41,13 +57,13 @@ No changes yet.
41
57
  ## 1.4.2 — 2026-07-02
42
58
 
43
59
  ### Changed
44
- - **README scorecard now includes the current Flutter and React Native rows.** The npm README and retained real-E2E results now show Flutter `fieldhouse-club` (**92.8**) and React Native `arena-fit` (**90.3**) as current Vise-arm-only native readiness evidence, with runtime-launch/screenshot proof and no console errors.
45
- - **Head-to-head benchmark boundary tightened.** The Android/iOS/Web Vise-vs-no-Vise average remains **91.9 vs 46.6** (+45.3 points), while Flutter and React Native are explicitly excluded from that lift until their no-Vise controls are rerun on the hardened harness.
60
+ - **README scorecard now includes the current Flutter and React Native rows.** The npm README and retained real-E2E results now show Flutter and React Native as current Vise-arm-only native readiness evidence, with runtime-launch/screenshot proof and no console errors.
61
+ - **Head-to-head benchmark boundary tightened.** Flutter and React Native are explicitly excluded from the Android/iOS/Web Vise-vs-no-Vise average until their no-Vise controls are rerun on the hardened harness.
46
62
 
47
63
  ## 1.4.1 — 2026-07-02
48
64
 
49
65
  ### Changed
50
- - **README evidence refreshed to the current real-E2E scorecard.** The npm README now leads with the retained July 2026 cross-platform scorecard: Vise average **91.9** vs no-Vise average **46.6** (+45.3 points), with Android/iOS/Web runtime-proof rows and the same methodology boundary as `benchmarks/real-e2e/RESULTS.md`.
66
+ - **README evidence refreshed to the current real-E2E scorecard.** The npm README now leads with the retained July 2026 cross-platform scorecard, with Android/iOS/Web runtime-proof rows and the same methodology boundary as `benchmarks/real-e2e/RESULTS.md`.
51
67
  - **Outdated benchmark figures removed from the shipped README.** Earlier SDK-compliance, design-conformance, feed-completeness, and Engagement Intelligence dogfood numbers were removed from the public README because they were measured on older builds/protocols and should not be mixed with the current scorecard.
52
68
 
53
69
  ## 1.4.0 — 2026-07-02
@@ -600,9 +616,9 @@ Docs-only patch; no CLI, MCP, rule, or sidecar behavior changes.
600
616
  - **`reactions.configured-name-used`** (all 5 platforms) downgraded to advisory. Rule fires on ~100% of correct apps (every tenant defaults to `"like"`) and was only clearable by a ritual comment. Version bumped to 2; existing compliance.json files will show contract-drift — run `vise sync` to update.
601
617
 
602
618
  ### Benchmark
603
- - Brand benchmark (an external brand design system × social.plus community feed, Sonnet n=3): pure-mcp 0/3 behavioral compliance (avg 2.3 behavioral findings), vise-design 3/3 (0). Ban-state is the standout discriminator — missed by all pure-mcp agents, fixed by all vise-design agents through the iteration loop.
604
- - Ambiguous-brief design test: vise-design 0 hex literals (all 3 seeds), pure-mcp 0/2/15 (high variance). Design loop is a variance-reduction tool.
605
- - Grader now partitions findings into behavioral / file-presence / attestation-dialect; headline score is behavioral-only.
619
+ - Brand benchmark (an external brand design system × social.plus community feed): the design loop improved behavioral compliance over a pure-MCP baseline; ban-state was the standout discriminator — missed by the baseline and fixed through the iteration loop.
620
+ - Ambiguous-brief design test: the design loop reduced hex-literal variance versus the baseline a variance-reduction tool.
621
+ - Grader now partitions findings into behavioral / file-presence / attestation-dialect; the headline signal is behavioral-only.
606
622
 
607
623
  ---
608
624
 
package/README.md CHANGED
@@ -106,7 +106,7 @@ Prefer a per-project install? `npm install -D @amityco/social-plus-vise`, then c
106
106
  4. **Build** — the agent edits your code, grounded by `vise search-docs` and `vise get-doc-page`.
107
107
  5. **Check & repair** — `vise check` reports deterministic findings, completeness gaps, and attestation needs. The agent fixes findings or records attestations with evidence, looping until green.
108
108
  6. **Sense** — `vise run-sensors` runs your project's own typecheck/build/lint/SDK smokes. Done means the contract and evidence are committed, not just that the agent stopped.
109
- 7. **Launch and verify** — for any user-visible handoff, ask before spending browser/simulator/emulator/device resources. If approved, open the actual target, check the selected journey, and record what data was discovered or created. Discover targets naturally from host app state, SDK queries, user selection, or SDK create-flow return values; if the tenant has no data, prepare Console data or seed safe sample data before calling the surface populated. When a `sp-vise/smoke.json` contract exists, run `vise smoke` against captured logs; `expect: "populated"` requires `loaded count=N` with `N > 0`. If launch verification is skipped, say what remains unverified.
109
+ 7. **Launch and verify** — for any user-visible handoff, ask before spending browser/simulator/emulator/device resources. If approved, open the actual target, check the selected journey, and record what data was discovered or created. Discover targets naturally from host app state, SDK queries, user selection, or SDK create-flow return values; if the tenant has no data, prepare Console data or seed safe sample data before calling the surface populated. When a `sp-vise/smoke.json` contract exists, run `vise smoke` against captured logs; `expect: "populated"` requires `loaded count=N` with `N > 0`. If runtime proof genuinely can't be produced — the user declines to spend device/emulator resources, or the environment is deviceless — record an honest waiver with `vise smoke waive` (rather than leaving a live surface red-forever or faking evidence); `vise check` then reports `runtime-proof-waived` as an explicit under-claim. If launch verification is skipped, say what remains unverified.
110
110
 
111
111
  ### Solution path & UIKit routing (advisory)
112
112
 
@@ -142,39 +142,65 @@ Vise can ingest your aesthetic from an HTML/CSS prototype (`vise design extract`
142
142
 
143
143
  ## Evidence
144
144
 
145
- Vise is measured against complete brownfield integrations, not isolated snippets. In the real end-to-end benchmark suite, agents were asked to add social.plus to existing product-shaped apps across five platforms. The current scorecard was produced with the Codex GPT-5.4 Medium harness; the protocol is designed for equivalent-tier coding models such as Claude Sonnet 4.6 or Gemini Flash 3.5, with each Vise/no-Vise pair kept on the same model and reasoning setting. The score combines workflow guidance, product surface completion, design fit, correctness, and efficiency. These July 2026 social.plus benchmark runs are directional product evidence from representative app fixtures, not a third-party audit.
145
+ We put Vise through the same brownfield social.plus integration twice per platform once through the **governed Vise workflow**, once from a structured checklist with **Vise switched off** (the control) and ran the whole thing with two coding agents: first **OpenAI Codex GPT-5.4**, then **Claude Sonnet 5** on a hardened protocol. Vise led on all five platform families with both agents. But the two headline gaps are **not** equally solid, and **neither raw average is the number to stand behind**.
146
146
 
147
- **Current end-to-end scorecard**
147
+ > **Three different numbers appear below. They measure different things:**
148
+ > - **+29.1** — Sonnet 5 *full weighted composite*. Includes the +90 definitional capability axis, so it is **not** the earned lift.
149
+ > - **+12.1** — Sonnet 5 *credible-only* (capability axis removed, four fair dimensions re-weighted to 100%). **This is the number we stand behind.**
150
+ > - **+23 to +31** — cross-model convergence deltas. **Still raw composites** (capability-inflated). They prove the lift points the **same direction** across agents — not its magnitude.
148
151
 
149
- | Platform | Brownfield product / social goal | With Vise | Without Vise | Improvement |
150
- |---|---|---:|---:|---:|
151
- | **Android** | Investor watchlist app with social circles | **94.3** | 31.2 | **+63.1** |
152
- | **iOS** | Editorial audio app with curator clubs | **90.1** | 43.0 | **+47.1** |
153
- | **Web** | Fitness media app with program communities | **91.4** | 65.6 | **+25.8** |
154
- | **Flutter** | Training clubhouse with squad discussions | **92.8** | 33.0 | **+59.8** |
155
- | **React Native** | Athlete training app with clubhouse feed | **90.3** | 67.3 | **+23.0** |
152
+ > All deltas are computed on **unrounded** composites, so hand-subtracting the rounded scores in a table can differ by 0.1 (e.g. 83.0 − 70.8 reads as ~12.2, but the exact delta is +12.1).
156
153
 
157
- Average with Vise: **91.8**. Average without Vise: **48.0**. Average improvement: **+43.8 points**.
154
+ ### Per-platform head-to-head
158
155
 
159
- **How the score is calculated:** each run is scored from 0-100 across five dimensions, then weighted into one overall score: capability activation (**25%**), product outcome (**25%**), design integration (**20%**), correctness (**20%**), and efficiency (**10%**). In shorthand:
156
+ Composite score, 0100 shared scale. Failed Codex controls (watchdog-killed before launch) are marked; those cells deflate the Codex control and inflate its gap.
160
157
 
161
- ```text
162
- overall =
163
- capability activation * 0.25 +
164
- product outcome * 0.25 +
165
- design integration * 0.20 +
166
- correctness * 0.20 +
167
- efficiency * 0.10
168
- ```
158
+ | Platform | Fixture | Sonnet 5 Vise | Sonnet 5 no-Vise | Sonnet Δ | Codex Vise | Codex no-Vise | Codex Δ |
159
+ |---|---|--:|--:|--:|--:|--:|--:|
160
+ | Web | PULSE / pulse-studio | 88.3 | 56.8 | **+31.5** | 91.4 | 65.6 | **+25.8** |
161
+ | React Native | Arena Fit | 89.7 | 62.1 | **+27.6** | 90.3 | 67.3 | **+23.0** |
162
+ | iOS | Luminary Club | 77.5 | 48.0 | +29.5 | 90.1 | 43.0 ⚠︎ | +47.1 ⚠︎ |
163
+ | Android | MarketPulse / market-pulse | 77.5 | 50.1 | +27.4 | 94.3 | 31.2 ❌ | +63.1 ❌ |
164
+ | Flutter | Fieldhouse | 78.0 | 48.5 | +29.5 | 92.8 | 33.0 ❌ | +59.8 ❌ |
165
+ | **Average** | 5 fixtures | **82.2** | **53.1** | **+29.1** | 91.8 | 48.0 | ~~+43.8~~ |
166
+
167
+ - ❌ **Control failed before launch.** Flutter's no-Vise control deleted `lib/main.dart` and was watchdog-terminated (33.0); Android's was depressed by an instrument failure (31.2). Both deflate the control and inflate the Codex gap.
168
+ - ⚠︎ **Control ran low but launched.** Codex iOS no-Vise reached only 43.0 — the lowest launched control in either set — on the earlier harness.
169
+
170
+ ### Averages: anchor on the clean run
171
+
172
+ - **Claude Sonnet 5 — anchor (+29.1).** Hardened protocol; **all 5 controls built and launched**. This is the clean, conservative headline. It still carries the +90 definitional axis, so the earned lift is +12.1 credible-only.
173
+ - **OpenAI Codex GPT-5.4 — caveated (~~+43.8~~).** Earlier, less-hardened harness; 2 of 5 controls failed before launch and iOS ran low. That larger gap is **inflated** and is not comparable to the Sonnet number.
174
+
175
+ ### The cross-model signal: where both controls launched, the agents agree
176
+
177
+ On the only two platforms where the Codex control actually built and launched — **Web** and **React Native** — the two agents' deltas land within ~5 points of each other:
178
+
179
+ - **Web:** Codex **+25.8** ≈ Sonnet 5 **+31.5** (agree within 5.7 pts)
180
+ - **React Native:** Codex **+23.0** ≈ Sonnet 5 **+27.6** (agree within 4.6 pts)
181
+
182
+ **Read these as raw composites, not the real-world lift.** Each Vise delta here still embeds the +90 definitional capability axis. So the convergence proves the lift points the **same direction** across two independent agents — it does **not** say the earned magnitude is +23–31. For the earned magnitude, use the credible-only number below. (iOS is left out of this window because the Codex iOS control ran low — the same reason its average is caveated.)
183
+
184
+ ### The credible-only lift: +12.1
185
+
186
+ Drop the Vise-definitional capability axis (the control scores 0 there **by construction**) and re-weight the remaining four dimensions to 100%:
187
+
188
+ | | Vise | no-Vise | Δ |
189
+ |---|--:|--:|--:|
190
+ | Full weighted composite (incl. capability axis) | 82.2 | 53.1 | +29.1 |
191
+ | **Credible-only composite (capability axis removed)** | **83.0** | **70.8** | **+12.1** |
192
+
193
+ (The +12.1 is the delta of the unrounded composites; hand-subtracting the rounded 83.0 − 70.8 reads as ~12.2.)
169
194
 
170
- Capability activation measures whether the Vise arm actually used the governed workflow (inspection, Engagement Intelligence selection, blueprint/sign-off artifacts, docs lookup, checks, sensors, and local `sp-vise/` evidence); no-Vise controls intentionally score 0 on that dimension because they must not use Vise. Product outcome and design integration are judged from runtime-visible social surfaces and screenshots. Correctness covers build/runtime hygiene, SDK-backed source, no leaked secrets, no hardcoded social object IDs, and completed handoff. Efficiency rewards validated, SDK-backed outcome delivered within the time/command budget. Caps lower the score when a run is quota-limited, explicitly unfinished, missing a required multi-surface workplan, or proves too little runtime surface coverage. Platform rows enter the head-to-head average only when the Vise and no-Vise arms target the same platform/scenario and are scored with the same launch-verification standard.
195
+ Where the +12.1 comes from (Sonnet 5): **Product outcome +17.6** and **Design integration +15.8** are the credible wins; **Correctness is a near-tie (+1.9** on Android the checklist control actually built cleaner); **Efficiency +11.7 is a scorer *budget* metric, not wall-clock** the governed arm is **slower** in real time (~2. the control on web); **Capability activation +90 is definitional**, kept out of the headline.
171
196
 
172
- What changed with Vise in the loop:
197
+ ### Methodology & caveats
173
198
 
174
- - The agent starts from a grounded plan instead of guessing the integration shape.
175
- - Product targets are discovered naturally from app state, SDK queries, user choices, or SDK create-flow results, not hardcoded IDs.
176
- - The stopping condition changes from "code was written" to "the requested social surface is planned, checked, and sensor-validated."
177
- - The same workflow applies across web, React Native, Flutter, Android, and iOS.
199
+ - **Vise is the deterministic CLI under test, not an AI model.** Each arm runs the same coding agent on the same brownfield fixture, live tenant, no mocking.
200
+ - **Scoring weights:** capability activation 25% (definitional), product outcome 25%, design integration 20%, correctness 20%, efficiency 10%. The credible-only composite drops the capability axis and re-weights the other four to 100%.
201
+ - **Deltas use unrounded scores.** Displayed scores are rounded to one decimal, so a hand-subtraction of two table cells can differ from the stated delta by 0.1.
202
+ - **Two runs, protocol hardened between them.** Codex GPT-5.4 (Medium) ran late June 2026 on the first, less-hardened harness; Claude Sonnet 5 ran early July 2026 on the current hardened protocol. Because the harness changed, the two agents' controls are **not directly comparable** — which is exactly why the cross-model view is limited to the two platforms where both controls launched.
203
+ - **n = 1 per arm, directional.** July 2026 product-evidence runs on representative fixtures — **not a third-party audit**. For a formal comparison, keep each Vise / no-Vise pair on the same model and reasoning setting.
178
204
 
179
205
  <sub>Cursor, Claude, Codex, GitHub Copilot, VS Code, and other product names are trademarks of their respective owners; social.plus is not affiliated with or endorsed by them.</sub>
180
206
 
@@ -206,8 +232,8 @@ Run `vise <command> --help` for full flags. JSON output is the default for agent
206
232
  | `vise plan-harness [path] --request "..."` | Pre-planning step: build the harness around the request |
207
233
  | `vise init [path] --request "..." [--answer key=value]` | Write the `sp-vise/` compliance contract once blocking intake is answered; exits 7 (`needs-clarification`) otherwise |
208
234
  | `vise workplan next [path] --request "..."` | For broad social requests: print the next uncompleted surface and its focused commands |
209
- | `vise workplan status [path] --request "..."` | Show the workplan sequence and completed surfaces |
210
- | `vise workplan complete [path] --request "..." --surface <id>` | Record a green-checked surface; snapshots evidence under `sp-vise/workplan-snapshots/<surface>/` |
235
+ | `vise workplan status [path] --request "..."` | Show the workplan sequence and completed surfaces; ignores unverifiable or drifted snapshot evidence. If the in-scope surface's live `vise check` is already green, auto-records that one surface (same evidence bar as `workplan complete`) so a working, check-green surface isn't left uncounted |
236
+ | `vise workplan complete [path] --request "..." --surface <id>` | Record a green-checked surface; snapshots evidence plus an integrity manifest under `sp-vise/workplan-snapshots/<surface>/` |
211
237
  | `vise workplan trim [path] --request "..." --surface <id> --reason "..."` | Deliberately omit a companion surface (surface-level scope-omit). `--reason` required; re-arms the blueprint sign-off gate (re-sign the trimmed blueprint before proceeding) |
212
238
 
213
239
  ### Creative pre-planning (advisory)
@@ -250,8 +276,9 @@ Everything in this group is local and advisory: no uploads, no `vise check` exit
250
276
 
251
277
  | Command | Purpose |
252
278
  |---|---|
253
- | `vise check [path]` | Re-validate against the recorded contract: `green`, `needs-attestation`, `deterministic-failures`, `blocked`, or `contract-drift` |
279
+ | `vise check [path]` | Re-validate against the recorded contract: `green`, `needs-attestation`, `deterministic-failures`, `blocked`, `contract-drift`, `completeness-gap`, `selected-capability-failures`, `no-platform` (no SDK platform detected — reported as a failure, not a vacuous green), or `runtime-proof-waived` |
254
280
  | `vise check [path] --ci` | Read-only variant that exits non-zero unless green (for CI) |
281
+ | `vise check [path] --allow-proof-waiver` | Accept an honest `runtime-proof-waived` result (from `vise smoke waive`) as passing (exit 0) instead of blocking; without it a waiver blocks CI by default |
255
282
  | `vise check [path] --new-only` | **Brownfield gate.** With a recorded baseline, gate only on findings introduced *since* the baseline (pre-existing ones are reported but excluded). Default `check` always gates on everything |
256
283
  | `vise baseline [path]` | Snapshot the current pre-existing findings to `sp-vise/baseline.json` so `check --new-only` can separate legacy debt from new gaps. `vise init --baseline` records it at init time |
257
284
  | `vise validate [path]` | Run the deterministic validators only (no attestation comparison) |
@@ -266,6 +293,7 @@ Everything in this group is local and advisory: no uploads, no `vise check` exit
266
293
  |---|---|
267
294
  | `vise run-sensors [path] [--dry-run]` | Run detected project scripts (npm, Gradle, Flutter, lint, typecheck, SDK smokes); `--dry-run` lists without executing |
268
295
  | `vise smoke [path] --log <file>` | Assess a captured mount-smoke log into a pass/fail verdict + record evidence. `expect: "populated"` requires `loaded count=N` with `N > 0`; this catches session-establish and empty-data gaps that static checks cannot see |
296
+ | `vise smoke waive [path] --reason "..." [--mode declined\|deviceless]` | Record an auditable runtime-proof waiver when proof is declined or no device/emulator is available, instead of faking evidence. `vise check` then reports `runtime-proof-waived` (exit 9; accept with `--allow-proof-waiver`) rather than a red-forever live surface |
269
297
  | `vise install-skill --target <host>` | Install the bundled skill into a coding host (see [Quick Start](#quick-start)) |
270
298
  | `vise print-skill` | Print the skill markdown to stdout |
271
299
  | `vise engagement init [path] [--tier ...] [--customer-id ...] [--scope ...]` | Record optional contractual scope metadata |
@@ -349,8 +377,8 @@ Vise writes local planning, compliance, design, and evidence artifacts under `sp
349
377
  | `sp-vise/learning-summary.json` | `vise learning record` | Derived summary; `recommendationOptimization.status: "not-active"` |
350
378
  | `sp-vise/flow.json` | `vise workplan next` / `trim` | Entry-state, selected solution path, active blueprint digest, sign-off state, and omitted companion surfaces |
351
379
  | `sp-vise/flow-blueprint.html` | `vise workplan next` | Human-readable blueprint preview for the alignment gate; review before passing `blueprint_confirmation=<digest>` |
352
- | `sp-vise/workplan.json` | `vise workplan complete` | Broad-request progress: completed surfaces, green-check evidence |
353
- | `sp-vise/workplan-snapshots/<surface>/` | `vise workplan complete` | Per-surface snapshots so later focused surfaces don't erase earlier proof |
380
+ | `sp-vise/workplan.json` | `vise workplan complete` | Broad-request progress: completed surfaces, green-check evidence, snapshot integrity digest |
381
+ | `sp-vise/workplan-snapshots/<surface>/` | `vise workplan complete` | Per-surface snapshots plus `snapshot-manifest.json` so later focused surfaces don't erase earlier proof |
354
382
  | `sp-vise/smoke.json` | project/runtime harness | Declared runtime-smoke surfaces and expected resolution states |
355
383
  | `sp-vise/evidence/runtime-smoke.json` | `vise smoke` | Captured runtime-smoke verdicts used by evidence-citing runtime rules |
356
384
  | `sp-vise/design-contract.json` | `vise design extract` | Extracted tokens, breakpoints, source digests, stable design digest |
@@ -133,7 +133,7 @@ export const CAPABILITIES = [
133
133
  label: "Post composer (create)",
134
134
  outcomes: ["add-feed"],
135
135
  symbols: [/\bcreatePost\b/, /PostRepository[\s\S]{0,20}create/i],
136
- hint: "createPost with a dynamic targetType (not a hardcoded literal)",
136
+ hint: "createPost with a valid user/community targetType and targetId bound to app/auth/route state; global feeds are read aggregates, not write targets",
137
137
  },
138
138
  {
139
139
  id: "pinned-posts",
package/dist/flow.js CHANGED
@@ -77,11 +77,11 @@ function surfaceReadiness(stage) {
77
77
  smokeExpectation: "populated",
78
78
  smokeReason: "A feed integration is only product-proven when visible posts render, not just an empty shell.",
79
79
  targetSources: [
80
- "Current-user or global feed when the selected product story supports it.",
80
+ "Global read feed when the selected product story supports aggregate browsing; user or community target for any post composer.",
81
81
  "Selected community returned by the community discovery/create flow.",
82
82
  "Selected profile/user object from host auth, profile, member, follower, or search state.",
83
83
  ],
84
- tenantData: ["A target global, community, or user feed is known, and it contains at least one visible post for the current user."],
84
+ tenantData: ["A global read feed, community feed, or user feed is known, and it contains at least one visible post for the current user. If a composer is included, its write target is user or community, never global."],
85
85
  consolePrep: ["Confirm post permissions, community privacy, review mode, and any selected post-type availability."],
86
86
  noDataFallback: [
87
87
  "Ask whether to create a visible dogfood post in the selected runtime feed target through Console or SDK post creation.",
@@ -6,6 +6,8 @@ const STATUS_GLOSS = {
6
6
  "contract-drift": "The recorded ruleset no longer matches the installed Vise — re-run init.",
7
7
  "completeness-gap": "Required capabilities are neither built nor opted out (scope-omit) yet.",
8
8
  "selected-capability-failures": "A selected optional capability's sensor failed.",
9
+ "no-platform": "No social.plus SDK platform was detected — there is nothing to validate; scaffold or point at a real app surface.",
10
+ "runtime-proof-waived": "Runtime proof was waived (declined / deviceless) — static checks pass but the live-data surface is NOT runtime-proven. Exits non-zero unless --allow-proof-waiver.",
9
11
  "needs-clarification": "Blocking intake questions are unresolved.",
10
12
  };
11
13
  function asString(value) {
package/dist/outcomes.js CHANGED
@@ -1,4 +1,17 @@
1
1
  import { experienceBundleFor } from "./experience.js";
2
+ export const OUTCOME_COMPANIONS = {
3
+ "add-feed": ["add-comments"],
4
+ "add-comments": ["add-feed"],
5
+ "add-community": ["add-feed", "add-comments"],
6
+ };
7
+ export function relatedOutcomes(outcomes) {
8
+ const set = new Set(outcomes);
9
+ for (const outcome of outcomes) {
10
+ for (const companion of OUTCOME_COMPANIONS[outcome] ?? [])
11
+ set.add(companion);
12
+ }
13
+ return set;
14
+ }
2
15
  export function hasAnswer(answers, id) {
3
16
  const value = answers[id];
4
17
  return typeof value === "string" && value.trim() !== "";
@@ -79,6 +92,7 @@ const REACTION_PATTERNS = [
79
92
  ];
80
93
  const MODERATION_OUTCOME_PATTERNS = [
81
94
  /\b(moderation|report|flag|block user|mute user|hide content|abuse|review queue|admin queue)\b/,
95
+ /\b(?:users?\s+(?:block(?:ing)?|mut(?:e|ing))|(?:block(?:ing)?|mut(?:e|ing))\s+(?:a\s+|the\s+)?users?)\b/,
82
96
  ];
83
97
  const CHAT_PATTERNS = [
84
98
  /\b(chat|messaging|dm|direct message|conversation|group chat|channel|inbox)\b/,
@@ -579,11 +593,11 @@ const addFeed = {
579
593
  });
580
594
  questions.push({
581
595
  id: "feed_target",
582
- question: "What concrete feed target should reads and post creation use?",
583
- why: "Prefer the global (app-wide) feed or the current user's feed for a general social feed both are ID-free, need no membership to post, and are the safe default. The no-invent rule applies to IDs: never invent a communityId, targetId, or feedId. Choose a community target only when the request names a community-scoped surface, and then source it from route/app state, SDK discovery, user selection, or a create flow.",
596
+ question: "What feed source and post creation target should the first feed use?",
597
+ why: "Global feed is a read aggregate from users the viewer follows and communities the viewer joined; it is not a post creation target. If the surface includes a composer, create posts only to a user target (usually the current user) or a community target sourced from route/app state, SDK discovery, user selection, or a create flow. Never invent a communityId, targetId, or feedId.",
584
598
  required: true,
585
599
  blocksImplementationWhenMissing: true,
586
- options: ["app-defined/global feed", "current user's feed", "selected user's feed", "community selected from route/discovery/create flow", "ask user at runtime"],
600
+ options: ["global read feed + current-user post target", "current user's feed + current-user post target", "community feed selected from route/discovery/create flow", "selected user's feed (read-only unless the app owns a valid user post target)", "ask user at runtime"],
587
601
  });
588
602
  questions.push({
589
603
  id: "target_screen_or_route",
@@ -631,7 +645,7 @@ const addFeed = {
631
645
  "lifecycle owner for subscribe/unsubscribe cleanup",
632
646
  "feature choice: feed, comments, profile, community, chat, notifications, or another social surface",
633
647
  "feed scope: global, user, or community",
634
- "concrete feed target for reads and post creation: app-defined/global feed, current user feed, selected user target, or community selected from route/discovery/create flow",
648
+ "feed source and post creation target: global is read-only aggregate; createPost targets must be user or community",
635
649
  "target screen or route for the feed UI",
636
650
  ],
637
651
  implementationRules: () => [
@@ -644,17 +658,17 @@ const addFeed = {
644
658
  : ["requiredInputs.design token or theme source file"];
645
659
  return [
646
660
  {
647
- step: "Confirm the target route/screen, feed scope, and concrete feed target before writing code.",
661
+ step: "Confirm the target route/screen, feed read source, and post creation target before writing code.",
648
662
  evidence: [
649
663
  "requiredInputs.feed scope",
650
- "requiredInputs.concrete feed target",
664
+ "requiredInputs.feed source and post creation target",
651
665
  "requiredInputs.target screen or route",
652
666
  ],
653
667
  },
654
668
  {
655
- step: "Bind targetType and targetId in createPost (and query) calls to the intake-resolved feed target e.g. communityId from route params, userId from auth context, or a prop passed from the screen's caller. A variable or prop that is declared but never wired to the actual target is the same intent gap as a hardcoded literal: the validator fires on literals; the correctness gap fires on unbound variables.",
669
+ step: "Bind feed queries to the intake-resolved read source, and bind createPost to a real write target. A global feed is read-only aggregate; do not call createPost with targetType/global. For a composer, use targetType=user with the current/app-selected user target or targetType=community with a communityId from route params, SDK discovery, user selection, or a create flow. A variable or prop that is declared but never wired to the actual target is the same intent gap as a hardcoded literal: the validator fires on literals; the correctness gap fires on unbound variables.",
656
670
  evidence: [
657
- "requiredInputs.concrete feed target",
671
+ "requiredInputs.feed source and post creation target",
658
672
  "requiredInputs.feed scope",
659
673
  ],
660
674
  },
@@ -791,8 +805,8 @@ const addFeed = {
791
805
  "profile.social-counts",
792
806
  ],
793
807
  stopConditions: (ctx) => filterStops(ctx.answers, [
794
- { id: "feed_target", text: "The concrete feed target is unknown; never invent a communityId, targetId, or feedId. For a general social feed, default to the ID-free app-wide global feed or the current user's feed; reserve a specific community/target for an explicitly community-scoped request." },
795
- { id: "feed_target", text: "If post creation is in scope, the write target must be a concrete feed the global or current-user feed (no id, no membership needed), or a community/selected target the user or app state provides (never a hardcoded or invented id)." },
808
+ { id: "feed_target", text: "The feed source and post creation target are unknown; never invent a communityId, targetId, or feedId. For a general social feed, a global feed may be the read source, but composer writes must target a user or community." },
809
+ { id: "feed_target", text: "If post creation is in scope, the write target must be user or community. Global feed is an aggregate read surface from followed users and joined communities, not a createPost target." },
796
810
  ]),
797
811
  resolvePlan: () => [
798
812
  {