# AI Onboarding Acceptance

This file defines machine-verifiable merge-ready gates for AI/coordinator provider onboarding.

## Manifest Gates

- `docs/ai-onboarding/access-reviews/<provider>.yml` exists, passes `docs/ai-onboarding/access-review.schema.json`, has `status: approved`, and has `may_continue: true`.
- `PYTHONPATH=src python3 -m pytest tests/unit/test_provider_manifest_schema.py -q`
- `PYTHONPATH=src python3 -m pytest tests/unit/test_manifest_bundle_sync.py -q`
- Manifest status for merge-ready provider is `ready` or stricter sync-back status accepted by `tests/unit/_manifest_sync.py`.
- `docs/ai-onboarding/known-providers.yml` entry contains an existing `manifest_path`.

## Fixture Gates

- Every required DOI purpose in `docs/ai-onboarding/provider-manifest.schema.json` is present in `fixtures.doi_samples`.
- `structure`, `figure`, and `references` DOI values are non-null.
- Every `main_path` step has a `route_contract` entry with non-empty success requirements.
- `PYTHONPATH=src python3 -m pytest tests/unit/test_provider_route_contract.py -q`
- Every non-null fixture purpose has a matching `markdown_contract` entry with positive and negative Markdown assertions.
- Capture failures use structured JSON stderr with `code` from `failure-recovery.md`.
- `UNSUITABLE_DOI_SAMPLE` changes only `fixtures.doi_samples.<purpose>` for the failed purpose.

## Implementation Gates

- Provider-local pytest from `briefs/implement-provider.yml` passes.
- `PYTHONPATH=src python3 -m pytest tests/unit/test_provider_markdown_review_contract.py -q`
- `PYTHONPATH=src python3 -m pytest tests/unit/test_provider_route_contract.py -q`
- `PYTHONPATH=src python3 -m pytest tests/unit/test_provider_bundle_completeness.py tests/unit/test_provider_owner_reuse.py -q`
- `PYTHONPATH=src python3 -m pytest tests/unit/test_golden_corpus_adapters.py tests/unit/test_provider_benchmark_samples.py tests/devtools/test_golden_criteria_live.py -q`
- `python3 scripts/validate_extraction_rules.py`
- `manifest_sync_back.py` is the only writer for `extraction_hints` and `success_criteria` sync-back fields.
- New provider integration must be synchronized through the provider fact sources: register a golden corpus adapter when golden replay fixtures exist, expose MCP provider status through the bundle-derived catalog, keep benchmark samples covered for official providers, and let live review support derive from provider capabilities.
- Shared integration runs after provider implementation and before snapshot generation; coordinator-owned changes must be traced to manifest facts, bundle sync-back, fixture replay, or provider-local test evidence.
- Local operator acceptance may use `python3 scripts/onboard_from_manifests.py run-checks --provider <provider> --all-local`; this command does not trigger GitHub CI.
- Full local orchestration may use `python3 scripts/onboard_from_manifests.py run --manifest docs/ai-onboarding/manifests/<provider>.yml --until merge-ready`; worker dispatch must go only through `PROVIDER_ONBOARDING_AGENT_CLI`.

## Markdown Review Gates

- `docs/ai-onboarding/reviews/<provider>.yml` exists and passes `docs/ai-onboarding/provider-review.schema.json`.
- `scripts/bootstrap_review_artifact.py` output is only a draft gate helper; acceptance still requires `markdown_semantic_reviewed: true` after real semantic review.
- Every non-null `fixtures.doi_samples.<purpose>` and every `extra_fixtures` item has a review artifact entry with `baseline_markdown_path`, `baseline_markdown_sha256`, `review_notes`, `sample_representative: true`, `markdown_semantic_reviewed: true`, `issues`, `assertions`, and `fixes`.
- `issues` and `fixes` use stable object ids; every fix references existing `issue_ids` and names at least one provider-local test.
- Review artifact values must not contain `TODO`, `TBD`, or `unknown` placeholders.
- Every non-null `fixtures.doi_samples.<purpose>` is represented in `tests/unit/test_<provider>_provider.py` by purpose name or DOI slug.
- Provider-local tests should prefer exact markers of the form `markdown-review: purpose=<purpose> doi=<doi>` next to the assertions generated from `markdown_contract`.
- Provider-local tests do not contain scaffold skipped placeholders or Markdown review-loop placeholders.
- Provider-local tests include at least one positive Markdown assertion and at least one negative site-chrome / access-noise / boilerplate assertion.
- Worker completion summary is secondary; acceptance uses `docs/ai-onboarding/reviews/<provider>.yml` as the durable source.

## Live Review Gates

- Browser/CDN-risk providers run provider subset live review, for example `PAPER_FETCH_RUN_LIVE=1 python3 scripts/run_golden_criteria_live_review.py --providers mdpi`.
- Live review validates `FetchEnvelope.source` against manifest `route_sources`; silent degradation from an expected HTML/XML source to PDF fallback is an acceptance issue unless that sample is explicitly a fallback sample.
- Live review reuses manifest `markdown_contract` positive and negative assertions to auto-classify content-missing and noise-leak issues before manual semantic signoff.

## Automation Gates

- `docs/ai-onboarding/automation-roadmap.md` documents which onboarding steps are automatable and which remain operator-controlled.
- `capture-fixtures` uses `--auto-via --fail-fast`; browser route selection must be allowed by access review.
- `scaffold` uses `--merge-existing=safe` and must not overwrite divergent existing provider files.
- `manifest-sync-back` uses `--sync-docs` and only updates known marker/provider entries, not unmarked human prose.
- Worker forbidden-path changes fail with `WORKER_MODIFIED_FORBIDDEN_FILE`.

## Drift Gates

- `PYTHONPATH=src python3 -m pytest tests/unit/test_human_docs_drift.py -q`
- `git grep -n "Human reference only" -- docs/provider-development.md docs/adding-a-provider.md`
- `git grep -n "docs/ai-onboarding" -- docs/provider-development.md docs/adding-a-provider.md`
- Legacy human-guide banned-token grep over `docs/ai-onboarding/` returns no matches.

## Structured Error Gates

Acceptance fails when any tool reports a JSON stderr `code` that maps to `retryable: false` in `failure-recovery.md`.

Acceptance remains blocked after retry budget exhaustion for:

- `DISCOVERY_RETRY_EXHAUSTED`
- `TASK_RETRY_EXHAUSTED`
- `MANIFEST_PROVIDER_CONFLICT`
- `BROWSER_RUNTIME_REQUIRED`
