@amityco/social-plus-vise 0.4.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/LICENSE +51 -0
- package/README.md +92 -0
- package/dist/outcomes.js +574 -0
- package/dist/server.js +810 -0
- package/dist/tools/compliance.js +965 -0
- package/dist/tools/docs.js +312 -0
- package/dist/tools/harness.js +229 -0
- package/dist/tools/integration.js +332 -0
- package/dist/tools/patch.js +67 -0
- package/dist/tools/project.js +908 -0
- package/dist/tools/resolve.js +120 -0
- package/dist/tools/sensors.js +185 -0
- package/dist/types.js +31 -0
- package/dist/version.js +19 -0
- package/package.json +64 -0
- package/rules/design.yaml +66 -0
- package/rules/feed.yaml +126 -0
- package/rules/live-data.yaml +66 -0
- package/rules/push.yaml +95 -0
- package/rules/sdk-lifecycle.yaml +422 -0
- package/rules/security.yaml +162 -0
- package/skills/social-plus-vise/SKILL.md +199 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "security",
|
|
3
|
+
"schema_version": 1,
|
|
4
|
+
"rules": [
|
|
5
|
+
{
|
|
6
|
+
"id": "typescript.secret.inline-api-key",
|
|
7
|
+
"version": 1,
|
|
8
|
+
"title": "TypeScript API keys must not be hardcoded in source",
|
|
9
|
+
"severity": "warning",
|
|
10
|
+
"rationale": "Inline API keys are committed to version control. Use the host app's environment or config pattern instead.",
|
|
11
|
+
"applies_when": { "platforms": ["typescript"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
12
|
+
"enforcement": {
|
|
13
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "typescript.secret.inline-api-key" }],
|
|
14
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "react-native.secret.inline-api-key",
|
|
19
|
+
"version": 1,
|
|
20
|
+
"title": "React Native API keys must not be hardcoded in source",
|
|
21
|
+
"severity": "warning",
|
|
22
|
+
"rationale": "Inline API keys are committed to version control. Use the host app's environment or config pattern instead.",
|
|
23
|
+
"applies_when": { "platforms": ["react-native"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
24
|
+
"enforcement": {
|
|
25
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "react-native.secret.inline-api-key" }],
|
|
26
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "typescript.secret.committed-env",
|
|
31
|
+
"version": 1,
|
|
32
|
+
"title": "TypeScript local env files must not contain committed API keys",
|
|
33
|
+
"severity": "warning",
|
|
34
|
+
"rationale": "A committed .env file can leak customer social.plus API keys. Commit templates, not live values.",
|
|
35
|
+
"applies_when": { "platforms": ["typescript"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
36
|
+
"enforcement": {
|
|
37
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "typescript.secret.committed-env" }],
|
|
38
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "typescript.secret.env-gitignore",
|
|
43
|
+
"version": 1,
|
|
44
|
+
"title": "TypeScript env secret files should be ignored",
|
|
45
|
+
"severity": "warning",
|
|
46
|
+
"rationale": "When SDK secrets are loaded from env files, local env files should be ignored so customer API keys are not accidentally committed.",
|
|
47
|
+
"applies_when": { "platforms": ["typescript"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
48
|
+
"enforcement": {
|
|
49
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "typescript.secret.env-gitignore" }],
|
|
50
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "gitignore_policy", "description": "Where local env files are ignored or otherwise prevented from commit.", "upload_policy": "upload-with-consent" }] }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "typescript.secret.env-example",
|
|
55
|
+
"version": 1,
|
|
56
|
+
"title": "TypeScript env secret config should have an example file",
|
|
57
|
+
"severity": "warning",
|
|
58
|
+
"rationale": "A placeholder env example lets agents and developers create local config without asking users to paste secrets into chat.",
|
|
59
|
+
"applies_when": { "platforms": ["typescript"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
60
|
+
"enforcement": {
|
|
61
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "typescript.secret.env-example" }],
|
|
62
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "template_path", "description": "Path to the committed env/config template with placeholder secret keys.", "upload_policy": "upload-with-consent" }] }
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "android.secret.inline-api-key",
|
|
67
|
+
"version": 1,
|
|
68
|
+
"title": "Android API keys must not be hardcoded in source",
|
|
69
|
+
"severity": "warning",
|
|
70
|
+
"rationale": "Inline API keys are committed to version control. Use BuildConfig, gradle properties, or a runtime secrets store instead.",
|
|
71
|
+
"applies_when": { "platforms": ["android"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
72
|
+
"enforcement": {
|
|
73
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "android.secret.inline-api-key" }],
|
|
74
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "flutter.secret.inline-api-key",
|
|
79
|
+
"version": 1,
|
|
80
|
+
"title": "Flutter API keys must not be hardcoded in source",
|
|
81
|
+
"severity": "warning",
|
|
82
|
+
"rationale": "Inline API keys are committed to version control. Use --dart-define, dotenv, or a runtime secrets store instead.",
|
|
83
|
+
"applies_when": { "platforms": ["flutter"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
84
|
+
"enforcement": {
|
|
85
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "flutter.secret.inline-api-key" }],
|
|
86
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "ios.secret.inline-api-key",
|
|
91
|
+
"version": 1,
|
|
92
|
+
"title": "iOS API keys must not be hardcoded in source",
|
|
93
|
+
"severity": "warning",
|
|
94
|
+
"rationale": "Inline API keys are committed to version control. Use xcconfig, Info.plist references, or a runtime secrets store instead.",
|
|
95
|
+
"applies_when": { "platforms": ["ios"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
96
|
+
"enforcement": {
|
|
97
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "ios.secret.inline-api-key" }],
|
|
98
|
+
"attestation": { "allowed": false, "host_agent_min_confidence": "high", "human_allowed": false, "evidence_required": [] }
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "android.logging.no-secret-in-log",
|
|
103
|
+
"version": 1,
|
|
104
|
+
"title": "Android logging must not include secret-shaped values",
|
|
105
|
+
"severity": "warning",
|
|
106
|
+
"rationale": "Logging apiKey, accessToken, refresh token, password, or other secret-shaped values to Log.* or println escapes secrets to crash reports, log aggregators, and shoulder surfers. Drop the log line or redact the value.",
|
|
107
|
+
"applies_when": { "platforms": ["android"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
108
|
+
"enforcement": {
|
|
109
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "android.logging.no-secret-in-log" }],
|
|
110
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "redaction_policy", "description": "Where the value being logged is redacted or proven to be a placeholder.", "upload_policy": "upload-with-consent" }] }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "flutter.logging.no-secret-in-log",
|
|
115
|
+
"version": 1,
|
|
116
|
+
"title": "Flutter logging must not include secret-shaped values",
|
|
117
|
+
"severity": "warning",
|
|
118
|
+
"rationale": "Logging apiKey, accessToken, refresh token, password, or other secret-shaped values to print, debugPrint, or developer.log escapes secrets to crash reports and log aggregators. Drop the log line or redact the value.",
|
|
119
|
+
"applies_when": { "platforms": ["flutter"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
120
|
+
"enforcement": {
|
|
121
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "flutter.logging.no-secret-in-log" }],
|
|
122
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "redaction_policy", "description": "Where the value being logged is redacted or proven to be a placeholder.", "upload_policy": "upload-with-consent" }] }
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "ios.logging.no-secret-in-log",
|
|
127
|
+
"version": 1,
|
|
128
|
+
"title": "iOS logging must not include secret-shaped values",
|
|
129
|
+
"severity": "warning",
|
|
130
|
+
"rationale": "Logging apiKey, accessToken, refresh token, password, or other secret-shaped values via print, NSLog, os_log, or Logger escapes secrets to the system log and crash reports. Drop the log line or redact the value.",
|
|
131
|
+
"applies_when": { "platforms": ["ios"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
132
|
+
"enforcement": {
|
|
133
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "ios.logging.no-secret-in-log" }],
|
|
134
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "redaction_policy", "description": "Where the value being logged is redacted or proven to be a placeholder.", "upload_policy": "upload-with-consent" }] }
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "typescript.logging.no-secret-in-log",
|
|
139
|
+
"version": 1,
|
|
140
|
+
"title": "TypeScript logging must not include secret-shaped values",
|
|
141
|
+
"severity": "warning",
|
|
142
|
+
"rationale": "Logging apiKey, accessToken, refresh token, password, or other secret-shaped values via console.* escapes secrets to browser devtools, server logs, and error trackers. Drop the log line or redact the value.",
|
|
143
|
+
"applies_when": { "platforms": ["typescript"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
144
|
+
"enforcement": {
|
|
145
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "typescript.logging.no-secret-in-log" }],
|
|
146
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "redaction_policy", "description": "Where the value being logged is redacted or proven to be a placeholder.", "upload_policy": "upload-with-consent" }] }
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "react-native.logging.no-secret-in-log",
|
|
151
|
+
"version": 1,
|
|
152
|
+
"title": "React Native logging must not include secret-shaped values",
|
|
153
|
+
"severity": "warning",
|
|
154
|
+
"rationale": "Logging apiKey, accessToken, refresh token, password, or other secret-shaped values via console.* escapes secrets to Metro, Flipper, and crash reports. Drop the log line or redact the value.",
|
|
155
|
+
"applies_when": { "platforms": ["react-native"], "outcomes": ["setup-sdk", "setup-push", "setup-live-data", "add-feed", "validate-setup"] },
|
|
156
|
+
"enforcement": {
|
|
157
|
+
"deterministic": [{ "check": "validator-finding-absent", "finding_rule_id": "react-native.logging.no-secret-in-log" }],
|
|
158
|
+
"attestation": { "allowed": true, "host_agent_min_confidence": "high", "human_allowed": true, "evidence_required": [{ "field": "redaction_policy", "description": "Where the value being logged is redacted or proven to be a placeholder.", "upload_policy": "upload-with-consent" }] }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: social-plus-vise
|
|
3
|
+
description: Use when implementing, validating, or debugging social.plus SDK features in a customer project. Guides the host AI agent to use the Vise CLI for docs lookup, project inspection, implementation planning, validation, and sensor runs instead of guessing SDK APIs or integration details.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# social.plus Vise
|
|
7
|
+
|
|
8
|
+
Vise is the deterministic tool surface. This skill is the AI-agent workflow layer.
|
|
9
|
+
|
|
10
|
+
Use the CLI first. Use MCP only when the host already has Vise MCP tools connected.
|
|
11
|
+
|
|
12
|
+
## Required Loop
|
|
13
|
+
|
|
14
|
+
Before editing customer code:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
vise inspect .
|
|
18
|
+
vise plan . --request "<user intent>"
|
|
19
|
+
vise init . --request "<user intent>"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then fetch docs cited by the plan or relevant to the requested feature:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
vise search-docs "<SDK feature or API pattern>"
|
|
26
|
+
vise get-doc-page "<canonical-doc-path>"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
After editing:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
vise check .
|
|
33
|
+
vise sync .
|
|
34
|
+
vise validate .
|
|
35
|
+
vise run-sensors .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Treat Vise runtime smoke sensors as real validation. For TypeScript/React Native projects, `vise run-sensors` may include `TypeScript SDK import smoke`; if it fails, the SDK package does not resolve from the host project runtime and the integration is not done.
|
|
39
|
+
|
|
40
|
+
In CI or pull-request pipelines, use `vise check . --ci`. It is read-only, exits non-zero unless compliance is green, and never writes deterministic-pass records; use `vise sync` only during the implementation loop after a local green check.
|
|
41
|
+
|
|
42
|
+
## Engagement Scope (Optional)
|
|
43
|
+
|
|
44
|
+
If the customer has set up `sp-vise/engagement.json` (via `vise engagement init`), respect the declared scope. `vise engagement show .` prints the engagement metadata: tier, customer id, contracted outcomes, reviewer assignment.
|
|
45
|
+
|
|
46
|
+
When `vise init` reports a `warnings` array containing "not in the engagement scope", surface that to the user — don't silently widen scope. The user either extends the scope by editing `engagement.json` or accepts that the current work is out-of-contract.
|
|
47
|
+
|
|
48
|
+
If no `engagement.json` exists, do not create one without the user's intent. `vise engagement init` is a contractual artifact; agents should only run it when the user explicitly asks to set up engagement metadata, typically with `--tier`, `--customer-id`, and `--scope`.
|
|
49
|
+
|
|
50
|
+
If `vise` is not installed, use:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install -g @amityco/social-plus-foundry
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then retry the `vise` command.
|
|
57
|
+
|
|
58
|
+
## Stop Instead Of Guessing
|
|
59
|
+
|
|
60
|
+
Ask the user before editing when required values are missing:
|
|
61
|
+
|
|
62
|
+
- region, auth/user identity, or session-handler ownership (which class/module implements `sessionWillRenewAccessToken`)
|
|
63
|
+
- feed target, community ID, target ID, feed ID, or channel ID
|
|
64
|
+
- notification platform type, token source, permission owner, or logout cleanup owner
|
|
65
|
+
- Live Object/Collection domain, object vs collection choice, lifecycle owner, or cleanup location
|
|
66
|
+
- app surface in a monorepo when Vise reports multiple surfaces
|
|
67
|
+
- design-token, theme, or component source for UI work
|
|
68
|
+
|
|
69
|
+
Never invent undocumented SDK APIs, IDs, credentials, or design systems.
|
|
70
|
+
|
|
71
|
+
## Secret Handling
|
|
72
|
+
|
|
73
|
+
Never ask the user to paste API keys, Firebase/APNS credentials, server-issued tokens, or other secrets into chat.
|
|
74
|
+
|
|
75
|
+
When a secret is required:
|
|
76
|
+
|
|
77
|
+
1. Find the app's existing environment/config pattern.
|
|
78
|
+
2. Create or update a non-secret template such as `.env.example`, and ensure local env files are ignored by git before telling the user where to put real values.
|
|
79
|
+
3. Add placeholder names only, such as `VITE_AMITY_API_KEY=`.
|
|
80
|
+
4. Tell the user exactly which local file and variable to fill in themselves.
|
|
81
|
+
5. Do not echo, log, commit, or attest the secret value.
|
|
82
|
+
|
|
83
|
+
If no safe ignored local env path or template path is clear, stop and tell the user which variable names are needed.
|
|
84
|
+
|
|
85
|
+
Do not write a real `.env` value for the user. If you create a local env file during implementation, it must contain placeholders only and the project must already ignore it. `vise check` flags committed env secrets and missing TypeScript env hygiene.
|
|
86
|
+
|
|
87
|
+
## Logging Discipline
|
|
88
|
+
|
|
89
|
+
Do not pass secret-shaped values (`apiKey`, `apiSecret`, `accessToken`, `refreshToken`, `bearerToken`, `clientSecret`, `password`) to logging calls. This includes:
|
|
90
|
+
|
|
91
|
+
- TypeScript / React Native: `console.log/info/warn/error/debug`
|
|
92
|
+
- Android Kotlin / Java: `Log.d/i/e/v/w`, `println`, `print`
|
|
93
|
+
- Flutter Dart: `print`, `debugPrint`, `developer.log`
|
|
94
|
+
- iOS Swift: `print`, `NSLog`, `os_log`, `Logger.log/info/debug/...`
|
|
95
|
+
|
|
96
|
+
`vise check` enforces `*.logging.no-secret-in-log` per platform. If you need to log around a value for debugging, log a redacted form (`apiKey ? "<set>" : "<missing>"`), not the value itself. Remove debug log lines before declaring done.
|
|
97
|
+
|
|
98
|
+
## Session Renewal
|
|
99
|
+
|
|
100
|
+
When you call SDK `login`, also implement the session-renewal handler in the same change. Access tokens expire in production; without a renewal handler the SDK cannot refresh and customers see silent auth failures.
|
|
101
|
+
|
|
102
|
+
Per platform:
|
|
103
|
+
|
|
104
|
+
- TypeScript / React Native: pass `sessionHandler` to `Client.login`, implement `sessionWillRenewAccessToken(renewal)` and call `renewal.renew()`.
|
|
105
|
+
- Android Kotlin: pass `AmitySessionHandler` to `AmityCoreClient.login`, override `sessionWillRenewAccessToken` and call `renewal.renew()`.
|
|
106
|
+
- Flutter Dart: implement `AmitySessionHandler.sessionWillRenewAccessToken(AmityAccessTokenRenewal)` and call `renewal.renew()`.
|
|
107
|
+
- iOS Swift: implement `AmitySessionHandler.sessionWillRenewAccessToken(renewal:)` and call `renewal.renew()`.
|
|
108
|
+
|
|
109
|
+
`vise check` enforces `*.session.renewal` per platform when login is present.
|
|
110
|
+
|
|
111
|
+
## SDK Version Handling
|
|
112
|
+
|
|
113
|
+
Do not use floating SDK dependency versions such as `latest`, `*`, `any`, `+`, or branch-based iOS package references. Pin the social.plus SDK to an explicit version or reviewed semver range, then let the host app's package manager lockfile capture the exact resolved version.
|
|
114
|
+
|
|
115
|
+
## Attestation Flow
|
|
116
|
+
|
|
117
|
+
`vise check` reports each applicable rule as one of `deterministic-pass`, `attestation-needed`, `failed`, or `blocked`. `attestation-needed` and `failed` are NOT warnings to skip — they block "I'm done." Resolve them in one of two ways:
|
|
118
|
+
|
|
119
|
+
1. **Make the deterministic check fire (preferred).** Re-read `vise explain <rule-id>` for the rule's enforcement details, adjust the code so the check passes, then run `vise check` again. After it goes green, run `vise sync` to persist the deterministic-pass attestation files.
|
|
120
|
+
2. **Record an attestation with evidence.** When the rule cannot fire because the customer's architecture is unconventional (DI wrappers, custom abstractions, etc.), use `vise attest`:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
vise attest . \
|
|
124
|
+
--rule typescript.client.region \
|
|
125
|
+
--confidence high \
|
|
126
|
+
--signer host-agent \
|
|
127
|
+
--rationale "API_REGIONS.EU is explicitly passed as the second argument to Client.createClient in src/socialSDK.ts." \
|
|
128
|
+
--evidence-file ./.tmp/evidence.json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The evidence file is a JSON object matching the `evidence_required` schema for that rule (`vise explain <rule-id>` shows the required fields). Include concrete source file paths in evidence values whenever the evidence depends on code, for example `{ "region_source": "src/socialSDK.ts" }` or `{ "login_flow": "src/auth/socialSession.ts" }`. `vise attest` fingerprints cited files, and future `vise check` runs mark the attestation stale if those files change.
|
|
132
|
+
|
|
133
|
+
### Confidence honesty
|
|
134
|
+
|
|
135
|
+
- `high` — direct evidence the deterministic check would have fired if it had been more flexible. Auto-recorded.
|
|
136
|
+
- `medium` — reasoned about it but cannot point to a single unambiguous location. May require human signer depending on rule.
|
|
137
|
+
- `low` — guess. Always requires `--signer human`.
|
|
138
|
+
|
|
139
|
+
If the rule's `escalation_threshold` is above your confidence, `vise attest --signer host-agent` is rejected. In v0.4 there is no hosted review queue yet, so the path is: stop, surface to the user with the rule id and the evidence you have, and ask them to run `vise attest --signer human --identity <their name or email>` themselves.
|
|
140
|
+
|
|
141
|
+
### What `vise sync` is NOT
|
|
142
|
+
|
|
143
|
+
- `vise sync` does **not** accept `--attest` or any flag. It only persists deterministic-pass results.
|
|
144
|
+
- Passing unknown flags to `vise sync` will error in v0.4 — don't try to use it as a shortcut for attestation.
|
|
145
|
+
- To record an attestation, use `vise attest`. Always.
|
|
146
|
+
|
|
147
|
+
### Treat warnings as blockers
|
|
148
|
+
|
|
149
|
+
If a legacy `vise validate` run reports `needs-review` with warnings, those warnings correspond to compliance rules in `attestation-needed` state. Do not interpret them as "code is fine, just static-analysis noise." Run `vise check` to get the structured rule list, then resolve each one as above.
|
|
150
|
+
|
|
151
|
+
## Feature Guidance
|
|
152
|
+
|
|
153
|
+
For feed or post creation:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
vise search-docs "create post feed target"
|
|
157
|
+
vise plan . --request "<feed or post request>"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
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.
|
|
161
|
+
|
|
162
|
+
For notification setup:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
vise search-docs "push notification device token unregister"
|
|
166
|
+
vise plan . --request "<notification request>"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Require platform, credential assumptions, device-token ownership, permission flow, registration timing after login, and unregister cleanup on logout or user switch.
|
|
170
|
+
|
|
171
|
+
For Live Objects or Live Collections:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
vise search-docs "Live Collection observe cleanup"
|
|
175
|
+
vise plan . --request "<live data request>"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Require object vs collection, observed domain, lifecycle owner, loading/error/update states, and observer/subscription cleanup.
|
|
179
|
+
|
|
180
|
+
## Monorepos
|
|
181
|
+
|
|
182
|
+
If `vise inspect .` reports multiple surfaces, choose the intended app with the user or surrounding task context. Pass it consistently:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
vise plan . --surface apps/web --request "<user intent>"
|
|
186
|
+
vise validate . --surface apps/web
|
|
187
|
+
vise run-sensors . --surface apps/web
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Final Response Discipline
|
|
191
|
+
|
|
192
|
+
Report:
|
|
193
|
+
|
|
194
|
+
- Vise commands used
|
|
195
|
+
- docs pages used
|
|
196
|
+
- files changed
|
|
197
|
+
- validation findings
|
|
198
|
+
- sensor results or why sensors were skipped
|
|
199
|
+
- unresolved user inputs or stop conditions
|