feat: third-party web-action contract — offer agentic browser before manual steps#24
Conversation
…manual steps When a specialist step needs action on a third-party website (API key registration, vendor accounts, dashboards), dispatchers now read references/THIRD-PARTY-ACTIONS.md: detect an agentic browser (Aside), STOP for per-task consent, keep credentials user-performed, never echo captured secrets, and verify tokens with one non-mutating call. Pinned in run-parity.ts (+4 checks x 6 trees, 5027 -> 5051). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
4 issues found across 16 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/gstack2/run-parity.ts">
<violation number="1" location="scripts/gstack2/run-parity.ts:176">
P2: Parity can still pass after losing several safety boundaries in `THIRD-PARTY-ACTIONS.md`, including no-install, named-site scope, user-only payment/identity steps, protected storage, and blocked manual fallback. Consider asserting each contract section’s critical invariant, not only the consent and API-verification phrases.</violation>
</file>
<file name="scripts/gstack2/generate-skill-tree.ts">
<violation number="1" location="scripts/gstack2/generate-skill-tree.ts:260">
P1: Agent-driven third-party actions can bypass the new contract because the dispatcher only requires it before directing the user to act. The gate should cover both taking the action and asking the user to take it, so the STOP/consent and secret-handling rules are loaded before either workflow.</violation>
<violation number="2" location="scripts/gstack2/generate-skill-tree.ts:528">
P2: Webhook-signing-secret setup can never satisfy this success gate because that secret is not an API credential and cannot be validated by an authenticated read-only API call. Keep the API probe for API credentials and specify an appropriate non-exposing verification path for other secret types.</violation>
<violation number="3" location="scripts/gstack2/generate-skill-tree.ts:530">
P3: The defer choice does not actually defer the workflow because it still emits the manual step list, making options B and C behaviorally identical. A deferred task should be marked blocked and stop without providing the instructions.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. | ||
| 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. | ||
| 4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. | ||
| 4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. Read \`references/THIRD-PARTY-ACTIONS.md\` before directing the user to act on a third-party website (API key registration, vendor accounts, dashboards). |
There was a problem hiding this comment.
P1: Agent-driven third-party actions can bypass the new contract because the dispatcher only requires it before directing the user to act. The gate should cover both taking the action and asking the user to take it, so the STOP/consent and secret-handling rules are loaded before either workflow.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/gstack2/generate-skill-tree.ts, line 260:
<comment>Agent-driven third-party actions can bypass the new contract because the dispatcher only requires it before directing the user to act. The gate should cover both taking the action and asking the user to take it, so the STOP/consent and secret-handling rules are loaded before either workflow.</comment>
<file context>
@@ -257,7 +257,7 @@ Web context: <none, optional, local-browser, or production>
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
-4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work.
+4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. Read \`references/THIRD-PARTY-ACTIONS.md\` before directing the user to act on a third-party website (API key registration, vendor accounts, dashboards).
5. If an old asset path is unavailable, use \`references/ASSETS.md\`. If legacy prose invokes another retired skill, resolve it through \`references/COMPATIBILITY.md\` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
</file context>
| 4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. Read \`references/THIRD-PARTY-ACTIONS.md\` before directing the user to act on a third-party website (API key registration, vendor accounts, dashboards). | |
| 4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. Read \`references/THIRD-PARTY-ACTIONS.md\` before taking or directing the user to take any action on a third-party website (API key registration, vendor accounts, dashboards). |
| thirdParty.includes('STOP and ask one explicit question before any browsing') | ||
| && thirdParty.includes('per-task consent') | ||
| && thirdParty.includes('never appears in chat output, logs, or shell history') | ||
| && thirdParty.includes('verify the captured credential with one non-mutating API call'), |
There was a problem hiding this comment.
P2: Parity can still pass after losing several safety boundaries in THIRD-PARTY-ACTIONS.md, including no-install, named-site scope, user-only payment/identity steps, protected storage, and blocked manual fallback. Consider asserting each contract section’s critical invariant, not only the consent and API-verification phrases.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/gstack2/run-parity.ts, line 176:
<comment>Parity can still pass after losing several safety boundaries in `THIRD-PARTY-ACTIONS.md`, including no-install, named-site scope, user-only payment/identity steps, protected storage, and blocked manual fallback. Consider asserting each contract section’s critical invariant, not only the consent and API-verification phrases.</comment>
<file context>
@@ -168,6 +168,18 @@ export function runParity(): ParityResult {
+ if (fs.existsSync(thirdPartyPath)) {
+ const thirdParty = fs.readFileSync(thirdPartyPath, 'utf8');
+ check(
+ thirdParty.includes('STOP and ask one explicit question before any browsing')
+ && thirdParty.includes('per-task consent')
+ && thirdParty.includes('never appears in chat output, logs, or shell history')
</file context>
| thirdParty.includes('STOP and ask one explicit question before any browsing') | |
| && thirdParty.includes('per-task consent') | |
| && thirdParty.includes('never appears in chat output, logs, or shell history') | |
| && thirdParty.includes('verify the captured credential with one non-mutating API call'), | |
| thirdParty.includes('Never install it, and never treat binary presence as consent to browse') | |
| && thirdParty.includes('STOP and ask one explicit question before any browsing') | |
| && thirdParty.includes('then offer A) drive it now through the agentic browser, B) manual instructions, C) defer') | |
| && thirdParty.includes('per-task consent') | |
| && thirdParty.includes('touch only the named site and actions') | |
| && thirdParty.includes('payment, and identity verification remain user-performed steps') | |
| && thirdParty.includes('never appears in chat output, logs, or shell history') | |
| && thirdParty.includes('owner-only permissions') | |
| && thirdParty.includes('Dashboard fields are often masked placeholders') | |
| && thirdParty.includes('verify the captured credential with one non-mutating API call') | |
| && thirdParty.includes('provide the manual steps and mark the step blocked on the user'), |
| '', | ||
| '3. When driving, touch only the named site and actions. Password entry, new-account credential choice, payment, and identity verification remain user-performed steps: hand off and wait instead of acting. Prefer credential flows that never expose the secret to the agent, such as password-manager autofill or host-native copy.', | ||
| '', | ||
| '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify the captured credential with one non-mutating API call before claiming success.', |
There was a problem hiding this comment.
P2: Webhook-signing-secret setup can never satisfy this success gate because that secret is not an API credential and cannot be validated by an authenticated read-only API call. Keep the API probe for API credentials and specify an appropriate non-exposing verification path for other secret types.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/gstack2/generate-skill-tree.ts, line 528:
<comment>Webhook-signing-secret setup can never satisfy this success gate because that secret is not an API credential and cannot be validated by an authenticated read-only API call. Keep the API probe for API credentials and specify an appropriate non-exposing verification path for other secret types.</comment>
<file context>
@@ -513,6 +513,25 @@ function webContextContract(): string {
+ '',
+ '3. When driving, touch only the named site and actions. Password entry, new-account credential choice, payment, and identity verification remain user-performed steps: hand off and wait instead of acting. Prefer credential flows that never expose the secret to the agent, such as password-manager autofill or host-native copy.',
+ '',
+ '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify the captured credential with one non-mutating API call before claiming success.',
+ '',
+ '5. If no agentic browser is available, or the user declines or defers, provide the manual steps and mark the step blocked on the user. Do not recommend or install new products to close the gap.',
</file context>
| '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify the captured credential with one non-mutating API call before claiming success.', | |
| '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify an API credential with one non-mutating API call before claiming success. For secrets that do not authenticate API calls, use the service\'s appropriate non-exposing verification flow and report exactly what was verified.', |
| '', | ||
| '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify the captured credential with one non-mutating API call before claiming success.', | ||
| '', | ||
| '5. If no agentic browser is available, or the user declines or defers, provide the manual steps and mark the step blocked on the user. Do not recommend or install new products to close the gap.', |
There was a problem hiding this comment.
P3: The defer choice does not actually defer the workflow because it still emits the manual step list, making options B and C behaviorally identical. A deferred task should be marked blocked and stop without providing the instructions.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/gstack2/generate-skill-tree.ts, line 530:
<comment>The defer choice does not actually defer the workflow because it still emits the manual step list, making options B and C behaviorally identical. A deferred task should be marked blocked and stop without providing the instructions.</comment>
<file context>
@@ -513,6 +513,25 @@ function webContextContract(): string {
+ '',
+ '4. A captured secret (API key, token, webhook signing secret) never appears in chat output, logs, or shell history. Write it to a user-approved local file with owner-only permissions or the user\'s secret store, and keep generated-file destinations out of version control. Dashboard fields are often masked placeholders; verify the captured credential with one non-mutating API call before claiming success.',
+ '',
+ '5. If no agentic browser is available, or the user declines or defers, provide the manual steps and mark the step blocked on the user. Do not recommend or install new products to close the gap.',
+ '',
+ ].join('\n');
</file context>
| '5. If no agentic browser is available, or the user declines or defers, provide the manual steps and mark the step blocked on the user. Do not recommend or install new products to close the gap.', | |
| '5. If no agentic browser is available or the user selects manual instructions, provide the manual steps and mark the step blocked on the user. If the user defers, mark the step blocked and stop without providing the manual list. Do not recommend or install new products to close the gap.', |
…ctions contract (parity pin 5032+24=5056) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…arty-actions (parity pin 5050+24=5074) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
What
When a specialist step requires action on a third-party website — registering an API key, creating a vendor/developer account, configuring a dashboard, webhook, OAuth app, or domain verification — gstack previously emitted a manual step list and moved on. Now every dispatcher reads a shared
references/THIRD-PARTY-ACTIONS.mdcontract before doing that:BROWSER-PROVIDERS.mdsection). Never install it; binary presence is not consent.How
Follows the established cross-dispatcher pattern (reference contract mirroring
webContextContract(), not a'*'overlay): newthirdPartyActionsContract()ingenerate-skill-tree.ts, one dispatch-protocol sentence, pinned inrun-parity.ts(+4 checks × 6 trees,EXPECTED_PARITY_CHECKS5027 → 5051). Two bisected commits: source change, then mandatory regen.Evidence
bun run test:gstack2: 26/26 files, 0 failures, exit 0bun test: exit 0Origin
Field failure 2026-07-23: registering a Duffel test API key for the uberflights project required exactly this behavior, and no skill offered it — the agent had to be manually told. The masked-token trap in item 4 comes from that session (the dashboard token field held a masked placeholder; the real value only existed behind the Copy button, caught by a 401 on the verify call).
🤖 Generated with Claude Code
Summary by cubic
Add a shared contract for third‑party web actions. Dispatchers now check for an agentic browser and offer to drive the task with per‑task consent and strict secret handling; fall back to manual if declined.
New Features
references/THIRD-PARTY-ACTIONS.mdviathirdPartyActionsContract()for all six skills, and require reading it before directing third‑party site actions.aside; STOP for per‑task choice (drive/manual/defer); scope to the named site/actions; keep passwords/payment/ID checks user‑performed; never echo secrets; store owner‑only or in a secret store; verify tokens with one non‑mutating API call; mark blocked if unavailable/declined.Refactors
EXPECTED_PARITY_CHECKSto 5074 and docs to 5,074 after merging the code‑intelligence contract; bump version to 1.63.0.0 and update CHANGELOG.Written for commit 915b57b. Summary will update on new commits.