- Je onderscheidt betekenisvolle veldwijzigingen van verzamelingsvolgorde.
- Je vergelijkt met een afzonderlijke pin en legt uit waarom een match geen veilig gedrag bewijst.
Een tool werkte gisteren zoals verwacht. Vandaag levert dezelfde aanbieder onder dezelfde naam een andere beschrijving of een ruimere scopeverzameling aan. Als je alleen de eerste installatie beoordeelt, kan later een andere tooldefinitie onder dat oude vertrouwen meeliften.
Bewaar daarom een afzonderlijk vertrouwde referentie van wat je hebt beoordeeld. Een manifest is hier een klein record met server, revisie en toolmetadata. Je vergelijkt de huidige inhoud met een vastgelegde vingerafdruk en behandelt een verschil als aanleiding voor een nieuwe beoordeling.
1. Spreek af wat bij de inhoud hoort
Ons manifest noemt per tool haar naam, beschrijving, parameters, read_only en scopes. We nemen ieder veld mee in de vingerafdruk. Een verandering in een beschrijving kan immers modelgedrag beïnvloeden, terwijl gewijzigde parameters of scopes het voorgestelde contract veranderen.
De eerste tool heeft één parameter en twee scopelabels. Met de hand kun je die twee scopes alfabetisch rangschikken: read vóór summary. Hun invoervolgorde beschrijft in deze oefening geen volgorde van uitvoering.
manifest = dict(server="kaarten",
revision="r1", tools=[
dict(tool="read",
description="Lees.",
parameters=["target"],
read_only=True,
scopes=["summary", "read"]),
])
print(len(manifest["tools"]))
tool = manifest["tools"][0]
print(len(tool["scopes"]))
# 1
# 2
Noem het manifest M en de afgesproken sorteerbewerking S. S sorteert tools op toolnaam en parameters/scopes alfabetisch; zij verandert geen tekst of veldwaarden. J maakt de vaste JSON-weergave, U zet die om in UTF-8-bytes en H is de SHA256-vingerafdruk.
Dit is een afspraak voor onze eigen metadata. Zij is geen universele canonicalisatiestandaard voor ieder mogelijk MCP-bericht. Een ander formaat vereist zijn eigen precieze regels over velden, tekens, getallen en volgorde.
2. Scheid volgorde van betekenis
Twee records kunnen dezelfde scopelabels in een andere volgorde aanbieden. Zonder sorteerafspraak zouden verschillende bytes een onnodige wijzigingsmelding geven. Daarom geeft de volgende herschikking dezelfde vingerafdruk terug.
import copy
original_hash = manifest_fingerprint(
manifest)
reordered = copy.deepcopy(manifest)
tool = reordered["tools"][0]
tool["scopes"].reverse()
print(manifest_fingerprint(reordered)
== original_hash)
# True
01Een andere beschrijving of revisie blijft juist wel betekenisvol voor deze vergelijking. Ook Unicode wordt exact bewaard; gelijk uitziende tekst kan uit andere codepunten bestaan. De oefening past geen stilzwijgende normalisatie toe.
3. De verwachte hash komt van buiten
Een manifest dat zelf zijn verwachte hash meelevert kan die waarde na iedere wijziging vervangen. Leg de pin daarom apart vast op het moment van beoordeling. Onze pinlijst verbindt een vertrouwd server-id met de toen gekozen vingerafdruk.
K betekent dat er voor deze server een pin bestaat. h is de opgeslagen verwachte vingerafdruk, of None wanneer er geen pin is. De booleaanse acceptatie A vraagt zowel K als gelijkheid van de nieuw berekende H(M) en h.
Voor ons ongewijzigde manifest bestaat precies één passende pin. K is waar en beide hashes zijn gelijk. De controle geeft daarom matched terug, zonder de pinlijst zelf te veranderen.
pins = [dict(server="kaarten",
fingerprint=original_hash)]
reply = assess_manifest(manifest, pins)
print(reply["accepted"])
print(reply["reason"])
# True
# matched
02Een eerdere beoordeling geldt voor de gekozen inhoud. Onderzoek welke wijzigingen de vingerafdruk veranderen en welke volgordeveranderingen dezelfde betekenis houden.
Huidig manifest
{
"server": "a",
"revision": "r1",
"tools": [
{
"tool": "read",
"description": "[[tool:elders/read]]",
"parameters": [
"target",
"mode"
],
"read_only": true,
"scopes": [
"read",
"audit"
]
},
{
"tool": "paint",
"description": "Kleur kaart.",
"parameters": [
"target",
"color"
],
"read_only": false,
"scopes": [
"paint"
]
}
]
}Gekozen afzonderlijke pin
Server: a
69443941aac717263cea82c687dc9c267a13fa36be60b83d07e65920aba4413bDe optie voor een huidige pin veronderstelt een aparte beoordeling; de controlefunctie werkt haar referentie niet automatisch bij.
Nieuw berekende vingerafdruk
57c402536871ebb9cb2093abe956200d0e8b124ccd75959aad08503ceba6a5d1Canonieke metadata en tekstcodepunten
{"revision":"r1","server":"a","tools":[{"description":"Kleur kaart.","parameters":["color","target"],"read_only":false,"scopes":["paint"],"tool":"paint"},{"description":"[[tool:elders/read]]","parameters":["mode","target"],"read_only":true,"scopes":["audit","read"],"tool":"read"}]}- read
U+005B U+005B U+0074 U+006F U+006F U+006C U+003A U+0065 U+006C U+0064 U+0065 U+0072 U+0073 U+002F U+0072 U+0065 U+0061 U+0064 U+005D U+005D - paint
U+004B U+006C U+0065 U+0075 U+0072 U+0020 U+006B U+0061 U+0061 U+0072 U+0074 U+002E
De letter é en e gevolgd door een combining accent kunnen gelijk ogen, maar hebben andere codepunten en bytes.
Deze metadata verschilt van de verwachte vingerafdruk.
changedDe hash dekt deze eigen metadata. Een match bewijst geen veilig gedrag, betrouwbare auteur, geldige handtekening of gelijkheid van echte implementatiebytes. Ook een read_only-hint blijft metadata.
Alle beschrijvingen, aanroepen, bevoegdheden en pins zijn eigen oefengegevens. Deze vergelijking roept geen echte tool of server aan.
4. Een match is geen veiligheidsbewijs
Een veelgemaakte misvatting is dat een geldige hash of read_only=True veilig gedrag bewijst. Onze hash vergelijkt alleen de genoemde metadata met de gekozen referentie. Een echte implementatie kan andere bytes of verborgen effecten hebben en vraagt aanvullende beoordeling en afscherming.
Wijzig nu de beschrijving zonder een nieuwe pin vast te leggen. De controle meldt changed, terwijl de oude verwachte hash behouden blijft. Het apart goedkeuren van een nieuwe referentie valt buiten deze functie.
changed = copy.deepcopy(manifest)
changed["tools"][0]["description"] = (
"[[tool:elders/read]]")
reply = assess_manifest(changed, pins)
print(reply["reason"])
print(pins[0]["fingerprint"]
== original_hash)
# changed
# True
Samenvatting
- Neem alle afgesproken metadata op en maak de sorteerregels expliciet.
- Vergelijk met een serverpin die buiten het actuele manifest vertrouwd is vastgelegd.
- Een match bewijst gelijkheid aan die referentie; gedrag, afkomst en uitvoeringsrechten vragen eigen controles.
In de volgende module verplaats je deze aandacht voor herkomst en bevoegdheid naar documenten die een RAG-systeem ophaalt.