Metadata-Version: 2.4
Name: evidence-loop-visibility-engine
Version: 0.2.0
Summary: A bounded, deterministic reference implementation for evidence-first visibility loops.
Author: Navid Broumandfar
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/NavidBroumandfar/evidence-loop-visibility-engine
Project-URL: Documentation, https://github.com/NavidBroumandfar/evidence-loop-visibility-engine/tree/main/docs
Project-URL: Issues, https://github.com/NavidBroumandfar/evidence-loop-visibility-engine/issues
Project-URL: Source, https://github.com/NavidBroumandfar/evidence-loop-visibility-engine
Keywords: evidence,seo,aeo,geo,llmo,loop-engineering,visibility
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: release
Requires-Dist: build==1.5.0; extra == "release"
Requires-Dist: twine==6.2.0; extra == "release"
Dynamic: license-file

![CI](https://github.com/NavidBroumandfar/evidence-loop-visibility-engine/actions/workflows/ci.yml/badge.svg)

# Evidence Loop Visibility Engine

**Evidence before action.**

A deterministic, offline reference implementation for turning bounded
visibility evidence into one reviewable proposal per site.

![A measured evidence loop moving through Observe, Choose, Propose, a visible verification gate, Record, and three honest terminal states](docs/assets/evidence-loop-system.svg)

## The 60-second explanation

The engine accepts strict, timestamped evidence packets, chooses one eligible
opportunity per site, and produces a proposal without changing the site. It
then verifies the proposal's lineage, routing, and approval boundary before it
records an atomic receipt.

Every run stops in an explicit state: `approval-required`, `clean-no-op`, or
`blocked`. Selection and receipts are deterministic, so the same exact input
bytes produce the same decision and digest. The installed runtime uses only
the Python standard library and makes no network, browser, provider, or
credential calls.

This is a control loop for reviewable decisions—not a black-box promise of
rankings, traffic, answer inclusion, citations, or causality.

## Who it is for

- Engineers building evidence-first SEO, AEO, GEO, or LLMO tooling.
- Technical SEO and editorial teams that need a reproducible proposal trail.
- Evaluators testing lineage, failure containment, and human approval gates.
- Operators who want a useful offline core before connecting any live system.

## Public core and private operation

This repository is a complete, useful offline core. It is not an intentionally
crippled demo, and its Apache-2.0 implementation has no artificial lock-in.
Real adapters, calibrated evidence and history, evaluation and operator
judgment, team workflows, and managed operation can add value around the core
without changing what the public package honestly does.

See the [open-core boundary](docs/open-core-boundary.md) for the extension
points, clean-room rule, and the line between public behavior and separately
operated systems.

## Quickstart

Python 3.10+ is required. Runtime dependencies are the Python standard
library only.

```console
python3 -m venv .venv
.venv/bin/python -m pip install -e .
.venv/bin/evidence-loop validate --input examples/normal.json
.venv/bin/evidence-loop run --input examples/normal.json --output work/normal
.venv/bin/evidence-loop demo --output work/demo
.venv/bin/evidence-loop benchmark
```

The package artifact exposes the same `evidence-loop` command. The committed
`examples/` files are readable fixtures; packaged resources make `demo` and
`benchmark` work after wheel or source-distribution installation too.

For release artifact validation, install the optional build tools and run the
same gate:

```console
.venv/bin/pip install -e '.[release]'
.venv/bin/python scripts/artifact_smoke.py
```

## One bounded cycle

**Observe -> Choose -> Propose -> Verify -> Record**

Choose is explicit: fresh, non-missing evidence is eligible; lower numeric
priority wins, then the stable opportunity ID breaks ties. Propose is the
runtime's Act step and never mutates a site. Verify is a distinct fail-closed
boundary before Record. See [LOOPS.md](LOOPS.md) and
[docs/loop-engineering.md](docs/loop-engineering.md).

## Input and output

An input document has reserved example URLs, evidence, and opportunities:

```json
{"schema_version":"1","sites":[{"site_id":"site-a","site":"https://a.example","evidence":[{"evidence_id":"ev-1","source_kind":"manual-observation","observed_at":"2026-01-15T10:00:00Z","completeness":"complete","freshness":"fresh","uncertainty":"low"}],"opportunities":[{"opportunity_id":"opp-1","domain":"technical-seo","title":"Review indexability signals","priority":1,"evidence_ids":["ev-1"],"approval_gate":"human-review"}]}]}
```

`run.json` preserves site, evidence IDs, source kind, timestamp,
completeness, freshness, uncertainty, routed capability, and approval gate:

```json
{"terminal_state":"approval-required","input_sha256":"<SHA-256 digest of exact input bytes>","sites":[{"site_id":"site-a","status":"approval-required","selected_opportunity_id":"opp-1","proposal":{"approval_required":true,"mutation_allowed":false,"evidence_ids":["ev-1"]}}],"safety":{"offline":true,"site_mutation":false,"provider_access":false}}
```

The CLI prints only safe counts, IDs, terminal state, and zero external calls
or cost. `last-success.json` is atomically replaced only for a non-blocked
run.

## Capability maturity

These are deterministic proposal templates, not SEO analysis or outcome
predictions:

| Allowlisted module | Maturity | Proposal boundary |
| --- | --- | --- |
| measurement-integrity | Implemented deterministic | Preserve source, window, completeness, freshness, uncertainty |
| technical-seo | Implemented deterministic | Propose an indexability/crawlability review |
| search-intent-content | Implemented deterministic | Propose an intent clarification review |
| aeo-answerability | Implemented deterministic | Propose a question/answer structure review |
| geo-citation-research | Synthetic observation | Observe a citation surface; never fabricate a GEO score |
| llmo-sampling | Synthetic observation | Specify fixed-prompt sampling, variance, terms, and cost gates |
| brand-governance | Approval-gated | Propose claim and voice consistency review |
| marketing-conversion | Approval-gated | Propose a measured conversion hypothesis review |

Unknown capability domains block their entire site lane. Other sites remain
isolated.

## Commands and exit codes

- `validate --input FILE`: strict validation; exit `0` when valid, `2` on a
  global input/path error.
- `run --input FILE --output DIR`: one bounded cycle; exit `0` for
  `approval-required` or `clean-no-op`, `3` for global `blocked`, and `2` for
  an input/output error.
- `demo --output DIR`: committed synthetic normal, clean-no-op, and contained
  failure examples; exit `0` when all complete.
- `benchmark`: deterministic public conformance cases and pass rate; exit `0`
  when all cases pass.

## Security and non-goals

The installed engine/CLI opens no network connection, invokes no browser or
provider, reads no credential environment, spawns no process, and mutates no
site. It rejects duplicate JSON keys, NaN/Infinity, oversized or deeply nested
input, unsafe IDs/timestamps/strings, lexical traversal, and symlink ancestors
or children. Output receipts are atomic. The release scanner is separate
defense-in-depth tooling and may invoke local Git to enumerate tracked files;
its heuristic is not proof of safety.

This is not an autonomous SEO, growth, ranking, traffic, answer, citation, or
conversion system. It does not claim special markup, `llms.txt`, or any file
guarantees Google or another system's visibility. It does not publish,
schedule, create backlinks, submit pages, or access private repositories.
Fixtures are synthetic and use reserved example domains.

## Documentation and development

- [Architecture](docs/architecture.md)
- [Loop Engineering](docs/loop-engineering.md)
- [Open-core boundary](docs/open-core-boundary.md)
- [Visibility domains](docs/visibility-domains.md)
- [Security model](docs/security.md)
- [Public claims](docs/public-claims.md)
- [Quickstart](docs/quickstart.md)
- [Release contract](docs/releasing.md)
- [CONTRIBUTING.md](CONTRIBUTING.md)

Run `make check` for tests, compilation, and the release scanner. Artifact
build/install smoke checks are in `scripts/artifact_smoke.py`.
