{"name":"BYOA Borrowing Capacity of Foo","description":"Berekent de maximale leencapaciteit voor een hypotheekdossier volgens het Foo Acceptatiekader Leencapaciteit 2026: het hoofdinkomen telt volledig mee, elk medeaanvragersinkomen voor 80%, en op dat toetsinkomen geldt een factor van 4,05 (onder EUR 45.000) of 4,80 (vanaf EUR 45.000). Foo raadpleegt hiervoor uitsluitend zijn eigen documentsysteem; het platform deelt alleen een dossiernummer.","version":"1.0.0","provider":{"organization":"Foo","url":"https://www.foo.example"},"supportedInterfaces":[{"url":"https://byoa-foo-borrowing-capacity-agent.external.aiplatform.triplebeta.nl/a2a","protocolBinding":"JSONRPC","protocolVersion":"1.0"}],"capabilities":{"streaming":false,"pushNotifications":false,"stateTransitionHistory":false},"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}},"security":[{"bearer":[]}],"defaultInputModes":["application/json"],"defaultOutputModes":["application/json"],"skills":[{"id":"assess_borrowing_capacity_foo","name":"Bepaal leencapaciteit (Foo)","description":"Berekent de maximale leencapaciteit voor een dossiernummer volgens het Foo Acceptatiekader Leencapaciteit 2026. Retourneert maxBorrowingCapacity (number, EUR), applicants (array van { name, grossIncome } met het bruto MAANDinkomen) en explanation (string).","tags":["assess_borrowing_capacity","market_nl"],"examples":["Bepaal de leencapaciteit voor dossier T4V5W6.","Wat kan de aanvrager van dossier G7H8J9 maximaal lenen volgens Foo?","Bereken de maximale hypotheek voor dossier K2L3M4."],"inputModes":["application/json"],"outputModes":["application/json"]}],"metadata":{"_comment":"Routing/registry hints for the A2A platform. This is a mock of a tenant-owned (Foo) external agent: a standalone pod, no Camunda, no self-announce. A tenant AI admin imports it via /api/agents/from-card; the platform's Agentic Cortex calls it at the url above when Foo substitutes it for Stater's borrowing-capacity agent.\n\nTHE TAGS ARE A CONTRACT, NOT KEYWORDS — DO NOT ADD `market_de`. The platform derives an agent's capabilities from skills[].tags, and a tenant substitute is admitted only when its capability set is EXACTLY EQUAL to the standard agent's (capabilitySetMatches). Stater's borrowing-capacity agent carries {assess_borrowing_capacity, market_nl}; its max-mortgage agent carries those plus market_de. Adding market_de here therefore makes this card equal to the agent we are NOT substituting and unequal to the one we ARE, and every invoke becomes a 403 with no fallback field — which the ACS reads as a hard denial with no manual-review path. Foo's own store holds the German dossiers too; that is fine. The tags are what must not move.\n\nThe skill ID may stay Foo-specific: capabilities come from `tags` and fall back to `id` only when tags are absent.\n\nNO `requiredScopes` HERE, and it is not an omission: the field is forbidden on a tenant card. A substituted call runs under the DEFAULT agent's MCP grant, so a scope declared here would name a grant that is not ours to narrow. This agent needs none regardless — it calls nothing.\n\nNO inputSchema/outputSchema either: tenantAgentFromCard rejects them. A tenant agent is held to the STANDARD agent's contracts, which is the whole reason Stater's wrappers stay in the chain.","cardSchemaVersion":2,"agentId":"borrowing-capacity","kind":"tenant","tenantScope":["foo"],"requestPayload":{"dossierNumber":"string (6-character alphanumeric dossier number, e.g. T4V5W6)"},"responsePayload":{"maxBorrowingCapacity":"number (EUR, Foo's figure per its own Acceptatiekader)","applicants":"array of { name: string, grossIncome: number } (gross MONTHLY income, matching what Stater's own agent reports)","explanation":"string (Dutch, states the weighting and the band factor applied)","assessor":"string (always 'foo-borrowing-capacity' — the marker proving this verdict is the tenant's, not Stater's)"}},"url":"https://borrowing-capacity-agent.foo.aiplatform.triplebeta.nl/a2a"}