AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Small MIT-licensed runtime for bounded LLM traversal, inspired by FPF and focused on practical agent behavior.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A small, deterministic Python runtime for agents that may reason freely but
must move through a workflow lawfully.
It keeps operational state, evidence freshness, transition legality,
authorization boundaries, and waiting conditions outside the model's prose
context. The model can inspect the map and choose; the runtime decides whether
the move is valid.
PyPI currently serves 1.9.5. Releases 1.9.6, 2.0.0 and 2.0.1 are tagged on
GitHub but their PyPI uploads are still blocked (see
PUBLISH-TRUSTED-PUBLISHER.md).
To install the current release, pin the tag:README 전문 보기 ↗A small Python library that tracks the state of a multi-step agent workflow and answers one question: is this next move allowed right now, and if not, why?
You describe a workflow as a graph (contexts, roles, evidence, gates, transitions). Your agent harness feeds the library the current state and the move the agent proposes. The library returns a legal/illegal outcome with the reason and a trace. It does not call a model, run tools, poll, or schedule anything.
PyPI: fpf-thinking-map · Current: 2.0.2 · License: MIT
Requires Python ≥ 3.12. No runtime dependencies.
pip install "fpf-thinking-map==2.0.2"
python -m fpf_thinking_map.verify # the package's own self-tests, 40 checks
python -m fpf_thinking_map.examples
Other releases on the index: 2.0.1, 2.0.0, 1.9.6.
from fpf_thinking_map import (
SemanticMap,
ContextPrimitive,
RolePrimitive,
GatePrimitive,
GateCheck,
TransitionPrimitive,
RuntimeBinding,
ThinkingMapTraversal,
)
semantic_map = SemanticMap()
semantic_map.register_context(ContextPrimitive("deploy", "Deploy"))
semantic_map.register_role(RolePrimitive("owner", "Owner", "deploy"))
semantic_map.register_gate(
GatePrimitive(
"release_gate",
"Release gate",
"deploy",
checks=[
GateCheck(
"tests",
"Tests are green",
required_evidence=["test_results"],
)
],
)
)
semantic_map.register_transition(
TransitionPrimitive(
"ship",
"Ship release",
"deploy",
"candidate",
"released",
required_gate_id="release_gate",
required_evidence=["test_results"],
)
)
traversal = ThinkingMapTraversal(semantic_map)
state = traversal.build_active_state(
RuntimeBinding(
task="release",
actor_role_ids=["owner"],
active_context_id="deploy",
current_evidence=["test_results"],
),
current_state="candidate",
)
inspection = traversal.step(state)
result = traversal.attempt_transition(state, "ship")
print(inspection.kind, result.kind, state.current_state)
# OutcomeKind.CONTINUE OutcomeKind.CONTINUE released
Replace the deploy vocabulary with your own contexts, roles, evidence and gates.
AuthorizationReceipt): scoped, non-replayable.PendingInput / AWAIT) from idle.MoveIntent) that can be inspected.ActiveState.checkpoint(),
from_checkpoint()); restore is all-or-nothing and never repairs.Given the same map, state, evidence and receipts, it returns the same result. The core modules call no clock, random source, network or model.
| Agent / host | This library |
|---|---|
| Interprets the task | Holds explicit traversal state |
| Generates options | Computes which moves are legal |
| Collects evidence | Checks presence and freshness |
| Proposes a move | Inspects or attempts that move |
| Explains the result | Returns a bounded outcome and trace |
| Requests human input | Enforces the authorization boundary |
| Runs tools and jobs | Never executes, polls or schedules them |
checkpoint() to persist a paused traversal.active_context_id
(advisory ADV-03): the harness must own continuity.requires_human_authorization defaults off.Full list of integrator boundaries: ADVISORIES.md.
python -m fpf_thinking_map.verify (40 checks) and
dev_mcp/test_server.py (45 checks) are written and run by the authors. They
check that the library does what it is specified to do. They have not been
audited by a third party.| Concern | Structures | Effect |
|---|---|---|
| Claim / assurance | ContextSlice, ClaimScope, FormalityLevel, ReliabilityPath | Typed scope; unknown stays unknown |
| Tool plans | CallPlanPrimitive, BudgetEnvelope | Incomplete plans → REVISE_PLAN |
| Autonomy | AutonomyBudgetDecl, AutonomyLedgerEntry | Opt-in budget; failure → ESCALATE |
| Work attribution | WorkPrimitive.performed_under | Wrong holder/context cannot complete |
| Gate join | GateDecision, OutcomeCause | ABSTAIN ≠ BLOCK (cause=gate_block) |
| Map integrity | ThinkingMapTraversal.validate_map() | Dangling refs / unknown IDs fail closed |
| Adjacency (2.0) | AdjacencyClearanceRule, AdjacentlyCleared | A confirmed-absent percept clears declared neighbours |
| Continuity (2.0.2) | ActiveState.checkpoint(), from_checkpoint() | Persist and restore a paused traversal |
| Gate result | Meaning | Typical outcome |
|---|---|---|
ABSTAIN (insufficient) | Not enough basis to say yes | COLLECT_EVIDENCE when evidence is declared |
BLOCK | Declared policy says no for this evaluation | Denied with cause=GATE_BLOCK |
BLOCK is hard for that evaluation; it is not automatically permanent. Checks
opt into BLOCK with failure_decision=GateDecision.BLOCK.
Four interactive traces
(evidence recovery, AWAIT, MoveIntent with authorization, ABSTAIN vs
BLOCK). They follow behavior covered by the test suite as of v1.9.5; they are
not a recording of a live model run and do not show later features.
| Line | Change |
|---|---|
| v1.0–v1.5 | Primitives, TTL, bridges, stagnation, stable public boundary |
| v1.6–v1.8 | Human authorization, receipts, AWAIT |
| v1.9 / 1.9.5 | Move identity; A.21 gate join (ABSTAIN vs BLOCK) |
| v1.9.6 | Failed-run revert terminal (XOR + distance bound) |
| v2.0.0 | Adjacency clearance (ADV-17) |
| v2.0.1 | Docs and metadata only; runtime identical to 2.0.0 |
| v2.0.2 | Copyright and SPDX notices on every source file (license unchanged); includes traversal checkpoint and restore (ADV-08) |
History: VERSION_TRACKER.md · CHANGELOG.md · Releases
| Priority | Advisory | One line |
|---|---|---|
| Sharp | ADV-03 | active_context_id is self-asserted: the harness must own continuity |
| Sharp | ADV-07 | RiskAbove string match is case-sensitive and fails silently |
| Common | ADV-01 | Stale evidence warns; it does not block unless gated |
| Common | ADV-10 | requires_human_authorization defaults off |
| 2.0 | ADV-17 | Adjacency clearance is only as sound as your declared biconditional |
MCP test harness: dev_mcp/ (run_scenario, get_advisories, run_verify).
| Path | Purpose |
|---|---|
fpf_thinking_map/ | The runtime (no dependencies) |
| ARCHITECTURE.md | Control flow |
| docs/deep/ADVISORIES.md | Integrator boundaries |
| bench/ | The ablation benchmark and its raw results |
| SHA256SUMS | Source file checksums |
MIT. Copyright (c) 2026 CONSOLIDARE CONTINUUM S.R.L.
Copyrighted build: release 2.0.2, commit
f0a17a543a23cbc8a33071b170a02ccf41fd33b7
(signed tag v2.0.2). Every source file in that commit carries the copyright
and SPDX notice.
The MIT license requires that the copyright notice and license text be kept in copies and substantial portions of the software; see LICENSE and NOTICE.
This is an independent implementation. It follows the public ailev/FPF work: upstream changes are reviewed and adopted, adapted or rejected (see docs/deep/UPSTREAM_SCOPE_INSPECTION.md). It is not affiliated with or endorsed by that project.