Policy Context and Explicit Decision Outcomes
Learning objective: Understand why the facts used to make a governance decision should be represented explicitly, and why the result should describe what happens next rather than collapse every decision into a boolean.
Difficulty: Beginner
Prerequisites: Decision Before Execution
Pattern Card
Problem: Decision facts can become scattered across application layers while a boolean result hides meaningful states such as defer, acknowledgment, or escalation.
Pattern: Build an explicit policy-context snapshot and return a structured decision outcome without performing the governed side effect.
Use when: A decision depends on multiple actor, resource, operation, environment, policy, or correlation facts, or when the host needs outcomes richer than allow/deny.
Prefer something simpler when: A local authorization policy or boolean result fully expresses the required behavior and the decision inputs do not need to be captured or reasoned about independently.
Observe: Policy evaluation consumes an explicit context snapshot and returns a structured outcome without performing the governed side effect.
This is the second foundational tutorial in ASI Backbone Learning.
It builds on Decision Before Execution, which established the first boundary:
Proposed action
↓
Governed decision
↓
Host-owned execution
This tutorial expands the middle of that flow:
Intent
↓
Policy Context
↓
Constraints
↓
Explicit Decision Outcome
The core idea is:
Make both the decision inputs and the decision result visible.
The Problem
A consequential operation is rarely evaluated from one fact.
A real decision may depend on:
- Who is proposing the operation.
- Which operation is being proposed.
- Which resource will be affected.
- The current state of that resource.
- Tenant, regional, or organizational boundaries.
- Environmental conditions.
- Risk or classification information.
- Policy version.
- Correlation and trace information.
- Prior acknowledgment or escalation state.
When these facts are scattered across controllers, services, claims, HTTP headers, global state, database calls, and logging statements, it becomes difficult to answer a basic question:
What information actually caused this decision?
The problem becomes worse when the result is reduced to:
bool allowed
A boolean can say yes or no.
It cannot explain whether the operation was:
- Allowed normally.
- Allowed with a warning.
- Denied.
- Deferred until later.
- Held for acknowledgment.
- Recommended for escalation.
A system that hides its inputs and compresses its outputs loses useful architectural information.
A Scattered Implementation
Consider the account-disable example from the first tutorial.
A controller might grow into something like this:
[HttpPost("{accountId}/disable")]
public async Task<IActionResult> DisableAccount(
string accountId,
CancellationToken cancellationToken)
{
bool isAdministrator = User.IsInRole("Administrator");
string? tenantId =
User.FindFirst("tenant_id")?.Value;
string? reason =
Request.Headers["X-Operation-Reason"]
.FirstOrDefault();
Account account =
await accountRepository.GetAsync(
accountId,
cancellationToken);
bool maintenanceHold =
await maintenanceService.IsActiveAsync(
cancellationToken);
bool allowed =
isAdministrator &&
account.TenantId == tenantId &&
!account.IsProtected &&
!maintenanceHold &&
!string.IsNullOrWhiteSpace(reason);
if (!allowed)
{
return Forbid();
}
await accountService.DisableAsync(
accountId,
cancellationToken);
return NoContent();
}
This may work.
But the decision inputs are now spread across:
Claims
Headers
Repository state
Environmental service
Route values
Local variables
And the result is still only:
true / false
Important information has been discovered, but not represented.
Separate Facts from Rules
A useful distinction is:
Policy context contains facts.
Constraints interpret those facts.
For example:
FACT
Requester is an administrator.
RULE
Only administrators may disable accounts.
Those are not the same thing.
Similarly:
FACT
Account is marked as protected.
RULE
Protected accounts require escalation.
Keeping facts and rules separate helps prevent a context object from becoming a hidden policy engine.
A context should describe the situation being evaluated.
A constraint or policy should decide what those facts mean.
Model the Proposed Intent
Start with the operation itself:
public sealed record DisableAccountIntent(
string AccountId,
string RequestedBy,
string Reason);
The intent answers:
What is being proposed?
It does not answer:
Should it happen?
That remains the job of policy evaluation.
Model Actor, Resource, and Environment
The context can be decomposed into smaller records:
public sealed record ActorContext(
string ActorId,
string TenantId,
bool IsAdministrator);
public sealed record AccountContext(
string AccountId,
string TenantId,
bool IsProtected,
bool IsAlreadyDisabled);
public sealed record EnvironmentContext(
bool MaintenanceHoldActive,
string Region);
Then combine the decision inputs:
public sealed record DisableAccountPolicyContext(
DisableAccountIntent Intent,
ActorContext Actor,
AccountContext Account,
EnvironmentContext Environment,
string CorrelationId,
string PolicyVersion);
Now the evaluator receives one explicit snapshot of the facts relevant to the decision.
The structure is visible:
Policy Context
|
+-- Intent
|
+-- Actor
|
+-- Resource
|
+-- Environment
|
+-- Correlation
|
+-- Policy identity
Context Is a Snapshot
A policy context is most useful when it represents the facts at evaluation time.
That matters because context can otherwise become a collection of live service dependencies:
public sealed class BadPolicyContext
{
public IUserDirectory UserDirectory { get; init; }
public IAccountRepository Accounts { get; init; }
public IMaintenanceService Maintenance { get; init; }
}
This object does not really contain context.
It contains ways to discover context later.
That creates several problems:
- Tests need more infrastructure.
- Evaluation may depend on call order.
- Facts may change during evaluation.
- The same policy input is difficult to reproduce.
- Audit evidence cannot easily describe what was actually observed.
Prefer gathering the required facts first:
Host gathers facts
↓
Context snapshot created
↓
Policy evaluates snapshot
This does not mean every value must be immutable forever.
It means the decision should have a clear understanding of the facts it evaluated.
Do Not Put Everything in Context
Explicit context does not mean unlimited context.
Avoid turning the context into:
Entire HTTP request
Entire user object
Entire database entity graph
Every environment variable
Every claim
Every configuration value
Include what is relevant to the decision.
This improves:
- Testability.
- Reviewability.
- Privacy.
- Serialization safety.
- Audit usefulness.
- Policy clarity.
A useful question is:
If this field changed, could it legitimately change the decision?
If the answer is no, the field may not belong in the policy context.
Model Outcomes Explicitly
Now make the result equally visible.
A framework-neutral outcome model might be:
public enum GovernanceDecisionOutcome
{
Allowed,
Warning,
Denied,
Deferred,
AcknowledgmentRequired,
EscalationRecommended
}
Each outcome answers a different operational question.
Allowed
The operation may cross the execution boundary.
Decision: Allowed
↓
Host may execute
Warning
The operation may proceed, but warning information should remain visible to the host or audit path.
Decision: Warning
↓
Host may execute
+
Warning reason retained
Denied
The operation should not execute.
Decision: Denied
↓
Stop
Deferred
The operation should not execute now, but the decision does not necessarily represent a permanent rejection.
Decision: Deferred
↓
Retry later or route elsewhere
Examples include:
- Temporary maintenance holds.
- Dependency unavailability.
- A policy decision requiring later reevaluation.
Acknowledgment Required
The operation cannot proceed until an acknowledgment boundary has been satisfied.
Decision: AcknowledgmentRequired
↓
Pause
↓
Obtain acknowledgment
↓
Re-enter governed flow
This is not the same as Allowed.
The acknowledgment requirement is part of the decision lifecycle.
Escalation Recommended
The operation should be routed to a higher-authority or specialized decision path before execution.
Decision: EscalationRecommended
↓
Do not execute
↓
Route for escalation
Examples include:
- Protected resources.
- High-risk operations.
- Policy ambiguity requiring human review.
Add Structured Reasons
An explicit outcome becomes much more useful when paired with structured reasons.
Use both:
- A machine-readable code.
- A human-readable explanation.
For example:
public sealed record DecisionReason(
string Code,
string Message);
A decision can then be modeled as:
public sealed record GovernanceDecision(
GovernanceDecisionOutcome Outcome,
IReadOnlyList<DecisionReason> Reasons)
{
public bool CanProceed =>
Outcome is GovernanceDecisionOutcome.Allowed
or GovernanceDecisionOutcome.Warning;
public static GovernanceDecision Allow() =>
new(
GovernanceDecisionOutcome.Allowed,
[]);
public static GovernanceDecision Warning(
string code,
string message) =>
new(
GovernanceDecisionOutcome.Warning,
[new DecisionReason(code, message)]);
public static GovernanceDecision Deny(
string code,
string message) =>
new(
GovernanceDecisionOutcome.Denied,
[new DecisionReason(code, message)]);
public static GovernanceDecision Defer(
string code,
string message) =>
new(
GovernanceDecisionOutcome.Deferred,
[new DecisionReason(code, message)]);
public static GovernanceDecision RequireAcknowledgment(
string code,
string message) =>
new(
GovernanceDecisionOutcome.AcknowledgmentRequired,
[new DecisionReason(code, message)]);
public static GovernanceDecision Escalate(
string code,
string message) =>
new(
GovernanceDecisionOutcome.EscalationRecommended,
[new DecisionReason(code, message)]);
}
A reason code might be:
account.disable.not-administrator
account.disable.cross-tenant
account.disable.protected-account
account.disable.maintenance-hold
account.disable.reason-required
The code is useful to software.
The message is useful to people.
Avoid making software parse human prose to determine what happened.
Evaluate the Context
A small policy can now consume the explicit context:
public sealed class DisableAccountPolicy
{
public GovernanceDecision Evaluate(
DisableAccountPolicyContext context)
{
if (!context.Actor.IsAdministrator)
{
return GovernanceDecision.Deny(
"account.disable.not-administrator",
"Only administrators may disable accounts.");
}
if (!string.Equals(
context.Actor.TenantId,
context.Account.TenantId,
StringComparison.Ordinal))
{
return GovernanceDecision.Deny(
"account.disable.cross-tenant",
"The actor and account belong to different tenants.");
}
if (context.Account.IsAlreadyDisabled)
{
return GovernanceDecision.Warning(
"account.disable.already-disabled",
"The account is already disabled.");
}
if (context.Account.IsProtected)
{
return GovernanceDecision.Escalate(
"account.disable.protected-account",
"Protected accounts require escalation.");
}
if (context.Environment.MaintenanceHoldActive)
{
return GovernanceDecision.Defer(
"account.disable.maintenance-hold",
"Account changes are temporarily deferred.");
}
if (string.IsNullOrWhiteSpace(
context.Intent.Reason))
{
return GovernanceDecision.RequireAcknowledgment(
"account.disable.reason-required",
"A reason must be supplied and acknowledged.");
}
return GovernanceDecision.Allow();
}
}
This example intentionally uses one policy class so the mechanics remain easy to see.
A larger system may compose many independent constraints.
The underlying principle stays the same:
Explicit facts
↓
Explicit rules
↓
Explicit outcome
Why Not Return HTTP Status Codes Directly?
A policy evaluator should usually avoid returning:
200
403
409
423
503
Those are transport-level decisions.
A governance outcome is a domain or architectural decision.
The host can translate it:
public static IResult ToHttpResult(
GovernanceDecision decision)
{
return decision.Outcome switch
{
GovernanceDecisionOutcome.Allowed =>
Results.Ok(),
GovernanceDecisionOutcome.Warning =>
Results.Ok(new
{
warning = decision.Reasons
}),
GovernanceDecisionOutcome.Denied =>
Results.Forbid(),
GovernanceDecisionOutcome.Deferred =>
Results.StatusCode(
StatusCodes.Status503ServiceUnavailable),
GovernanceDecisionOutcome.AcknowledgmentRequired =>
Results.Conflict(new
{
state = "acknowledgment-required",
reasons = decision.Reasons
}),
GovernanceDecisionOutcome.EscalationRecommended =>
Results.Conflict(new
{
state = "escalation-recommended",
reasons = decision.Reasons
}),
_ => Results.StatusCode(
StatusCodes.Status500InternalServerError)
};
}
The exact HTTP mapping is application-specific.
That is the point.
The governance model remains independent of HTTP.
The same decision can later be consumed by:
- A web API.
- A message consumer.
- A background worker.
- A CLI.
- A desktop application.
- An AI tool gateway.
Context Should Not Decide Its Own Outcome
Avoid methods such as:
public sealed record PolicyContext(...)
{
public bool IsAllowed()
{
// policy logic here
}
}
The object now contains both:
Facts
+
Rules
That may be appropriate for a small domain object enforcing its own invariant.
But for a reusable governance pipeline, it makes policy harder to replace, compose, test, version, or explain.
Keep the distinction intentional.
Outcomes Should Describe State, Not Trigger Work
Avoid:
public sealed class GovernanceDecision
{
public async Task ExecuteAsync()
{
...
}
}
A decision describes what the evaluator concluded.
It should not quietly acquire execution authority.
This preserves the boundary established in the first tutorial:
The decision informs execution. The host owns execution.
Composition Requires a Policy
Once more than one rule can contribute, the system needs an explicit composition strategy.
Suppose evaluation produces:
Warning: account already disabled
Deferred: maintenance hold active
Denied: actor is not authorized
Which result wins?
There is no universal answer that every system must use.
The important architectural requirement is that precedence should be defined, not accidental.
Possible policies include:
- Denial short-circuits all later rules.
- All constraints run and reasons are accumulated.
- Threat findings take precedence over ordinary warnings.
- Acknowledgment or escalation is introduced by a final decision policy.
- The first terminal outcome wins.
- The most restrictive outcome wins according to a documented ordering.
Do not let precedence emerge from whichever if statement happens to execute first unless that ordering is intentional.
Determinism Matters
Given the same:
Intent
Context
Policy version
a deterministic policy should normally produce the same outcome.
That improves:
- Testing.
- Reproduction.
- Incident analysis.
- Audit interpretation.
- Policy review.
Not all inputs are deterministic.
Examples include:
- External risk scores.
- Time-dependent facts.
- Probabilistic classifications.
- Remote policy services.
When nondeterministic inputs matter, represent the observed result in context when practical.
For example:
public sealed record RiskContext(
decimal Score,
string Source,
DateTimeOffset ObservedAt);
The policy can then evaluate what was observed rather than silently invoking an external scorer during the decision.
Preserve Policy Identity
If policy changes over time, the same context may legitimately produce a different decision under a different policy version.
That is why decision context often benefits from fields such as:
string CorrelationId
string PolicyVersion
string? PolicyHash
These values do not decide the operation by themselves.
They help explain which decision process was applied.
The dedicated Policy Versioning and Decision Provenance tutorial continues from this field-level introduction into stable policy identity, fingerprints, drift, execution freshness, rollback, and historical decision evidence.
A useful conceptual record is:
Intent
+
Context snapshot
+
Policy identity
=
Decision evidence
Later tutorials will expand this into acknowledgment and audit residue.
Keep Sensitive Data Out of Reason Messages
Structured reasons are useful, but they can become a data-leak path.
Avoid:
Denied because user's SSN is 123-45-6789.
Prefer:
Code:
data.release.restricted-classification
Message:
The requested resource has a restricted classification.
Decision reasons may reach:
- Logs.
- Audit stores.
- HTTP responses.
- User interfaces.
- Telemetry.
- Support tooling.
Treat them as potentially observable.
Test the Decision Matrix
Explicit context and outcomes make table-driven testing straightforward.
For example:
| Scenario | Expected outcome | Expected reason |
|---|---|---|
| Non-administrator | Denied |
account.disable.not-administrator |
| Cross-tenant account | Denied |
account.disable.cross-tenant |
| Already disabled | Warning |
account.disable.already-disabled |
| Protected account | EscalationRecommended |
account.disable.protected-account |
| Maintenance hold | Deferred |
account.disable.maintenance-hold |
| Missing reason | AcknowledgmentRequired |
account.disable.reason-required |
| Normal request | Allowed |
none |
A test can then verify both outcome and reason:
[Theory]
[InlineData(
false,
false,
false,
false,
"Reason",
GovernanceDecisionOutcome.Denied,
"account.disable.not-administrator")]
[InlineData(
true,
false,
false,
true,
"Reason",
GovernanceDecisionOutcome.Deferred,
"account.disable.maintenance-hold")]
public void Evaluate_ReturnsExpectedOutcome(
bool isAdministrator,
bool isProtected,
bool alreadyDisabled,
bool maintenanceHold,
string reason,
GovernanceDecisionOutcome expectedOutcome,
string expectedReasonCode)
{
var context = CreateContext(
isAdministrator,
isProtected,
alreadyDisabled,
maintenanceHold,
reason);
GovernanceDecision decision =
new DisableAccountPolicy()
.Evaluate(context);
Assert.Equal(
expectedOutcome,
decision.Outcome);
Assert.Contains(
decision.Reasons,
item => item.Code == expectedReasonCode);
}
The test is now describing policy behavior rather than reproducing controller implementation details.
Test Context Construction Separately
There are really two questions:
1. Did the host construct the correct context?
2. Did the policy evaluate that context correctly?
Those deserve separate tests.
A context-construction test can verify that:
Actor claim
↓
ActorContext.TenantId
Database state
↓
AccountContext.IsProtected
Configuration / service state
↓
EnvironmentContext.MaintenanceHoldActive
A policy test can then work entirely with in-memory context.
This separation makes failures easier to diagnose.
Common Failure Modes
1. Context Becomes a Service Locator
Avoid putting repositories, HTTP contexts, database contexts, or broad service providers inside policy context.
Gather facts before evaluation.
2. Context Contains Policy Conclusions
Avoid fields such as:
bool ShouldDeny
bool RequiresEscalation
unless those are genuinely upstream facts produced by a separate authoritative subsystem.
Context should not smuggle the final decision into the evaluator.
3. Boolean Outcomes Return
A rich context does little good if the policy still ends with:
return true;
Preserve meaningful decision states.
4. Reason Codes Are Unstable Prose
Avoid using human text as the machine identifier:
"You cannot do that right now."
Prefer a stable code:
account.disable.maintenance-hold
and allow the explanatory message to evolve separately.
5. Outcome Meaning Is Ambiguous
If one team interprets Deferred as "retry automatically" and another interprets it as "send for human review," the outcome is not sufficiently defined.
Document what each state means to the host.
6. Context Is Captured Too Late
If the host performs part of the side effect and only then constructs policy context, the decision boundary has already been crossed.
Context must be available before governed execution.
7. Policy Context Becomes an Audit Dump
Not every context field belongs in durable audit storage.
Decision context and audit residue are related but different concepts.
The next tutorial will examine that boundary more closely.
Tradeoffs
Benefits
- Decision inputs become reviewable.
- Policies are easier to unit test.
- Outcomes carry operational meaning.
- Reason codes improve diagnostics and automation.
- Policy versions can be correlated with decisions.
- Transport concerns remain outside the core decision model.
- Host execution behavior becomes easier to map explicitly.
- AI-generated proposals can be evaluated through the same contract.
Costs
- More modeling types.
- Context construction becomes a deliberate responsibility.
- Teams must define outcome semantics.
- Composition rules must be documented.
- Context schemas may evolve with policy requirements.
- Poorly bounded context can become bloated or privacy-sensitive.
The goal is not maximum structure.
The goal is enough structure to make consequential decisions understandable.
Relationship to AsiBackbone
This tutorial is framework-neutral, but the working AsiBackbone repository provides concrete versions of these concepts.
Working Implementation Map
The Learning example intentionally compresses the architecture so the policy boundary is easy to see. The production framework separates those responsibilities across smaller abstractions and integration layers.
| Tutorial concept | Working implementation | What to inspect |
|---|---|---|
| Framework-neutral policy context contract | IAsiBackboneConstraintEvaluationContext |
The minimum context surface shared by evaluators and constraints. |
| Concrete context snapshot | AsiBackboneConstraintEvaluationContext |
Correlation ID, policy version/hash, and normalized host-provided metadata. |
| Explicit outcome vocabulary | GovernanceDecisionOutcome |
The framework's allowed, warning, denied, deferred, acknowledgment-required, and escalation-recommended states. |
| Structured decision result | GovernanceDecision |
Outcome, stable reason codes, correlation and trace identifiers, policy identity, and CanProceed. |
| Constraint composition | DefaultAsiBackbonePolicyEvaluator |
How constraint results are accumulated and composed into a governance decision. |
| Domain- or host-specific final decision rules | IAsiBackboneDecisionPolicy |
The post-composition boundary that can introduce deferred, acknowledgment-required, or escalation-recommended outcomes. |
| Transport mapping | AsiBackboneHttpResultMappingExtensions |
How a governance decision is translated into HTTP without moving transport concerns into the Core decision model. |
| End-to-end policy behavior | PolicyEvaluatorEndToEndTests |
Executable examples of evaluator behavior and decision composition. |
The framework currently distinguishes these outcomes:
Allowed
Warning
Denied
Deferred
AcknowledgmentRequired
EscalationRecommended
The Learning example uses the same vocabulary so the conceptual model maps cleanly to the working implementation.
Follow the Full Evaluation Path
For a code-first inspection, follow these references in order:
IAsiBackboneConstraintEvaluationContext— begin with the context contract.AsiBackboneConstraintEvaluationContext— inspect the default concrete context snapshot.DefaultAsiBackbonePolicyEvaluator— follow constraint evaluation and composition.IAsiBackboneDecisionPolicy— see where broader host or domain policy can refine the composed result.GovernanceDecision— inspect the final structured decision contract.AsiBackboneHttpResultMappingExtensions— observe transport mapping after the governance decision exists.
For architectural explanation rather than source code, see:
- Policy Evaluator Pipeline — explains the evaluator flow and composition boundary.
- Custom Decision Policy Examples — shows how host-specific policy can transform a composed result without pushing those rules into individual constraints.
The Learning records such as ActorContext, AccountContext, and EnvironmentContext are teaching-specific shapes. They are not copies of framework production types. The important mapping is architectural: explicit facts enter evaluation, policy interprets those facts, and a structured decision leaves evaluation.
Apply the Pattern to AI
An AI tool request makes explicit policy context especially useful.
Avoid:
Model proposes:
"delete customer record"
Host:
"Model is trusted, execute."
Prefer:
AI proposal
↓
Intent
↓
Host constructs context
|
+-- authenticated actor
+-- tenant
+-- requested tool
+-- target resource
+-- classification
+-- environment
+-- policy identity
↓
Governance decision
↓
Allowed / Warning / Denied /
Deferred / AcknowledgmentRequired /
EscalationRecommended
↓
Host-controlled next step
The model can contribute information to the proposal.
It should not silently define the authoritative security or governance context.
That remains a host responsibility.
The model may propose. The host retains execution authority.
Exercise
Extend the account-disable example from Decision Before Execution.
Create a policy context containing:
Intent
Actor
Account
Environment
CorrelationId
PolicyVersion
Then implement at least these outcomes:
Allowed
Denied
Deferred
AcknowledgmentRequired
EscalationRecommended
Add Warning if you want the host to proceed while retaining a non-blocking concern.
Write tests that prove:
- Every modeled scenario returns the expected outcome.
- Every non-allowed outcome has a stable reason code.
- A normal request is allowed.
- A blocked decision remains blocked regardless of transport mapping.
- Context construction and policy evaluation can be tested independently.
For additional practice, add a new context field:
DataClassification
Then introduce a rule that changes the decision for restricted data without modifying the executor.
If changing the rule requires changing execution code, examine whether policy and execution have become coupled again.
For a guided version of this exercise, continue with the Policy Context and Explicit Decision Outcomes learner exercise. It asks you to observe the information lost by boolean-only decisions, add a new context fact and structured rule, make precedence intentional, and preserve stable reason codes.
Review Questions
Before moving on, you should be able to answer:
- What is policy context?
- Why should context contain facts rather than policy conclusions?
- Why is a context snapshot easier to test than a collection of service dependencies?
- When is a boolean result insufficient?
- What is the operational difference between
Denied,Deferred,AcknowledgmentRequired, andEscalationRecommended? - Why should reason codes be machine-readable and stable?
- Why should governance outcomes remain independent of HTTP status codes?
- What does policy identity add to a decision?
- What problems arise when context becomes too broad?
- Why should the host, not an AI model, construct authoritative policy context?
Next
The next foundational topic is Acknowledgment and Audit Residue.
That tutorial expands the lifecycle after a decision:
Decision
↓
Acknowledgment when required
↓
Host action
↓
Audit residue
It will examine how a consequential operation can pause for explicit acknowledgment and how structured evidence can preserve what happened without confusing governance evidence with ordinary application logging.
Related Content
- Foundational Tutorial Index — view the complete five-tutorial governed-execution learning path.
- Decision Before Execution — revisit the separation between proposed intent, governance decisions, and host-owned execution.
- Constraint Composition and Policy Precedence — go deeper on how independent constraint results are combined into a base decision and how explicit precedence avoids accidental rule-order behavior.
- When ASP.NET Core Authorization Is Enough — compare this richer decision model with built-in ASP.NET Core policies, requirements, handlers, and resource-based authorization, including cases where the simpler authorization model is the better choice.
- Acknowledgment and Audit Residue — continue from explicit decision outcomes into acknowledgment, re-evaluation, correlation, and governance evidence.
- Scoped Capability and Host-Owned Execution — follow allowed or acknowledged decisions into narrowly scoped execution authority.
- Governed AI Tool Gateway — see authoritative host context and explicit decision outcomes applied to AI-proposed tool actions.
- Policy Context and Explicit Decision Outcomes sample — run the companion decision matrix and observe explicit context snapshots, structured reason codes, and host-controlled next-step semantics.
- Policy Context and Explicit Decision Outcomes learner exercise — modify the sample to explore boolean information loss, context evolution, structured reasons, and rule precedence.
- Executable Samples — explore the published companion-sample guide before following a canonical sample README.
- Hands-On Labs — practice constructing policy context, defining decision outcomes, and reasoning about governance boundaries.
Read it. Run it. Question it. Improve it.