aiml
SearchMy learning
Menu

Lesson 21 of 36Module 8

Handle conflicting documentation

Gate explicit contract claims before generation

Filter synthetic developer documentation by the requested version, compare explicit contract directives, and withhold answer requests when claims conflict.

Prerequisites

The preceding corpus, retrieval and context modules; source identity and version filtering.

By the end, you can

  • Bind supported directive claims to exact source versions and quoted spans.
  • Distinguish agreement, same-version conflict and missing claims.
  • Prepare a cited request only when every eligible source supplies the same supported claim.
Runtime
Python 3.11+; standard library only
Dependencies
Standard library only; preserved answer replay or synthetic source fixtures, no provider SDK

Lab code, tests and fixtures (ZIP, 2.8 MB)Quiz check your understanding

Progress is saved in this browser.

Build a pre-generation gate for explicitly structured contract claims in synthetic developer documentation. It selects the requested version, compares supported directive values and prepares a cited request only when they agree. No model generates an answer in this lab.

When you need this. Use it when candidate documentation can describe different versions or conflicting rules and the application needs a clear decision about whether to prepare an answer request or stop for clarification.

Prerequisites. Review version filtering and source identity. The supplied Quill SDK and its contract directives are original synthetic teaching fixtures, separate from the preceding context fixture and the preserved model baseline. Quill is not a claimed real SDK.

The corpus changes here so conflicts can be represented as explicit, testable directives. These Quill claims are a separate contract exercise, not extra pages added to the Python index. The gate compares declared values; it is not a semantic contradiction detector for arbitrary prose. Carry its version-selection rule into an application only after defining that application’s own claim schema.

Pinned syntheticdeveloper docsRequestedAPI versionSelect exact versionParse supportedcontract directivesSamevalue?Cited answer requestNo generation callConflict or missing claimNo answer requestdocsversioneligible docsclaimsagreedisagreemissingdata flowfailure
The gate compares explicit directive values in the synthetic fixture. It does not infer contradictions in arbitrary prose, choose a winner by recency, or generate an answer. Missing or conflicting in-scope claims prevent request preparation.

Select the requested version before comparing claims

The caller supplies controlled candidate source IDs, a requested API version and a claim key. The local loader verifies pinned source bytes. The gate then keeps exact version matches; a newer-looking version is not an authority rule or a fallback for a missing requested version.

The recorded wrong-version case excludes an incompatible newer source and uses only the requested version. This is a source-eligibility decision. It does not decide whether two remaining sources agree.

Parse only the supported directive grammar

The fixture expresses contracts as exact whole-line directives such as @quill create_copy existing_path=refuse. The parser recognizes only the documented operation, keys and enumerated values. It records the exact quote, line and character offsets, raw source hash, version and document revision beside each claim.

This makes the proposition being compared explicit. Ordinary paragraphs remain context; the program does not infer their meaning, extract arbitrary claims or detect natural-language contradictions. A source that contains no requested directive leaves the claim unsupported; its silence does not imply agreement.

Invalid directive. Malformed directive-like lines, unknown values, unsupported operations or keys, and duplicate directives raise DirectiveError. The parser does not convert an unfamiliar rule into a guessed known value. Only eligible sources are parsed for claims, although pinned-byte loading still checks the manifest’s source files.

Withhold the request when in-scope claims disagree

When every eligible source supplies the requested claim and all values agree, the result is ready. Its answer_request retains all supporting quotes and source identities. The request has not been dispatched, counted against a model context budget or answered by a model.

Same-version conflict. Different values for the same supported proposition return conflict and no answer request. Both claims remain available for inspection. Candidate order, URL appearance and recency do not silently pick a winner.

The comparison is over the fixture’s explicit directives. Agreement between those values does not prove that all surrounding prose is consistent, that the sources are authoritative, or that a future answer will be correct.

Controlled caseGate statusReasonAnswer request
newer-wrong-version-excludedreadyeligible_directives_agreeprepared
compatible-agreementreadyeligible_directives_agreeprepared
same-version-conflictconflictsame_version_directives_disagreewithheld
absent-versionnot_in_docsno_eligible_versionwithheld
missing-claimnot_in_docsrequested_claim_missingwithheld
partial-missing-claimnot_in_docsrequested_claim_missingwithheld
unknown-directive-valuerefusedunknown_directive_valuewithheld
malformed-directiverefusedmalformed_directivewithheld

Keep missing claims separate from agreement

Missing claim. An absent requested version, empty candidate list or missing requested key returns not_in_docs with no request. If one eligible source has a claim and another eligible source lacks it, the conservative policy still withholds the request. It does not discard the incomplete source merely to produce agreement.

Changed source. Editing a pinned source without updating its manifest raises IngestionError during loading. Updating source bytes and their manifest deliberately would create a different input revision; the gate would need to run again against that revision.

Request and source shape checks also reject duplicate or unknown candidate IDs, unsupported requested claims and missing version metadata. These are consistency boundaries for the local fixture, not an authorization or publisher-authentication system.

Execute the conflict gate

Download the complete lab. It contains the original synthetic documents, reused pinned-source loader, directive parser, gate, tests and actual output.

conflicts.pySource · pythonDownload
"""Gate explicit synthetic contract directives; not a general prose detector."""
import hashlib
import json
from pathlib import Path
import re
from load_documents import load_documents

VALUES={'existing_path':{'refuse','overwrite'},'close_required':{'yes','no'}}
DIRECTIVE=re.compile(r'@quill ([a-z_]+) ([a-z_]+)=([a-z_]+)')


class DirectiveError(ValueError):
    """Eligible source directives cannot satisfy the narrow parser contract."""


class GateError(ValueError):
    """The controlled request is invalid."""


def digest(value):
    return hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode('utf-8')).hexdigest()


def claims_from_source(source):
    revision=digest({key:value for key,value in source.items() if key!='text'})
    claims={};offset=0
    for line_number,line in enumerate(source['text'].splitlines(keepends=True),1):
        quote=line.rstrip('\r\n')
        if '@quill' in quote or quote.lstrip().startswith('@'):
            match=DIRECTIVE.fullmatch(quote)
            if match is None:raise DirectiveError('malformed_directive')
            operation,key,value=match.groups()
            if operation!='create_copy':raise DirectiveError('unsupported_operation')
            if key not in VALUES:raise DirectiveError('unsupported_claim_key')
            if value not in VALUES[key]:raise DirectiveError('unknown_directive_value')
            if key in claims:raise DirectiveError('duplicate_directive')
            claims[key]={'source_id':source['source_id'],'version':source['version'],'path':source['path'],'url':source.get('url'),'source_sha256':source['sha256'],'document_revision':revision,'operation':operation,'claim_key':key,'value':value,'start_line':line_number,'end_line':line_number,'start':offset,'end':offset+len(quote),'quote':quote}
        offset+=len(line)
    return claims


def gate(manifest,candidate_ids,requested_version,claim_key='existing_path'):
    if not isinstance(candidate_ids,list) or any(not isinstance(sid,str) or not sid for sid in candidate_ids):raise GateError('invalid_candidate_ids')
    if len(set(candidate_ids))!=len(candidate_ids):raise GateError('duplicate_candidate')
    if not isinstance(requested_version,str) or re.fullmatch(r'[0-9]+\.[0-9]+',requested_version) is None:raise GateError('invalid_requested_version')
    if not isinstance(claim_key,str) or claim_key not in VALUES:raise GateError('unsupported_requested_claim')
    loaded=load_documents(Path(manifest));sources={s['source_id']:s for s in loaded['documents']}
    if any(sid not in sources for sid in candidate_ids):raise GateError('unknown_candidate')
    selected=[sources[sid] for sid in candidate_ids]
    if any(not isinstance(s.get('version'),str) or re.fullmatch(r'[0-9]+\.[0-9]+',s['version']) is None for s in selected):raise GateError('invalid_source_version')
    eligible=[s for s in selected if s['version']==requested_version]
    excluded=[s['source_id'] for s in selected if s['version']!=requested_version]
    base={'requested_version':requested_version,'claim_key':claim_key,'operation':'create_copy','candidate_ids':list(candidate_ids),'eligible_source_ids':[s['source_id'] for s in eligible],'excluded_wrong_version_ids':excluded,'answer_request':None}
    if not eligible:return {**base,'status':'not_in_docs','reason':'no_eligible_version','claims':[]}
    claims=[];missing=[]
    for source in eligible:
        parsed=claims_from_source(source)
        if claim_key not in parsed:missing.append(source['source_id'])
        else:claims.append(parsed[claim_key])
    if missing:return {**base,'status':'not_in_docs','reason':'requested_claim_missing','missing_claim_source_ids':missing,'claims':claims}
    if len({claim['value'] for claim in claims})>1:return {**base,'status':'conflict','reason':'same_version_directives_disagree','claims':claims}
    request={'messages':[{'role':'system','content':'Describe only the supplied explicit fictional API contract. Cite every supplied source ID. Do not invent an unsupported rule.'},{'role':'user','content':json.dumps({'requested_version':requested_version,'operation':'create_copy','claim_key':claim_key,'source_claims':claims},sort_keys=True)}]}
    return {**base,'status':'ready','reason':'eligible_directives_agree','agreed_value':claims[0]['value'],'claims':claims,'answer_request':request}
Run the local labTerminal · bash
python run.py --output scratch-result.json
python -m unittest discover -v
Saved CLI result fieldsRecorded output (excerpt) · jsonFull output
[
  {
    "case_id": "newer-wrong-version-excluded",
    "status": "ready",
    "reason": "eligible_directives_agree"
  },
  {
    "case_id": "compatible-agreement",
    "status": "ready",
    "reason": "eligible_directives_agree"
  },
  {
    "case_id": "same-version-conflict",
    "status": "conflict",
    "reason": "same_version_directives_disagree"
  },
  {
    "case_id": "absent-version",
    "status": "not_in_docs",
    "reason": "no_eligible_version"
  },
  {
    "case_id": "missing-claim",
    "status": "not_in_docs",
    "reason": "requested_claim_missing"
  },
  {
    "case_id": "partial-missing-claim",
    "status": "not_in_docs",
    "reason": "requested_claim_missing"
  },
  {
    "case_id": "unknown-directive-value",
    "status": "refused",
    "reason": "unknown_directive_value"
  },
  {
    "case_id": "malformed-directive",
    "status": "refused",
    "reason": "malformed_directive"
  }
]

This CLI stops at request preparation. A later caller must apply its context budget and dispatch policy before generation. The lab runs no inference, measures no semantic contradiction-detection accuracy, and supplies no deployed service or throughput benchmark.

Inspect the complete saved result
Actual local execution recordRecorded output · jsonDownload
{
  "execution_mode": "offline-explicit-synthetic-directive-gate",
  "model_called": false,
  "fixture_kind": "original synthetic developer documentation; Quill is fictional",
  "grammar": "exact whole line @quill create_copy existing_path=refuse|overwrite or close_required=yes|no",
  "cases": [
    {
      "case_id": "newer-wrong-version-excluded",
      "candidate_ids": [
        "quill-guide",
        "quill-new-version"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "requested_version": "1.0",
        "claim_key": "existing_path",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide",
          "quill-new-version"
        ],
        "eligible_source_ids": [
          "quill-guide"
        ],
        "excluded_wrong_version_ids": [
          "quill-new-version"
        ],
        "answer_request": {
          "messages": [
            {
              "role": "system",
              "content": "Describe only the supplied explicit fictional API contract. Cite every supplied source ID. Do not invent an unsupported rule."
            },
            {
              "role": "user",
              "content": "{\"claim_key\": \"existing_path\", \"operation\": \"create_copy\", \"requested_version\": \"1.0\", \"source_claims\": [{\"claim_key\": \"existing_path\", \"document_revision\": \"fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4\", \"end\": 172, \"end_line\": 5, \"operation\": \"create_copy\", \"path\": \"docs/quill-guide.md\", \"quote\": \"@quill create_copy existing_path=refuse\", \"source_id\": \"quill-guide\", \"source_sha256\": \"d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2\", \"start\": 133, \"start_line\": 5, \"url\": \"https://quill.invalid/teaching/1.0/quill-guide\", \"value\": \"refuse\", \"version\": \"1.0\"}]}"
            }
          ]
        },
        "status": "ready",
        "reason": "eligible_directives_agree",
        "agreed_value": "refuse",
        "claims": [
          {
            "source_id": "quill-guide",
            "version": "1.0",
            "path": "docs/quill-guide.md",
            "url": "https://quill.invalid/teaching/1.0/quill-guide",
            "source_sha256": "d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2",
            "document_revision": "fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "refuse",
            "start_line": 5,
            "end_line": 5,
            "start": 133,
            "end": 172,
            "quote": "@quill create_copy existing_path=refuse"
          }
        ]
      }
    },
    {
      "case_id": "compatible-agreement",
      "candidate_ids": [
        "quill-guide",
        "quill-reference"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "requested_version": "1.0",
        "claim_key": "existing_path",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide",
          "quill-reference"
        ],
        "eligible_source_ids": [
          "quill-guide",
          "quill-reference"
        ],
        "excluded_wrong_version_ids": [],
        "answer_request": {
          "messages": [
            {
              "role": "system",
              "content": "Describe only the supplied explicit fictional API contract. Cite every supplied source ID. Do not invent an unsupported rule."
            },
            {
              "role": "user",
              "content": "{\"claim_key\": \"existing_path\", \"operation\": \"create_copy\", \"requested_version\": \"1.0\", \"source_claims\": [{\"claim_key\": \"existing_path\", \"document_revision\": \"fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4\", \"end\": 172, \"end_line\": 5, \"operation\": \"create_copy\", \"path\": \"docs/quill-guide.md\", \"quote\": \"@quill create_copy existing_path=refuse\", \"source_id\": \"quill-guide\", \"source_sha256\": \"d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2\", \"start\": 133, \"start_line\": 5, \"url\": \"https://quill.invalid/teaching/1.0/quill-guide\", \"value\": \"refuse\", \"version\": \"1.0\"}, {\"claim_key\": \"existing_path\", \"document_revision\": \"dbc5c8bbffb9276508728fa9faf9dffdaa8463dc5ca88228852744843889756e\", \"end\": 166, \"end_line\": 5, \"operation\": \"create_copy\", \"path\": \"docs/quill-reference.md\", \"quote\": \"@quill create_copy existing_path=refuse\", \"source_id\": \"quill-reference\", \"source_sha256\": \"77dac3a322bf772c26674696a7820c55e947b52eb475e6599b95c14ed9075d92\", \"start\": 127, \"start_line\": 5, \"url\": \"https://quill.invalid/teaching/1.0/quill-reference\", \"value\": \"refuse\", \"version\": \"1.0\"}]}"
            }
          ]
        },
        "status": "ready",
        "reason": "eligible_directives_agree",
        "agreed_value": "refuse",
        "claims": [
          {
            "source_id": "quill-guide",
            "version": "1.0",
            "path": "docs/quill-guide.md",
            "url": "https://quill.invalid/teaching/1.0/quill-guide",
            "source_sha256": "d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2",
            "document_revision": "fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "refuse",
            "start_line": 5,
            "end_line": 5,
            "start": 133,
            "end": 172,
            "quote": "@quill create_copy existing_path=refuse"
          },
          {
            "source_id": "quill-reference",
            "version": "1.0",
            "path": "docs/quill-reference.md",
            "url": "https://quill.invalid/teaching/1.0/quill-reference",
            "source_sha256": "77dac3a322bf772c26674696a7820c55e947b52eb475e6599b95c14ed9075d92",
            "document_revision": "dbc5c8bbffb9276508728fa9faf9dffdaa8463dc5ca88228852744843889756e",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "refuse",
            "start_line": 5,
            "end_line": 5,
            "start": 127,
            "end": 166,
            "quote": "@quill create_copy existing_path=refuse"
          }
        ]
      }
    },
    {
      "case_id": "same-version-conflict",
      "candidate_ids": [
        "quill-guide",
        "quill-conflicting-guide"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "requested_version": "1.0",
        "claim_key": "existing_path",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide",
          "quill-conflicting-guide"
        ],
        "eligible_source_ids": [
          "quill-guide",
          "quill-conflicting-guide"
        ],
        "excluded_wrong_version_ids": [],
        "answer_request": null,
        "status": "conflict",
        "reason": "same_version_directives_disagree",
        "claims": [
          {
            "source_id": "quill-guide",
            "version": "1.0",
            "path": "docs/quill-guide.md",
            "url": "https://quill.invalid/teaching/1.0/quill-guide",
            "source_sha256": "d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2",
            "document_revision": "fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "refuse",
            "start_line": 5,
            "end_line": 5,
            "start": 133,
            "end": 172,
            "quote": "@quill create_copy existing_path=refuse"
          },
          {
            "source_id": "quill-conflicting-guide",
            "version": "1.0",
            "path": "docs/quill-conflicting-guide.md",
            "url": "https://quill.invalid/teaching/1.0/quill-conflicting-guide",
            "source_sha256": "b67b7e53117f9e954edd60cc050b3eed2541bdebb3349a12ab6d4ded376e85df",
            "document_revision": "75a663bc55f56fd0411656c4e686468d34389d1d6863a07fd9ef798aee2faa0b",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "overwrite",
            "start_line": 5,
            "end_line": 5,
            "start": 131,
            "end": 173,
            "quote": "@quill create_copy existing_path=overwrite"
          }
        ]
      }
    },
    {
      "case_id": "absent-version",
      "candidate_ids": [
        "quill-guide",
        "quill-new-version"
      ],
      "requested_version": "3.0",
      "claim_key": "existing_path",
      "result": {
        "requested_version": "3.0",
        "claim_key": "existing_path",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide",
          "quill-new-version"
        ],
        "eligible_source_ids": [],
        "excluded_wrong_version_ids": [
          "quill-guide",
          "quill-new-version"
        ],
        "answer_request": null,
        "status": "not_in_docs",
        "reason": "no_eligible_version",
        "claims": []
      }
    },
    {
      "case_id": "missing-claim",
      "candidate_ids": [
        "quill-guide"
      ],
      "requested_version": "1.0",
      "claim_key": "close_required",
      "result": {
        "requested_version": "1.0",
        "claim_key": "close_required",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide"
        ],
        "eligible_source_ids": [
          "quill-guide"
        ],
        "excluded_wrong_version_ids": [],
        "answer_request": null,
        "status": "not_in_docs",
        "reason": "requested_claim_missing",
        "missing_claim_source_ids": [
          "quill-guide"
        ],
        "claims": []
      }
    },
    {
      "case_id": "partial-missing-claim",
      "candidate_ids": [
        "quill-guide",
        "quill-missing-claim"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "requested_version": "1.0",
        "claim_key": "existing_path",
        "operation": "create_copy",
        "candidate_ids": [
          "quill-guide",
          "quill-missing-claim"
        ],
        "eligible_source_ids": [
          "quill-guide",
          "quill-missing-claim"
        ],
        "excluded_wrong_version_ids": [],
        "answer_request": null,
        "status": "not_in_docs",
        "reason": "requested_claim_missing",
        "missing_claim_source_ids": [
          "quill-missing-claim"
        ],
        "claims": [
          {
            "source_id": "quill-guide",
            "version": "1.0",
            "path": "docs/quill-guide.md",
            "url": "https://quill.invalid/teaching/1.0/quill-guide",
            "source_sha256": "d031c7d2dd38a33f9f1c89b0439ca5711e0f32b94ed6e0eacf5cfd175f8d9cf2",
            "document_revision": "fb2123ad052ea8002fedb4a708debd0b40e1aaa4d8ec34bd6c3f70aa01769ad4",
            "operation": "create_copy",
            "claim_key": "existing_path",
            "value": "refuse",
            "start_line": 5,
            "end_line": 5,
            "start": 133,
            "end": 172,
            "quote": "@quill create_copy existing_path=refuse"
          }
        ]
      }
    },
    {
      "case_id": "unknown-directive-value",
      "candidate_ids": [
        "quill-unknown-value"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "status": "refused",
        "error": "DirectiveError",
        "reason": "unknown_directive_value",
        "answer_request": null
      }
    },
    {
      "case_id": "malformed-directive",
      "candidate_ids": [
        "quill-malformed"
      ],
      "requested_version": "1.0",
      "claim_key": "existing_path",
      "result": {
        "status": "refused",
        "error": "DirectiveError",
        "reason": "malformed_directive",
        "answer_request": null
      }
    }
  ],
  "changed_source": {
    "status": "refused",
    "error": "IngestionError",
    "reason": "hash_mismatch",
    "answer_request": null
  },
  "policy": "Exact requested version before directive parsing. Any eligible source missing the requested key withholds the request. No source-priority or newest-version winner.",
  "limit": "This parses explicit machine-readable teaching contracts, not arbitrary prose contradictions or semantic agreement. A prepared cited request is not a generated answer or a correctness/security guarantee."
}

The CLI ending shows malformed directives and changed source bytes being refused. The fixture-specific gate prepares or withholds requests; it does not generate an answer.

Compare the recorded behavior

Compare the wrong-version exclusion case with the same-version conflict. Explain why the first can prepare a request while the second must retain both claims without choosing a winner. Then inspect the partial-missing-key case and trace a quoted claim back to its pinned source span.

Two eligible sources for the requested version give different supported directive values. What does this gate do?

Choose one answer, then check your reasoning.

Read the explanation

Agreement is checked only over the supported synthetic directive grammar; this is not a general prose contradiction detector.

What’s next

Continue with Add Search and Read Tools.

References

The earlier versioning and filtering lessons define the reused source boundaries. The official Python regular-expression documentation, checked on 23 October 2026, describes whole-string matching used for the narrow directive grammar. The conflict and withholding policies are implemented application choices, not a model-based evaluation or a claim about arbitrary documentation prose.

Written by Arjun Prabhulal.

Module 8

Answer generation