# D4D generic-arm generation prompt — v2

**This is v1 plus three uniform decision rules, and nothing else.** The
substitution fields, outputs, header block, constraints and the four original
rules are byte-identical to
`src/download/prompts/d4d_generic_arm_prompt.md`; a test asserts that the only
difference is the block marked `ADDED IN v2`.

## Why v2 exists

Fitness scoring against the schema (see `evidence_score.py`) flagged 131 defective
fields across all four projects in the v1 generic runs, in three classes:

| class | AI_READI | CHORUS | CM4AI | VOICE |
|---|---|---|---|---|
| form — multivalued slots collapsed into one object | 14 | 12 | 16 | 8 |
| substance — a pointer or a non-answer instead of the content | 17 | 12 | 5 | 6 |
| target — the neighbouring field answered instead | 6 | 12 | 18 | 5 |

Every class hits every project, and the affected slots overlap between them.
These are failures in how the schema is used, not facts about any dataset, so the
correction can be stated without naming a project — which is exactly what makes
it admissible here.

## Why these three additions are generic and not priming

Measured against the taxonomy in `.claude/commands/d4d-full-core.md`:

- they apply identically to every project, naming no project, dataset or input
  set;
- they state no target count, no expected density, and no expected relationship
  to any other arm — so they are decision rules, not outcome expectations;
- they concern the schema, which every arm shares.

The project-specific forms of the same corrections are **excluded on purpose**.
"CM4AI has ~47 creators, list them individually" is factual disambiguation and
belongs in the tuned arm, and its "~47" is an outcome expectation that belongs in
neither. "Earlier runs collapsed `intended_uses`" is a quality warning. If a
correction could only be stated by naming a dataset, that is the signal it does
not belong in this file.

## What is NOT in this file, deliberately

The prediction that these rules reduce form/substance/target counts. That
sentence would be an outcome expectation, and writing it here would instruct the
model to produce the result the re-run is supposed to test. It lives in
`notes/generic_v2_analysis_plan.md`, registered before any generation runs.

## Relationship to v1

v1 is not superseded and must not be edited. The 2026-07-28 generic series was
produced under it, and it remains the baseline this version is measured against.
Runs under this file take a distinct label (`-generic-v2`).

The **generic** arm's defining property: every Grand Challenge and every arm
receives *this exact text*. Only the mechanical fields below are substituted —
project name, arm label, method, input bundle, output paths. Nothing here is
specific to a GC, a dataset, or an input set.

That is the whole point. The comparator arm (**tuned**) carries GC-specific and
input-set-specific content, and the difference between the two is what the study
measures. Any GC-specific sentence added here silently converts the generic arm
into a third condition and destroys the comparison — as happened to the
2026-07-28 `-deprimed` series, which removed expectation statements but retained
per-GC factual notes and is therefore neither generic nor tuned.

Uniform decision rules are permitted and belong here, because applying one rule
identically to every GC is part of the method rather than tuning. What is
forbidden is a rule, fact, warning, or expectation that applies to some GCs and
not others.

**Editing rule:** a change to this file changes the generic arm for every
project at once. Re-run the whole arm after editing it; do not edit it to fix
one project's output.

---

## Substitution fields

| Field | Meaning |
|---|---|
| `{PROJECT}` | AI_READI, CHORUS, CM4AI, or VOICE |
| `{ARM}` | arm display name, e.g. `BASELINE (input documents only)` |
| `{METHOD}` | output method directory, e.g. `claudecode_agent` |
| `{BUNDLE}` | the single declared input bundle path |
| `{LABEL}` | run label, e.g. `2026-07-28_claude-opus-5-generic_rep1` |
| `{MANIFEST_LINE}` | the `# Source manifest:` header line for this arm |
| `{RUNTIME}` | what is executing this — `Claude Code` or `Claude API (direct)` |
| `{PROVIDER}` | `Anthropic`, or the proxy actually reached |
| `{MODEL}` | the model identifier the request will carry |

The last three used to be hardcoded to `Claude Code` / `Anthropic` /
`claude-opus-5[1m]`. When the API path reused this prompt verbatim, every record
it produced claimed to have been generated by Claude Code on a model it never
touched — a false provenance claim in the artifact itself.

---

## Prompt body

Generate paired full and core D4D records for the {PROJECT} project.

READ FIRST, IN THIS ORDER, AND FOLLOW EXACTLY:

1. `.claude/agents/d4d-provenance-guard.md` — the factual evidence boundary.
   Enforce it in every phase.
2. `.claude/commands/d4d-full-core.md` — the four-phase playbook.

Execution mode: four-phase project agent. Phase 1 full generation, Phase 2 core
generation, Phase 3 source/provenance audit, Phase 4 strict reconciliation.
Phase 2 must wait for a validated Phase 1 file.

VERSION LABEL — use verbatim in every output path: {LABEL}

ARM: {ARM}

DECLARED INPUT BUNDLE — your only source of dataset facts:
    {BUNDLE}

Full schema: `src/data_sheets_schema/schema/data_sheets_schema_all.yaml` (class
`Dataset`)
Core schema: `src/data_sheets_schema/schema/data_sheets_schema_core_all.yaml`
(class `CoreDataset`)

OUTPUTS — do not write outside these three:

- Full:   `data/d4d_concatenated/{METHOD}/{LABEL}/{PROJECT}_d4d.yaml`
- Core:   `data/d4d_concatenated/{METHOD}_core/{LABEL}/{PROJECT}_d4d_core.yaml`
- Report: `data/d4d_concatenated/{METHOD}_core/{LABEL}/{PROJECT}_reconciliation.md`

HEADER BLOCK — use exactly:

    # D4D Datasheet for {PROJECT} Dataset
    # Generation Method: schema-grounded agentic, phase 1
    # Agent runtime: {RUNTIME}
    # Provider: {PROVIDER}
    # Model: {MODEL}
    # Mode: four-phase project agent, generic-v2 prompt
    # Prompt: src/download/prompts/d4d_generic_arm_prompt_v2.md (identical for all projects)
    # Arm: {ARM}
    # Source bundle: {BUNDLE}
    {MANIFEST_LINE}
    # Schema: src/data_sheets_schema/schema/data_sheets_schema_all.yaml
    # Prior D4D factual reuse: prohibited
    # Temperature: 0.0
    # Generated: {DATE}

CORE HEADER BLOCK — use exactly (it is not the full-record block with two
words changed; four lines differ and two have no counterpart above):

    # D4D Core Datasheet for {PROJECT} Dataset
    # Generation Method: schema-grounded agentic, phase 2
    # Agent runtime: {RUNTIME}
    # Provider: {PROVIDER}
    # Model: {MODEL}
    # Mode: four-phase project agent, generic-v2 prompt
    # Prompt: src/download/prompts/d4d_generic_arm_prompt_v2.md (identical for all projects)
    # Arm: {ARM}
    # Source bundle: {BUNDLE}
    # Sources: {BUNDLE} + data/d4d_concatenated/{METHOD}/{LABEL}/{PROJECT}_d4d.yaml
    {MANIFEST_LINE}
    # Schema: src/data_sheets_schema/schema/data_sheets_schema_core_all.yaml
    # Prior D4D factual reuse: prohibited
    # Temperature: 0.0
    # Generated: {DATE}
    # Phase 4 reconciliation: completed

`# Sources:` is required, not decorative: it is what ties a core record to the
full record it was projected from, and the provenance guard checks for it. Write
`# Phase 4 reconciliation: completed` only once phase 4 has actually run.

AFTER Phase 4, write a LIVE provenance record:

    poetry run d4d provenance record --project {PROJECT} --method {METHOD} --label {LABEL} --input-bundle {BUNDLE}

VALIDATE both files before finishing:

    poetry run linkml-validate -s src/data_sheets_schema/schema/data_sheets_schema_all.yaml -C Dataset <full>
    poetry run linkml-validate -s src/data_sheets_schema/schema/data_sheets_schema_core_all.yaml -C CoreDataset <core>

ABSOLUTE CONSTRAINT — do not read, open, grep, or consult any previously
generated D4D record, from any arm, any label, or any date. This includes
everything under `data/d4d_concatenated/` and any `*_crate_d4d.yaml` or
`*_crate_mapped_d4d.yaml` under `data/ro-crate_packages/`. Your only factual
inputs are the declared bundle above and the schema files. Prior-D4D reuse is a
defect under the provenance guard.

UNIFORM DECISION RULES — these apply identically to every project and every arm:

- Populate a slot only where the declared bundle supports it. Prefer omission
  over inference: an absent slot is a correct answer when the evidence is
  absent, and a plausible guess is not.
- Where the declared bundle contains sources that disagree, represent what the
  evidence states rather than silently selecting one. Do not merge distinct
  entities into a single claim.
- `Dataset` admits one referent. Choose the one the declared bundle best
  supports, state that choice in the reconciliation report, and hold to it
  consistently across both records.
- There is no target slot count, no expected density, and no expected
  relationship to any other arm or project. Apply your own judgment about what
  the evidence supports.

--- ADDED IN v2 ---

- When a slot's declared range is multivalued, emit one object per distinct
  entity. Collapsing several entities into a single object — several creators in
  one Creator, several uses in one intended_use — populates the slot without
  representing what it declares.
- Populate a slot with the information the field asks for, not with a pointer to
  where that information lives, and not with a statement that it is pending or
  absent. A value recording that documentation exists elsewhere has not answered
  the field; omit the slot instead.
- Read the slot's description before populating it. Where the evidence answers a
  neighbouring field — the access route rather than the distribution formats,
  the release cadence rather than the future-use impacts — put it in the field it
  answers, or omit it.

--- END ADDED IN v2 ---

RETURN: full slot count, core slot count, whether both validated, and the
reconciliation outcome. Return data, not prose.
