afterautism-cli 1.0.0

Headless command-line interface for the AfterAutism engine
# AfterAutism — The Engine

[![License: AGPL-3.0-or-later](https://img.shields.io/badge/License-AGPL%203.0-or--later-blue.svg)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-1.85+-orange.svg)](https://www.rust-lang.org)
[![Build Status](https://github.com/AutismDisorder/AfterAutism/actions/workflows/ci.yml/badge.svg)](https://github.com/AutismDisorder/AfterAutism/actions/workflows/ci.yml)

> **AfterAutism is a generic data-management engine.** Not a researcher tool. Not a GUI application.
>
> **The Engine is the product.** Everything else — UIs, adapters, verticals — is a consumer of it.
>

# I am temporarily unable to accept contributions. Contributions will later host their CLA terms.
---

## Why This Exists

Data management tools are stuck at "search a database, wait for records." The only lever left is **scale** — both up (enterprises with data centers, full-page rendering, no culling) and down (consumers with compressed text-only nodes, aggressive culling). Same engine, different scales.

The researcher UI is one vertical; the Engine is the platform.

---

## What You Get

A Rust workspace of **15 crates** providing a domain-agnostic foundation for managing millions of records — embeddable as one dependency:

| Crate | Purpose | Key Features |
|-------|---------|--------------|
| [`afterautism`]crates/afterautism | **Facade** | One crate to embed the whole engine; feature flags + prelude |
| [`afterautism-core`]crates/afterautism-core | Shared foundation | `NodeId`/`AdapterId`, `NetworkGate` (offline-by-default, per-domain allowlist), `ErrorKind` classification |
| [`afterautism-adapter`]crates/afterautism-adapter | Extension contract | Public `Adapter` trait, `BatchBuilder`, typed `AdapterCapabilities`, ABI version |
| [`afterautism-adapter-records`]crates/afterautism-adapter-records | Reference adapter | CSV / JSONL ingest, in-repo proof of the contract |
| [`afterautism-adapter-markdown`]crates/afterautism-adapter-markdown | Reference adapter | Heading hierarchy + wiki-link graph |
| [`afterautism-ingest`]crates/afterautism-ingest | Ingestion pipeline | Strip (configurable, fuzzed), refresh, sync coordinator, file/gzip/http/retry fetchers, rate limiting |
| [`afterautism-storage`]crates/afterautism-storage | Persistence | Versioned corpus, SQLite + FTS5 (rank + snippets), staging + atomic swap, backup/restore, migrations, AES-GCM field encryption, append-only audit log |
| [`afterautism-topology`]crates/afterautism-topology | Graph + filtering | Typed-edge graph, emphasis filter, BFS/DFS, shortest path, components, cycles, centrality |
| [`afterautism-query`]crates/afterautism-query | Query language | Typed IR + parser + executor, keyset pagination, prepared queries, explain, vector search + hybrid |
| [`afterautism-concurrency`]crates/afterautism-concurrency | Concurrency | LRU cache, cancellation tokens, bounded worker pool |
| [`afterautism-metrics`]crates/afterautism-metrics | Telemetry | Counters, gauges, histograms (p50/p90/p99), JSON snapshot |
| [`afterautism-cli`]crates/afterautism-cli | Headless CLI | create/ingest/query/export/backup/restore |
| [`afterautism-benchmarks`]benches | Benchmarks | ingest/query/filter/open suites (criterion) |
| `afterautism-fuzz` | Fuzzing | libfuzzer target for the stripper |

**No GUI. No Chromium. No wgpu. No App.** Just the Engine.

---

## Architecture

```
┌─────────────────────────────────────────────────────────────────────┐
│                         ENGINE (this workspace)                     │
├────────────────┬────────────────┬────────────────┬──────────────────┤
│   afterautism-core      │  afterautism-adapter    │   afterautism-ingest    │   afterautism-storage     │
│  Types,        │  Adapter trait │  Strip +       │  Versioned       │
│  NetworkGate   │  (extension    │  idempotent    │  corpus,         │
│                │   point)       │  refresh       │  SQLite + FTS5   │
├────────────────┼────────────────┼────────────────┼──────────────────┤
│  afterautism-topology   │                │                │                  │
│  Typed-edge    │                │                │                  │
│  graph,        │                │                │                  │
│  visual filter │                │                │                  │
└────────────────┴────────────────┴────────────────┴──────────────────┘
```

**Stability contract:** Public API stable across v1.x. Deprecating a core method requires v2.

**v0.3 (current):** The engine owns the local-file ingest path.
`afterautism-ingest::IngestCoordinator` drives `Adapter::ingest(&Source)`
for local adapters and maps the batch to a `SourceRefreshOutcome` (with an
optional staging-corpus write) — GUI consumers no longer re-implement that
orchestration by hand, and the "empty batch = unchanged" semantics are
engine-owned. The engine gains its first in-repo reference adapter,
`afterautism-adapter-records` (CSV/JSONL), built on `BatchBuilder` — the
extension point (AC-009) now has an in-repo proof instead of living only
as desktop-side crates. `NodeKind::FullPage` is reachable (the storage
schema always accepted `full_page`; adapters with `supports_full_page()`
can now mark the nodes they emit) and `write_batch` persists the node's
real kind instead of hardcoding `text`. `IngestError` gains an
`Adapter` variant so adapter failures flow through the crate-level error
type. All crates inherit the workspace package metadata (`repository`,
`homepage`, `readme`, `keywords`, `categories`) so published crates are
no longer metadata-incomplete.

**v0.2:** The engine `Adapter` trait gained the real sync ingest contract
(`Adapter::ingest(&Source)` — v0.1 had no ingest method at all),
`Source`/`SourceMeta` moved into `afterautism-adapter` (re-exported by
`afterautism-ingest`), and `BatchBuilder` removes hand-rolled node-id
counters from adapters. Topology's text filter is allocation-free
(scale-contract filter budget), storage writes are `ON CONFLICT` upserts
with a read-first `application_id` + `user_version` gate (schema v2, unique
edge index for idempotent refresh), and the versioned-corpus header is the
spec for a future non-SQLite payload.

---

## The Extension Point: Write an Adapter

You have a data type — logs, metrics, traces, CSV, JSONL, graph dumps, search indexes. You write **one adapter** (~100 LoC) implementing the `Adapter` trait:

```rust
use afterautism_adapter::{Adapter, AdapterId, IngestBatch, Node, Edge, EdgeType};
use afterautism_core::NodeId;
use async_trait::async_trait;

struct MyLogAdapter;

#[async_trait]
impl Adapter for MyLogAdapter {
    fn id(&self) -> AdapterId { AdapterId::from_raw(0xDEADBEEF) }

    async fn ingest(&self, source: &str) -> Result<IngestBatch, Error> {
        // Parse your format → Nodes + typed Edges
        // The Engine handles storage, topology, filtering, tiering
    }

    fn edge_types(&self) -> Vec<EdgeType> {
        // Your relevance-point vocabulary (e.g., "same_service", "causal_link", "time_window")
    }
}
```

Register it at startup. The Engine (`afterautism-topology`, `afterautism-storage`, `afterautism-ingest`) works unchanged — no Engine edits needed.

---

## Key Properties

| Property | Implementation |
|----------|----------------|
| **Offline by default** | `NetworkGate` in `afterautism-core` — all outbound I/O structurally refused unless explicitly permitted (AC-010) |
| **Idempotent refresh** | Staging index → atomic swap; never mutates live corpus mid-run (AC-006) |
| **Adversarial-safe strip** | Rejects binary-posed-as-HTML, oversized, non-UTF8, script/style/svg, malformed entities (AC-005) |
| **Visual filtering** | Filter = visual emphasis (matched +5% scale, unmatched → near-black), never hides nodes (AC-008) |
| **Versioned corpus** | 16-byte header (magic, major, minor, schema); forward-read ignores, backward-read works, future-major refuses (AC-012) |

---

## Performance Targets

| Metric | Target |
|--------|--------|
| Max corpus | 100M+ nodes |
| RSS ceiling | Machine-bound |
| Metadata refresh | ≥10,000/sec |
| Frame target | 60 FPS @ 10M |

---

## Quick Start

```bash
# Build the Engine (release profile optimized)
cargo build --workspace --release

# Run all tests (68 unit tests + doc tests)
cargo test --workspace

# Add as dependency in your Adapter crate
# [dependencies]
# afterautism-core = { git = "https://github.com/AutismDisorder/AfterAutism", package = "afterautism-core" }
# afterautism-adapter = { git = "https://github.com/AutismDisorder/AfterAutism", package = "afterautism-adapter" }
# afterautism-ingest = { git = "https://github.com/AutismDisorder/AfterAutism", package = "afterautism-ingest" }
# afterautism-storage = { git = "https://github.com/AutismDisorder/AfterAutism", package = "afterautism-storage" }
# afterautism-topology = { git = "https://github.com/AutismDisorder/AfterAutism", package = "afterautism-topology" }
```

---

## License

Licensed under **AGPL-3.0-or-later** (free, network-copyleft).

---

## Repository & Author

**Repository:** https://github.com/AutismDisorder/AfterAutism  
**Author:** AutismDisorder

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for DCO sign-off requirements and contribution guidelines.

---

## Security

See [SECURITY.md](SECURITY.md) for vulnerability reporting and security policy.