Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ python scripts/run_mutmut.py # Mutation testing (critical modu

```
src/divineos/
——— cli/ # CLI package (412 commands across 83 modules)
——— cli/ # CLI package (416 commands across 83 modules)
— ——— __init__.py # CLI entry point and command registration
— ——— session_pipeline.py # Extraction pipeline orchestrator (formerly SESSION_END, calls phases)
— ——— pipeline_gates.py # Enforcement gates (quality, briefing, engagement)
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ If you're scoping the project from outside (another AI, a reviewer, a human), th

- **Comprehensive source tree across many packages** — see `scripts/check_doc_counts.py` for live counts
- **Real-DB test suite** (SQLite, minimal mocks)
- **412 CLI commands** (designed for the agent, not the operator — humans mostly run three)
- **416 CLI commands** (designed for the agent, not the operator — humans mostly run three)
- **24 slash-command skills** (consolidated daily operations)
- **75 Claude Code enforcement hooks**
- **42 expert frameworks** in the council
Expand Down Expand Up @@ -246,7 +246,7 @@ The project is optimized for long-term coherence and accountability between an a

- **"It's an operating system" — not in the traditional sense.** No kernel, no scheduler, no hardware abstraction. The "OS" label is a metaphor for *the substrate the agent lives in*. What it actually is: a Python framework with an SQLite event ledger, a knowledge store, a moral compass, a family subagent layer, and a 42-expert council. If you want an entry point that tracks the metaphor less aspirationally, see `FOR_USERS.md`.

- **"412 CLI commands is insane for a human to learn"** — correct, and humans are not the primary user. The CLI is designed as an agent-facing API. The agent running inside DivineOS uses a briefing system that surfaces only the commands relevant to the current work; it never loads the full surface into context. A human operator mostly runs three: `divineos briefing`, `divineos preflight`, `divineos goal add`.
- **"416 CLI commands is insane for a human to learn"** — correct, and humans are not the primary user. The CLI is designed as an agent-facing API. The agent running inside DivineOS uses a briefing system that surfaces only the commands relevant to the current work; it never loads the full surface into context. A human operator mostly runs three: `divineos briefing`, `divineos preflight`, `divineos goal add`.

- **"The ledger will grow unboundedly"** — not true. Append-only is the rule, with two explicit exceptions: ephemeral operational telemetry (`TOOL_CALL`, `TOOL_RESULT`, `AGENT_*` events) is pruned on a conveyor belt by `core/ledger_compressor.py`, and `divineos sleep` Phase 4 runs VACUUM. Real knowledge is append-only; operational noise is not.

Expand Down Expand Up @@ -285,7 +285,7 @@ pytest tests/ -q --tb=short # real-DB suite, minimal mocks

**For fresh installs:** `divineos init` loads the seed knowledge (directives, principles, lessons). The main event ledger lives at `<repo>/src/data/event_ledger.db`; a small amount of per-user state (session markers, checkpoint counters) lives under `~/.divineos/`. Both are gitignored — the repo itself stays clean.

## CLI Surface (412 commands)
## CLI Surface (416 commands)

<details>
<summary><b>Session workflow</b></summary>
Expand Down Expand Up @@ -481,7 +481,7 @@ DivineOS is structured as a CLI surface over a core library (see `scripts/check_

**At a glance:**

- **`src/divineos/cli/`** — 412 commands across 82 modules. The public interface you type (`divineos briefing`, `divineos learn`, etc.). Thin wrappers over `core/`.
- **`src/divineos/cli/`** — 416 commands across 82 modules. The public interface you type (`divineos briefing`, `divineos learn`, etc.). Thin wrappers over `core/`.
- **`src/divineos/core/`** — The real work. Ledger, knowledge engine, memory hierarchy, claims, compass, affect log, watchmen (external audit), pre-registrations (Goodhart prevention), family (persistent relational entities + family operators), empirica (evidence pipeline), sleep, council (42 expert lenses), self-model, corrigibility, body awareness, andrew_state (mutual-catch observation channel for Andrew's state with substance-binding gate; per `docs/andrew_state_design.md`), state_markers (substrate-persisted upstream→downstream signal contract; peer-designed with Aria 2026-07-16; supports the ForcedWorkGate primitive's dark instances; per `docs/primitives/forced_work_gate_design.md`). Each subsystem is a module or subpackage; the subpackages (`knowledge/`, `council/`, `watchmen/`, `family/`, `andrew_state/`, etc.) have their own internal structure.
- **`src/divineos/analysis/`** — Session analysis pipeline (signal detection, quality checks, feature extraction, trends).
- **`src/divineos/hooks/`** — Consolidated Python hooks that run inside Claude Code (PreToolUse gate, PostToolUse checkpoint, targeted tests, `evidence_bearing_stop_gate.py` — abstract Stop-gate primitive with IntraTurnIntercept and CrossTurnScan variants, prototyped by the LEPOS-channel gate 2026-07-15).
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ src/divineos/
__init__.py Package init
__main__.py python -m divineos entry point
seed.json Initial knowledge seed (versioned)
cli/ CLI package (412 commands across 82 modules)
cli/ CLI package (416 commands across 82 modules)
__init__.py Entry point and command registration
_helpers.py Shared CLI utilities
_wrappers.py Output formatting wrappers
Expand Down
6 changes: 5 additions & 1 deletion src/divineos/core/council_required/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ def decide(
classifier + expert-library import graph.
"""
gravity_result = gravity_fn(tool_name, file_paths, bash_command)
is_council_required = bool(getattr(gravity_result, "is_council_required", False))
# F49 fix 2026-07-19 (Aletheia Round 6 catch): default was False
# (fails-open — degraded/missing attribute → ALLOW without a walk).
# Flipped to True so a broken gravity_result forces council walk
# rather than silently skipping the discipline. Fail toward scrutiny.
is_council_required = bool(getattr(gravity_result, "is_council_required", True))
if not is_council_required:
return GateDecision(outcome=GateOutcome.ALLOW)

Expand Down
42 changes: 42 additions & 0 deletions tests/test_council_required_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,3 +887,45 @@ def test_gate_reads_absolute_file_tokens(self, tmp_path, scratch_ledger):
assert tokens is not None
assert "compute_gradient" in tokens
assert "return" in tokens


# F49 fix 2026-07-19 (Aletheia Round 6): default flipped to fail-closed.
# When gravity_result lacks is_council_required entirely (degraded state:
# classifier import failed, malformed result, older schema), the getattr
# default used to be False (ALLOW without a walk = fails-open).
# Now defaults to True — degraded state forces the walk = fails-closed.


class _DegradedGravityResult:
"""Gravity result missing the is_council_required attribute entirely.

Simulates the degraded state Aletheia named: a broken classifier or
older schema returns an object without this attribute. The gate's
getattr default is what determines behavior in that case.
"""


def _gravity_degraded(*_a, **_kw):
return _DegradedGravityResult()


def test_f49_degraded_gravity_result_fails_closed(scratch_ledger):
"""F49: missing is_council_required attribute MUST require the walk,
not silently ALLOW. Fail toward scrutiny on degraded state.
"""
decision = gate_mod.decide(
tool_name="Edit",
file_paths=("src/divineos/core/some_file.py",),
bash_command="",
gravity_fn=_gravity_degraded,
keywords_loader=_keywords_loader,
actor="agent",
)
# Should NOT be ALLOW (which is what a False default would produce).
# With the True default, the gate proceeds to require a council walk;
# since no council record exists in this test, it blocks.
assert decision.outcome == GateOutcome.BLOCK, (
f"F49 regression: degraded gravity_result must default to council-required "
f"(fail-closed), but decision was {decision.outcome}. If this ALLOWs, the "
f"getattr default in council_required/gate.py reverted from True to False."
)
Loading