atavi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/TESTING.md ADDED
@@ -0,0 +1,68 @@
1
+ # Testing
2
+
3
+ ATAVI needs a package-level test strategy, not just command smoke tests.
4
+
5
+ ## Test layers
6
+
7
+ ### Layer 1: Manifest integrity
8
+
9
+ Goal: fail fast if the shipped package stops containing required protocol or
10
+ template files.
11
+
12
+ Current coverage:
13
+
14
+ - `scripts/check-manifest.js`
15
+ - `doctor` command tests
16
+
17
+ ### Layer 2: CLI contract
18
+
19
+ Goal: verify the user-facing package commands keep working.
20
+
21
+ Current coverage:
22
+
23
+ - `--path`
24
+ - `init`
25
+ - `doctor`
26
+ - `validate`
27
+ - `resume-check`
28
+
29
+ ### Layer 3: Scaffold contract
30
+
31
+ Goal: verify `.atavi/` contains the exact files a host AI expects.
32
+
33
+ Current coverage:
34
+
35
+ - scaffold file existence
36
+ - idempotent init behavior
37
+ - registry and report placeholders
38
+ - explicit memory bucket scaffolding
39
+ - pass and log placeholder scaffolding
40
+ - snapshot coverage for scaffolded markdown
41
+ - deeper memory layout coverage
42
+ - host compatibility coverage for Codex, Claude, and Gemini guidance
43
+
44
+ ## Planned deepening inside this repo
45
+
46
+ The product is all-or-nothing in terms of quality bar, so the test plan should
47
+ grow toward:
48
+
49
+ - config schema validation tests
50
+ - snapshot tests for scaffolded markdown files
51
+ - deeper resume-state tests around `status.md` and `config.json`
52
+ - memory layout tests
53
+ - host compatibility tests for Codex / Claude / Gemini loading patterns
54
+
55
+ ## Run commands
56
+
57
+ ```bash
58
+ node scripts/check-manifest.js
59
+ node test/run-all.js
60
+ ```
61
+
62
+ ## CI expectation
63
+
64
+ CI must stop merges that:
65
+
66
+ - remove a packaged asset
67
+ - break a top-level command
68
+ - change scaffold output unintentionally
package/bin/atavi.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runCli } from "../src/cli.js";
4
+
5
+ runCli(process.argv.slice(2)).catch((error) => {
6
+ const message = error instanceof Error ? error.message : String(error);
7
+ process.stderr.write(`${message}\n`);
8
+ process.exitCode = 1;
9
+ });
10
+
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "atavi",
3
+ "version": "0.1.0",
4
+ "description": "Host-agnostic multi-agent iterative research refinement protocol.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/mechramc/Atavi#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/mechramc/Atavi/issues"
10
+ },
11
+ "bin": "bin/atavi.js",
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "files": [
16
+ "bin/",
17
+ "src/",
18
+ "protocol/",
19
+ "templates/",
20
+ "README.md",
21
+ "HOSTS.md",
22
+ "ARCHITECTURE.md",
23
+ "CONTRIBUTING.md",
24
+ "TESTING.md",
25
+ "CHANGELOG.md",
26
+ "LICENSE"
27
+ ],
28
+ "engines": {
29
+ "node": ">=20"
30
+ },
31
+ "scripts": {
32
+ "test": "node test/run-all.js",
33
+ "test:watch": "node --watch test/run-all.js",
34
+ "lint": "node --check bin/atavi.js && node --check src/cli.js && node --check src/commands/init.js && node --check src/commands/migrate.js && node --check src/commands/memory-export.js && node --check src/commands/memory-import.js && node --check src/commands/doctor.js && node --check src/commands/path.js && node --check src/commands/validate.js && node --check src/commands/resume-check.js && node --check src/lib/filesystem.js && node --check src/lib/protocol-manifest.js && node --check src/lib/config.js && node --check src/lib/status.js && node --check src/lib/memory.js",
35
+ "check": "node scripts/check-manifest.js",
36
+ "check:release": "node scripts/check-release-surface.js",
37
+ "ci": "node scripts/check-manifest.js && node scripts/check-release-surface.js && node test/run-all.js"
38
+ },
39
+ "keywords": [
40
+ "ai",
41
+ "agents",
42
+ "research",
43
+ "cli",
44
+ "protocol",
45
+ "orchestration"
46
+ ],
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/mechramc/Atavi.git"
50
+ }
51
+ }
@@ -0,0 +1,149 @@
1
+ # ATAVI
2
+
3
+ ATAVI is a host-agnostic multi-agent iterative research refinement protocol.
4
+ The package does not run the research loop itself. It ships the protocol, agent
5
+ contracts, templates, and scaffold helpers that a host AI can execute.
6
+
7
+ ## Core Position
8
+
9
+ - ATAVI is a protocol, not a daemon-backed application.
10
+ - The host AI is the orchestrator.
11
+ - Novelty verification is mandatory before any experiment survives.
12
+ - Cross-pollination is mandatory on every pass.
13
+ - Every decision must be inspectable through persistent artifacts.
14
+
15
+ ## Modes
16
+
17
+ ### Full
18
+
19
+ Run the complete refinement loop with adaptive agent selection, convergence
20
+ tracking, final report generation, and persistent memory updates.
21
+
22
+ ### Scout
23
+
24
+ Run novelty search only. Produce a Prior Art Registry and verdicts for claims
25
+ or experiments without generating new experimental design work.
26
+
27
+ ### Theorist
28
+
29
+ Formalize a thesis into falsifiable claims, metrics, assumptions, and limits.
30
+
31
+ ### Vision
32
+
33
+ Challenge the framing before the loop starts. Produce a Reimagination Brief
34
+ that argues for the original direction, a stronger direction, or a hybrid.
35
+
36
+ ### Audit
37
+
38
+ Review a product or system and produce a completion summary that covers
39
+ architecture gaps, security issues, edge cases, tests, observability, and
40
+ deployment risk.
41
+
42
+ ## Adaptive Agent Selection
43
+
44
+ ATAVI always includes:
45
+
46
+ - Theorist
47
+ - Experimentalist
48
+ - Scout
49
+
50
+ ATAVI conditionally adds:
51
+
52
+ - Critic when cost of failure is high, work is irreversible, or the novelty
53
+ landscape is crowded
54
+ - Synthesist when the problem spans multiple domains or adjacent disciplines
55
+
56
+ ## Run Lifecycle
57
+
58
+ 1. Detect an ATAVI invocation inside the host environment.
59
+ 2. Discover the input spec, codebase, or product documents.
60
+ 3. Extract and confirm a research brief.
61
+ 4. Create a local `.atavi/` workspace.
62
+ 5. Execute the multi-pass refinement loop.
63
+ 6. Compile `ATAVI-REPORT.md`.
64
+ 7. Persist reusable memory artifacts for future runs.
65
+
66
+ ## Refinement Loop
67
+
68
+ Each pass runs in four ordered phases.
69
+
70
+ ### Phase 1: Independent Work
71
+
72
+ Each agent writes a POD to `.atavi/pass-N/[agent]-pod.md`.
73
+
74
+ ### Phase 2: Cross-Pollination
75
+
76
+ Each agent reads the other PODs and writes a CPR to
77
+ `.atavi/pass-N/cross-pollination/[agent]-cpr.md`.
78
+
79
+ ### Phase 3: Synthesis
80
+
81
+ The host AI updates the Claim Registry, Experiment Ledger, Prior Art Registry,
82
+ conflict list, and convergence score. The host also writes a pass summary to
83
+ `.atavi/pass-N/synthesis.md`.
84
+
85
+ ### Phase 4: Decision Gate
86
+
87
+ The host AI either terminates, continues, or escalates to the researcher based
88
+ on convergence, blocking concerns, and surviving experiments. The pass outcome
89
+ is written to `.atavi/pass-N/decision.md`, and cross-pass state remains visible
90
+ in `.atavi/status.md` and `.atavi/run-log.md`.
91
+
92
+ ## Novelty Gate
93
+
94
+ The Scout performs structured novelty search on every active claim and active
95
+ experiment. Verdicts are:
96
+
97
+ - `NOVEL`
98
+ - `PARTIAL`
99
+ - `DUPLICATE`
100
+ - `SUPERSEDED`
101
+
102
+ Duplicate or superseded experiments are killed unless the Experimentalist
103
+ supplies a concrete methodological delta and the Scout re-verifies it.
104
+
105
+ Claim-level novelty evidence is recorded in `.atavi/registries/prior-art.md`.
106
+ Experiment-level novelty verdicts are recorded in
107
+ `.atavi/registries/experiments.md` and summarized in `.atavi/pass-N/synthesis.md`.
108
+
109
+ ## Convergence
110
+
111
+ Agents vote on surviving experiments using:
112
+
113
+ - `STRONG_YES`
114
+ - `YES`
115
+ - `WEAK_YES`
116
+ - `NO`
117
+
118
+ ATAVI converges when the convergence threshold is met for two consecutive
119
+ passes. If perfect agreement happens too early, the host must force an
120
+ adversarial pass to avoid a coherence trap.
121
+
122
+ ## Persistent Memory
123
+
124
+ ATAVI stores:
125
+
126
+ - prior art cache
127
+ - kill archive
128
+ - claim patterns
129
+ - convergence history
130
+ - strategy insights
131
+
132
+ Memories are scoped by domain and keywords, weighted by confidence, expired
133
+ when stale, and corrected when contradicted by new evidence.
134
+
135
+ Reusable memory exports are written into `.atavi/memory/` after a run, using
136
+ the bucketed directories for prior art cache, kill archive, claim patterns,
137
+ convergence history, and strategy insights.
138
+
139
+ ## Output Contract
140
+
141
+ The final report must include:
142
+
143
+ - completion summary
144
+ - executive summary
145
+ - ranked recommended experiments
146
+ - rejected experiments / kill log
147
+ - final claim registry
148
+ - final prior art registry
149
+ - full process log
@@ -0,0 +1,19 @@
1
+ # Critic
2
+
3
+ ## Mandate
4
+
5
+ Stress-test the run adversarially when the cost of being wrong is high or the
6
+ landscape is crowded.
7
+
8
+ ## Responsibilities
9
+
10
+ - Attempt to falsify claims.
11
+ - Expose confounds and brittle assumptions.
12
+ - Challenge weak differentiation stories.
13
+ - Raise blocking concerns when the run is drifting into self-confirmation.
14
+
15
+ ## Constraints
16
+
17
+ - Do not replace the Theorist or Experimentalist.
18
+ - Every criticism must be concrete, testable, and written for action.
19
+
@@ -0,0 +1,30 @@
1
+ # Experimentalist
2
+
3
+ ## Mandate
4
+
5
+ Design the experiments that reduce uncertainty about the thesis.
6
+
7
+ ## Responsibilities
8
+
9
+ - Propose experiments for the current claim set.
10
+ - Define variables, controls, runtime, feasibility, and failure criteria.
11
+ - Rank experiments by information gain.
12
+ - Respond to Scout novelty verdicts with either differentiation or rejection.
13
+ - Design ablations that isolate causal mechanisms.
14
+
15
+ ## Constraints
16
+
17
+ - Do not redefine claims or metrics directly.
18
+ - Every experiment needs a pre-registered expected outcome.
19
+ - Every infeasible or low-value experiment must be explicitly killed.
20
+
21
+ ## Output
22
+
23
+ Write a POD containing:
24
+
25
+ - status summary
26
+ - active experiments
27
+ - killed experiments
28
+ - requests to other agents
29
+ - confidence scores
30
+
@@ -0,0 +1,34 @@
1
+ # Scout
2
+
3
+ ## Mandate
4
+
5
+ Protect the run from reinventing prior work and missing decisive outside
6
+ evidence.
7
+
8
+ ## Responsibilities
9
+
10
+ - Search the web and domain-specific sources for every active claim.
11
+ - Search the web and domain-specific sources for every active experiment.
12
+ - Log search queries and top findings.
13
+ - Issue `NOVEL`, `PARTIAL`, `DUPLICATE`, or `SUPERSEDED` verdicts.
14
+ - Surface adjacent work that could strengthen or redirect the run.
15
+
16
+ ## Constraints
17
+
18
+ - Web search is non-negotiable.
19
+ - At least three distinct queries per claim and two per experiment.
20
+ - Do not modify claims or propose experiments.
21
+ - A `DUPLICATE` or `SUPERSEDED` verdict kills an experiment unless a concrete
22
+ methodological delta is re-verified.
23
+
24
+ ## Output
25
+
26
+ Write a POD containing:
27
+
28
+ - status summary
29
+ - prior art findings
30
+ - novelty verdicts
31
+ - killed items
32
+ - requests to other agents
33
+ - confidence scores
34
+
@@ -0,0 +1,19 @@
1
+ # Synthesist
2
+
3
+ ## Mandate
4
+
5
+ Find useful analogies, methods, and literature from adjacent domains when the
6
+ problem is cross-disciplinary.
7
+
8
+ ## Responsibilities
9
+
10
+ - Surface methods from adjacent domains.
11
+ - Identify vocabulary mismatches that hide relevant prior art.
12
+ - Suggest productive cross-domain bridges for the Experimentalist and Theorist.
13
+
14
+ ## Constraints
15
+
16
+ - Do not own the novelty gate.
17
+ - Do not directly propose final experiments without routing through the
18
+ Experimentalist.
19
+
@@ -0,0 +1,31 @@
1
+ # Theorist
2
+
3
+ ## Mandate
4
+
5
+ Own the theoretical framework. Convert a thesis into falsifiable claims,
6
+ metrics, assumptions, and limits.
7
+
8
+ ## Responsibilities
9
+
10
+ - Decompose the thesis into discrete claims.
11
+ - Define metrics for each claim.
12
+ - Surface hidden assumptions.
13
+ - Reject experiments that do not actually test the stated claims.
14
+ - Revise claims when Scout evidence narrows or reframes the thesis.
15
+
16
+ ## Constraints
17
+
18
+ - Do not propose experiments directly.
19
+ - Flag tautologies, already-proven claims, and untestable claims.
20
+ - Maintain a structured Claim Registry update in every pass.
21
+
22
+ ## Output
23
+
24
+ Write a POD containing:
25
+
26
+ - status summary
27
+ - active claims
28
+ - killed claims
29
+ - requests to other agents
30
+ - confidence scores
31
+
package/src/cli.js ADDED
@@ -0,0 +1,98 @@
1
+ import { commandDoctor } from "./commands/doctor.js";
2
+ import { commandInit } from "./commands/init.js";
3
+ import { commandMemoryExport } from "./commands/memory-export.js";
4
+ import { commandMemoryImport } from "./commands/memory-import.js";
5
+ import { commandMigrate } from "./commands/migrate.js";
6
+ import { commandPath } from "./commands/path.js";
7
+ import { commandResumeCheck } from "./commands/resume-check.js";
8
+ import { commandValidate } from "./commands/validate.js";
9
+
10
+ const VERSION = "0.1.0";
11
+
12
+ function helpText() {
13
+ return `atavi
14
+
15
+ Host-agnostic multi-agent iterative research refinement protocol.
16
+
17
+ Usage:
18
+ atavi --help
19
+ atavi --version
20
+ atavi --path
21
+ atavi init [target]
22
+ atavi migrate [target]
23
+ atavi memory-export [target] [output]
24
+ atavi memory-import <source> [target]
25
+ atavi doctor
26
+ atavi validate [target]
27
+ atavi resume-check [target]
28
+
29
+ Commands:
30
+ --path Print the absolute path to the packaged protocol directory.
31
+ init Scaffold a .atavi workspace in the target directory.
32
+ migrate Add missing scaffold files and schema metadata to an existing workspace.
33
+ memory-export Copy `.atavi/memory` to an export directory.
34
+ memory-import Copy memory files into `.atavi/memory` without overwriting existing entries.
35
+ doctor Verify packaged protocol files and basic host prerequisites.
36
+ validate Validate the scaffolded .atavi/config.json contract.
37
+ resume-check Validate `.atavi/config.json` and `.atavi/status.md` for resume safety.
38
+
39
+ Notes:
40
+ atavi is intentionally thin. The host AI runs the protocol.
41
+ This package ships the protocol, agent role files, templates, and scaffold helpers.`;
42
+ }
43
+
44
+ export async function runCli(argv, io = process) {
45
+ const [command, ...rest] = argv;
46
+
47
+ if (!command || command === "--help" || command === "-h" || command === "help") {
48
+ io.stdout.write(`${helpText()}\n`);
49
+ return;
50
+ }
51
+
52
+ if (command === "--version" || command === "-v" || command === "version") {
53
+ io.stdout.write(`${VERSION}\n`);
54
+ return;
55
+ }
56
+
57
+ if (command === "--path" || command === "path") {
58
+ await commandPath(io);
59
+ return;
60
+ }
61
+
62
+ if (command === "init") {
63
+ await commandInit(rest, io);
64
+ return;
65
+ }
66
+
67
+ if (command === "doctor") {
68
+ await commandDoctor(io);
69
+ return;
70
+ }
71
+
72
+ if (command === "memory-export") {
73
+ await commandMemoryExport(rest, io);
74
+ return;
75
+ }
76
+
77
+ if (command === "memory-import") {
78
+ await commandMemoryImport(rest, io);
79
+ return;
80
+ }
81
+
82
+ if (command === "migrate") {
83
+ await commandMigrate(rest, io);
84
+ return;
85
+ }
86
+
87
+ if (command === "validate") {
88
+ await commandValidate(rest, io);
89
+ return;
90
+ }
91
+
92
+ if (command === "resume-check") {
93
+ await commandResumeCheck(rest, io);
94
+ return;
95
+ }
96
+
97
+ throw new Error(`Unknown command: ${command}`);
98
+ }
@@ -0,0 +1,39 @@
1
+ import { access } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import path from "node:path";
4
+ import { protocolFiles, protocolRoot, templateFiles } from "../lib/protocol-manifest.js";
5
+
6
+ async function canRead(filePath) {
7
+ try {
8
+ await access(filePath, constants.R_OK);
9
+ return true;
10
+ } catch {
11
+ return false;
12
+ }
13
+ }
14
+
15
+ export async function commandDoctor(io) {
16
+ const root = protocolRoot();
17
+ const required = [...protocolFiles(), ...templateFiles()].map((relativePath) => path.join(root, relativePath));
18
+ const missing = [];
19
+
20
+ for (const filePath of required) {
21
+ if (!(await canRead(filePath))) {
22
+ missing.push(filePath);
23
+ }
24
+ }
25
+
26
+ if (missing.length > 0) {
27
+ io.stdout.write("ATAVI doctor: FAIL\n");
28
+ for (const filePath of missing) {
29
+ io.stdout.write(`missing ${filePath}\n`);
30
+ }
31
+ throw new Error("Packaged protocol is incomplete.");
32
+ }
33
+
34
+ io.stdout.write("ATAVI doctor: OK\n");
35
+ io.stdout.write(`protocol root: ${root}\n`);
36
+ io.stdout.write("required files: present\n");
37
+ io.stdout.write("host requirement: your AI environment must support file I/O and web search for Scout runs\n");
38
+ }
39
+
@@ -0,0 +1,26 @@
1
+ import path from "node:path";
2
+ import { ensureDirectory, pathExists, writeFileIfMissing } from "../lib/filesystem.js";
3
+ import { scaffoldFiles } from "../lib/protocol-manifest.js";
4
+
5
+ export async function commandInit(args, io) {
6
+ const targetArg = args.find((arg) => !arg.startsWith("-")) ?? ".";
7
+ const targetDir = path.resolve(process.cwd(), targetArg);
8
+ const workspaceDir = path.join(targetDir, ".atavi");
9
+
10
+ await ensureDirectory(workspaceDir);
11
+
12
+ let created = 0;
13
+
14
+ for (const file of scaffoldFiles()) {
15
+ const destination = path.join(workspaceDir, file.relativePath);
16
+ const didCreate = await writeFileIfMissing(destination, file.contents);
17
+ if (didCreate) {
18
+ created += 1;
19
+ }
20
+ }
21
+
22
+ const status = (await pathExists(path.join(workspaceDir, "status.md"))) ? "ready" : "incomplete";
23
+ io.stdout.write(`Scaffolded ${workspaceDir}\n`);
24
+ io.stdout.write(`Created ${created} new file(s). Workspace status: ${status}.\n`);
25
+ }
26
+
@@ -0,0 +1,22 @@
1
+ import path from "node:path";
2
+ import { exportMemory, resolveMemoryDirectory } from "../lib/memory.js";
3
+
4
+ export async function commandMemoryExport(args, io) {
5
+ const targetArg = args.find((arg) => !arg.startsWith("-")) ?? ".";
6
+ const outputArg = args.filter((arg) => !arg.startsWith("-"))[1] ?? path.join(targetArg, ".atavi", "exports", "memory");
7
+ const sourceMemoryDir = await resolveMemoryDirectory(targetArg);
8
+
9
+ if (!sourceMemoryDir) {
10
+ io.stdout.write("ATAVI memory-export: FAIL\n");
11
+ io.stdout.write(`missing memory ${path.resolve(targetArg)}\n`);
12
+ throw new Error("ATAVI memory directory was not found.");
13
+ }
14
+
15
+ const outputDir = path.resolve(outputArg);
16
+ const result = await exportMemory(sourceMemoryDir, outputDir);
17
+
18
+ io.stdout.write("ATAVI memory-export: OK\n");
19
+ io.stdout.write(`source: ${sourceMemoryDir}\n`);
20
+ io.stdout.write(`output: ${outputDir}\n`);
21
+ io.stdout.write(`exported files: ${result.exportedFiles}\n`);
22
+ }
@@ -0,0 +1,31 @@
1
+ import path from "node:path";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { importMemory, resolveMemoryDirectory } from "../lib/memory.js";
4
+
5
+ export async function commandMemoryImport(args, io) {
6
+ const positionalArgs = args.filter((arg) => !arg.startsWith("-"));
7
+ const sourceArg = positionalArgs[0];
8
+ const targetArg = positionalArgs[1] ?? ".";
9
+
10
+ if (!sourceArg) {
11
+ throw new Error("memory-import requires a source path");
12
+ }
13
+
14
+ const sourceMemoryDir = await resolveMemoryDirectory(sourceArg);
15
+ if (!sourceMemoryDir) {
16
+ io.stdout.write("ATAVI memory-import: FAIL\n");
17
+ io.stdout.write(`missing memory ${path.resolve(sourceArg)}\n`);
18
+ throw new Error("ATAVI source memory directory was not found.");
19
+ }
20
+
21
+ const targetMemoryDir = path.join(path.resolve(targetArg), ".atavi", "memory");
22
+ await mkdir(targetMemoryDir, { recursive: true });
23
+
24
+ const result = await importMemory(sourceMemoryDir, targetMemoryDir);
25
+
26
+ io.stdout.write("ATAVI memory-import: OK\n");
27
+ io.stdout.write(`source: ${sourceMemoryDir}\n`);
28
+ io.stdout.write(`target: ${targetMemoryDir}\n`);
29
+ io.stdout.write(`imported files: ${result.importedFiles}\n`);
30
+ io.stdout.write(`skipped files: ${result.skippedFiles}\n`);
31
+ }