Research status. I have working local prototypes for typed functions and proposal-first actions. They demonstrate the pattern; they are not a finished production platform.
Knowing the answer is different from doing the thing
In one prototype test, the system prepared a valid change, then the underlying object changed before approval. The proposal was rejected as stale. That failure was the correct result.
The first task is a calculation. It takes inputs, applies logic, and returns a result. The second changes shared state. It needs authority, validation, and a record of who approved it.
In my architecture, I give these two responsibilities different names. A function computes. An action governs change. Palantir Functions can participate in edits through function-backed Actions; the boundary I care about is that consequential change still passes through an explicit action contract.
Functions make capability reusable
A function is a named piece of logic with a clear contract. It declares the inputs it accepts and the output it returns. It can be versioned, tested, and used by more than one application or agent.
In a support workflow, a function might calculate response risk from priority, age, and ownership. It returns a score and explanation. It does not quietly reassign or close the case. Its value comes from producing the same inspectable result wherever it is called.
This resembles the role of the reusable layers in my engineering work. Pattern linting answers whether code matches a known risk shape. CodeGraph answers how code is connected. A verifier proves a property about the resulting change. Each capability has a boundary instead of being hidden inside one large prompt.
Actions put a contract around change
An action starts where a function's answer stops. Reassign case, request customer input, and close case all change state. They should declare which object they affect, what parameters they accept, which conditions must be true, and which permission is required.
The local action prototype I have been building uses a deliberate path:
- Validate the request and its typed inputs.
- Preview the exact before-and-after change.
- Create a proposal without changing the object.
- Ask the authorised person to approve or dismiss it.
- Revalidate against current state before execution.
- Record the outcome in an audit trail.
The revalidation step matters. A proposal can be sensible when created and unsafe ten minutes later. Approval should apply to the current object, not to a stale memory of it.
The agent should not have a secret side door
If a human must use a governed action to change an object, an agent should use the same path. Giving the agent a raw database tool would make every rule in the action layer optional.
In my prototype, the agent can prepare a proposal. It cannot claim the proposal was executed, and it cannot bypass the approval queue. A rejected or stale proposal is still useful evidence because it shows what the agent tried to do and why the system stopped it.
This design is inspired by patterns documented in Palantir's public material on Functions and Action types. I am studying the pattern, not claiming that my prototype reproduces the platform.
Good verbs make the system easier to trust
A vague tool such as update_anything transfers too much judgement into the prompt. A specific action such as mark_claim_reviewed can require a claim, a reviewer, supporting evidence, and a reason.
The smaller contract is less flexible, but that is the point. It makes the consequential part of the system boring enough to inspect.
Once the verbs are explicit, some of them can run repeatedly. That introduces a new question: when should work continue without waiting for me to start it?