Skip to main content
Glama
README.md
# Base120

**120 named mental models for structured reasoning — a stdlib-only Python library.**

**Version 2.0.0** · [Changelog](CHANGELOG.md) · [PyPI](https://pypi.org/project/base120/) · [Documentation](docs/) · [Examples](examples/) · [Contributing](CONTRIBUTING.md)

Use them to analyze problems, design systems, and make decisions — whether you are a human, an AI agent, or a fleet of both.

[![License: Apache 2.0](https://img.shields.io/badge/license-Apache_2.0-blue)](LICENSE)
[![Models](https://img.shields.io/badge/models-120-brightgreen)]()
[![Domains](https://img.shields.io/badge/domains-6-blue)]()
[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)
[![Dependencies](https://img.shields.io/badge/dependencies-0-success)]()
[![CI](https://github.com/hummbl-io/base120/actions/workflows/ci.yml/badge.svg)](https://github.com/hummbl-io/base120/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/base120)](https://pypi.org/project/base120/)
[![Code of Conduct](https://img.shields.io/badge/CoC-Contributor%20Covenant-ff69b4)](CODE_OF_CONDUCT.md)
[![Security](https://img.shields.io/badge/security-policy-blue)](SECURITY.md)

---

## Quick Start

```bash
pip install base120
```

```python
from base120 import Engine

engine = Engine()
operator = engine.get("P6")
print(operator.name)  # → Point-of-View Anchoring

prompt = engine.prompt("P6", "How should we price the certification tier?")
print(prompt)
```

That's it. Zero dependencies. No network calls. No telemetry. Just 120 reasoning primitives you can call from any Python 3.11+ environment.

---

## Table of Contents

- [What is Base120?](#what-is-base120)
- [The 6 Transformation Families](#the-6-transformation-families)
- [The 120 Models](#the-120-models)
- [Installation](#installation)
- [Python SDK](#python-sdk)
- [CLI](#cli)
- [MCP Server](#mcp-server)
- [Ledger](#ledger)
- [Examples](#examples)
- [Why Base120?](#why-base120)
- [Comparison](#comparison)
- [Consuming the Registry](#consuming-the-registry)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)

---

## What is Base120?

Base120 is a **canonical registry of 120 mental models** organized into 6 transformation families, with a stdlib-only Python SDK for programmatic access.

Each model is a **named, versioned reasoning primitive** — not a vague platitude, but a specific operator you can apply to a problem, generate a prompt from, and persist a governance-readable record of.

### Design Principles

- **Stdlib-only**: Zero third-party runtime dependencies. The entire library runs on Python 3.11+ with no installs beyond `pip install base120`.
- **Deterministic**: Same input, same output. No LLM calls, no network, no randomness. Every operator lookup is reproducible.
- **Tuple-native**: Every operator application produces a JSONL tuple you can persist to an append-only ledger.
- **Agent-friendly**: Works with Claude Code, Codex, Cursor, Copilot, and any MCP-compatible agent via the `base120-mcp` entry point.
- **Human-friendly**: The CLI and Python API are equally usable by a human in a terminal and an AI agent in a pipeline.
- **Frozen canon**: The 120-model registry is versioned and frozen. Implementations in other languages conform to this registry.

### What Base120 is NOT

- **Not an LLM**: Base120 doesn't call models. It provides the reasoning structure; you provide the intelligence (human or AI).
- **Not a prompt library**: Base120 generates operator-specific prompts, but the operators themselves are the value — structured reasoning primitives, not canned text.
- **Not a framework**: No base classes to inherit, no decorators to apply, no middleware to configure. Import, call, done.
- **Not a SaaS**: No API keys, no rate limits, no vendor lock-in. The registry is a YAML file you can read with any language.

---

## The 6 Transformation Families

Base120 organizes mental models into 6 families based on the type of cognitive transformation they perform:

| Family | Code | Focus | Question it answers | Example Models |
|--------|------|-------|---------------------|----------------|
| **Perspective** | P | Viewpoints, framing, empathy | "How else can I see this?" | P1 First Principles, P5 Empathy Mapping, P10 Context Windowing |
| **Inversion** | IN | Counterfactuals, negation, contradiction | "What if the opposite is true?" | IN1 Reductio ad Absurdum, IN5 Worst-Case Analysis, IN6 Pre-Mortem |
| **Composition** | CO | Building, combining, layering | "How do I assemble this from parts?" | CO1 Modularity, CO5 Interface Design, CO10 Protocol Layering |
| **Decomposition** | DE | Breaking down, isolating, factoring | "What are the pieces?" | DE1 Root Cause Analysis, DE5 Separation of Concerns, DE8 Dimensional Reduction |
| **Recursion** | RE | Self-reference, iteration, meta-reasoning | "How does this feed back on itself?" | RE1 Feedback Loop, RE5 Recursion, RE8 Self-Reference |
| **Systems** | SY | Dynamics, emergence, control | "How does the whole behave?" | SY1 Causal Loop Diagrams, SY13 Reinforcing Feedback, SY18 Resilience Engineering |

### Why 6 families?

Most mental-models resources present a flat list of 50-100 models with no structure. Base120's 6-family taxonomy gives you:

- **A navigation map**: Know which family to reach for based on the type of thinking you need.
- **A completeness check**: Each family has 18-20 models, so you can tell when you've exhausted a mode of thinking.
- **A composition grammar**: Families chain naturally — Perspective → Inversion → Decomposition → Composition → Recursion → Systems is a common decision-making arc.

### Family deep dives

- [Perspective (P)](#domain-p--perspective-p1p18) — 18 operators for viewpoints, framing, and empathy
- [Inversion (IN)](#domain-in--inversion-in1in18) — 18 operators for counterfactuals, negation, and contradiction
- [Composition (CO)](#domain-co--composition-co1co20) — 20 operators for building, combining, and layering
- [Decomposition (DE)](#domain-de--decomposition-de1de20) — 20 operators for breaking down, isolating, and factoring
- [Recursion (RE)](#domain-re--recursion-re1re20) — 20 operators for self-reference, iteration, and meta-reasoning
- [Systems (SY)](#domain-sy--systems-sy1sy20) — 20 operators for dynamics, emergence, and control

---

## The 120 Models

<details>
<summary><strong>Click to expand the full model list</strong></summary>

### Domain P — Perspective (P1–P18)

- P1 First Principles Framing
- P2 Stakeholder Mapping
- P3 Identity Stack
- P4 Lens Shifting
- P5 Empathy Mapping
- P6 Point-of-View Anchoring
- P7 Perspective Switching
- P8 Narrative Framing
- P9 Cultural Lens Shifting
- P10 Context Windowing
- P11 Role Perspective-Taking
- P12 Temporal Framing
- P13 Spatial Framing
- P14 Reference Class Framing
- P15 Assumption Surfacing
- P16 Identity-Context Reciprocity
- P17 Frame Control & Reframing
- P18 Horizon Scanning

### Domain IN — Inversion (IN1–IN18)

- IN1 Reductio ad Absurdum
- IN2 Proof by Contradiction
- IN3 Negation Testing
- IN4 Counterfactual Reasoning
- IN5 Worst-Case Analysis
- IN6 Pre-Mortem
- IN7 Regret Minimization
- IN8 Inversion Principle
- IN9 Constraint Relaxation
- IN10 Opposite Thinking
- IN11 Devil's Advocate
- IN12 Second-Order Negation
- IN13 Assumption Violation
- IN14 Boundary Stressing
- IN15 Failure Mode Enumeration
- IN16 Adversarial Generation
- IN17 Exclusion Analysis
- IN18 Complement Thinking

### Domain CO — Composition (CO1–CO20)

- CO1 Modularity
- CO2 Abstraction
- CO3 Encapsulation
- CO4 Interface Design
- CO5 Protocol Layering
- CO6 Dependency Injection
- CO7 Pipeline Construction
- CO8 Orchestration
- CO9 Service Composition
- CO10 Microservice Decomposition
- CO11 Event-Driven Architecture
- CO12 API Gateway Pattern
- CO13 Federation
- CO14 Polyglot Persistence
- CO15 CQRS
- CO16 Event Sourcing
- CO17 Saga Pattern
- CO18 Strangler Fig Pattern
- CO19 Sidecar Pattern
- CO20 Ambassador Pattern

### Domain DE — Decomposition (DE1–DE20)

- DE1 Root Cause Analysis
- DE2 Five Whys
- DE3 Fault Tree Analysis
- DE4 Fishbone Diagram
- DE5 Separation of Concerns
- DE6 Dimensional Reduction
- DE7 Factor Analysis
- DE8 Principal Component Analysis
- DE9 Feature Extraction
- DE10 Domain-Driven Design
- DE11 Bounded Context
- DE12 Aggregate Decomposition
- DE13 Entity-Relationship Modeling
- DE14 Normalization
- DE15 Refactoring
- DE16 Extract Method
- DE17 Decompose Conditional
- DE18 Replace Inheritance
- DE19 Split Phase
- DE20 Replace Algorithm

### Domain RE — Recursion (RE1–RE20)

- RE1 Feedback Loop
- RE2 Recursion
- RE3 Iteration
- RE4 Self-Reference
- RE5 Meta-Reasoning
- RE6 Reflection
- RE7 Introspection
- RE8 Bootstrapping
- RE9 Self-Modification
- RE10 Auto-Tuning
- RE11 Meta-Learning
- RE12 Transfer Learning
- RE13 Curriculum Learning
- RE14 Active Learning
- RE15 Reinforcement Learning
- RE16 Q-Learning
- RE17 Policy Gradient
- RE18 Actor-Critic
- RE19 Multi-Agent Reinforcement
- RE20 Hierarchical Reinforcement

### Domain SY — Systems (SY1–SY20)

- SY1 Causal Loop Diagrams
- SY2 Stock and Flow
- SY3 Systems Archetypes
- SY4 Leverage Points
- SY5 Tragedy of the Commons
- SY6 Fixes That Fail
- SY7 Shifting the Burden
- SY8 Eroding Goals
- SY9 Escalation
- SY10 Success to the Successful
- SY11 Limits to Growth
- SY12 Balancing Feedback
- SY13 Reinforcing Feedback
- SY14 Homeostasis
- SY15 Resilience
- SY16 Antifragility
- SY17 Optionality
- SY18 Redundancy
- SY19 Diversity
- SY20 Modularity

</details>

**Total: 120 models.** Full registry in [`Base120_Canonical_Model_Registry.yaml`](Base120_Canonical_Model_Registry.yaml).

---

## Installation

### From PyPI

```bash
pip install base120
```

### From source

```bash
git clone https://github.com/hummbl-io/base120.git && cd base120
pip install -e ".[test]"
```

### Requirements

- Python 3.11+
- Zero runtime dependencies (stdlib only)

---

## Python SDK

### Core API

```python
from base120 import Engine, Ledger

engine = Engine()

# Look up an operator by ID
operator = engine.get("P6")
print(operator.name)        # → Point-of-View Anchoring
print(operator.family)      # → P (Perspective)
print(operator.description) # → Anchor analysis to a specific viewpoint

# Generate an operator-specific prompt for a problem
prompt = engine.prompt("P6", "How should we price the certification tier?")
print(prompt)

# Apply an operator and persist a governance-readable record
result = engine.record(
    "P6",
    "How should we price the certification tier?",
    "Anchor the offer to the compliance officer's risk budget.",
    0.85,  # confidence score
)

# Persist to an append-only ledger
ledger = Ledger("base120-ledger.jsonl")
ledger.append(result.to_tuple())
```

### Engine methods

| Method | Returns | Description |
|--------|---------|-------------|
| `engine.get(operator_id)` | `Operator` | Look up a single operator by ID (e.g., `"P6"`) |
| `engine.list()` | `list[Operator]` | List all 120 operators |
| `engine.families()` | `dict` | List the 6 transformation families |
| `engine.prompt(operator_id, problem)` | `str` | Generate an operator-specific prompt for a problem |
| `engine.record(operator_id, problem, response, confidence)` | `Result` | Apply an operator and produce a ledger tuple |

### Operator attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| `operator.id` | `str` | The operator code (e.g., `"P6"`) |
| `operator.name` | `str` | Human-readable name (e.g., `"Point-of-View Anchoring"`) |
| `operator.family` | `str` | The transformation family (e.g., `"P"`) |
| `operator.description` | `str` | What the operator does |

---

## CLI

```bash
# List all 120 operators
base120 list

# Inspect one operator
base120 get P6

# Generate an operator-specific prompt for a problem
base120 prompt P6 "How should we price the certification tier?"

# List the 6 transformation families
base120 families
```

### CLI examples

```bash
$ base120 get IN6
ID:          IN6
Name:        Pre-Mortem
Family:      IN (Inversion)
Description: Imagine the project has failed; work backward to identify causes

$ base120 prompt IN6 "Should we migrate from REST to GraphQL?"
# Generates a pre-mortem prompt: "Assume the migration has shipped and
# failed catastrophically. What went wrong? List the top 5 failure modes
# and their early-warning signals."
```

---

## MCP Server

Base120 ships with an MCP (Model Context Protocol) server entry point, so any MCP-compatible agent can use the 120 operators directly:

```bash
# Run the MCP server
base120-mcp
```

Learn more about MCP at the [Model Context Protocol specification](https://modelcontextprotocol.io/).

### Configuration for Claude Code

Add to your [Claude Code](https://docs.anthropic.com/en/docs/claude-code) MCP config:

```json
{
  "mcpServers": {
    "base120": {
      "command": "base120-mcp"
    }
  }
}
```

### Configuration for Cursor

Add to your [Cursor](https://docs.cursor.com/context/model-context-protocol) MCP config:

```json
{
  "mcpServers": {
    "base120": {
      "command": "base120-mcp"
    }
  }
}
```

Once configured, your agent can call `base120.get`, `base120.list`, `base120.prompt`, and `base120.families` as MCP tools.

---

## Ledger

Every operator application can be persisted as a JSONL tuple to an append-only ledger:

```python
from base120 import Engine, Ledger

engine = Engine()
ledger = Ledger("decisions.jsonl")

# Apply an operator and record the result
result = engine.record(
    "DE1",                                    # operator ID
    "Reduce release risk.",                   # problem
    "Split blockers by owner.",               # response
    0.9,                                      # confidence
)

ledger.append(result.to_tuple())

# Query high-drift records (confidence < threshold)
high_drift = ledger.cut(0.5)
for record in high_drift:
    print(record)
```

### Ledger tuple format

Each ledger entry is a JSONL tuple with:

- `operator_id`: The operator code (e.g., `"DE1"`)
- `problem`: The problem statement
- `response`: The applied response
- `confidence`: Float 0.0–1.0
- `timestamp`: ISO 8601 timestamp

The ledger is append-only — records are never modified or deleted, making it suitable for audit trails and governance review.

---

## Examples

### Example 1: Structured Decision-Making

**Problem**: "Should we migrate from REST to GraphQL?"

```python
from base120 import Engine

engine = Engine()

# Step 1 — P1 (First Principles): What are the irreducible requirements?
print(engine.prompt("P1", "Should we migrate from REST to GraphQL?"))
# → "What are the irreducible requirements? Latency, cacheability, client flexibility."

# Step 2 — IN5 (Worst-Case Analysis): What if the migration takes 6 months?
print(engine.prompt("IN5", "Should we migrate from REST to GraphQL?"))
# → "What if the migration takes 6 months and breaks mobile clients?"

# Step 3 — DE5 (Separation of Concerns): Which parts need flexibility?
print(engine.prompt("DE5", "Should we migrate from REST to GraphQL?"))
# → "Which parts of the API actually need flexibility? Read paths vs write paths."

# Step 4 — CO1 (Modularity): Can we support both during transition?
print(engine.prompt("CO1", "Should we migrate from REST to GraphQL?"))
# → "Can we support both during transition? BFF pattern, not big-bang."

# Step 5 — SY13 (Feedback Loops): How do we know it's working?
print(engine.prompt("SY13", "Should we migrate from REST to GraphQL?"))
# → "How do we know it's working? Metrics: latency p99, error rate, client adoption."
```

Each step names the model, applies it, and passes output to the next. No vague advice — explicit reasoning with receipts.

### Example 2: Pre-Mortem for a Launch

```python
from base120 import Engine, Ledger

engine = Engine()
ledger = Ledger("launch-premortem.jsonl")

# Run a pre-mortem on the launch plan
result = engine.record(
    "IN6",                                          # Pre-Mortem
    "Launch the new pricing tier next Monday.",     # problem
    "Top failure mode: existing customers downgrade to the new tier, cannibalizing revenue.",
    0.8,                                            # confidence
)

ledger.append(result.to_tuple())
print("Pre-mortem recorded. Review before launch.")
```

### Example 3: Multi-Agent Reasoning

```python
from base120 import Engine

engine = Engine()

# An AI agent applies Perspective operators to gather viewpoints
viewpoints = [engine.prompt(f"P{i}", "Design a rate limiter") for i in [1, 5, 6, 10]]

# Then applies Inversion to stress-test
failure_modes = [engine.prompt(f"IN{i}", "Design a rate limiter") for i in [5, 6, 15]]

# Then applies Systems to understand dynamics
dynamics = [engine.prompt(f"SY{i}", "Design a rate limiter") for i in [1, 12, 13]]
```

### Example 4: Reading the Registry Directly (Any Language)

The canonical registry is a YAML file — you can read it from any language without installing Base120:

```python
import yaml  # any YAML parser

with open("Base120_Canonical_Model_Registry.yaml") as f:
    registry = yaml.safe_load(f)

models = {m["id"]: m for m in registry["models"]}
print(models["P1"]["name"])   # → First Principles Framing
print(models["IN6"]["name"])  # → Pre-Mortem
print(models["SY13"]["name"]) # → Reinforcing Feedback
```

```javascript
// Node.js
import yaml from 'js-yaml';
import { readFileSync } from 'fs';

const registry = yaml.load(readFileSync('Base120_Canonical_Model_Registry.yaml', 'utf8'));
const models = Object.fromEntries(registry.models.map(m => [m.id, m]));
console.log(models.P1.name);   // → First Principles Framing
```

```rust
// Rust (using serde_yaml)
let registry: serde_yaml::Value = serde_yaml::from_str(&std::fs::read_to_string("Base120_Canonical_Model_Registry.yaml")?)?;
let models = registry["models"].as_sequence().unwrap();
```

---

## Why Base120?

### The problem with existing mental-models resources

Most mental-models resources fall into one of three categories:

1. **Content sites** ([Farnam Street](https://fs.blog/mental-models/), [fs.blog](https://fs.blog/)): Great explanations, no programmatic access. You read them, then forget which model applies when.
2. **Awesome-lists** ([awesome-mental-models](https://github.com/AdrienLemaire/awesome-mental-models), [awesome-concepts](https://github.com/lukasz-madon/awesome-concepts)): Curated links, no executable tooling. You star them, then never use them.
3. **Claude Code skills** ([cc-thinking-skills](https://github.com/tjboudreaux/cc-thinking-skills), [mental-models-os](https://github.com/darnoux/mental-models-os)): Platform-specific, not a general library. You install them, then can't use them outside Claude Code.

Base120 fills the structural hole: **a general-purpose Python library** with a structured taxonomy, stdlib-only design, and multi-surface delivery (Python SDK + CLI + MCP + REST).

### What you get

- **120 operators** — the largest catalog among general-purpose mental-models libraries
- **6-family taxonomy** — structured navigation, not a flat list
- **Zero dependencies** — installs in seconds, runs anywhere Python 3.11+ runs
- **Deterministic** — same input, same output, every time
- **Agent-native** — MCP server built in, works with Claude Code, Cursor, Codex, Copilot
- **Human-native** — CLI and Python API equally usable
- **Ledger-native** — every application persists a governance-readable record
- **Frozen canon** — the registry is versioned and frozen; other-language implementations conform to it

### Use cases

- **Decision-making frameworks**: Apply structured reasoning to hard decisions, with receipts.
- **AI agent reasoning**: Give agents a vocabulary of 120 reasoning primitives via MCP.
- **Multi-agent coordination**: Different agents apply different families; the ledger records who did what.
- **Audit trails**: Every reasoning step is persisted, queryable, and reviewable.
- **Education**: Learn the 6-family taxonomy and when to reach for each mode of thinking.
- **Research**: Cite the canonical registry in papers; the YAML is the source of truth.

---

## Comparison

| Feature | Base120 | cc-thinking-skills | mental-models (cyperx84) | awesome-concepts |
|---------|---------|-------------------|-------------------------|-----------------|
| **Model count** | 120 | 28 | 98 | ~100 (links) |
| **Taxonomy** | 6 transformation families | Flat list | Flat list | Flat list |
| **Python library** | Yes | No (JS skills) | Yes | No |
| **CLI** | Yes | No | Yes | No |
| **MCP server** | Yes | No | Yes | No |
| **Dependencies** | Zero (stdlib only) | N/A | Standard | N/A |
| **Ledger** | Yes (append-only JSONL) | No | No | No |
| **License** | Apache 2.0 | MIT | MIT | CC0 |
| **Platform** | Any Python 3.11+ | Claude Code only | Python + Claude Code | Web (links) |
| **Deterministic** | Yes | No (LLM-based) | No | N/A |
| **Cross-language registry** | Yes (YAML) | No | No | N/A |

### Positioning

- **vs. [cc-thinking-skills](https://github.com/tjboudreaux/cc-thinking-skills)** (946 stars): cc-thinking-skills is a Claude Code skill pack with 28 models. Base120 is a general Python library with 120 models, a CLI, an MCP server, and a structured taxonomy. Use both — cc-thinking-skills for Claude Code workflows, Base120 for any Python or agent pipeline.
- **vs. [mental-models (cyperx84)](https://github.com/cyperx84/claude-skills-mental-models)** (13 stars): cyperx84's package is Claude Code-centric with 98 models and a flat list. Base120 has 120 models, a 6-family taxonomy, stdlib-only design, and a ledger.
- **vs. [awesome-concepts](https://github.com/lukasz-madon/awesome-concepts)** (624 stars): awesome-concepts is a curated list of links. Base120 is an executable library. Use awesome-concepts to discover concepts, Base120 to apply them programmatically.
- **vs. [pyreason](https://github.com/lab-v2/pyreason)** (344 stars): pyreason is academic logic inference, not decision-making mental models. Different category — use pyreason for neurosymbolic reasoning, Base120 for cognitive frameworks.
- **vs. [llm-reasoners](https://github.com/maitrix-org/llm-reasoners)** (2,341 stars): llm-reasoners is LLM reasoning research (training/inference), not mental models for decision-making. Different category — use llm-reasoners for LLM reasoning research, Base120 for structured human/agent reasoning.

---

## Consuming the Registry

The canonical registry is [`Base120_Canonical_Model_Registry.yaml`](Base120_Canonical_Model_Registry.yaml) — a single YAML file that is the source of truth for all 120 operators.

### Registry structure

```yaml
version: "1.0.0"
models:
  - id: "P1"
    name: "First Principles Framing"
    family: "P"
    description: "Reason from irreducible truths, not analogies"
  - id: "P2"
    name: "Stakeholder Mapping"
    family: "P"
    description: "Identify all parties affected by a decision"
  # ... 118 more
```

### Implementing in another language

The registry is language-agnostic. To implement Base120 in Rust, Go, TypeScript, etc.:

1. Parse `Base120_Canonical_Model_Registry.yaml` with any YAML parser
2. Implement the 4 `Engine` methods: `get`, `list`, `families`, `prompt`
3. Implement the `Ledger` for append-only JSONL persistence
4. Validate against the test corpus in `tests/`

See [`docs/consuming-base120.md`](docs/consuming-base120.md) for the full consumption contract.

### Data files

The `registries/` directory contains derived data files (JSON, etc.) generated from the canonical YAML. These are included for convenience but the YAML is the source of truth.

---

## Documentation

- [Spec v1.0.0](docs/spec-v1.0.0.md) — Base120 specification
- [Consuming Base120](docs/consuming-base120.md) — How to consume Base120 as infrastructure
- [Corpus Contract](docs/corpus-contract.md) — Golden corpus contract for implementers
- [Drift Detection](docs/drift-detection.md) — Semantic drift detection
- [Examples](examples/) — Contract examples

---

## Contributing

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

### Areas where we need help

- **Other-language implementations**: Rust, Go, TypeScript ports of the Engine and Ledger
- **New operators**: Propose new operators for the assessment queue (families are capped at 20 each)
- **Examples**: Real-world decision-making examples using Base120
- **Documentation**: Translations, tutorials, blog posts

### Development setup

```bash
git clone https://github.com/hummbl-io/base120.git && cd base120
pip install -e ".[test]"
python -m pytest tests/ -v
```

---

## HUMMBL Ecosystem

Base120 is part of the [HUMMBL](https://hummbl.io) cognitive AI architecture:

- [hummbl-governance](https://github.com/hummbl-io/hummbl-governance) — Governance runtime (kill switch, circuit breaker, cost governor)
- [arbiter](https://github.com/hummbl-io/arbiter) — Agent-aware code quality scoring and attribution
- [hummbl-bibliography](https://github.com/hummbl-io/hummbl-bibliography) — Bibliography for the HUMMBL cognitive framework

---

## License

Apache 2.0 — see [LICENSE](LICENSE).

---

## Star History

If Base120 helps you make better decisions, give it a star — it helps others discover it.

[![Star History Chart](https://api.star-history.com/svg?repos=hummbl-io/base120&type=Date)](https://star-history.com/#hummbl-io/base120&Date)

---

Built by [HUMMBL LLC](https://hummbl.io). Base120 powers the cognitive layer behind multi-agent coordination at scale.