@amityco/social-plus-vise 0.14.3 → 0.14.4
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 +2 -1
- package/README.md +3 -3
- package/dist/capabilities.js +27 -8
- package/dist/tools/compliance.js +2 -2
- package/package.json +1 -1
- package/skills/social-plus-vise/SKILL.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,7 @@ 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
|
-
## 0.14.
|
|
7
|
+
## 0.14.4 — 2026-06-04
|
|
8
8
|
|
|
9
9
|
**Theme:** Completeness-gap enforcement and add-feed guidance hardening (image upload + poll creation + pagination build step).
|
|
10
10
|
|
|
@@ -17,6 +17,7 @@ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/
|
|
|
17
17
|
### Fixed
|
|
18
18
|
- **`targetType` rule recommendation tightened:** the `validateFeedTargetTypeExplicit` validator recommendation now explicitly calls for binding `targetType` to the intake-resolved feed target (e.g. `communityId` from route params, `userId` from auth context) rather than simply avoiding a literal. Prevents agents from introducing an unbound variable that satisfies the literal check while leaving the same intent gap.
|
|
19
19
|
- **Completeness assessment note language corrected:** `vise plan` completeness note and `assessCompleteness` output no longer say "advisory — never fails the check". They now accurately state that missing items cause `vise check` to exit `completeness-gap` (exit code 5).
|
|
20
|
+
- **Scope-omit markers now require a reason:** `// vise: scope-omit <id>` no longer clears a completeness gap by itself. The marker must include a reason (for example `// vise: scope-omit post-poll — polls disabled for this tenant`) or the capability remains `missing`.
|
|
20
21
|
|
|
21
22
|
### Changed
|
|
22
23
|
- **`SKILL.md` scope-omit enforcement:** the Required Loop section now treats missing completeness items as a stop condition, not a suggestion. Agents must either implement or `// vise: scope-omit <id> — <reason>` each missing capability before reporting done.
|
package/README.md
CHANGED
|
@@ -77,9 +77,9 @@ Vise validates on three layers, and the layer is set by the *kind of claim* —
|
|
|
77
77
|
|---|---|---|---|
|
|
78
78
|
| **SDK compliance** | "this is **wrong**" | 300 deterministic rules (session renewal, live-collection vs one-shot, no secret in logs, parent-child rendering, ban-state gating…) | **Hard gate** — `vise check` blocks until green or attested. A small advisory subset surfaces as informational only and never blocks. |
|
|
79
79
|
| **Design conformance** | "this **looks off**" | extract the customer's design system into a contract, then check token usage | **Advisory** — `vise design check`/`preview`; never fails a build |
|
|
80
|
-
| **Feature completeness** | "this is **missing**" | Vise proposes the full SDK feature surface per outcome; the agent opts out of anything out of scope with a recorded reason | **
|
|
80
|
+
| **Feature completeness** | "this is **missing**" | Vise proposes the full SDK feature surface per outcome; the agent opts out of anything out of scope with a recorded reason | **Decision gate** — `vise check` exits `completeness-gap` until each missing capability is built or validly opted out |
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
Correctness is gated by deterministic rules or attestations. Completeness is gated by explicit scope decisions: if a capability is legitimately out of scope, record `// vise: scope-omit <id> — <reason>` and it no longer blocks. Conformance remains advisory because "matches the brand" is legitimately subjective. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
83
83
|
|
|
84
84
|
### Relationship to social.plus Block Factory
|
|
85
85
|
|
|
@@ -414,7 +414,7 @@ jobs:
|
|
|
414
414
|
| `2` | One or more rules have deterministic failures |
|
|
415
415
|
| `3` | One or more blockers fired (missing prerequisite, e.g. `google-services.json`) |
|
|
416
416
|
| `4` | Contract drift — rules in `sp-vise/compliance.json` no longer match the current ruleset |
|
|
417
|
-
| `5` | One or more expected capabilities are neither implemented nor opted-out — add the capability or place `// vise: scope-omit <id> — <reason>` |
|
|
417
|
+
| `5` | One or more expected capabilities are neither implemented nor validly opted-out — add the capability or place `// vise: scope-omit <id> — <reason>` |
|
|
418
418
|
|
|
419
419
|
`vise check --ci` is read-only. It never updates `sp-vise/`. The JSON output includes a `ci` block with structured details for pipeline logs.
|
|
420
420
|
|
package/dist/capabilities.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Feature-completeness assessment
|
|
2
|
+
* Feature-completeness assessment.
|
|
3
3
|
*
|
|
4
4
|
* Boundary (see the validation-boundaries principle): completeness is a "this is
|
|
5
|
-
* missing" claim — a universal-negative over open-ended correct implementations
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* missing" claim — a universal-negative over open-ended correct implementations
|
|
6
|
+
* unless the customer/agent explicitly removes it from scope. Missing capabilities
|
|
7
|
+
* now produce `completeness-gap` in `vise check`; a recorded scope-omit reason is
|
|
8
|
+
* the false-positive escape hatch.
|
|
8
9
|
*
|
|
9
10
|
* Memory-independence comes from inversion: VISE authors the canonical capability
|
|
10
11
|
* set per outcome; the agent must OPT OUT of a capability with a recorded reason
|
|
@@ -367,7 +368,7 @@ export const CAPABILITIES = [
|
|
|
367
368
|
hint: "respect Amity's server-side notification settings/preferences (getSettings)",
|
|
368
369
|
},
|
|
369
370
|
];
|
|
370
|
-
const ADVISORY_NOTE = "Build each missing capability, or opt out with a recorded reason: `// vise: scope-omit <id> <reason>`. Missing capabilities that are neither built nor opted-out cause `vise check` to exit with status `completeness-gap` (exit code 5).";
|
|
371
|
+
const ADVISORY_NOTE = "Build each missing capability, or opt out with a recorded reason: `// vise: scope-omit <id> — <reason>`. A scope-omit marker without a reason is invalid and still counts as missing. Missing capabilities that are neither built nor validly opted-out cause `vise check` to exit with status `completeness-gap` (exit code 5).";
|
|
371
372
|
/** The Vise-authored capability checklist for an outcome (for `vise plan` feed-forward). */
|
|
372
373
|
export function capabilityChecklist(outcome) {
|
|
373
374
|
return CAPABILITIES.filter((c) => c.outcomes.includes(outcome)).map((c) => ({ id: c.id, label: c.label, hint: c.hint }));
|
|
@@ -376,14 +377,24 @@ export function capabilityChecklist(outcome) {
|
|
|
376
377
|
export function assessCompleteness(source, outcome) {
|
|
377
378
|
const caps = CAPABILITIES.filter((c) => c.outcomes.includes(outcome));
|
|
378
379
|
const optOuts = new Map();
|
|
380
|
+
const invalidOptOuts = new Map();
|
|
379
381
|
const omitPattern = /vise:\s*scope-omit\s+([a-z][\w-]*)\s*(?:[—:|-]+\s*(.*))?/gi;
|
|
380
382
|
let match;
|
|
381
383
|
while ((match = omitPattern.exec(source)) !== null) {
|
|
382
|
-
|
|
384
|
+
const id = match[1].toLowerCase();
|
|
385
|
+
const reason = (match[2] ?? "").trim();
|
|
386
|
+
if (reason) {
|
|
387
|
+
optOuts.set(id, reason);
|
|
388
|
+
invalidOptOuts.delete(id);
|
|
389
|
+
}
|
|
390
|
+
else if (!optOuts.has(id)) {
|
|
391
|
+
invalidOptOuts.set(id, "scope-omit marker must include a reason");
|
|
392
|
+
}
|
|
383
393
|
}
|
|
384
394
|
const present = [];
|
|
385
395
|
const missing = [];
|
|
386
396
|
const optedOut = [];
|
|
397
|
+
const invalid = [];
|
|
387
398
|
for (const cap of caps) {
|
|
388
399
|
if (optOuts.has(cap.id)) {
|
|
389
400
|
optedOut.push({ id: cap.id, reason: optOuts.get(cap.id) });
|
|
@@ -392,10 +403,18 @@ export function assessCompleteness(source, outcome) {
|
|
|
392
403
|
present.push({ id: cap.id, label: cap.label });
|
|
393
404
|
}
|
|
394
405
|
else {
|
|
395
|
-
|
|
406
|
+
const invalidReason = invalidOptOuts.get(cap.id);
|
|
407
|
+
if (invalidReason) {
|
|
408
|
+
invalid.push({ id: cap.id, reason: invalidReason });
|
|
409
|
+
}
|
|
410
|
+
missing.push({
|
|
411
|
+
id: cap.id,
|
|
412
|
+
label: cap.label,
|
|
413
|
+
hint: invalidReason ? `${cap.hint}; found scope-omit marker without a reason, so add a reason or implement it` : cap.hint,
|
|
414
|
+
});
|
|
396
415
|
}
|
|
397
416
|
}
|
|
398
|
-
return { outcome, present, missing, optedOut, note: ADVISORY_NOTE };
|
|
417
|
+
return { outcome, present, missing, optedOut, invalidOptOuts: invalid, note: ADVISORY_NOTE };
|
|
399
418
|
}
|
|
400
419
|
// ── Bounded source read (advisory; perf-bounded like the design check scan) ──
|
|
401
420
|
const SCAN_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".dart", ".kt", ".java", ".swift", ".vue"]);
|
package/dist/tools/compliance.js
CHANGED
|
@@ -456,9 +456,9 @@ export async function checkCompliance(repoPath) {
|
|
|
456
456
|
const needsAttestation = results.some((result) => result.status === "attestation-needed" || result.status === "stale");
|
|
457
457
|
// Precedence: blocked (3) > deterministic-failures (2) > needs-attestation (1) > completeness-gap (5) > green (0).
|
|
458
458
|
// Contract drift (exit 4) is handled earlier and short-circuits the loop.
|
|
459
|
-
// Completeness-gap: capabilities that are neither present nor opted-out require an explicit decision
|
|
459
|
+
// Completeness-gap: capabilities that are neither present nor validly opted-out require an explicit decision
|
|
460
460
|
// (build it, or place // vise: scope-omit <id> — <reason>). The scope-omit escape hatch keeps this
|
|
461
|
-
// FP-free
|
|
461
|
+
// FP-free because any capability can be excluded with a recorded reason. Failure to assess is silently ignored.
|
|
462
462
|
const completeness = (await assessProjectCompleteness(inspection.effectiveRoot, compliance.outcome).catch(() => null)) ?? undefined;
|
|
463
463
|
const hasCompletenessGap = (completeness?.missing.length ?? 0) > 0;
|
|
464
464
|
// Blocked wins because the agent cannot proceed without customer input;
|
package/package.json
CHANGED
|
@@ -244,13 +244,13 @@ vise plan . --request "<feed or post request>"
|
|
|
244
244
|
|
|
245
245
|
Require a concrete target from the app: current user feed, selected community, selected channel, or another user-provided domain object. Do not hardcode random target IDs.
|
|
246
246
|
|
|
247
|
-
**Decide engagement scope explicitly — Vise authors the checklist, you subtract with a reason.** `vise plan` returns a `completenessChecklist` (the canonical capabilities for the outcome, e.g. comments, reactions, pagination, polls, media, moderation) and `vise check` reports each as present / missing / opted-out.
|
|
247
|
+
**Decide engagement scope explicitly — Vise authors the checklist, you subtract with a reason.** `vise plan` returns a `completenessChecklist` (the canonical capabilities for the outcome, e.g. comments, reactions, pagination, polls, media, moderation) and `vise check` reports each as present / missing / opted-out. Missing items that are neither built nor validly opted-out produce `completeness-gap` (exit code 5), because they are silent drops. For each capability: build it, or explicitly opt out with a recorded marker in the code so the omission is reviewable, not accidental:
|
|
248
248
|
|
|
249
249
|
```
|
|
250
250
|
// vise: scope-omit poll — text + image feed only; polls disabled for this tenant
|
|
251
251
|
```
|
|
252
252
|
|
|
253
|
-
Do not report the integration complete while any capability is `missing`. Re-run `vise check .` after placing a scope-omit marker to confirm it moves from `missing` to `opted-out`.
|
|
253
|
+
Do not report the integration complete while any capability is `missing`. A scope-omit marker must include a reason after the capability id; otherwise it remains invalid and the capability still counts as missing. Re-run `vise check .` after placing a scope-omit marker to confirm it moves from `missing` to `opted-out`.
|
|
254
254
|
|
|
255
255
|
**Demo wiring (when the app needs to compile before the real target source exists):** even at the top-level `App` / `MaterialApp` / `_app.tsx` / `AppDelegate` wiring site, do not pass a literal string. Use the host platform's compile-time env channel so the rule sees no string literal at the call site:
|
|
256
256
|
|