amicus 0.4.0__tar.gz → 0.5.0__tar.gz
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.
- {amicus-0.4.0 → amicus-0.5.0}/.claude-plugin/marketplace.json +6 -1
- {amicus-0.4.0 → amicus-0.5.0}/.claude-plugin/plugin.json +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/.codex-plugin/plugin.json +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/.mcp.json +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/AGENTS.md +7 -2
- {amicus-0.4.0 → amicus-0.5.0}/CHANGELOG.md +121 -1
- {amicus-0.4.0 → amicus-0.5.0}/PKG-INFO +15 -10
- {amicus-0.4.0 → amicus-0.5.0}/README.md +14 -9
- {amicus-0.4.0 → amicus-0.5.0}/docs/MIGRATION.md +33 -6
- {amicus-0.4.0 → amicus-0.5.0}/docs/RELEASING.md +41 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0033-an-unreadable-review-answer-is-delivered-unstructured.md +1 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0035-a-backend-answer-is-kept-on-the-job-record.md +1 -0
- amicus-0.5.0/docs/adr/0036-a-refused-answer-file-is-answer-unavailable.md +69 -0
- amicus-0.5.0/docs/claude-help/2.1.278/claude-help.txt +302 -0
- amicus-0.5.0/docs/claude-help/2.1.278/claude-version.txt +1 -0
- amicus-0.5.0/docs/codex-help/0.155.1/codex-help.txt +112 -0
- amicus-0.5.0/docs/codex-help/0.155.1/codex-version.txt +1 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.43.1/FINDINGS.md +24 -0
- amicus-0.5.0/docs/kimi-help/2.0.2/FINDINGS.md +86 -0
- amicus-0.5.0/docs/kimi-help/2.0.2/kimi-help.txt +51 -0
- amicus-0.5.0/docs/kimi-help/2.0.2/kimi-version.txt +1 -0
- amicus-0.5.0/docs/kimi-help/2.0.2/provider-list-shape.json +18 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/superpowers/specs/2026-09-04-amicus-design.md +4 -3
- {amicus-0.4.0 → amicus-0.5.0}/pyproject.toml +1 -1
- amicus-0.5.0/scripts/check_backend_compat.py +347 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/choosing-a-backend.md +4 -1
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/options-and-errors.md +4 -2
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/reading-results.md +19 -3
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/sync-vs-async.md +4 -2
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/__init__.py +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/binary.py +8 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/config.py +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/adapter.py +1 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/binary.py +8 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/config.py +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/contract.py +6 -4
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/__init__.py +8 -1
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/adapter.py +2 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/binary.py +8 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/config.py +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/contract.py +8 -4
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/config/__init__.py +31 -9
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/errors.py +7 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/lifecycle.py +30 -10
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/finalize.py +197 -28
- amicus-0.5.0/src/amicus/orchestration/run.py +368 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/codes.py +4 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/fingerprint.py +6 -2
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/params.py +3 -2
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/results.py +22 -14
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/backend/protocol.py +10 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/conventions/envelope.py +1 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/server.py +4 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/__init__.py +2 -3
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/_meta.py +4 -13
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/discovery.py +21 -9
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/dry_run.py +8 -54
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/manifest_snapshot.all.json +289 -725
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/manifest_snapshot.claude.json +289 -725
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/manifest_snapshot.codex-kimi.json +289 -725
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/result_format_snapshot.json +7 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/wire_shape_snapshot.json +4 -4
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/fake_codex.py +29 -4
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/fake_kimi.py +29 -5
- amicus-0.5.0/tests/support/livegate.py +22 -0
- amicus-0.5.0/tests/test_artifact_references.py +296 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_async_tools.py +1 -1
- amicus-0.5.0/tests/test_check_backend_compat.py +310 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_contract.py +37 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codes.py +3 -2
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_config.py +2 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_contract.py +35 -2
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_live.py +5 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_commands.py +28 -2
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_compaction.py +1 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_discovery.py +11 -11
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_discovery_cost.py +27 -2
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_dry_run.py +99 -56
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_fingerprint.py +3 -3
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_contract.py +5 -2
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_plugin.py +26 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_sync_tools.py +151 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_lifecycle.py +33 -4
- amicus-0.5.0/tests/test_livegate.py +46 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_manifest.py +4 -4
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_meta.py +61 -22
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_migration_doc.py +8 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_packaging.py +3 -3
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_params.py +26 -0
- amicus-0.5.0/tests/test_relative_config_paths.py +110 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_release_state.py +26 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_results.py +27 -11
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_run.py +260 -1
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_skill_contract.py +17 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_sync_tools.py +132 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_tasks_client.py +0 -1
- {amicus-0.4.0 → amicus-0.5.0}/uv.lock +1 -1
- amicus-0.4.0/src/amicus/orchestration/run.py +0 -219
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/SKILL.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/references/design-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/references/docs-checklist.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/references/examples.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/references/review-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-docs/tests/scenarios.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/SKILL.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/decisions/001-github-fact-sheet.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/audit-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/config-checklist.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/README.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/codeowners.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/harness-deny.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/identity.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/repo-files.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/required-checks.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/rulesets.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/examples/workflows.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/operating-playbook.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/setup-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/references/threat-model.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/tests/check_authority.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-github/tests/scenarios.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/SKILL.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/decisions/001-mcp-2026-07-28-rebase.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/decisions/002-machine-code-rename-rationale.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/decisions/003-offending-value-omission.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/decisions/004-ownership-boundaries.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/contract-checklist.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/design-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/examples.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/mcp-2025-11-25-compat.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/mcp-vs-cli.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/native-wire-shapes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/review-workflow.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/references/vocabulary.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/check_fact_sync.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/check_rule_ids.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/check_stale_terms.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/fixtures/github_issues.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/fixtures/github_repo_resource.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/rule-ids.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario1-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario1-outputschema-error.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario2-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario2-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario3-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario3-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario4-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario4-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario5-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario5-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario6-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario6-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-11-scenario7-trigger.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario1-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario3-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario3-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario5-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-29-scenario5-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-30-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/runs/2026-07-30-scenario8-severity-calibration.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/scenarios.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/test_check_fact_sync.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/test_check_rule_ids.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/test_validate_fixture.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/agent-friendly-mcp/tests/validate_fixture.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/SKILL.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/agents/openai.yaml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/references/example-audit.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/rescore-2026-08-06/preregistration.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/rescore-2026-08-06/results.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario1-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario2-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario2-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario3-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario3-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario4-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario4-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario5-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario5-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario6-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario6-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario7-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario7-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario8-baseline.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario8-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-07-11-scenario9-trigger.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-06-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-06-scenario6-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-confirmation-r1-both-directions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario1-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario2-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario5-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario6-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario7-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/runs/2026-08-23-scenario8-with-skill.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.agents/skills/separating-context-from-constraints/tests/scenarios.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.gitattributes +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/CODEOWNERS +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/copilot-instructions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/dependabot.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/workflows/ci.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/workflows/codeql.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/workflows/dependency-review.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/workflows/publish.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.github/workflows/test.yml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/.gitignore +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/CLAUDE.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/LICENSE +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/adversarial.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/consult.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/delegate-async.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/delegate.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/dry-run.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/jobs.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/review.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/commands/amicus/status.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/2026-09-04-naming-and-scoping-notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/DEPRECATING-SIBLINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0001-annotations-follow-the-worst-enabled-backend.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0002-backend-options-is-a-closed-superset.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0003-workspace-resolution.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0004-tasks-and-jobs.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0005-error-envelope-and-repair-precedence.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0006-fingerprint-and-surface-digest.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0007-m1-codex-port-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0008-m2-jobs-surface-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0009-m3-kimi-port-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0010-m4-claude-port-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0011-m5-tasks-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0012-m6-packaging-decisions.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0013-proceed-without-trademark-clearance.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0014-release-predicate-on-the-tag.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0015-mcp-json-pins-an-already-published-release.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0016-skill-rules-are-a-complete-contract.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0017-an-unreadable-machine-enum-falls-to-its-own-floor.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0018-the-catalog-carries-a-ttl-and-resource-reads-do-not.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0019-review-results-disclose-coverage-as-a-field.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0020-idempotency-keys-on-the-sync-tools.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0021-repair-arguments-are-a-complete-call.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0022-consume-reports-its-discard-outcome.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0023-dependency-loggers-are-owned-at-a-warning-floor.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0024-prose-list-loss-is-disclosed-never-folded.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0025-success-meta-is-sparse-on-every-tool.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0026-a-not-run-review-carries-no-confidence-rating.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0027-every-instructions-rule-fits-the-shown-prefix.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0028-a-deprecated-tool-keeps-its-record-beside-one-marker.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0029-the-backend-sdk-lives-in-tree.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0030-the-sdk-keeps-what-a-backend-imports.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0031-the-marketplace-pointer-decides-what-users-run.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0032-a-claude-review-defaults-to-readonly-access.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/0034-claude-usage-is-read-from-model-usage.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/adr/README.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.263/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.263/claude-help.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.263/claude-version.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.263/envelope-shape.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.274/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.274/budget-stop-envelope-shape.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/claude-help/2.1.274/claude-version.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/claude-code/2.1.263/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/claude-code/2.1.263/connection.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/claude-code/2.1.263/host-output.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/codex/0.153.4/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/codex/0.153.4/connection.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/codex/0.153.4/host-output.jsonl +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/free-scenarios/claude-code/2.1.263/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/free-scenarios/claude-code/2.1.263/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/free-scenarios/claude-code/2.1.263/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/claude-code/2.1.263/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/claude-code/2.1.263/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/claude-code/2.1.263/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/codex/0.153.4/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/codex/0.153.4/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/install-smoke/codex/0.153.4/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-f3-recon-attempt/claude-code/2.1.265/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-f3-recon-attempt/claude-code/2.1.265/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-f3-recon-attempt/claude-code/2.1.265/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-old-text-new-grader/claude-code/2.1.263/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-old-text-new-grader/claude-code/2.1.263/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-old-text-new-grader/claude-code/2.1.263/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-rerun/claude-code/2.1.263/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-rerun/claude-code/2.1.263/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-rerun/claude-code/2.1.263/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-response-contract/claude-code/2.1.263/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-response-contract/claude-code/2.1.263/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s6-response-contract/claude-code/2.1.263/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s7-rule5-recheck/claude-code/2.1.265/notes.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s7-rule5-recheck/claude-code/2.1.265/server.log +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/host-captures/s7-rule5-recheck/claude-code/2.1.265/transcript.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.41.0/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.41.0/kimi-help.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.41.0/kimi-version.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.41.0/provider-list-shape.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.42.0/FINDINGS.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.42.0/kimi-help.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.42.0/kimi-version.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.42.0/provider-list-shape.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.43.1/kimi-help.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.43.1/kimi-version.txt +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/kimi-help/0.43.1/provider-list-shape.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/reviews/2026-09-07-agent-friendly-mcp-walk.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/superpowers/plans/2026-09-04-amicus-execution-model.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/superpowers/specs/2026-09-15-amicus-M8-sdk-in-tree-design.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/docs/superpowers/specs/2026-09-16-amicus-release-activation-design.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/prek.toml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/capture_claude_differentials.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/capture_codex_differentials.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/capture_kimi_differentials.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/check_commit_message.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/check_github_actions_pinning.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/check_release_state.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/scripts/record_live_gate_evidence.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/SKILL.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/active-workflows.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/blind-comparison.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/independent-attempt.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/review-revise.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/reviewing-a-returned-diff.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/references/server-down-fallback.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/skills/collaborating-with-amicus/tests/scenarios.md +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/_worker.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/appstate.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/adapter.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/adversarial.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/contract.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/options.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/claude/status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/options.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/codex/status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/options.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/backends/kimi/status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/compaction.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/config/envspec.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/delivery.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/idempotency.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/lookup.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/polling.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/store.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/jobs/taskmap.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/manifest.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/middleware.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/obs.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/gitdiff.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/gitproc.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/isolation.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/prompts.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/review.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/workspace.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/orchestration/worktree.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/packaging.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/plugin.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/py.typed +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/registry.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/request.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/result_format_snapshot.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/envelope.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/field_policy.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/instructions.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/options.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/publish.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/schemas/structured.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/backend/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/backend/contract.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/conventions/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/conventions/annotations.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/conventions/preflight.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/jsoncache.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/pathalias.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/redaction.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/runtime.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/core/streamcap.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/testing/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/testing/conformance.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/sdk/testing/surface_honesty.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/surface.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/_guard.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/_prepare.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/_resolve.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/consult.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/delegate.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/jobs.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/resources.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/tools/review.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/src/amicus/wire_shape_snapshot.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/conftest.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/claude_budget_stop_envelope.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/claude_differentials.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/claude_golden_envelope.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/codex_differentials.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/fakebackend/pyproject.toml +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/fakebackend/src/fakebackend/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/fixtures/kimi_differentials.json +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/conftest.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_annotations.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_classified_failure_fields.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_conformance_fakes.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_conformance_inspector.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_contract.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_envelope.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_fingerprint.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_git_isolation.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_gitdiff.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_gitproc.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_idempotency.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_jobs.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_jsoncache.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_orphan_sweep.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_outcome_inspector.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_pair_parity_kit.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_pathalias.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_preflight.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_prompts.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_redaction.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_run_request.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_runtime.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_runtime_kill_and_sweep_paths.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_streamcap.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_surface_honesty_kit.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_usage_cache_fields.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_workspace.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_worktree.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/sdk/test_worktree_config.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/__init__.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/claudefixtures.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/codexfixtures.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/fake_claude.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/fakeplugin.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/kimifixtures.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/support/pair_parity.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_adversarial.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_cache_hints.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_check_commit_message.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_check_github_actions_pinning.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_adapter.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_argv_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_binary.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_config.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_golden_envelope.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_live.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_plugin.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_result_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_claude_sync_tools.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_adapter.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_argv_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_binary.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_plugin.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_result_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_codex_status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_config.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_conftest_guards.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_delivery.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_envelope.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_envspec.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_errors.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_fastmcp_argument_log.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_field_policy.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_finalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_guard.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_host_captures.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_import_contracts.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_instructions.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_isolation.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_job_durability.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_job_tools.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_adapter.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_argv_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_binary.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_cli.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_config.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_live.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_models.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_normalize.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_result_differential.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_kimi_status.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_live_gate_report.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_live_suite_hygiene.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_log_redaction.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_lookup.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_middleware.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_obs.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_options.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_paid_tools.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_plugin.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_poll_hint.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_prepare.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_prompts.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_publish.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_registry.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_release_evidence.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_request.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_resources.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_result_format.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_review.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_review_artifact.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_sdk_in_tree.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_server.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_structured.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_surface.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_surface_honesty.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_taskmap.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_tasks_spike.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_wheel_seam.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_wire_shape.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_worker.py +0 -0
- {amicus-0.4.0 → amicus-0.5.0}/tests/test_workspace.py +0 -0
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
"plugins": [
|
|
8
8
|
{
|
|
9
9
|
"name": "amicus",
|
|
10
|
-
"source":
|
|
10
|
+
"source": {
|
|
11
|
+
"source": "url",
|
|
12
|
+
"url": "https://github.com/briandconnelly/amicus.git",
|
|
13
|
+
"ref": "v0.4.0",
|
|
14
|
+
"sha": "970905ad7141d2d3e650b7401685b893abf258db"
|
|
15
|
+
},
|
|
11
16
|
"description": "One MCP server for every second-opinion model: consult, review, and delegate with the backend as a parameter."
|
|
12
17
|
}
|
|
13
18
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "One MCP server for every second-opinion model: consult, review, and delegate with the backend as a parameter.",
|
|
5
5
|
"author": { "name": "Brian Connelly", "url": "https://github.com/briandconnelly" },
|
|
6
6
|
"homepage": "https://github.com/briandconnelly/amicus",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "One MCP server for every second-opinion model: consult, review, and delegate with the backend as a parameter.",
|
|
5
5
|
"author": { "name": "Brian Connelly", "url": "https://github.com/briandconnelly" },
|
|
6
6
|
"homepage": "https://github.com/briandconnelly/amicus",
|
|
@@ -29,7 +29,7 @@ The rules bind; the context after them explains and points elsewhere.
|
|
|
29
29
|
17. Never edit a sibling checkout (`~/projects/codex-in-claude`, `~/projects/moonbridge`, `~/projects/claude-in-codex`, `~/projects/pontonier`).
|
|
30
30
|
18. Never write a prompt input — every field in `INPUT_FIELDS` (`src/amicus/request.py`): `question`, `task`, `extra_context`, `instructions_append`, `focus`, `target`, `evidence` — to disk, to a worker's argv or to a log; it travels over the worker's stdin.
|
|
31
31
|
This binds amicus's own handling and everything it commits, including host captures and eval prompt bodies, which are recorded as an id and a `sha256` instead.
|
|
32
|
-
A backend's own native carrier is exempt where
|
|
32
|
+
A backend's own native carrier is exempt where no documented or observed way to avoid it has been found on the backend CLI release an amicus release is validated against, re-checked before every amicus release on the CLI versions its rule-20 evidence is recorded on, and the carrier is disclosed in its `CARRIERS` string and surfaced on `amicus_backends`; the three that exist today are Kimi's handshake file, the kimi CLI's own session store, and Codex's `-c developer_instructions` argv token.
|
|
33
33
|
Prompt text that a test or capture script assembles entirely from its own literals is exempt, including the `build_*_prompt` output committed in `tests/fixtures/*_differentials.json`; it stays verbatim, because a differential must show what changed and a hash cannot.
|
|
34
34
|
No exemption reaches text that amicus itself, or anyone working in this repository, copies, derives or replays from a prompt anyone sent: that stays bound however it is later stored or relabelled.
|
|
35
35
|
A backend's answer, and the result amicus builds from it — its parsed fields and, for a delegate, the diff captured from the worktree — is output, not a prompt input, even where it quotes or paraphrases one: amicus keeps it only on the job record (`result.json`, written through a staging file in the same directory), under the job retention the tool surface discloses (`AMICUS_JOB_TTL`, the per-workspace cap, `amicus_job_consume_result`), and writes it to no log, argv or other file; what this repository commits of an answer stays bound by the sentence before this one wherever the answer repeats a prompt anyone sent.
|
|
@@ -63,7 +63,12 @@ The package is `amicus` under `src/`; each backend is a plugin under `src/amicus
|
|
|
63
63
|
It was copied from [pontonier](https://github.com/briandconnelly/pontonier) v0.9.0, and amicus no longer depends on pontonier (ADR 0029).
|
|
64
64
|
ADR 0030 holds it to that role, so what only the server uses lives in the amicus package that owns it: the job store is `amicus.jobs`, worktrees and diff gathering are `amicus.orchestration`, and the fingerprint mechanics are `amicus.schemas.fingerprint`.
|
|
65
65
|
Import boundaries between layers are enforced by the import-linter contracts in `pyproject.toml`.
|
|
66
|
-
A backend's own prompt carriers (for Codex, the developer-instructions argv token and the stdin prompt) are disclosed on `amicus_backends`.
|
|
66
|
+
A backend's own prompt carriers (for Codex, the developer-instructions argv token and the stdin prompt; for Kimi, the handshake file and the CLI's own session store) are disclosed on `amicus_backends`.
|
|
67
|
+
Rule 18's exemption is bounded by evidence rather than by proof, because whether a closed-source CLI offers an alternative cannot be proven, only looked for: the condition is that none was found, documented or observed, and the looking is repeated before every amicus release, on the exact CLI versions the rule-20 evidence run uses.
|
|
68
|
+
It is tied to the release rather than to a change in a backend's supported-version set because that set is coarse: a kimi patch release still parses as its minor, and every claude 2.x release is covered by major 2, so a new CLI release can become supported without the set ever changing.
|
|
69
|
+
Kimi's handshake file exists because kimi ignores stdin.
|
|
70
|
+
Codex's argv token exists because `codex exec --help` (0.155.1) offers the prompt, on stdin, and no flag for developer-role instructions, which leaves the `developer_instructions` config value, set with `-c` on argv or from a config file; argv is the one that leaves nothing on disk.
|
|
71
|
+
Kimi's session store is different in kind: the CLI rather than amicus writes it, it outlives the run, and amicus does not delete it; the 0.43.1 probe that found no way to switch it off, and what that probe did not test, are recorded in `docs/kimi-help/0.43.1/FINDINGS.md`.
|
|
67
72
|
|
|
68
73
|
### The gate
|
|
69
74
|
|
|
@@ -20,6 +20,125 @@ per-change, as its own lead says.
|
|
|
20
20
|
|
|
21
21
|
## [Unreleased]
|
|
22
22
|
|
|
23
|
+
## [0.5.0] - 2026-09-20
|
|
24
|
+
|
|
25
|
+
Across this release the discovery surface moves `amicus/0.1/schema-35`, what 0.4.0 shipped, to
|
|
26
|
+
`amicus/0.1/schema-39`, and stored job results move `RESULT_FORMAT` 7 to 9, so a job result 0.4.0
|
|
27
|
+
stored cannot be delivered after upgrading. The entries labelled **Breaking** are the changes a
|
|
28
|
+
caller or operator using 0.4.0 has to handle, and `docs/MIGRATION.md` ("Upgrading from 0.4.0")
|
|
29
|
+
walks through each. It was checked against codex-cli 0.155, Kimi Code 2.0 and Claude Code 2.1.278.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- Kimi Code 2.0 is a supported version, so `amicus_backends` no longer warns on it. Kimi Code
|
|
34
|
+
went from 0.43.1 to 2.0.2 in one upgrade; amicus has seen no 1.x and claims none. It was
|
|
35
|
+
checked against the 0.43.1 capture at zero spend: `--help` differs by one new subcommand and no
|
|
36
|
+
option, the `provider list --json` shape is identical, and `kimi session` still offers `list`
|
|
37
|
+
only and still reads the existing session store, so no new way to avoid that carrier was
|
|
38
|
+
found. The kimi live suite then passed on 2.0.2, which exercises consult, the read-only tool
|
|
39
|
+
profile, review and delegate; whether 2.0.2 still writes to the session store was not looked
|
|
40
|
+
at in that run (#202).
|
|
41
|
+
- Releasing now checks the backend CLIs first. `docs/RELEASING.md` gains a precondition, run
|
|
42
|
+
immediately before the release evidence: bring `codex`, `kimi` and `claude` to their latest
|
|
43
|
+
releases, run the new zero-spend `scripts/check_backend_compat.py` (installed and latest
|
|
44
|
+
version, the warnings `amicus_backends` would raise, and the flags each `--help` declares
|
|
45
|
+
against the newest committed capture), and do the AGENTS.md rule-18 carrier re-check by
|
|
46
|
+
reading, which no script can. Codex gains its first committed help capture (0.155.1), held
|
|
47
|
+
to the flags amicus always sends as Kimi's and Claude's already were, and Claude gains one for
|
|
48
|
+
2.1.278. Nothing about how amicus runs changes (#188).
|
|
49
|
+
- codex-cli 0.155 is a supported version, so `amicus_backends` no longer warns on it. It was
|
|
50
|
+
checked against 0.154.0 at zero spend: `--help`, `exec --help`, `exec review --help` and
|
|
51
|
+
`login --help` are byte-identical, the unknown-feature error and the logged-out `login status`
|
|
52
|
+
line are unchanged, both features amicus disables on every run are still `stable`, the cached
|
|
53
|
+
model list is the same seven slugs in the same order, the tool list sent to `gpt-5.5` is
|
|
54
|
+
identical with and without those disables, and the four config keys amicus pins with `-c` are
|
|
55
|
+
accepted under `--strict-config` while an unknown key is still rejected in the form amicus
|
|
56
|
+
parses. No paid call was part of the check (#187).
|
|
57
|
+
|
|
58
|
+
### Removed
|
|
59
|
+
|
|
60
|
+
- **Breaking.** `amicus_dry_run`, the deprecated alias of `amicus_review_changes_dry_run`, is
|
|
61
|
+
removed. It was deprecated in 0.3.0 (#98) with a marker in its lifecycle `_meta`, on its
|
|
62
|
+
`amicus_capabilities` row and at the head of its description, each naming 0.5.0, and ADR 0028
|
|
63
|
+
removes a tool at the end of its window. Call `amicus_review_changes_dry_run` with the same
|
|
64
|
+
arguments. The server now lists 18 tools, and no tool carries a deprecation marker; the
|
|
65
|
+
mechanism and `amicus_capabilities.deprecation_policy` stay (#204).
|
|
66
|
+
|
|
67
|
+
### Fixed
|
|
68
|
+
|
|
69
|
+
- **Surface.** A replayed keyed `_async` call can hand back a job that is already terminal, and
|
|
70
|
+
its handle's `follow_up` still said `poll_job_status` / `amicus_job_status`, which the skill's
|
|
71
|
+
own rules forbid for a finished job. A terminal handle now carries `next_step:
|
|
72
|
+
fetch_job_result` and `tool: amicus_job_result` with the same `job_id` and `workspace_root`; a
|
|
73
|
+
running handle is unchanged. The two are separate correlated shapes in the output schema, so
|
|
74
|
+
no mismatched step/tool pair is admitted. `fetch_job_result` is a new `repair.next_step`
|
|
75
|
+
value. A caller that went by `status`, as the 0.4.0 descriptions told it to, changes nothing
|
|
76
|
+
(#103).
|
|
77
|
+
- **Surface.** The `idempotency_key` parameter description said the key is scoped to "this tool
|
|
78
|
+
+ backend + workspace", which reads as though the same key on another backend were a separate
|
|
79
|
+
identity. It never was: the key is scoped to the tool and the workspace, and `backend` is one
|
|
80
|
+
of the arguments that must match, so that call is an `idempotency_conflict`. The description
|
|
81
|
+
now says so; behaviour is unchanged (#178).
|
|
82
|
+
- **Breaking.** An answer file amicus refuses to read is no longer delivered as an empty answer.
|
|
83
|
+
The bounded reader accepts only a regular file within 1,000,000 bytes (ADR 0009), and a file
|
|
84
|
+
it refused was indistinguishable from a backend that wrote nothing: a Codex review came back
|
|
85
|
+
`invalid_json`, and a Codex consult came back `ok: true` with "(the backend returned no
|
|
86
|
+
message)". Both are now the new error `answer_unavailable`, with `error.details.reason` one of
|
|
87
|
+
`artifact_oversize` (carrying `limit_bytes` and, when known, `actual_bytes`),
|
|
88
|
+
`artifact_not_regular` or `artifact_unreadable`, never the path. It is temporary only for an
|
|
89
|
+
unreadable file whose cause passes (descriptor or memory exhaustion); oversize repairs with
|
|
90
|
+
`reduce_input`. Every other failure is still reported as itself, a refusal
|
|
91
|
+
standing in only for a clean exit diagnosed as empty. A Kimi run whose stream carried the
|
|
92
|
+
answer, captured whole, is delivered with a `meta.security_warnings` entry. A delegate with no
|
|
93
|
+
such answer keeps its captured diff, with amicus's own summary saying the backend's could not
|
|
94
|
+
be read and `raw_response.text` left null. An absent or empty file is unchanged: that is the
|
|
95
|
+
backend saying nothing. The reader also now reads to the end of the file, where one short
|
|
96
|
+
`read` could have delivered a prefix as the whole answer. The new error code is one of the two changes that move
|
|
97
|
+
`RESULT_FORMAT` in this release, since an older reader's closed set of codes rejects it (#162).
|
|
98
|
+
- **Breaking.** A finding that cited one of amicus's own temporary files no longer carries it.
|
|
99
|
+
Kimi is handed its prompt as a file, so a finding could come back with `file` set to
|
|
100
|
+
`<tmp>/amicus-kimi-handshake-…/prompt.md` and `line` set to an offset into amicus's framing:
|
|
101
|
+
a path deleted before the result is read, and a line into nothing the caller supplied. Every
|
|
102
|
+
reference to a run's own staged files is now replaced by `[amicus temporary file]`, in the
|
|
103
|
+
summary, the prose lists, a finding's text and `raw_response.text`, before the result is
|
|
104
|
+
built or stored; a `file` that named one is null together with its `line`; and
|
|
105
|
+
`findings_diagnostics.reasons` reports `backend_artifact_reference_removed` at `dropped: 0`.
|
|
106
|
+
It never moves a verdict, and a failed run's error message is scrubbed the same way. Only the
|
|
107
|
+
run's own staged paths match, the files it listed and anything under Kimi's per-run handshake
|
|
108
|
+
directory, at path boundaries, so a workspace file that merely looks like one is untouched.
|
|
109
|
+
A JSON answer is judged by what it decodes to, object keys included, whatever spelling it
|
|
110
|
+
used; an answer that is prose around a JSON fragment is never decoded, so there the `\/` and
|
|
111
|
+
`\u002f` spellings of a separator are recognised and a path spelled wholly in `\uXXXX` is
|
|
112
|
+
not (#207). The new reason is the other change that moves `RESULT_FORMAT`, so a job result
|
|
113
|
+
0.4.0 stored is `job_result_incompatible` after upgrading: fetch it first
|
|
114
|
+
(`docs/MIGRATION.md`, "Upgrading from 0.4.0") (#140).
|
|
115
|
+
|
|
116
|
+
- The codex live gate, whose passing run is part of the evidence a release is tagged on, could
|
|
117
|
+
pass on a codex version amicus had never checked: it asserted only the `codex-cli` prefix, as
|
|
118
|
+
0.3.0's run on 0.154.0 showed. It now requires the installed minor to be in the built-in
|
|
119
|
+
`SUPPORTED_VERSIONS` and `amicus_backends` to report no warnings, so neither an ambient
|
|
120
|
+
`AMICUS_CODEX_SUPPORTED_VERSIONS` nor an unparseable version string can vouch for one (#113).
|
|
121
|
+
- Kimi's `carriers` disclosure on `amicus_backends(detail="full")` now names the kimi CLI's own
|
|
122
|
+
session store (observed under `~/.kimi-code/sessions`), whose files can hold the whole prompt and
|
|
123
|
+
any answer produced. amicus does not delete it, and `AMICUS_JOB_TTL`, the per-workspace cap and
|
|
124
|
+
`amicus_job_consume_result` never reach it. Kimi's `readonly_honesty` no longer says Kimi
|
|
125
|
+
"cannot MODIFY anything": read-only removes the agent's shell and write tools, not the CLI's
|
|
126
|
+
own session files. Nothing about what is written changed; only what is said about it (#179).
|
|
127
|
+
- A relative `AMICUS_STATE_DIR`, `AMICUS_CODEX_BIN`, `AMICUS_KIMI_BIN` or `AMICUS_CLAUDE_BIN` is
|
|
128
|
+
now refused instead of being resolved against the process's working directory. The server and
|
|
129
|
+
each job worker resolve configuration separately, and a worker runs from its job directory, so
|
|
130
|
+
a relative value named one place to the server and another to the worker. With a relative
|
|
131
|
+
state directory the server now refuses to start, naming the variable on stderr: falling back
|
|
132
|
+
to the default would keep whole answers somewhere the operator did not choose. A relative
|
|
133
|
+
binary override makes that backend report the override as unusable, as a missing file already
|
|
134
|
+
did. Absolute values are unchanged, and so is a leading `~` in `AMICUS_STATE_DIR`, which is
|
|
135
|
+
still expanded. `$XDG_CACHE_HOME` is different: a value that is not absolute as written,
|
|
136
|
+
`~/cache` included, is ignored and never expanded, as the XDG Base Directory specification
|
|
137
|
+
requires (#173).
|
|
138
|
+
- `config.settings()` no longer documents itself as never raising: it never raises on a
|
|
139
|
+
malformed or conflicting setting, and an unresolvable home directory is a startup failure
|
|
140
|
+
(#147).
|
|
141
|
+
|
|
23
142
|
## [0.4.0] - 2026-09-18
|
|
24
143
|
|
|
25
144
|
Across this release the discovery surface moves `amicus/0.1/schema-30`, what 0.3.0 shipped, to
|
|
@@ -715,7 +834,8 @@ per-change rather than net, so they also name intermediate states that no releas
|
|
|
715
834
|
- The tagged publish path to pypi.org has never run. Only the TestPyPI dispatch path has been exercised.
|
|
716
835
|
- Eval scenario S6 in `skills/collaborating-with-amicus/tests/scenarios.md` passed on one run (status: `pass`, validated by that run alone); an M7 follow-up run against the current skill text did not isolate the still-open F3 finding, so F3 remains open. S7 (real-host approval friction) has failed both of its recorded runs (status: `fail`); an M7 zero-spend recheck reached neither a pass nor a fail and is recorded as inconclusive, so it does not move S7's status. See their `status` fields and ADR 0012.
|
|
717
836
|
|
|
718
|
-
[Unreleased]: https://github.com/briandconnelly/amicus/compare/v0.
|
|
837
|
+
[Unreleased]: https://github.com/briandconnelly/amicus/compare/v0.5.0...HEAD
|
|
838
|
+
[0.5.0]: https://github.com/briandconnelly/amicus/compare/v0.4.0...v0.5.0
|
|
719
839
|
[0.4.0]: https://github.com/briandconnelly/amicus/compare/v0.3.0...v0.4.0
|
|
720
840
|
[0.3.0]: https://github.com/briandconnelly/amicus/compare/v0.2.0...v0.3.0
|
|
721
841
|
[0.2.0]: https://github.com/briandconnelly/amicus/compare/v0.1.0...v0.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: amicus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: One MCP server for every second-opinion model: consult, review, and delegate with the backend as a parameter
|
|
5
5
|
Project-URL: Homepage, https://github.com/briandconnelly/amicus
|
|
6
6
|
Project-URL: Repository, https://github.com/briandconnelly/amicus
|
|
@@ -73,7 +73,7 @@ The plugins launch the server from a published release tag, pinned in
|
|
|
73
73
|
"mcpServers": {
|
|
74
74
|
"amicus": {
|
|
75
75
|
"command": "uvx",
|
|
76
|
-
"args": ["--from", "git+https://github.com/briandconnelly/amicus.git@v0.
|
|
76
|
+
"args": ["--from", "git+https://github.com/briandconnelly/amicus.git@v0.5.0", "amicus-mcp"]
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -114,7 +114,7 @@ anything.
|
|
|
114
114
|
|
|
115
115
|
## The tools
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
Eighteen tools, in five groups. Discovery, previews and job
|
|
118
118
|
management are free; the verbs and their background twins invoke the selected backend and spend
|
|
119
119
|
its quota.
|
|
120
120
|
|
|
@@ -122,7 +122,7 @@ its quota.
|
|
|
122
122
|
| --- | --- |
|
|
123
123
|
| Discovery — free | `amicus_backends`, `amicus_capabilities`, `amicus_models` |
|
|
124
124
|
| Verbs — paid | `amicus_consult`, `amicus_review_changes`, `amicus_delegate`, `amicus_adversarial_review` |
|
|
125
|
-
| Previews — free | `amicus_review_changes_dry_run` (review), `amicus_delegate_dry_run
|
|
125
|
+
| Previews — free | `amicus_review_changes_dry_run` (review), `amicus_delegate_dry_run` |
|
|
126
126
|
| Background twins — paid | the four verbs again, each with an `_async` suffix |
|
|
127
127
|
| Jobs — free | `amicus_job_status`, `amicus_job_result`, `amicus_job_consume_result`, `amicus_job_list`, `amicus_job_cancel` |
|
|
128
128
|
|
|
@@ -157,6 +157,10 @@ the backend and the feature, rather than failing obscurely.
|
|
|
157
157
|
(`AMICUS_JOB_TTL`, default 24h; an expired record is removed on a later job call, not by a
|
|
158
158
|
daemon), the per-workspace cap evicts it or `amicus_job_consume_result` removes it. It can
|
|
159
159
|
quote what you sent. Your inputs themselves are never written there ([ADR 0035](docs/adr/0035-a-backend-answer-is-kept-on-the-job-record.md)).
|
|
160
|
+
- **Kimi keeps its own copy.** The kimi CLI writes its own session files (observed under
|
|
161
|
+
`~/.kimi-code/sessions`), which can hold the whole prompt and any answer produced. amicus found
|
|
162
|
+
no documented way to switch that off and does not delete them, and none of the retention controls above reach it; Codex and Claude
|
|
163
|
+
run with their session persistence disabled.
|
|
160
164
|
|
|
161
165
|
## Configuration
|
|
162
166
|
|
|
@@ -177,12 +181,13 @@ the new ones.
|
|
|
177
181
|
|
|
178
182
|
## Status and known limits
|
|
179
183
|
|
|
180
|
-
0.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
184
|
+
0.5.0 is the current release, and it is a breaking one: the deprecated `amicus_dry_run` alias is
|
|
185
|
+
gone, an answer file amicus refuses to read is now the error `answer_unavailable` rather than an
|
|
186
|
+
empty answer, and a finding that cited one of amicus's own temporary files no longer carries that
|
|
187
|
+
path. The discovery surface moved from `amicus/0.1/schema-35` to `amicus/0.1/schema-39` and stored job results from `RESULT_FORMAT` 7 to
|
|
188
|
+
`9`, so a job result 0.4.0 stored cannot be read after upgrading.
|
|
189
|
+
[`docs/MIGRATION.md`](docs/MIGRATION.md#upgrading-from-040) explains how to upgrade, and
|
|
190
|
+
[`CHANGELOG.md`](CHANGELOG.md) lists every user-visible change.
|
|
186
191
|
|
|
187
192
|
One known limit: a third-party backend distribution can load through the `amicus.backends`
|
|
188
193
|
entry-point group, but cannot yet be enabled or called. `AMICUS_BACKENDS` and the `backend`
|
|
@@ -44,7 +44,7 @@ The plugins launch the server from a published release tag, pinned in
|
|
|
44
44
|
"mcpServers": {
|
|
45
45
|
"amicus": {
|
|
46
46
|
"command": "uvx",
|
|
47
|
-
"args": ["--from", "git+https://github.com/briandconnelly/amicus.git@v0.
|
|
47
|
+
"args": ["--from", "git+https://github.com/briandconnelly/amicus.git@v0.5.0", "amicus-mcp"]
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -85,7 +85,7 @@ anything.
|
|
|
85
85
|
|
|
86
86
|
## The tools
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
Eighteen tools, in five groups. Discovery, previews and job
|
|
89
89
|
management are free; the verbs and their background twins invoke the selected backend and spend
|
|
90
90
|
its quota.
|
|
91
91
|
|
|
@@ -93,7 +93,7 @@ its quota.
|
|
|
93
93
|
| --- | --- |
|
|
94
94
|
| Discovery — free | `amicus_backends`, `amicus_capabilities`, `amicus_models` |
|
|
95
95
|
| Verbs — paid | `amicus_consult`, `amicus_review_changes`, `amicus_delegate`, `amicus_adversarial_review` |
|
|
96
|
-
| Previews — free | `amicus_review_changes_dry_run` (review), `amicus_delegate_dry_run
|
|
96
|
+
| Previews — free | `amicus_review_changes_dry_run` (review), `amicus_delegate_dry_run` |
|
|
97
97
|
| Background twins — paid | the four verbs again, each with an `_async` suffix |
|
|
98
98
|
| Jobs — free | `amicus_job_status`, `amicus_job_result`, `amicus_job_consume_result`, `amicus_job_list`, `amicus_job_cancel` |
|
|
99
99
|
|
|
@@ -128,6 +128,10 @@ the backend and the feature, rather than failing obscurely.
|
|
|
128
128
|
(`AMICUS_JOB_TTL`, default 24h; an expired record is removed on a later job call, not by a
|
|
129
129
|
daemon), the per-workspace cap evicts it or `amicus_job_consume_result` removes it. It can
|
|
130
130
|
quote what you sent. Your inputs themselves are never written there ([ADR 0035](docs/adr/0035-a-backend-answer-is-kept-on-the-job-record.md)).
|
|
131
|
+
- **Kimi keeps its own copy.** The kimi CLI writes its own session files (observed under
|
|
132
|
+
`~/.kimi-code/sessions`), which can hold the whole prompt and any answer produced. amicus found
|
|
133
|
+
no documented way to switch that off and does not delete them, and none of the retention controls above reach it; Codex and Claude
|
|
134
|
+
run with their session persistence disabled.
|
|
131
135
|
|
|
132
136
|
## Configuration
|
|
133
137
|
|
|
@@ -148,12 +152,13 @@ the new ones.
|
|
|
148
152
|
|
|
149
153
|
## Status and known limits
|
|
150
154
|
|
|
151
|
-
0.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
0.5.0 is the current release, and it is a breaking one: the deprecated `amicus_dry_run` alias is
|
|
156
|
+
gone, an answer file amicus refuses to read is now the error `answer_unavailable` rather than an
|
|
157
|
+
empty answer, and a finding that cited one of amicus's own temporary files no longer carries that
|
|
158
|
+
path. The discovery surface moved from `amicus/0.1/schema-35` to `amicus/0.1/schema-39` and stored job results from `RESULT_FORMAT` 7 to
|
|
159
|
+
`9`, so a job result 0.4.0 stored cannot be read after upgrading.
|
|
160
|
+
[`docs/MIGRATION.md`](docs/MIGRATION.md#upgrading-from-040) explains how to upgrade, and
|
|
161
|
+
[`CHANGELOG.md`](CHANGELOG.md) lists every user-visible change.
|
|
157
162
|
|
|
158
163
|
One known limit: a third-party backend distribution can load through the `amicus.backends`
|
|
159
164
|
entry-point group, but cannot yet be enabled or called. `AMICUS_BACKENDS` and the `backend`
|
|
@@ -130,7 +130,7 @@ Most amicus tools take `backend` as a required parameter (no default); pick `"co
|
|
|
130
130
|
## Behavior deltas
|
|
131
131
|
|
|
132
132
|
`amicus_dry_run` was renamed `amicus_review_changes_dry_run` (#98), and the sibling maps above point at the new name.
|
|
133
|
-
The old name
|
|
133
|
+
The old name worked as a deprecated alias in 0.3.x and 0.4.x, and 0.5.0 removed it at the end of that window (#204); the new name takes the same arguments.
|
|
134
134
|
Call the new name in anything you write now.
|
|
135
135
|
|
|
136
136
|
Review results and `amicus_review_changes_dry_run` carry a top-level `coverage` object, in the shape `codex_review_changes` returns (#65).
|
|
@@ -193,6 +193,33 @@ A `null` there means no loaded plugin declares one.
|
|
|
193
193
|
The `amicus://backends/{backend}` resource is always the full entry.
|
|
194
194
|
`amicus_capabilities(detail="contracts")` is removed: pass `include_tool_details=false` for the same rowless payload, and `detail` now selects only how much each `tool_details` row carries (`summary` is `name`, `cost`, `stability`, `backends`; `full` adds the rest, including `error_codes`).
|
|
195
195
|
|
|
196
|
+
## Upgrading from 0.4.0
|
|
197
|
+
|
|
198
|
+
The changes below are the ones an operator or caller using amicus 0.4.0 has to handle before running 0.5.0.
|
|
199
|
+
`CHANGELOG.md`'s 0.5.0 section lists every user-visible change since 0.4.0, including the ones that require no migration.
|
|
200
|
+
|
|
201
|
+
**A job result stored by 0.4.0 is no longer readable (#140, #162).**
|
|
202
|
+
`RESULT_FORMAT` moved from 7 to 9: to 8 because `findings_diagnostics.reasons` gained `backend_artifact_reference_removed`, and to 9 because `error.code` gained `answer_unavailable`, each a value a 0.4.0 reader's closed enum rejects.
|
|
203
|
+
`amicus_job_result` and `amicus_job_consume_result` return `job_result_incompatible` for a record 0.4.0 wrote.
|
|
204
|
+
Fetch or consume any stored result you still need before upgrading; the record itself stays until `AMICUS_JOB_TTL` or the per-workspace cap evicts it.
|
|
205
|
+
|
|
206
|
+
**A finding that cited one of amicus's own temporary files no longer carries it (#140).**
|
|
207
|
+
On Kimi, which is handed its prompt as a file, a finding could come back with `file` set to that temporary path and `line` set to an offset into amicus's framing.
|
|
208
|
+
Such a `file` is now null together with its `line`, the path is replaced by `[amicus temporary file]` wherever the answer's text named it, and `findings_diagnostics.reasons` says `backend_artifact_reference_removed` at `dropped: 0`.
|
|
209
|
+
A caller that treated any non-null `findings_diagnostics` as loss should read the reason: this one loses nothing a caller could have opened.
|
|
210
|
+
|
|
211
|
+
**`amicus_dry_run` is gone (#204).**
|
|
212
|
+
It was the deprecated alias of `amicus_review_changes_dry_run` since 0.3.0 (#98), with a marker in its lifecycle `_meta` and on its `amicus_capabilities` row naming 0.5.0 as its removal, and ADR 0028 removes a tool at that release.
|
|
213
|
+
Call `amicus_review_changes_dry_run` with the same arguments; the result is the same except that `tool` names the tool you called.
|
|
214
|
+
A call to the old name now returns `isError: true` with the text `Unknown tool: 'amicus_dry_run'` and no `structuredContent`: it comes from the MCP layer, so there is no amicus error envelope and no `error.code` to branch on.
|
|
215
|
+
|
|
216
|
+
**An answer file amicus refuses to read is `answer_unavailable`, not an empty answer (#162).**
|
|
217
|
+
amicus reads a backend's answer file only if it is a regular file within a 1,000,000-byte limit.
|
|
218
|
+
A refused file used to be indistinguishable from a backend that wrote nothing: a Codex review returned `invalid_json`, and a Codex consult returned `ok: true` with the summary "(the backend returned no message)".
|
|
219
|
+
Both now return `answer_unavailable` with `error.details.reason` set to `artifact_oversize`, `artifact_not_regular` or `artifact_unreadable`; it is temporary only for an unreadable file whose cause passes, such as descriptor exhaustion, and for oversize its repair is `reduce_input`.
|
|
220
|
+
A caller that treated "(the backend returned no message)" as the backend having nothing to say should branch on `ok` first, as it always should have.
|
|
221
|
+
A delegate whose summary file was refused, and which has no other whole answer from the backend, is still `ok: true` when its diff was captured, with the diff and a `meta.security_warnings` entry.
|
|
222
|
+
|
|
196
223
|
## Upgrading from 0.3.0
|
|
197
224
|
|
|
198
225
|
The changes below are the ones an operator or caller using amicus 0.3.0 has to handle before running 0.4.0.
|
|
@@ -206,7 +233,7 @@ The settings where this matters most are the ones whose default is looser than w
|
|
|
206
233
|
**A review amicus cannot parse is delivered as `unstructured` (#139).**
|
|
207
234
|
A review or critique whose answer is not one readable JSON object returned `invalid_json` or `schema_violation`; it now returns `ok: true` with `review_status: unstructured`, `verdict` and `confidence` set to `unknown`, and the whole answer in `raw_response.text` at `detail="full"`.
|
|
208
235
|
Branch on `review_status` before reading the verdict, and read that text before paying for the same review again.
|
|
209
|
-
Only an
|
|
236
|
+
Only an answer amicus could not read at all is still an error: `invalid_json` for an empty one, or `empty_response` on Kimi, which detects it first, and, from 0.5.0, `answer_unavailable` for an answer file amicus refuses to read (see "Upgrading from 0.4.0").
|
|
210
237
|
|
|
211
238
|
**A job result stored by 0.3.0 is no longer readable (#139).**
|
|
212
239
|
`RESULT_FORMAT` moved from 6 to 7 for the unstructured review result, so `amicus_job_result` and `amicus_job_consume_result` return `job_result_incompatible` for a record 0.3.0 wrote rather than manufacturing the new shape for an older run.
|
|
@@ -237,18 +264,18 @@ Poll only while `status` is `running`; a caller that read a non-null hint as "st
|
|
|
237
264
|
**A review amicus cannot parse is delivered as `unstructured` (#139).**
|
|
238
265
|
A review or critique whose answer is not one readable JSON object returned `invalid_json` or `schema_violation`; it now returns `ok: true` with `review_status: unstructured`, `verdict` and `confidence` `unknown`, and the whole answer in `raw_response.text` at `detail="full"`.
|
|
239
266
|
Branch on `review_status` before reading the verdict, and read that text before paying for the same review again.
|
|
240
|
-
Only an
|
|
267
|
+
Only an answer amicus could not read at all is still an error: `invalid_json` for an empty one, or `empty_response` on Kimi, which detects it first, and, from 0.5.0, `answer_unavailable` for an answer file amicus refuses to read (see "Upgrading from 0.4.0").
|
|
241
268
|
|
|
242
269
|
**A job result stored by 0.2.0 is no longer readable (#65, #52, #139).**
|
|
243
|
-
`RESULT_FORMAT` moved from 4 to
|
|
270
|
+
`RESULT_FORMAT` moved from 4 to 9, so `amicus_job_result` and `amicus_job_consume_result` return `job_result_incompatible` for a record 0.2.0 wrote, rather than a result whose new fields would answer for a run that never measured them.
|
|
244
271
|
Fetch or consume any stored result you still need before upgrading; the record itself stays until `AMICUS_JOB_TTL` or the per-workspace cap evicts it.
|
|
245
272
|
|
|
246
273
|
**An empty `idempotency_key` is rejected (#66).**
|
|
247
274
|
The four `_async` tools accepted `""`; every paid tool now rejects it before spending as `invalid_arguments` (`minLength: 1`).
|
|
248
275
|
Omit the key instead.
|
|
249
276
|
|
|
250
|
-
**`amicus_dry_run` is a deprecated alias (#98).**
|
|
251
|
-
Call `amicus_review_changes_dry_run
|
|
277
|
+
**`amicus_dry_run` is a deprecated alias (#98), and 0.5.0 removed it (#204).**
|
|
278
|
+
Call `amicus_review_changes_dry_run`.
|
|
252
279
|
|
|
253
280
|
**Two workspace errors carry no `repair` (#42).**
|
|
254
281
|
`invalid_workspace_root` and `workspace_outside_roots` return `error.repair: null`, because no call can supply the caller's directory; read `details.field` and `details.candidate_roots` instead.
|
|
@@ -83,6 +83,46 @@ Check two things by reading the file.
|
|
|
83
83
|
First, its install section must not still carry the pre-release note saying amicus is unpublished and that the instructions work from the first tagged release onward — once you are releasing, that sentence is false and must be removed in the release PR.
|
|
84
84
|
Second, its "Status and known limits" section must not claim anything the release contradicts, in particular the line stating amicus has never been published to PyPI.
|
|
85
85
|
|
|
86
|
+
### The backend CLIs are current and checked
|
|
87
|
+
|
|
88
|
+
A release vouches for the `codex`, `kimi` and `claude` that are installed when its rule-20 evidence is recorded, and those CLIs release far more often than amicus does.
|
|
89
|
+
Do this last among the preconditions, immediately before the evidence run in the release sequence, because a check done a week earlier describes CLIs that have since moved.
|
|
90
|
+
|
|
91
|
+
First bring each CLI to its latest release on the machine that will record the evidence.
|
|
92
|
+
`codex` and `claude` are npm packages, so `npm view @openai/codex version` and `npm view @anthropic-ai/claude-code version` name the latest and the usual npm upgrade installs it.
|
|
93
|
+
`kimi` is Kimi Code, which updates itself: run `kimi upgrade`.
|
|
94
|
+
It is also published to npm, so `npm view @moonshot-ai/kimi-code version` names its latest; PyPI's `kimi-cli` is a different distribution whose version says nothing about it.
|
|
95
|
+
Expect a major version number to mean less than it says: 0.43.1 was followed directly by 2.0.0, whose only major change was a command that opens the desktop app's page.
|
|
96
|
+
|
|
97
|
+
Then run the mechanical half, which spends nothing: it runs `--version`, `--help` and each backend's free login probe, and sends no prompt.
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
uv run python scripts/check_backend_compat.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Yes is exit status 0, with each backend reported as installed and authenticated, no `FAIL` line, and `same flags` against its newest committed capture.
|
|
104
|
+
A `FAIL` line names what is wrong: a CLI that is not installed or not authenticated, a `--help` that could not be read, an installed version outside the supported versions of the contract amicus ships (read from the contract itself, so a `AMICUS_*_SUPPORTED_*` override in the environment cannot vouch for it), any warning `amicus_backends` would raise, a flag amicus always sends that `--help` no longer declares as an option, an installed prerelease or development build (`0.155.1-beta.1`, `0.155.1+local`), which is not the published release even where its numbers match, an installed version behind the latest release npm reports, or an npm lookup that failed.
|
|
105
|
+
It fails closed: help that cannot be read, or a latest release that cannot be looked up, is a failure rather than a pass, and `--offline` exists to say out loud that the lookup was skipped, which is not good enough for a release.
|
|
106
|
+
A flag counts only where `--help` declares it as an option, never where another option's description happens to name it.
|
|
107
|
+
`FLAGS DIFFER` is not by itself a failure, since upstream adds flags constantly, but every removed flag must be looked up in that backend's `contract.py` before going on.
|
|
108
|
+
`latest unknown` fails the check for every backend, because all three are on npm and it means the lookup failed rather than that the version matched.
|
|
109
|
+
|
|
110
|
+
When a CLI's version has no capture of its own, commit one with the change that adds support for it, so the next release has something to compare against.
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
uv run python scripts/check_backend_compat.py --write
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Adding a minor to a backend's `SUPPORTED_VERSIONS` is its own PR, made the way #112 and #194 were: a zero-spend comparison against the previous minor, recorded in the PR.
|
|
117
|
+
`tests/test_codex_contract.py`, `tests/test_kimi_contract.py` and `tests/test_claude_contract.py` then hold every committed capture to the flags the contract sends.
|
|
118
|
+
|
|
119
|
+
The script cannot do the other half, which AGENTS.md rule 18 requires before every release: the carrier re-check.
|
|
120
|
+
Rule 18 exempts a backend's native prompt carrier only where no documented or observed way to avoid it has been found on the CLI release being validated.
|
|
121
|
+
For each of the three versions the script printed, read that CLI's `--help` and its release notes since the previous amicus release (for kimi, the GitHub releases of `MoonshotAI/kimi-code`) for anything that would avoid a listed carrier: a flag or setting that stops kimi keeping a session, a way to hand kimi its prompt without a file, or a codex channel for developer instructions other than `-c` on argv.
|
|
122
|
+
If one has appeared, the exemption no longer holds for that carrier, and using the new mechanism is a change to make before this release rather than after it.
|
|
123
|
+
If none has, say so in the release PR, naming the three versions, so the next reader can see the looking was done and on what.
|
|
124
|
+
The probe that stands behind kimi's session store, and what it did not test, is `docs/kimi-help/0.43.1/FINDINGS.md`.
|
|
125
|
+
|
|
86
126
|
## The release sequence
|
|
87
127
|
|
|
88
128
|
Rules 19 and 20 together shape this sequence, and a future maintainer should not "simplify" it back.
|
|
@@ -110,6 +150,7 @@ The tag therefore deliberately points at a commit that is in `main`'s history bu
|
|
|
110
150
|
Record the branch tip's SHA; call it the release commit, and note it well — it is the commit that gets tagged, and it will not be `main`'s head after the next step.
|
|
111
151
|
If the PR C branch gains any commit after this point — an "Update branch" click, or a review pushing a change — this step must be redone from the new tip: the evidence would otherwise cover a commit that is no longer what step 4 actually merges.
|
|
112
152
|
The evidence run below spends real quota on all three backends; a maintainer who has to redo this step must not reuse the earlier record, even though re-spending that quota is tempting.
|
|
153
|
+
Immediately before it, run the backend-CLI precondition above, `uv run python scripts/check_backend_compat.py` and the rule-18 carrier re-check, because the evidence vouches for exactly the CLI versions installed at this moment.
|
|
113
154
|
Run `uv run python scripts/record_live_gate_evidence.py`.
|
|
114
155
|
The script itself forces `AMICUS_REQUIRE_LIVE=1` into each backend's subprocess environment, so prefixing the command with it is optional; its own usage string documents `AMICUS_REQUIRE_LIVE=1 uv run python scripts/record_live_gate_evidence.py`, and either form runs the same live gates.
|
|
115
156
|
This spends real quota on all three backends and requires the maintainer's authorization in the session where it runs.
|
{amicus-0.4.0 → amicus-0.5.0}/docs/adr/0033-an-unreadable-review-answer-is-delivered-unstructured.md
RENAMED
|
@@ -39,6 +39,7 @@ It would also keep a result that holds the backend's whole answer behind `ok: fa
|
|
|
39
39
|
It stays `invalid_json` with the shared table's `retry_then_report`, which is honest there: an empty answer is the case a retry can plausibly change.
|
|
40
40
|
Kimi detects an empty answer before a result is built and reports it as `empty_response`, with the same repair; that code was emitted but missing from every tool's `error_codes`, and is now listed on each paid tool that can select Kimi.
|
|
41
41
|
An answer file amicus refuses to read, because it is not a regular file or exceeds the artifact cap, also reaches this path as empty, so the message says amicus read no answer rather than that the backend returned none.
|
|
42
|
+
That sentence is superseded by ADR 0036 (#162): a refused answer file is `answer_unavailable`, and only a genuinely empty answer reaches this path.
|
|
42
43
|
`schema_violation` is no longer a review outcome and leaves the review tools' `error_codes`.
|
|
43
44
|
That also settles #116's point about a deterministic `invalid_json`: the deterministic cases now reach the caller as `unstructured`, carrying no retry advice.
|
|
44
45
|
|
|
@@ -51,3 +51,4 @@ The boundary is checked by carrier, not by semantic derivation: `tests/test_sync
|
|
|
51
51
|
Statements that were overbroad under the exception are narrowed to the input half: `request.py`'s module docstring and the design spec's "Jobs and tasks" section.
|
|
52
52
|
`FINGERPRINT` moves to schema-35 for the description text; `RESULT_FORMAT` does not move, since nothing stored changes.
|
|
53
53
|
Kimi's own session log, which keeps the full prompt and answer outside amicus's retention, is a separate disclosure gap filed as #179.
|
|
54
|
+
That gap was closed by disclosure, not deletion: Kimi's `CARRIERS` and read-only statement now name the session store, and `docs/kimi-help/0.43.1/FINDINGS.md` records why amicus does not remove it.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# ADR 0036: an answer file amicus refuses to read is `answer_unavailable`
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted (2026-09-19)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
amicus reads a backend's answer file through a bounded reader: `O_NOFOLLOW`, regular files only, at most 1,000,000 bytes (ADR 0009).
|
|
8
|
+
The reader returned an empty string for a file it refused, and the run loop dropped empty texts, so a refusal was indistinguishable from a backend that wrote nothing (#162).
|
|
9
|
+
ADR 0033 recorded the consequence for reviews, `invalid_json` with a message hedged to cover both cases.
|
|
10
|
+
It did not record the worse one: a Codex consult in the same state returned `ok: true` with the summary "(the backend returned no message)".
|
|
11
|
+
|
|
12
|
+
The reader also made a single `read` call, which may return short, so a prefix of an answer could be delivered as the whole of it.
|
|
13
|
+
|
|
14
|
+
## Decision
|
|
15
|
+
|
|
16
|
+
**A refusal is its own error, `answer_unavailable`.**
|
|
17
|
+
No code in the closed catalog was honest for it.
|
|
18
|
+
`empty_response` is declared per feature and listed only where Kimi can be selected, it means "exit 0 with no answer", and it repairs with a retry, which is wrong for a deterministic oversize.
|
|
19
|
+
`invalid_json` is wrong for consult and delegate, `internal_error` says amicus broke, and `input_too_large` and `context_too_large` are about input.
|
|
20
|
+
A Codex design consult reached the same conclusion, and the maintainer chose a new code over reusing one.
|
|
21
|
+
|
|
22
|
+
**The code is amicus's own, not the SDK's.**
|
|
23
|
+
It lives in `LOCAL_CODES` and `errors._LOCAL_RULES`, because `UNIVERSAL_CODES` is the intersection the sibling bridges emit and this comes from amicus's orchestration (ADR 0030).
|
|
24
|
+
|
|
25
|
+
**`error.details.reason` is a fixed token, and nothing else identifies the file.**
|
|
26
|
+
`artifact_oversize` carries `limit_bytes`, and `actual_bytes` when `fstat` knew the size; `artifact_not_regular` and `artifact_unreadable` stay apart, because one is a security invariant holding and the other an operational failure.
|
|
27
|
+
The path, an errno and exception text never appear: a delegate's answer path is model-controlled (ADR 0009).
|
|
28
|
+
Oversize and not-a-regular-file are never temporary: oversize repairs with `reduce_input`, the other with `inspect_and_retry`.
|
|
29
|
+
`artifact_unreadable` is temporary only when the cause was: descriptor or memory exhaustion or an interrupted call (`EMFILE`, `ENFILE`, `ENOMEM`, `EINTR`, `EAGAIN`) passes, so the identical call may succeed and the repair is `retry_after_delay`, while a permission or I/O error is about the file and repairs with `inspect_and_retry`.
|
|
30
|
+
The errno decides and stays internal; a second Copilot review caught the first version, which called every refusal permanent.
|
|
31
|
+
A retry is a new paid run either way, since the refused run itself finished, and the repair prose says so.
|
|
32
|
+
|
|
33
|
+
**An absent or empty file is not a refusal.**
|
|
34
|
+
The backend writing nothing is a different fact from amicus refusing what it wrote, and keeps its old meaning.
|
|
35
|
+
|
|
36
|
+
**Only a refusal of an answer artifact counts.**
|
|
37
|
+
`PreparedRun.answer_artifacts` names them; Codex stages its input schema in `artifact_paths` too, and refusing that says nothing about the answer.
|
|
38
|
+
|
|
39
|
+
**Every other failure wins, with one exception.**
|
|
40
|
+
A non-zero exit, a timeout, a missing binary and any failure an inspector reports are the more accurate account.
|
|
41
|
+
The exception is a clean exit an inspector diagnosed as `empty_response`: the refusal is why the run looked empty, so it is what is reported.
|
|
42
|
+
The first draft superseded any clean-exit failure, which would have hidden an inspector's auth or rate-limit finding; a Codex review and a Copilot review both caught it.
|
|
43
|
+
|
|
44
|
+
**Another channel is a substitute only if it was captured whole.**
|
|
45
|
+
Kimi's stream can carry the answer when its answer file is refused.
|
|
46
|
+
It is delivered, with a `meta.security_warnings` entry, only when the capture was neither truncated nor failed (`CommandRun.output_truncated` and `capture_failed`), because a damaged capture can lose the true final message while an earlier one still parses.
|
|
47
|
+
That check is its own: `meta.truncated` reports a bounded review input or delegate diff, not stream capture, so a delivered stream answer can sit beside `meta.truncated: true` when the diff was over its limit.
|
|
48
|
+
|
|
49
|
+
**A delegate keeps its diff.**
|
|
50
|
+
The diff is captured from the worktree, not read from the answer file, so it is still the honest primary result.
|
|
51
|
+
A whole stream answer comes first: a Kimi delegate whose stream survived keeps the backend's own summary and `raw_response.text`, as above.
|
|
52
|
+
Only when no such answer exists is the summary amicus's own, and then it says so, `raw_response.text` stays null rather than carry amicus's words as the backend's, and the summary makes no claim about the diff's completeness, which `meta.truncated` and `meta.redacted_paths` describe.
|
|
53
|
+
With no diff either, it is `answer_unavailable`.
|
|
54
|
+
|
|
55
|
+
**Nothing is truncated to fit.**
|
|
56
|
+
A truncated structured consult would fall into the prose branch and be delivered as a successful answer, and a truncated review cannot be parsed.
|
|
57
|
+
|
|
58
|
+
**The reader reads to the end.**
|
|
59
|
+
It loops up to one byte past the cap, which bounds memory, tolerates a short `read`, and notices a file that grew after `fstat`.
|
|
60
|
+
|
|
61
|
+
## Consequences
|
|
62
|
+
|
|
63
|
+
`error.code` is a closed enum, so a reader of the previous result format rejects a stored error carrying the new value: `RESULT_FORMAT` moves 8 to 9, and `FINGERPRINT` to schema-37.
|
|
64
|
+
`tools/list` does not carry error codes, so its measured size does not move.
|
|
65
|
+
The code is listed on every paid tool that can select a backend answering through a file, and not on adversarial review, which only Claude runs and which answers on stdout.
|
|
66
|
+
ADR 0033's sentence about a refused answer file is superseded by this record.
|
|
67
|
+
|
|
68
|
+
Not established: whether a real backend's answer file can reach the cap.
|
|
69
|
+
Stdout is capped separately at 10 MB, and the short-read fix is a property of `read(2)` rather than an observed failure.
|