5
17 Comments

NAEOS Technical Build Log #003-What Happens When Policy Changes Mid-Task?

Here's a simple experiment I'm using to think about AI agent governance.

Start with:

Policy v1

Dependency X is allowed.

The coding agent receives a task.

It creates a plan:

Install X → modify configuration → implement feature → run tests.

So far, everything is valid.

Then something changes.

Policy v2

Dependency X is no longer allowed.

The agent still has its original plan.

Its context still contains the old decision.

Its generated code may still assume X exists.

Now we have an interesting question:

Should the system trust the plan because it was valid when created?

I don't think so.

A plan is not an authorization token.

This leads to an important NAEOS design principle:

Authorization must be evaluated at the controllable execution boundary, not only when the plan is created.

The agent can continue reasoning.

It can update its plan.

But before the externally meaningful action occurs, the current policy should be evaluated again.

That creates something like:

Plan → Policy Check → Execute

rather than:

Plan → Execute

This distinction becomes particularly important when agents operate asynchronously or for long periods.

Policies change.

Repositories change.

Dependencies change.

Permissions expire.

Security conditions change.

An agent's context can become stale without the model itself becoming “wrong.”

The system needs to recognize that difference.

That's one reason I'm treating policy and runtime as separate concerns from the model in NAEOS.

The model is responsible for proposing.

The governance layer is responsible for deciding.

The runtime is responsible for executing.

The observation layer is responsible for establishing evidence.

I'm now interested in testing this with multiple coding agents against the same repository.

If two agents receive the same task and the policy changes halfway through, can the governance layer consistently prevent the stale plan from becoming an unauthorized action?

That's the experiment.

Repository:
https://github.com/NAEOS-foundation/naeos

What would you re-check at the execution boundary in an agent system?

on September 26, 2026
  1. 1

    Strong yes on evaluating at the boundary. The dimension I'd add to the two-agent test is identity. If both agents act through the same long-lived credential, "policy v2 allows this action" still can't tell you which agent asked, and you can't revoke one without revoking the other. We hit the credential side of this before the plan side: nearly every MCP server we wired up wanted one long-lived key sitting in a plain JSON file, so the token outlived both the task and the policy version. In your two-agent run, will each agent get its own scoped short-lived credential, or is policy the only thing that differs between them?

  2. 1

    I like the 'a plan is not an authorization token' line. One nasty edge case I’d add is - what if the policy check passes, the action is sent, and then the response times out?

    At that point you don’t actually know whether the side effect happened, so blindly retrying can be worse than failing. I think “unknown” needs to be a real state in these systems, not just treated as an error.

    1. 1

      Yes — I think “unknown” needs to be a first-class execution state.

      A timeout after authorization is especially dangerous because the runtime has lost observation of the side effect, not necessarily the side effect itself.

      So I don't think the safe state machine is simply:

      authorized → success / failure

      It needs something closer to:

      authorized → executing → confirmed / rejected / unknown

      And “unknown” should block an automatic retry unless the system can establish whether the original side effect occurred or prove that the operation is safely idempotent.

      This also reinforces the separation I'm trying to establish in NAEOS:

      Policy decides whether an action is allowed.
      Runtime executes it.
      Observation establishes what actually happened.

      If observation is lost, the system shouldn't invent a success or failure state just to keep the workflow moving.

      This is a really good edge case for the experiment. I'll add it to the execution-boundary tests.

  3. 1

    Really solid approach — I'm juggling something similar myself (building Xstream4K on the side), what's been the hardest part for you so far?

    1. 1

      Thanks — the hardest part so far has actually been defining the boundary precisely.

      The easy version is: “check the policy before the agent acts.”

      The harder question is: what exactly are we authorizing, against which state, and how do we know that authorization is still valid when the side effect happens?

      That led me toward context-bound, short-lived authorization that gets revalidated against current policy and repository state at the execution boundary.

      The interesting part is making that deterministic and observable across different coding agents, rather than relying on the agent to remember the rules.

      That's what I'm testing with NAEOS now.

  4. 1

    Alongside the policy version, I’d re check the concrete target and capability scope. An approval can become unsafe if the branch, working tree, lockfile, or command arguments change afterward. Binding authorization to a digest of the proposed action and relevant state and making it shortlived and single use would force re planning instead of silently reusing an old “yes.” For the 2 agent test, will approval be capability level or tied to an exact diff and command?

    1. 1

      Yes — this is exactly the distinction I want to test.

      I'm leaning toward authorization being bound to the concrete execution intent rather than treating it as a broad capability grant.

      So the authorization context would include things like:

      • policy/version
      • capability scope
      • target/repository state
      • proposed action or diff
      • command/arguments
      • relevant schema/version

      Then the runtime revalidates those assumptions at the side-effect boundary.

      I also like the short-lived/single-use property. That makes an authorization an assertion about a specific execution context, rather than a reusable “yes” that an agent can carry forward indefinitely.

      For the two-agent experiment, I'll test both cases explicitly: a capability-level approval versus an approval bound to the exact proposed action/state.

      That should make the stale-authorization failure mode observable rather than theoretical.

  5. 1

    The Plan then Policy Check then Execute pattern maps directly to what I see in long coding sessions. We run multi-hour builds on our SEO platform across seven languages, and the context window itself is the stale-plan problem in miniature. An agent proposes a fix based on state it read forty minutes ago. If a dependency updated or a config changed in between, the fix is syntactically valid but semantically wrong.

    The latest model upgrade improved this specific failure mode. It re-reads the actual error trace instead of pattern-matching to a cached fix from earlier in the session. Three or four debugging passes compressed to one. That is basically your governance principle applied at the model level: re-evaluate at the execution boundary, not just at planning time.

    The two-agent experiment against the same repo is the right test. The interesting edge case is when one agent gets the updated policy but the other has enough context to produce a valid-looking but unauthorized commit.

    1. 1

      Exactly. I think the stale-context problem is actually broader than model quality.

      A model can re-read the latest error and improve its reasoning, but that still doesn't make its existing authorization valid.

      The multi-agent case is where this becomes more interesting for NAEOS:

      Agent A → approved under Policy v1
      Policy changes → Policy v2
      Agent B → sees the new state
      Agent A → tries to execute the old plan

      The runtime should not have to decide which agent has the “better” context. It should evaluate the execution request against the current policy and state at the controllable boundary.

      That's the experiment I'm trying to formalize with NAEOS: keeping proposal, authorization, execution, and evidence as separate concerns.

  6. 1

    This is where the technical experiment starts becoming a strategic question: if governance consistently controls authorization at the execution boundary, what does that justify NAEOS owning as its foundational layer?

    1. 1

      That's the question I'm trying to answer through the experiments rather than define upfront.

      My current hypothesis is that NAEOS should own the engineering control plane around AI coding agents—not the model and not the repository itself.

      That means the layer responsible for:

      • turning agent proposals into policy-evaluable requests
      • evaluating authorization
      • enforcing the decision at execution boundaries
      • producing durable evidence of what was proposed, allowed, executed, and observed

      The important part is that this should remain agent/model/vendor neutral.

      If the experiment holds across different coding agents, that's a much stronger foundation for what NAEOS should own.

      1. 1

        That makes sense. I think this is also where the question in my email becomes relevant — what the evidence ultimately justifies NAEOS committing to own as its foundational layer. I’ll leave the rest there so we can keep that discussion in email.

  7. 1

    Spot on with validating right at the side-effect boundary. On top of checking policy versions, I’d also re-check structural file/repo state at that same moment. If a concurrent merge modified the codebase, executing that stale plan risks code corruption alongside policy violations.

    Are you feeding policy rejections back into the context window for live re-planning, or hard-killing the execution?

    1. 1

      Yes — I think the repo-state check belongs at the same boundary.

      A policy-valid plan can still be invalid against the repository state it was originally derived from.

      So I'm thinking of the boundary as something closer to:

      Plan → Revalidate Policy → Revalidate State → Authorize → Execute → Observe

      On rejection, I don't think the default should always be “hard kill.”

      A policy rejection should terminate that authorization attempt, but the agent can potentially receive the rejection as a new input and produce a revised proposal.

      The important distinction is that replanning must not implicitly preserve the previous authorization.

      New proposal → new evaluation → new authorization.

      That's the part I'd like to test explicitly.

  8. 1

    I’d re-check authorization freshness at the exact moment the side effect is about to happen, not just when the plan is created. The execution request should probably carry the policy/version and relevant state it was evaluated against, then the runtime should revalidate that before granting the capability.
    I’d also test the race condition explicitly: agent A gets approval → policy changes → agent A tries to execute the old plan. If that old decision can still produce a side effect, that’s probably the boundary worth investigating.

    1. 1

      Yes. The race condition you described is exactly the case I want to make explicit.

      I'm currently thinking of an execution request as carrying the context under which it was authorized:

      policy/version
      schema/version
      relevant repository/state identity
      authorization decision

      Then the runtime revalidates those assumptions before allowing the side effect.

      So an authorization isn't simply:

      “Agent A is allowed to do X.”

      It's closer to:

      “Agent A may perform X against state S under policy P, subject to validation at execution time.”

      If P or S has changed, the old authorization should no longer be sufficient.

      That distinction may become one of the more important primitives in NAEOS.

      1. 1

        Exactly. Treating authorization as context-bound and revalidated at execution time seems much safer than treating it as a static permission. The policy and state becoming part of the authorization context also makes the race-condition boundary much clearer. That could be a really important primitive for NAEOS.