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
19 changes: 19 additions & 0 deletions .github/workflows/install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Installer controls
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
installer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Validate standalone entrypoint and refusal controls
run: |
sh -n install.sh
python3 scripts/test-install-release.py
204 changes: 15 additions & 189 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,7 @@
<img src="assets/logo.svg" width="200" alt="Camayoc logo — loose gray strands enter from the left, the keeper's yupana counting board hangs from the main cord at center, and ordered, colored, knotted quipu pendants emerge on the right"/>
</p>

<h1 align="center">camayoc</h1>

<p align="center">
<em>🧶 Agents that check what was already decided, and record new decisions with how they know</em>
</p>

<p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache-2.0"/></a>
<a href="https://github.com/scbrown/camayoc/actions/workflows/ci.yml"><img src="https://github.com/scbrown/camayoc/actions/workflows/ci.yml/badge.svg" alt="CI"/></a>
<a href="https://github.com/scbrown/caboodle"><img src="https://img.shields.io/badge/stack-quipu-8B5E3C.svg" alt="Part of the caboodle stack"/></a>
</p>

[Watch the 90-second native bootstrap recording](docs/demos/bootstrap-v0.1.2/README.md).
# camayoc

**Camayoc gives AI coding agents a governed memory: a starter vocabulary for
work, decisions and outcomes, loaded into a [quipu](https://github.com/scbrown/quipu)
Expand All @@ -27,37 +15,20 @@ plain scripts any agent that speaks HTTP can use.
The *quipucamayoc* was the Inca official who kept the quipus and certified what
was read back out of them.

## Why you would want it

- **Agents ask before they re-decide.** The skill has them query what was
already decided, and why, before choosing again.
- **Every fact says how it was learned.** A record without an honest
`observed` / `declared` / `inferred` tag is refused at write, so a guess
cannot pass as an observation.
- **It proves its own gate.** Bootstrap sends records that must be refused and
fails loudly if the store accepts one.

The long form (its place in the stack, what runs today, what it deliberately is
not): [Why camayoc](https://scbrown.github.io/camayoc/why-camayoc.html).

## Install

As a Claude Code plugin, in Claude Code:

```text
/plugin marketplace add scbrown/camayoc
/plugin install camayoc@camayoc
```sh
curl -fsSL https://raw.githubusercontent.com/scbrown/camayoc/main/install.sh | sh
```

From a shell, for any other agent or for scripts:

```bash
git clone --depth 1 https://github.com/scbrown/camayoc
```
Python 3.9+, curl, and a Linux or macOS shell. Downloads and verifies the latest source package into `~/.local/share/camayoc/TAG`.
No native executable, server or agent enrollment is installed.

There is nothing else to install first: bootstrap brings its own quipu.
Set `STACK_INSTALL_ROOT` on the receiving shell for another prefix.
Pinned releases, alternatives, configuration and removal are in the
[installation and usage reference](docs/installation-reference.md).

## First success in three commands
## Try it

From an empty directory, bootstrap a governed memory and watch it prove its gate:

Expand All @@ -80,106 +51,14 @@ Decision with no provenance tag. The store refused it. That refusal is the
guarantee everything else rests on. Stop the server with
`kill "$(cat .quipu/server.pid)"`; the full log is in `bootstrap.log`.

## On your own data

| you want to | run |
|---|---|
| check whether a question is covered by the competency suite | `python3 camayoc/scripts/competency.py "<question>"` |
| map a question to a stored query with Jev (needs a TypeSafe key) | `python3 camayoc/scripts/competency.py --map "<question>"` |
| preview an advisory ordered-rubric benchmark without a key | `just jev-bench bench/ordinal/na-htm.jsonl --slot ordinal` ([pilot and replay](bench/ordinal/README.md)) |
| see which competency questions have a stored query | `python3 camayoc/scripts/query_coverage.py` |
| check a proposal against decisions already made | `python3 camayoc/scripts/settled_decisions.py "<proposal>" --declared <file>` |
| see the quarantine planes and their labels | `python3 camayoc/scripts/planes.py status` |

Every script: [Reference](https://scbrown.github.io/camayoc/reference.html).

## Wire it into your agent

With the plugin installed, run this once in Claude Code:

```text
/camayoc:bootstrap
```

It does what the shell bootstrap does, then offers the rest of the stack.
From then on every session opens with a memory status line (`ACTIVE`,
`reachable but gate not proven`, or `unreachable`), and the skill teaches the
agent to query first, record at the moment, and tag honestly. Without the
plugin, `bash camayoc/scripts/bootstrap.sh --with-claude-hooks` adds the same
status hook to `.claude/settings.json`. The plugin also declares a `jev` MCP
server for typed decisions. Details: [Using it with agents](https://scbrown.github.io/camayoc/agents.html).

### Typed decisions with jev-mcp

The plugin registers the stdio server in
[scripts/jev_mcp.py](scripts/jev_mcp.py). It exposes these tools:
## Next steps

| Tool | Input and result |
| --- | --- |
| `jev_noul` | `state`, `instructions`; returns a yes/no probability. Optional `true` and `false` describe the criteria. |
| `jev_choice` | `state`, `instructions`, `criteria` (option ID to text); returns a choice and probabilities. |
| `jev_score` | `state`, `instructions`, `levels` (2–10 ordered strings); returns an ordered-level score. |
| `map_question` | `question`; reports a competency-question match and its stored-query coverage, or `abstained` / `human_reads`. |
| `jev_dry_run` | `kind` (`noul`, `choice` or `score`) and that tool's inputs; returns the request without sending it. |
- [Tambo](https://github.com/intigraph/tambo): guided installation of the complete stack.
- [Detailed examples and agent setup](docs/installation-reference.md).

For an agent that reads `.mcp.json`, register the server directly:
**Load this repository’s graph:** public repository-pendant assets have not yet been verified. When a release supplies the archive, checksum and provenance, follow the [verified import workflow](https://scbrown.github.io/quipu/sharing/index.html): extract the share directory and use `quipu import SHARE_DIR --db repository.db`. Import stages knowledge; ROOT stays unchanged.

```json
{
"mcpServers": {
"jev": {
"command": "python3",
"args": ["/path/to/camayoc/scripts/jev_mcp.py"]
}
}
}
```

Live calls use `TYPESAFE_API_KEY`, then the file named by
`TYPESAFE_API_KEY_FILE`, then the default in
[`jev.resolve_key`](scripts/jev.py). Keep a key file private (`0600`);
do not put a key in the registration file. Dry runs need no key. A missing
or malformed key produces a readable tool error, with no lexical fallback.

Choice adds a none-of-these option by default and reports `chose_none`;
setting `none_text` to `""` deliberately removes that escape hatch.
Treat decisions as **inferred**, retain their request, usage and model, and
check confidence before acting. The server does not retry failed calls.
Usage is logged to `JEV_USAGE_LOG`, otherwise
`SHANTY_ROOT/jev-usage.jsonl`, otherwise the local state path declared in
`scripts/jev_mcp.py`. Logging failure does not retry a decision.

## Deployment events

Camayoc records deployments from the tools that make them, as CDEvents mapped
to `DeploymentEvent`. Each emitter reports what the tool itself says
happened, including failures that a surrounding job reports as green.

| Tool | How | Standard |
| --- | --- | --- |
| GitHub or Forgejo Actions | [reusable Action](actions/deployment-event/README.md) | CDEvents `pipelineRun.finished` |
| Ansible | [callback plugin](emitters/ansible/README.md) | CDEvents `pipelineRun.finished`, one per host |
| Terraform | [`apply -json` wrapper](emitters/terraform/README.md) | CDEvents `pipelineRun.finished` |

## Before you start

**Platforms.** Bootstrap downloads a quipu release on Linux x86_64. On other
platforms it builds quipu with `cargo`, or uses a `quipu-server` already on
your `PATH`. The scripts need `bash`, `curl` and `python3`.

**Exit codes.** Bootstrap exits 1 if nothing could be installed, 2 if the store
accepted a record it must refuse, and 3 if no verdict could be reached. See
[Getting started](https://scbrown.github.io/camayoc/getting-started.html#when-something-fails).

## What's next

- [The camayoc book](https://scbrown.github.io/camayoc/): getting started, agents, reference and the design notes, in reading order
- [Docs map](https://scbrown.github.io/camayoc/docs-map.html): every document in this repository, routed
- [Ingress](https://scbrown.github.io/camayoc/design/ingress.html): how knowledge earns its way into the graph

## 🧺 The stack

Caboodle installs these together and proves each one works; every tool also stands alone.
## The stack

<!-- stack-table:start -->

Expand All @@ -205,57 +84,4 @@ when.

<!-- stack-table:end -->

## Contributing

```bash
just test
just check # the local quality gate
```

## 📜 License

[Apache-2.0](LICENSE)

### Incremental verdict adapters

`blocked_by.py` and `review_due.py` also accept `--describe` and `--changes`
for Chaski's incremental protocol. `--describe` prints watched predicates, type
IRIs and trusted planes without querying the store. `--changes` consumes one
JSON request with `now` and either `discover: true`, `route: [fact changes]`, or
`items: [local keys]`. Responses carry protocol `version: 1` and respectively
`items`, `items`, or `scope`/`records`/`next_checks`.

Routing follows changed observations to their WorkItems, then reverse blocker
edges to dependent work. Review routing follows verification links, including
retracted `old_value` links. Existing graph-plane and legacy/public vocabulary
rules apply unchanged. Discovery reads the candidate catalogue only; Chaski
queues bounded evaluation batches instead of scanning verdicts in one process.
The command budgets graph reads at eight per second and caches identical reads
within a request. The ordinary full-evaluation CLI remains the parity oracle.

Future review ages and date blockers supply exact deadlines. Only external
probes and arbitrary resolution queries retain individual 15-minute checks,
because their dependencies cannot be enumerated from graph changes. Missing
facts and unanchored ages remain UNKNOWN and await a relevant change; they do
not cause a repeated population scan. Transport failures fail the invocation,
so the consumer retains pending work. This protocol performs no graph writes.

### Reflection cycle and lane expiry

Tracker ingress classifies a `dream-cycle` label as `DreamCycle`. Its ordinary
idle limit follows tracker activity. A crew cycle also has the `dream` label and
the controller's `DREAM consolidate:` or `DREAM propose:` title. Its creation records an immutable
observation of the reflection lane, typed `Service`, with kind `DreamLane` and a
12-hour idle limit. The lane clock uses cycle creation time; later comments,
completion, retries and out-of-order ingress cannot postpone or rewind it.

The existing change adapter subscribes to kind changes, observations and age
attributes. Persisted deadlines drive lapses without adding a periodic scanner.
Review verdicts carry a unique kind as receiver context; ambiguous kinds omit it
and retain the receiver's ordinary policy. Routing severity belongs to reviewed
receiver configuration. Load the expanded core shape set before enabling ingress
that writes `DreamLane`; this feature adds a kind value, not a new RDF class.

Lane signals measure absence of cycle creation, not successful completion or
available capacity. Shantytown retains its capacity gates and rotates past stale
queued cycles; this projection never closes a claimed item or starts a crew pane.
[License](LICENSE).
Loading
Loading