Sharing Learnings Without Leaking Secrets
When an agent's lesson is good enough to share, every value it touched needs a privacy call. Scan the bytes for secrets and you are guessing at something the bytes cannot answer.
The payoff from an agent learning something is sharing it. The lesson one agent works out on a hard task becomes available to the rest, so nobody pays that cost twice. But the moment a learning leaves one agent and enters a pool the others read from, you owe a privacy decision on every value that learning touched. Get it wrong in one direction and you bury something useful. Get it wrong in the other and you leak a credential into a place every other agent in the organisation can see.
The obvious way to make that call is to look at the data. Scan the tool inputs and outputs for things that look like secrets: tokens, anything matching the shape of an API key, anything with a name like password. We did this, and it works until it doesn't.
The list never closes
A payment task once produced a perfectly shareable lesson about retry behaviour. It never got shared. One of the tool's arguments was an idempotency key, a token used to deduplicate requests, and its name contained the word "key". The scanner flagged the whole trace as sensitive and held the lesson back. That token was about as secret as an order number.
So you add an exception for idempotency keys. Then a routing key trips it. Then a shard key. The list of "looks like a secret but isn't" grows forever, because you are asking a question the data cannot answer. Is batch-2025-q3-001 a secret? In one tool it is a public batch identifier you could print on an invoice. In another it is a tenant key that unlocks an account. The string is identical. Nothing in the bytes tells you which world you are in, so anything that decides from the bytes alone is guessing, and it will be confidently wrong in both directions.
Ask the thing that already knows
There is a party that knows the answer, and it is not the scanner. The tool that produced the value knows whether its api_key argument is a credential and whether the email it returns is personal data. That knowledge exists the moment the value is created. The guessing approach throws it away and then tries to reconstruct it downstream from vocabulary, which is how you end up maintaining a dictionary of suspicious word fragments.
So we stopped reconstructing it. A tool states once which of its fields are sensitive. The idempotency key is no longer a credential because its author never said it was one. The customer email stays private because the tool that returned it said so. No dictionary, no exception list, no adjacent-category guesswork.
A floor, not a ceiling
A declaration sets where a field starts, not where it ends. Mark a field secret and it is locked down. Mark it shareable and you have made a starting claim, not the last word: if the value carries the shape of a live credential, it is treated as secret regardless of what the tool said. A classification only ever moves one way, toward more caution, and never back. A tool can earn a field more protection, never less. The scan would sooner over-guard a value than risk waving a real secret through, so a careless, or even dishonest, "shareable" cannot open a door.
Why the source, not the sink
Declaring at the source answers for the fields a tool names, and that is most of them. It never answers for all of them. There is always a tool you did not write, a return value nobody labelled, a parameter someone added last week in a hurry. For those the call is open again with nothing to lean on, so Hyperstruck falls back to a default: share what it is unsure of, or hold it back. It holds it back.
That looks overcautious until you price the two mistakes. Hold a shareable lesson back by mistake and nothing is lost. The knowledge still exists, kept private with the agent that found it, and the moment you confirm it is safe you release it to the rest. The error cost you a delay. Leak a secret by mistake and there is no taking it back. The other agents have already read it, and deleting the entry afterwards does not unread it. The only real remedy is to rotate the exposed credential, if you notice it went out at all. One slip costs you a delay, the other costs you a breach.
This is the same logic that says ask the source in the first place. The tool that produced a value is the one place the answer is reliable, so you take it from there wherever you can and err toward caution wherever you cannot. None of this is new outside of agents. Data platforms classify at the column, not by sniffing query results. Typed-secret libraries mark a value at the type so it cannot be logged by accident. They put the call where the knowledge already is, because when one mistake is a delay and the other is a breach, you stop asking the data to confess what it is and ask the party that always knew.