Every time thcode routes an artifact to an AI for Thai specialist service, local read permission is not enough. The payload is leaving the workspace and traveling to an external endpoint, so a separate, explicit transfer consent decision is required for each exact operation — independent of any Full Access flag, Work Mode profile, or prior session approval. This page explains how the consent pipeline is structured, what information it captures, how it validates the credential-to-host binding, and precisely what causes a service call to be blocked.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Temicide/thcode/llms.txt
Use this file to discover all available pages before exploring further.
Why Transfer Consent Is Required
Data leaves the local workspace
Specialist calls send artifact bytes to a remote HTTPS endpoint. That transfer is a distinct trust boundary from local file reads, which is why it requires its own consent decision.
Consent is per-exact-operation
Any change in the artifact content, payload classification, recipient endpoint, or manifest fields makes a prior consent stale. The service call fails closed and fresh consent is required.
- A separately configured AI for Thai credential — the
aiforthaicredential group, bound to its verified host. A Typhoon key cannot substitute. - An available health state — the specialist’s health check must currently report
availablefor the exact configuration generation in use. A force-fresh call additionally requiresavailablehealth; a cached-hit path does not. - Explicit transfer consent — the user must grant consent to the exact
PreparedPayloadManifestproduced for this operation. No approval from a different operation substitutes.
AD-17 states that consent is independent per exact transfer. Full Access, local approval, cache reuse, and prior consent never substitute for a fresh exact consent decision.
The Prepared Payload Manifest
Before consent is requested,buildSpecialistPreparedPayloadManifest assembles a PreparedPayloadManifest that captures every field that defines the transfer. The manifest is the stable, tamper-evident identity of what is being sent, where it is going, and under what conditions.
manifestDigest is a SHA-256 hash of all manifest fields in canonical JSON order. payloadByteDigest is a SHA-256 hash of the framed artifact bytes (each artifact framed as <contentKind>\n<mediaType>\n<contentHash>\n<byteLen>\n<content>). Both digests are verified again immediately before any wire transfer — a changed field fails the call closed.
Payload Classification
The manifest’sclassification field is derived from the artifacts and the capability registry entry:
| Classification | Condition |
|---|---|
unresolved | Any artifact has privacyClassification === 'secret'. Transfer is blocked. |
sensitive | Registry entry has requiresConsent: true or data classes containing sensitive, personal, or pii. |
internal | Any artifact has privacyClassification === 'internal'. |
public | No sensitive indicators from artifacts or registry entry. |
Retention Handling
resolveRetentionHandling maps the registry entry’s retentionClassification.policy string to one of four RetentionHandling values. When in doubt the function returns unknown, which causes the consent gate to fail closed:
retention === 'unknown' value blocks consent with cause: 'retention-unknown'.
The Consent Dialog
buildConsentDialogSummary constructs a ConsentDialogSummary — a secret-free surface presented to the user before any data is sent. It contains everything relevant to an informed decision, and nothing that could leak artifact content.
initialFocus is always 'consent-review' — the dialog opens focused on reviewing, never on granting. In development and test environments, a runtime assertion verifies that no artifact text has leaked into the summary by scanning for text segments of four characters or more.
Safe Payload Summary
SafePayloadSummary describes the payload without exposing content:
Evaluating Transfer Consent
requestSpecialistTransferConsent wraps evaluateTransferConsent from permissions/transferConsent.ts. Evaluation is purely synchronous and returns a typed ConsentEvaluationResult:
Classification check
If
manifest.classification === 'unresolved', return cause: 'classification-unresolved'. No service is contacted.Retention check
If
manifest.retention === 'unknown', return cause: 'retention-unknown'. A verified provider contract is required.Endpoint check
If
manifest.recipient.verifiedEndpoint is empty, return cause: 'destination-unresolved'.Manifest digest recomputation
The manifest digest is recomputed from scratch and compared against
manifest.manifestDigest. Any field change returns cause: 'manifest-digest-mismatch'.Payload byte digest check
currentPayloadByteDigest (computed fresh from the current artifact bytes) must equal manifest.payloadByteDigest. Any byte change returns cause: 'payload-byte-digest-mismatch'.Safety check
The sanitizer result must be
ok: true. An unsafe payload (detected credentials, unresolved local paths, unsafe active content) returns cause: 'unsafe-payload'.The Transfer Consent Record
A granted consent is aTransferConsent — a fully-bound, secret-free record:
TransferConsent carries no secrets — only digests, identities, versions, and timestamps. It is projected into a ConsentReference (a further-reduced, secret-free handle) for use in Evidence records and dialog display:
toConsentReference performs this projection — it strips callCount, operationId, promptRoundId, activationId, activation/authority revision fields, and policyVersion, keeping only the fields appropriate for Evidence and dialog surfaces.
Revalidation Before Transport
Consent granted at dialog time must be revalidated immediately before the wire transfer viarevalidateSpecialistTransferConsent. This detects any change between consent grant and the actual transport moment:
activationId returns cause: 'activation-changed'. A changed activation or authority revision also returns cause: 'activation-changed'. Any other manifest or payload change returns cause: 'manifest-digest-mismatch'. All of these block the transfer.
Credential Identity and Host Binding
CredentialIdentity in permissions/credentialIdentity.ts defines the binding between a credential and its one verified service host. An AI for Thai key is bound to AI for Thai endpoints only.
checkCredentialBoundary enforces that no credential is ever routed to a different group’s service host:
Credential Request Validation
validateCredentialRequest enforces three transport-time rules:
| Violation | cause | Explanation |
|---|---|---|
| Cross-origin redirect accepted | cross-origin-redirect | Credential is bound to the verified host; redirects are refused |
| TLS verification bypassed | tls-bypass | Downgrade/bypass of TLS verification is refused |
| Requested host ≠ verified host | host-mismatch | The outbound request target must exactly match the registered host |
Staleness After Credential Rotation
isCredentialAuthorityStale returns true when a prior approval or consent can no longer be trusted because the credential has been rotated or the health configuration generation has changed:
What Happens Without Consent
Classification unresolved (secret artifact)
Classification unresolved (secret artifact)
If any prepared artifact carries
privacyClassification === 'secret', the manifest classification is set to 'unresolved'. The consent evaluation returns cause: 'classification-unresolved' with the explanation: “Payload classification is unresolved; classify before requesting transfer consent.” No service call is made.Retention policy unknown
Retention policy unknown
If the capability registry entry’s
retentionClassification.policy does not match any of the known patterns, resolveRetentionHandling returns 'unknown'. Consent evaluation returns cause: 'retention-unknown': “Recipient retention/deletion handling is unknown; a verified provider contract is required.”Unsafe payload content
Unsafe payload content
Credentials (Authorization headers, Bearer tokens, API keys), unresolved local paths, and unsafe active content (script tags,
javascript: URIs, inline event handlers) are detected by the sanitizer. The prepared content must pass sanitizer checks before consent is granted. If unsafe content is detected, cause: 'unsafe-payload' blocks the transfer.Manifest or payload changed
Manifest or payload changed
Any field change between manifest build and the consent evaluation, or between consent grant and the pre-transport revalidation, causes
cause: 'manifest-digest-mismatch' or cause: 'payload-byte-digest-mismatch'. Fresh preparation and consent are required.Credential-boundary violation
Credential-boundary violation
Routing an
aiforthai credential toward a typhoon or scbx service host (or vice versa) is a credential-boundary violation. The call is denied before any outbound connection, and only sanitized Evidence is produced.Sensitive Tool Categories
Tools that process identity, biometric, or medical data produce artifacts withprivacyClassification === 'sensitive' or registry entries with requiresConsent: true and sensitive data classes. These produce a classification: 'sensitive' manifest, which:
- Is shown to the user with the sensitive classification prominently displayed in the
ConsentDialogSummary. - Still requires the same explicit per-operation consent as any other transfer.
- Is never silently downgraded to
'public'or'internal'.
'unresolved' (from a 'secret' artifact) is the only classification that blocks transfer outright regardless of user action. All other classifications require affirmative user consent before proceeding.