@amityco/social-plus-vise 0.14.16 → 0.14.18
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 +21 -0
- package/README.md +3 -3
- package/dist/capabilities.js +98 -0
- package/dist/outcomes.js +12 -3
- package/dist/productExpectations.js +92 -0
- package/dist/tools/compliance.js +26 -1
- package/dist/tools/integration.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ 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.18 — 2026-06-05
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **Broader product-first rule surface:** feed target resolution, feed UI states, feed pagination, UGC moderation affordances, post status filtering, opaque pagination cursors, and server-synced unread counts now surface through shared product expectation IDs while preserving the exact platform `contractRuleId`/`validator.sensorId` evidence.
|
|
11
|
+
- **Capability feed-forward expansion:** the promoted feed/data expectations now participate in platform capability preflight where the bundled SDK surface proves support, so plans can show product-level expectations before implementation rather than only after `vise check`.
|
|
12
|
+
- **Validation checklist clarity:** add-feed, add-comments, and add-chat plans now use product-level expectation IDs for the promoted shared behaviors instead of exposing platform-specific validator names as the primary checklist items.
|
|
13
|
+
|
|
14
|
+
### Verified
|
|
15
|
+
- Focused CLI, fixture, MCP, product-flow, agent-flow, capability, native-idiom, and rule-coverage suites passed. A local iOS `whoops` plan smoke confirmed the broader product ids with iOS sensor evidence.
|
|
16
|
+
|
|
17
|
+
## 0.14.17 — 2026-06-05
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- **Product-first plan rules:** `vise plan` now shows shared product expectation IDs as primary `applicableRules[].rule_id` values when a rule is backed by platform-specific sensors, while preserving the exact `contract_rule_id`, `contract_rule_digest`, and `validator.sensorId` evidence needed for debugging and attestations.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **Design rejection flow coverage:** the host-agent smoke now locks the behavior where `design_contract_confirmation=no` rejects the preview, withholds the design contract from feed-forward, asks for a replacement design source, and blocks `vise init` until that source is resolved.
|
|
24
|
+
|
|
25
|
+
### Verified
|
|
26
|
+
- Full `npm run validate` passed. A local iOS `whoops` plan smoke confirmed shared chat ids are public while iOS sensor ids remain as validator evidence.
|
|
27
|
+
|
|
7
28
|
## 0.14.16 — 2026-06-05
|
|
8
29
|
|
|
9
30
|
### Changed
|
package/README.md
CHANGED
|
@@ -161,16 +161,16 @@ Aggregate: **98/99 expected feed capabilities** and **27/27 selected optional ca
|
|
|
161
161
|
|
|
162
162
|
### Current Release Validation
|
|
163
163
|
|
|
164
|
-
Version 0.14.
|
|
164
|
+
Version 0.14.18 carries current release proof around the full feed-forward, product-expectation, and validation flow:
|
|
165
165
|
|
|
166
166
|
| Surface | What was validated |
|
|
167
167
|
|---|---|
|
|
168
168
|
| **Product flow** | Local end-to-end smoke covers design extraction, plan feed-forward, blocking intake, answered init, capability check, design conformance, and sensor discovery. |
|
|
169
169
|
| **Plan questions** | Plans surface blocking questions such as `feature_surface` and `design_contract_confirmation`, plus optional choices such as `feed_optional_capabilities`. |
|
|
170
170
|
| **Capability-to-sensor flow** | Vise checks platform support, matches the prompt to available capabilities, offers supported features as questions, records answers, and turns selected answers into sensors in `vise check`. |
|
|
171
|
-
| **Shared product expectations** | Public IDs such as `comments.thread-read-write` stay platform-agnostic while check results retain concrete `contractRuleId` and `validator.sensorId` evidence. |
|
|
171
|
+
| **Shared product expectations** | Public IDs such as `feed.target-resolved`, `moderation.affordance-present`, `comments.thread-read-write`, and `chat.unread-visible` stay platform-agnostic while check results retain concrete `contractRuleId` and `validator.sensorId` evidence. |
|
|
172
172
|
| **Rule detection** | TP-track dashboard detects **311/311 seeded rule gaps (100.0%)** in the static corpus. |
|
|
173
|
-
| **Packed-package smoke** |
|
|
173
|
+
| **Packed-package smoke** | Packed-package and host-agent smokes exercise the release tarball path, surfaced plan questions, selected optional capability sensors, rejected design confirmation handling, and exact contract-rule evidence for shared product expectations. |
|
|
174
174
|
|
|
175
175
|
### Supporting Proof
|
|
176
176
|
|
package/dist/capabilities.js
CHANGED
|
@@ -427,6 +427,104 @@ export const OPTIONAL_CAPABILITIES = [
|
|
|
427
427
|
},
|
|
428
428
|
];
|
|
429
429
|
export const SHARED_PRODUCT_EXPECTATIONS = [
|
|
430
|
+
{
|
|
431
|
+
id: "feed.target-resolved",
|
|
432
|
+
label: "Resolved feed target",
|
|
433
|
+
outcomes: ["add-feed"],
|
|
434
|
+
kind: "shared-expectation",
|
|
435
|
+
availability: [
|
|
436
|
+
{
|
|
437
|
+
label: "SDK feed target/query APIs",
|
|
438
|
+
symbols: [/\btargetId\b/i, /\btargetType\b/i, /\bgetUserFeed\b/i, /\bgetCommunityFeed\b/i, /\bgetGlobalFeed\b/i, /\bgetPosts\b/i, /\bqueryPosts\b/i],
|
|
439
|
+
},
|
|
440
|
+
],
|
|
441
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
442
|
+
hint: "bind targetType and targetId to route params, auth context, or customer-owned selection state; do not invent literals",
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
id: "feed.ui-states-present",
|
|
446
|
+
label: "Feed loading/empty/error states",
|
|
447
|
+
outcomes: ["add-feed"],
|
|
448
|
+
kind: "shared-expectation",
|
|
449
|
+
availability: [
|
|
450
|
+
{
|
|
451
|
+
label: "SDK feed collection/query APIs",
|
|
452
|
+
symbols: [/\bgetUserFeed\b/i, /\bgetCommunityFeed\b/i, /\bgetGlobalFeed\b/i, /\bgetPosts\b/i, /\bqueryPosts\b/i],
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
456
|
+
hint: "render loading, empty, error, and data states around the feed collection instead of only the success path",
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
id: "feed.pagination-wired",
|
|
460
|
+
label: "Feed pagination",
|
|
461
|
+
outcomes: ["add-feed"],
|
|
462
|
+
kind: "shared-expectation",
|
|
463
|
+
availability: [
|
|
464
|
+
{
|
|
465
|
+
label: "SDK pagination APIs",
|
|
466
|
+
symbols: [/\bnextPage\b/i, /\bnextPageToken\b/i, /\bloadMore\b/i, /\bonNextPage\b/i, /\bhasNext\b/i],
|
|
467
|
+
},
|
|
468
|
+
],
|
|
469
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
470
|
+
hint: "wire load-more or automatic paging to the SDK collection; a fixed first page is incomplete",
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
id: "moderation.affordance-present",
|
|
474
|
+
label: "UGC moderation affordance",
|
|
475
|
+
outcomes: ["add-feed", "add-comments", "add-chat"],
|
|
476
|
+
kind: "shared-expectation",
|
|
477
|
+
availability: [
|
|
478
|
+
{
|
|
479
|
+
label: "SDK moderation/reporting APIs",
|
|
480
|
+
symbols: [/\bflagPost\b/i, /\bflagComment\b/i, /\bflagMessage\b/i, /\breport\b/i, /\bmoderation\b/i, /\bblockUser\b/i],
|
|
481
|
+
},
|
|
482
|
+
],
|
|
483
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
484
|
+
hint: "show report/flag/block/hide affordances on user-generated content, scoped to the surface being built",
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
id: "posts.status-filtered",
|
|
488
|
+
label: "Post status filtering",
|
|
489
|
+
outcomes: ["add-feed"],
|
|
490
|
+
kind: "shared-expectation",
|
|
491
|
+
availability: [
|
|
492
|
+
{
|
|
493
|
+
label: "SDK post status/filter APIs",
|
|
494
|
+
symbols: [/\bstatus\b/i, /\bstatuses\b/i, /\bfeedType\b/i, /\bpublished\b/i, /\bincludeDeleted\b/i],
|
|
495
|
+
},
|
|
496
|
+
],
|
|
497
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
498
|
+
hint: "filter post queries to published/non-deleted content so moderated or deleted posts do not leak into normal feeds",
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
id: "pagination.cursor-opaque",
|
|
502
|
+
label: "Opaque pagination cursors",
|
|
503
|
+
outcomes: ["add-feed", "add-comments", "add-chat"],
|
|
504
|
+
kind: "shared-expectation",
|
|
505
|
+
availability: [
|
|
506
|
+
{
|
|
507
|
+
label: "SDK cursor pagination APIs",
|
|
508
|
+
symbols: [/\bnextPage\b/i, /\bnextPageToken\b/i, /\bloadMore\b/i, /\bonNextPage\b/i, /\bhasNext\b/i],
|
|
509
|
+
},
|
|
510
|
+
],
|
|
511
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
512
|
+
hint: "pass SDK-provided cursor tokens or call SDK next-page helpers; never compute numeric page offsets",
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
id: "unread.server-synced",
|
|
516
|
+
label: "Server-synced unread counts",
|
|
517
|
+
outcomes: ["add-feed", "add-chat"],
|
|
518
|
+
kind: "shared-expectation",
|
|
519
|
+
availability: [
|
|
520
|
+
{
|
|
521
|
+
label: "SDK unread state",
|
|
522
|
+
symbols: [/\bunreadCount\b/i, /\bChannelUnread\b/i, /\bobserveUserUnread\b/i, /\bgetUnread\w*\b/i, /\bgetTotalChannelUnread\b/i],
|
|
523
|
+
},
|
|
524
|
+
],
|
|
525
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
526
|
+
hint: "source unread badges from the SDK stream instead of counting stale local arrays",
|
|
527
|
+
},
|
|
430
528
|
{
|
|
431
529
|
id: "feed.rich-post-rendering",
|
|
432
530
|
label: "Rich post rendering",
|
package/dist/outcomes.js
CHANGED
|
@@ -653,7 +653,13 @@ const addFeed = {
|
|
|
653
653
|
validation: (platform) => [
|
|
654
654
|
"feed target identified",
|
|
655
655
|
"no invented communityId/targetId/feedId",
|
|
656
|
-
|
|
656
|
+
"feed.target-resolved",
|
|
657
|
+
"feed.ui-states-present",
|
|
658
|
+
"feed.pagination-wired",
|
|
659
|
+
"moderation.affordance-present",
|
|
660
|
+
"posts.status-filtered",
|
|
661
|
+
"pagination.cursor-opaque",
|
|
662
|
+
"unread.server-synced",
|
|
657
663
|
"feed.rich-post-rendering",
|
|
658
664
|
"feed.rich-post-composer-scope",
|
|
659
665
|
"comments.thread-read-write",
|
|
@@ -789,7 +795,8 @@ const addComments = {
|
|
|
789
795
|
"no invented postId/commentId",
|
|
790
796
|
`${platform}.comments.target-resolved`,
|
|
791
797
|
"comments.thread-read-write",
|
|
792
|
-
|
|
798
|
+
"moderation.affordance-present",
|
|
799
|
+
"pagination.cursor-opaque",
|
|
793
800
|
],
|
|
794
801
|
stopConditions: (ctx) => filterStops(ctx.answers, [
|
|
795
802
|
{ id: "comment_target", text: "The comment target entity is unknown; do not invent postId, commentId, or parent entity references." },
|
|
@@ -1021,7 +1028,9 @@ const addChat = {
|
|
|
1021
1028
|
`${platform}.chat.channel-target-resolved`,
|
|
1022
1029
|
`${platform}.chat.message-observer-cleanup`,
|
|
1023
1030
|
`${platform}.chat.send-error-handling`,
|
|
1024
|
-
|
|
1031
|
+
"moderation.affordance-present",
|
|
1032
|
+
"unread.server-synced",
|
|
1033
|
+
"pagination.cursor-opaque",
|
|
1025
1034
|
"chat.unread-visible",
|
|
1026
1035
|
...(platform === "android" || platform === "flutter" || platform === "ios" ? ["chat.message-order-explicit"] : []),
|
|
1027
1036
|
],
|
|
@@ -1,4 +1,93 @@
|
|
|
1
|
+
export const PRODUCT_EXPECTATION_TITLES = {
|
|
2
|
+
"feed.target-resolved": "Feed target comes from app state",
|
|
3
|
+
"feed.ui-states-present": "Feed renders loading, empty, and error states",
|
|
4
|
+
"feed.pagination-wired": "Feed pagination is wired",
|
|
5
|
+
"moderation.affordance-present": "UGC moderation affordance is present",
|
|
6
|
+
"posts.status-filtered": "Post queries filter unsafe statuses",
|
|
7
|
+
"pagination.cursor-opaque": "Pagination cursors stay opaque",
|
|
8
|
+
"unread.server-synced": "Unread counts use the server-synced stream",
|
|
9
|
+
"feed.rich-post-rendering": "Feed renders rich post types",
|
|
10
|
+
"feed.rich-post-composer-scope": "Feed composer surfaces rich post scope",
|
|
11
|
+
"comments.thread-read-write": "Comment threads support reading and creation",
|
|
12
|
+
"chat.unread-visible": "Chat unread counts are visible",
|
|
13
|
+
"chat.message-order-explicit": "Chat message order is explicit",
|
|
14
|
+
"profile.social-counts": "Profile social counts come from the SDK",
|
|
15
|
+
};
|
|
16
|
+
const platformBindings = (expectationId, sensorsByPlatform) => Object.entries(sensorsByPlatform).flatMap(([platform, sensors]) => (Array.isArray(sensors) ? sensors : [sensors]).map((sensorId) => ({
|
|
17
|
+
expectationId,
|
|
18
|
+
sensorId,
|
|
19
|
+
platform,
|
|
20
|
+
})));
|
|
1
21
|
export const PRODUCT_EXPECTATION_BINDINGS = [
|
|
22
|
+
...platformBindings("feed.target-resolved", {
|
|
23
|
+
typescript: ["typescript.feed.target.literal", "typescript.feed.target-type-explicit"],
|
|
24
|
+
"react-native": ["react-native.feed.target.literal", "react-native.feed.target-type-explicit"],
|
|
25
|
+
android: ["android.feed.target.literal", "android.feed.target-type-explicit"],
|
|
26
|
+
flutter: ["flutter.feed.target.literal", "flutter.feed.target-type-explicit"],
|
|
27
|
+
ios: ["ios.feed.target.literal", "ios.feed.target-type-explicit"],
|
|
28
|
+
}),
|
|
29
|
+
...platformBindings("feed.ui-states-present", {
|
|
30
|
+
typescript: "typescript.feed.ui-states-present",
|
|
31
|
+
"react-native": "react-native.feed.ui-states-present",
|
|
32
|
+
android: "android.feed.ui-states-present",
|
|
33
|
+
flutter: "flutter.feed.ui-states-present",
|
|
34
|
+
ios: "ios.feed.ui-states-present",
|
|
35
|
+
}),
|
|
36
|
+
...platformBindings("feed.pagination-wired", {
|
|
37
|
+
typescript: "typescript.feed.pagination-wired",
|
|
38
|
+
"react-native": "react-native.feed.pagination-wired",
|
|
39
|
+
android: "android.feed.pagination-wired",
|
|
40
|
+
flutter: "flutter.feed.pagination-wired",
|
|
41
|
+
ios: "ios.feed.pagination-wired",
|
|
42
|
+
}),
|
|
43
|
+
...platformBindings("moderation.affordance-present", {
|
|
44
|
+
typescript: [
|
|
45
|
+
"typescript.feed.moderation-affordance-present",
|
|
46
|
+
"typescript.comments.moderation-affordance-present",
|
|
47
|
+
"typescript.chat.moderation-affordance-present",
|
|
48
|
+
],
|
|
49
|
+
"react-native": [
|
|
50
|
+
"react-native.feed.moderation-affordance-present",
|
|
51
|
+
"react-native.comments.moderation-affordance-present",
|
|
52
|
+
"react-native.chat.moderation-affordance-present",
|
|
53
|
+
],
|
|
54
|
+
android: [
|
|
55
|
+
"android.feed.moderation-affordance-present",
|
|
56
|
+
"android.comments.moderation-affordance-present",
|
|
57
|
+
"android.chat.moderation-affordance-present",
|
|
58
|
+
],
|
|
59
|
+
flutter: [
|
|
60
|
+
"flutter.feed.moderation-affordance-present",
|
|
61
|
+
"flutter.comments.moderation-affordance-present",
|
|
62
|
+
"flutter.chat.moderation-affordance-present",
|
|
63
|
+
],
|
|
64
|
+
ios: [
|
|
65
|
+
"ios.feed.moderation-affordance-present",
|
|
66
|
+
"ios.comments.moderation-affordance-present",
|
|
67
|
+
"ios.chat.moderation-affordance-present",
|
|
68
|
+
],
|
|
69
|
+
}),
|
|
70
|
+
...platformBindings("posts.status-filtered", {
|
|
71
|
+
typescript: "typescript.posts.status-filter-applied",
|
|
72
|
+
"react-native": "react-native.posts.status-filter-applied",
|
|
73
|
+
android: "android.posts.status-filter-applied",
|
|
74
|
+
flutter: "flutter.posts.status-filter-applied",
|
|
75
|
+
ios: "ios.posts.status-filter-applied",
|
|
76
|
+
}),
|
|
77
|
+
...platformBindings("pagination.cursor-opaque", {
|
|
78
|
+
typescript: "typescript.pagination.cursor-opaque",
|
|
79
|
+
"react-native": "react-native.pagination.cursor-opaque",
|
|
80
|
+
android: "android.pagination.cursor-opaque",
|
|
81
|
+
flutter: "flutter.pagination.cursor-opaque",
|
|
82
|
+
ios: "ios.pagination.cursor-opaque",
|
|
83
|
+
}),
|
|
84
|
+
...platformBindings("unread.server-synced", {
|
|
85
|
+
typescript: "typescript.unread.subscribed-not-counted",
|
|
86
|
+
"react-native": "react-native.unread.subscribed-not-counted",
|
|
87
|
+
android: "android.unread.subscribed-not-counted",
|
|
88
|
+
flutter: "flutter.unread.subscribed-not-counted",
|
|
89
|
+
ios: "ios.unread.subscribed-not-counted",
|
|
90
|
+
}),
|
|
2
91
|
{
|
|
3
92
|
expectationId: "feed.rich-post-rendering",
|
|
4
93
|
sensorId: "typescript.feed.post-datatype-handled",
|
|
@@ -266,6 +355,9 @@ export function productFindingIdentity(sensorId) {
|
|
|
266
355
|
export function publicProductRuleId(ruleId) {
|
|
267
356
|
return productExpectationBindingForSensor(ruleId)?.expectationId ?? ruleId;
|
|
268
357
|
}
|
|
358
|
+
export function productExpectationTitle(expectationId) {
|
|
359
|
+
return PRODUCT_EXPECTATION_TITLES[expectationId];
|
|
360
|
+
}
|
|
269
361
|
export function findingMatchesId(finding, id) {
|
|
270
362
|
return finding.ruleId === id || finding.sensorId === id;
|
|
271
363
|
}
|
package/dist/tools/compliance.js
CHANGED
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { assessProjectCompleteness, assessProjectSelectedOptionalCapabilities, availableOptionalCapabilityIds, optionalCapabilityChecklist, platformCapabilityAvailability, selectedOptionalCapabilityIds, } from "../capabilities.js";
|
|
6
6
|
import { getOutcomeDefinition, hasAnswer, planContextFor, resolveOutcome, } from "../outcomes.js";
|
|
7
|
-
import { contractRuleCandidatesForPublicId, hasMultipleContractRuleCandidates, productExpectationBindingForSensor, publicProductRuleId, } from "../productExpectations.js";
|
|
7
|
+
import { contractRuleCandidatesForPublicId, hasMultipleContractRuleCandidates, productExpectationBindingForSensor, productExpectationTitle, publicProductRuleId, } from "../productExpectations.js";
|
|
8
8
|
import { objectInput, optionalBooleanField, optionalStringField, stringField, textResult } from "../types.js";
|
|
9
9
|
import { packageVersion } from "../version.js";
|
|
10
10
|
import { DESIGN_CONTRACT_CONFIRMATION_ANSWER_ID, buildDesignBrief, designContractConfirmationFromAnswers, designPreviewPath, readDesignContract, } from "./design.js";
|
|
@@ -476,6 +476,9 @@ function preferredPlatform(platforms) {
|
|
|
476
476
|
export async function applicableComplianceRuleSummaries(outcome, platforms) {
|
|
477
477
|
return (await applicableRules(outcome, platforms)).map(ruleRefForFile);
|
|
478
478
|
}
|
|
479
|
+
export async function applicableCompliancePlanRuleSummaries(outcome, platforms) {
|
|
480
|
+
return (await applicableRules(outcome, platforms)).map(ruleRefForPlan);
|
|
481
|
+
}
|
|
479
482
|
export async function checkCompliance(repoPath) {
|
|
480
483
|
const repoRoot = path.resolve(repoPath);
|
|
481
484
|
const compliance = await readCompliance(repoRoot);
|
|
@@ -932,6 +935,28 @@ function ruleRefForFile(rule) {
|
|
|
932
935
|
title: rule.title,
|
|
933
936
|
};
|
|
934
937
|
}
|
|
938
|
+
function ruleRefForPlan(rule) {
|
|
939
|
+
const publicRuleId = publicProductRuleId(rule.id);
|
|
940
|
+
const base = ruleRefForFile(rule);
|
|
941
|
+
if (publicRuleId === rule.id) {
|
|
942
|
+
return base;
|
|
943
|
+
}
|
|
944
|
+
const binding = productExpectationBindingForSensor(rule.id);
|
|
945
|
+
return {
|
|
946
|
+
...base,
|
|
947
|
+
rule_id: publicRuleId,
|
|
948
|
+
public_rule_id: publicRuleId,
|
|
949
|
+
title: productExpectationTitle(publicRuleId) ?? rule.title,
|
|
950
|
+
contract_rule_id: rule.id,
|
|
951
|
+
contract_rule_digest: base.rule_digest,
|
|
952
|
+
validator: binding
|
|
953
|
+
? {
|
|
954
|
+
platform: binding.platform,
|
|
955
|
+
sensorId: binding.sensorId,
|
|
956
|
+
}
|
|
957
|
+
: undefined,
|
|
958
|
+
};
|
|
959
|
+
}
|
|
935
960
|
// Benchmark-measured friction: agents looped on attest dialect for ~25 min/cell when docs and SDK
|
|
936
961
|
// disagreed on exact invocation syntax (capability-matrix 2026-06, Row 5). Hand them the exact incantation.
|
|
937
962
|
function attestHint(rule, compliance) {
|
|
@@ -3,7 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { BROAD_SOCIAL_REGEX, DESIGN_REGEX, getOutcomeDefinition, hasAnswer, planContextFor, resolveOutcome, } from "../outcomes.js";
|
|
4
4
|
import { objectInput, optionalStringField, stringField, textResult } from "../types.js";
|
|
5
5
|
import { availableOptionalCapabilityIds, capabilityChecklist, optionalCapabilityChecklist, platformCapabilityAvailability, selectedOptionalCapabilityIds, } from "../capabilities.js";
|
|
6
|
-
import {
|
|
6
|
+
import { applicableCompliancePlanRuleSummaries } from "./compliance.js";
|
|
7
7
|
import { DESIGN_CONTRACT_CONFIRMATION_ANSWER_ID, buildDesignBrief, designContractConfirmationFromAnswers, designPreviewPath, readDesignContract, } from "./design.js";
|
|
8
8
|
import { sdkVersionGuidance } from "./sdkVersion.js";
|
|
9
9
|
import { detectCommandSensors } from "./harness.js";
|
|
@@ -121,7 +121,7 @@ async function buildIntegrationPlan(repoPath, request, surfacePath, answers = {}
|
|
|
121
121
|
docs: definition.docs(platform).filter((doc) => doc.path !== "unknown"),
|
|
122
122
|
surface: inspection.selectedSurface ? { path: inspection.selectedSurface.path, platforms: inspection.selectedSurface.platforms } : undefined,
|
|
123
123
|
availableSurfaces: inspection.surfaces,
|
|
124
|
-
applicableRules: await
|
|
124
|
+
applicableRules: await applicableCompliancePlanRuleSummaries(outcome, inspection.platforms),
|
|
125
125
|
sensors: sensors.map((sensor) => ({ name: sensor.name, command: sensor.command, source: sensor.source })),
|
|
126
126
|
stopConditions: composeStopConditions(ctx, definition.stopConditions(ctx), inspection.surfaces, surfacePath),
|
|
127
127
|
evidencePolicy: "Every implementation step must cite at least one detected file, docs page, validator rule, or required user input. If evidence is missing, stop and ask the user instead of inventing details.",
|
package/package.json
CHANGED