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
30 changes: 21 additions & 9 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Deep technical documentation for MAP (Modular Agentic Planner) implementation.

MAP is a Python 3.11+ CLI (`mapify`) plus provider-specific prompt/skill scaffolding that turns interactive coding agents (Claude Code and Codex CLI) into a repeatable engineering workflow: `SPEC -> PLAN -> TEST -> CODE -> REVIEW -> LEARN`. It emphasizes explicit artifacts, small reviewable contracts, deterministic prompt/runtime guardrails, and post-run learning handoffs persisted alongside the project.

The current package is `mapify-cli` `3.10.0`. It ships a Typer CLI, provider delivery helpers, shared workflow-state and verification utilities, bundled Claude/Codex templates, hook scripts, cross-session memory helpers, skill-evaluation utilities, and tests that validate template contracts, artifact schemas, prompt tone, provider surfaces, workflow gates, memory hooks, skill-eval behavior, and token-budget behavior.
The current package is `mapify-cli` `3.21.0`. It ships a Typer CLI, provider delivery helpers, shared workflow-state and verification utilities, bundled Claude/Codex templates, hook scripts, cross-session memory helpers, skill-evaluation utilities, install manifest/lock auditing, and tests that validate template contracts, artifact schemas, prompt tone, provider surfaces, workflow gates, memory hooks, skill-eval behavior, token-budget behavior, and install integrity.

The remainder of this file contains the deeper implementation dive (workflow-specific agent sequences, artifact specs, MCP integration, template maintenance, and context engineering).

Expand Down Expand Up @@ -66,7 +66,7 @@ The remainder of this file contains the deeper implementation dive (workflow-spe
- `src/mapify_cli/memory/`: cross-session scratch capture, digest schema, finalize, and recall helpers used by generated hooks and `/map-memory-now`
- `src/mapify_cli/skills_eval/`: skill trigger eval runner, assertions, aggregation, Claude dispatcher, description optimizer, patcher, proposer, schema, and HTML viewer
- `src/mapify_cli/templates/`: Shipped provider templates, hooks, agents, references, rule files, Codex config, and shared `.map/scripts/` payloads used by `mapify init`
- `src/mapify_cli/{token_budget,workflow_state,workflow_finalizer,verification_recorder,skill_ir,dependency_graph,repo_insight,_locking}.py`: Deterministic helpers used by templates, release checks, locks, and tests
- `src/mapify_cli/{token_budget,workflow_state,workflow_finalizer,verification_recorder,skill_ir,dependency_graph,repo_insight,_locking,install_manifest}.py`: Deterministic helpers used by templates, release checks, locks, install auditing, and tests
- `tests/`: Unit and integration coverage for CLI behavior, generated templates, hooks, workflow artifacts, SkillIR, provider frontmatter, and artifact schemas
- `docs/`: Workflow docs, deep dives, and planning history

Expand All @@ -78,12 +78,14 @@ The remainder of this file contains the deeper implementation dive (workflow-spe
- `.codex/`: Codex CLI config, hooks, and TOML agents generated by `mapify init . --provider codex`
- `.map/<branch>/`: Branch-scoped run artifacts (plans/contracts, check outputs, review notes, learning handoffs, session-memory digests)
- `.map/eval-runs/<skill>/`: durable skill-evaluation run logs and optimization JSON/HTML reports
- `.map/mapify.lock.json`: Install manifest/lock — aggregate audit of all MAP-managed files, written by `mapify init` and read by `mapify check-installed`

Claude skill metadata includes `skillClass` in `.claude/skills/skill-rules.json` so the runtime contract is explicit: `task` skills behave like manual slash workflows or opt-in interactive task surfaces, `reference` skills provide inline guidance, and `hybrid` skills combine reference material with declared runtime effects. Today the MAP slash surfaces are `task` skills, including `/map-understand`, whose checklist is transient in the conversation and has no runtime effects; `map-state` is `hybrid` because it documents planning state and ships hooks/scripts that interact with `.map/<branch>/` artifacts, and `map-so-search` is `hybrid` because it ships a script with declared network/credential runtime effects (the opt-in SOFA search; see [Stack Overflow for Agents (SOFA) Integration](#stack-overflow-for-agents-sofa-integration)).

## Runtime Flows

- **Initialize**: `mapify init` selects a provider, copies templates, and writes provider-specific prompts/skills plus shared `.map/` scripts.
- **Initialize**: `mapify init` selects a provider, copies templates, and writes provider-specific prompts/skills plus shared `.map/` scripts. At the end of init, `build_manifest()` scans the installed provider directories for all MAP-MANAGED files and writes `.map/mapify.lock.json` — recording each file's path, SHA-256 content/template hash, management mode (`fenced`/`full`/`hooks-merge`), and install timestamp. This manifest is the audit baseline for `mapify check-installed`.
- **Audit Install**: `mapify check-installed [project-path]` reads `.map/mapify.lock.json` and compares it against the current filesystem. It reports missing files (in manifest, absent on disk), drifted files (template_hash changed — a newer MAP template is available), orphaned files (MAP-managed on disk but not in the manifest), and ok files (present and matching). Exit codes: 0=all ok, 1=issues found, 2=no manifest. Security invariants: no absolute paths are stored in the manifest; `settings.local.json` (machine-specific statusline config) is excluded from the committed manifest; symlinks are excluded from scanning.
- **Run Workflow**: User triggers MAP commands (e.g., `/map-plan`, `/map-efficient`, `/map-check`, `/map-review`, `/map-learn`, `/map-understand`) through the provider UI, or `$map-*` skills for Codex. Each command orchestrates a specific agent sequence or teaching loop defined in generated skill/template files.
- **Apply Minimality Doctrine**: `.map/config.yaml` controls `minimality` (`off`, `lite`, `full`, `ultra`). The global default is `lite` (Phase 3 flip, #183) for ALL projects — keyless configs that previously loaded as `off` now resolve to `lite` at both the `MapConfig` and runner `_load_minimality_level` layers; set `minimality: off` to opt out (bare `off` is YAML-coerced to a boolean and normalized back to the `off` level so opt-out is not silently lost). Runtime prompt builders inject the doctrine into Actor context, Evaluator scores `simplicity` while keeping `completeness` highest-weight, Monitor distinguishes real scope/risk drift from harmless implementation size, and the orchestrator forwards only BLOCKER-class retry feedback back to Actor. Decomposer blueprints classify active subtasks with `requiredness`/`pruneable`; only `full`/`ultra` may carry a non-empty `deferred_yagni` parking lot, and plan approval must expose those omissions plus restore hints before execution. If the user restores an omission, `restore_deferred_yagni` rewrites `blueprint.json` and the task plan before approval continues. `run_health_report.json` records the historical minimality level for each workflow, and `mapify minimality-report` compares complete `off` and opt-in cohorts, reports sample gaps and cohort branch names, lists next telemetry actions, and emits a candidate-only manual review gate before maintainers consider the Phase 3 global default flip.
- **Persist Artifacts**: Each workflow stage records durable artifacts under `.map/<branch>/`, including specs, blueprints, test contracts, verification summaries, review bundles, learning handoffs, token-budget reports, run-health reports, and retry quarantine state. Research/discovery uses a single namespace: plan-scope discovery is `.map/<branch>/research/plan__discovery.md`, and subtask-scope artifacts are `.map/<branch>/research/<subtask_id>__<kind>.md`; legacy `findings_<branch>.md` files are compatibility fallbacks, not the primary source.
Expand All @@ -101,6 +103,7 @@ Claude skill metadata includes `skillClass` in `.claude/skills/skill-rules.json`
- **Deterministic helpers**: `src/mapify_cli/*` helper modules and `.map/scripts/` templates enforce artifact schemas, workflow state, prompt budgets, SkillIR checks, memory finalization, skill-eval assertions, and prior-stage validation.
- **Host-path and lock contract**: `src/mapify_cli/_locking.py` owns the `flock_with_state` implementation; `src/mapify_cli/templates/references/host-paths.md` is the shipped user-facing reference for `MAP_*`, `~/.map/`, and lock state-marker semantics.
- **Spec citation gate**: `.map/scripts/validate_spec_citations.py` and its template twin validate `file:line` references before `/map-plan` decomposes work.
- **Install manifest**: `.map/mapify.lock.json` is the audit lock written by `mapify init` via `src/mapify_cli/install_manifest.py`; `mapify check-installed` reads it to detect missing/drifted/orphaned MAP-managed files. Security invariants: no absolute paths, no secrets, machine-local `settings.local.json` excluded from the committed manifest.
- **Documentation**: `README.md`, `docs/USAGE.md`, `docs/INSTALL.md`, and this document define expected behavior and invariants.

## Worktree Isolation (per-subtask sandboxing)
Expand Down Expand Up @@ -392,9 +395,9 @@ Information not available in current evidence.

## Freshness

Last refreshed: 2026-06-05
Last refreshed: 2026-07-05

Refresh reason: Daily architecture refresh after committed cross-session memory hooks, host-conditional skill installation, and `mapify skill-eval` run/optimize/view work changed the top-level MAP runtime contract.
Refresh reason: Incremental refresh after install manifest/lock (#313) added `src/mapify_cli/install_manifest.py`, `mapify check-installed` command, and `.map/mapify.lock.json` to the system contract.

Evidence source files:
- `README.md`
Expand All @@ -403,6 +406,7 @@ Evidence source files:
- `docs/INSTALL.md`
- `src/mapify_cli/`
- `src/mapify_cli/_locking.py`
- `src/mapify_cli/install_manifest.py`
- `src/mapify_cli/delivery/providers.py`
- `src/mapify_cli/workflow_state.py`
- `.claude/references/host-paths.md`
Expand All @@ -420,14 +424,22 @@ Evidence source files:
- `Makefile`
- `tests/`

Current delta captured: MAP now documents and tests cross-session memory capture
Current delta captured: install manifest/lock (#313) — `mapify init` now scans
all installed provider directories for MAP-MANAGED metadata at the end of
initialization and writes `.map/mapify.lock.json` recording content hash,
template hash, management mode (`fenced`/`full`/`hooks-merge`), and timestamp for
every managed file. `mapify check-installed` compares the current filesystem
against the manifest and reports missing/drifted/orphaned files with appropriate
exit codes (0=ok, 1=issues, 2=no manifest). Security invariants: no absolute
paths or secrets stored; `settings.local.json` excluded; symlinks excluded.
28 tests in `tests/test_install_manifest.py` cover all verification criteria.

Earlier delta (2026-06-05): MAP documents and tests cross-session memory capture
and recall through generated hooks plus `/map-memory-now`; host-conditional
installation prunes skills whose commands are unavailable; `map-skill-eval` is a
measurement-only skill backed by `mapify skill-eval run`; `mapify skill-eval
optimize` uses train/test splits, overfit rejection, proposer iterations,
optional template patching, and HTML reports; and skill-eval fixtures/tests now
cover run logs, optimizer schemas, patch safety, viewer rendering, and the
no-Anthropic invariant across optimizer modules.
optional template patching, and HTML reports.

## Table of Contents

Expand Down
80 changes: 80 additions & 0 deletions src/mapify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,86 @@ def check_installed(
raise typer.Exit(1)


@app.command()
def uninstall(
project_path: Optional[Path] = typer.Argument(
None,
help="Project root directory (defaults to current directory).",
),
yes: bool = typer.Option(
False,
"--yes",
"-y",
help="Skip confirmation prompt.",
),
) -> None:
"""Remove MAP-owned config entries from provider config files.

Reads .map/mapify.lock.json and removes only the config-merge entries
MAP injected (MCP server keys in .mcp.json, the MAP statusline in
settings.local.json). User-modified or user-owned entries are
preserved. Installed files (.claude/, .map/scripts/, etc.) are
NOT removed by this command.

Exit codes: 0 = ok / nothing to remove, 1 = error, 2 = no manifest.
"""
from mapify_cli.install_manifest import read_manifest, reconcile_config

target = project_path or Path.cwd()

manifest = read_manifest(target)
if manifest is None:
console.print(
f"[yellow]No install manifest found at "
f"{target / '.map' / 'mapify.lock.json'}[/yellow]"
)
console.print("[dim]Run [cyan]mapify init .[/cyan] to generate the manifest.[/dim]")
raise typer.Exit(2)

if not manifest.config_entries:
console.print("[green]No MAP-owned config entries in the manifest.[/green]")
return

console.print(
f"[bold]MAP config entries to remove[/bold] "
f"(provider: [cyan]{manifest.provider}[/cyan]):"
)
for entry in manifest.config_entries:
console.print(f" [dim]{entry.file}[/dim] [cyan]{entry.key_path}[/cyan]")

console.print()
if not yes:
confirm = typer.confirm(
"Remove these MAP-owned config entries?",
default=False,
)
if not confirm:
console.print("[dim]Aborted.[/dim]")
return

result = reconcile_config(target)

if result.removed:
console.print(f"[green]Removed ({len(result.removed)}):[/green]")
for label in result.removed:
console.print(f" [green]✓[/green] {label}")

if result.skipped:
console.print(
f"[yellow]Skipped ({len(result.skipped)}) — user-modified, preserved:[/yellow]"
)
for label in result.skipped:
console.print(f" [yellow]~[/yellow] {label}")

if result.missing:
console.print(f"[dim]Already absent ({len(result.missing)}):[/dim]")
for label in result.missing:
console.print(f" [dim]-[/dim] {label}")

if not result.removed and not result.skipped and not result.missing:
console.print("[dim]Nothing to do.[/dim]")


# Research localization eval commands


Expand Down
Loading
Loading