Files

7.5 KiB

Generic CaseBuilder foundation v1

architecture.md remains authoritative. This milestone assembles supplied data deterministically. It performs no LLM calls, interpretation, hypothesis generation, diagnosis, investigation, external research or project-specific adapter work. Tester hypotheses remain supplied data, never generated or promoted to facts.

Explicit input contracts

The manifest may declare artifacts.case_inputs, pointing to a UTF-8 JSON index:

{
  "format": "viano-case-inputs",
  "format_version": 1,
  "reports": ["original/report.data"],
  "reproductions": ["original/reproduction.data"],
  "context": {
    "runtime": ["original/runtime.bin"],
    "database": [],
    "source": [],
    "research": []
  },
  "attachments": []
}

Paths and extensions have no inherent meaning. Listed reports conform to report-v1.schema.json, reproductions to reproduction-v1.schema.json, and the index to case-inputs-v1.schema.json. Schemas are bundled offline Draft 2020-12 contracts. Unlisted files are preserved as unclassified inputs without parsing or guessing their role. A missing index produces explicit data-quality gaps. Invalid declared versions/contracts, duplicate JSON keys, repeated sources within an index role, unsafe or absent references are controlled errors.

A report requires format viano-bug-report and format_version 1. Optional fields: title, summary, observations, comments, tester_hypotheses, expected_behavior, expected_behavior_complete and entities. Statements have nonblank text, optional author and timezone-aware observed_at, and optionally a structured claim with key and JSON value. Categories are producer-supplied, not inferred from prose. Unknown extensions remain accessible in the preserved source file.

{
  "format": "viano-bug-report",
  "format_version": 1,
  "title": "A generic observed problem",
  "observations": [{"text": "The switch remains off", "author": "Tester A"}],
  "tester_hypotheses": [{"text": "Perhaps a timing issue"}],
  "expected_behavior": [{"text": "The switch turns on"}],
  "expected_behavior_complete": false,
  "entities": [{"type": "component", "id": "42", "roles": ["focus"]}]
}

A reproduction requires format viano-reproduction and format_version 1. Optional fields: steps (strings), observations (human statements), events_ref, attachments, facts and entities. Facts have a name and JSON value: they are supplied facts, not independently verified technical findings. Events, attachments and all context files remain opaque references with hashes/sizes. Supplied research stays separate; no research is performed and no local implementation facts are inferred from it.

Canonical case and provenance

case-v1.schema.json defines format viano-case, format_version 1, builder_version 1, and the architecture's main blocks: case, bug, human_observations, expected_behavior, reproduction, entities, runtime_facts, database_context, source_context, research, data_quality, inputs.

Identity/project/revision come only from the manifest. Each statement/fact/entity has a source path and JSON Pointer with provenance kind. Human statements retain author/time. Observations, comments, tester hypotheses and expected behavior are separate. Record IDs use O/C/T/E/F namespaces; previous IDs remain stable by source path and pointer when inputs are appended. Facts use F0001 etc. Reproduction IDs follow source order. Integer entity IDs become strings; equal integer/string IDs of the same explicit type combine roles and retain every source. No domain types, relations or content are invented.

Expected-behavior completeness is missing, unspecified, reported_complete, reported_partial or conflicting. Reported completeness is an assertion by the reporter, not a sufficiency judgment. Different canonical JSON values for the same explicit claim key within observations or expected behavior are flagged with source references. Natural-language contradictions are not interpreted; comments and tester hypotheses never participate in fact or conflict inference.

Large context/events stay outside case JSON. Fact values over the inline limit use value_ref (source path and JSON Pointer) instead of value; nothing is truncated or replaced by a synthetic null. Old structured inputs are inherited from the prior case's role inventory, hash-checked, and re-read from their immutable originals. A returning index can add only new reports without losing old statements, facts or provenance. Prior case files remain explicitly referenced. Incompatible prior canonical case contracts are rejected instead of guessed.

Artifact and checkpoint integration

from viano_bug_analysis.case import CaseBuilder, CaseBuildError
from viano_bug_analysis.lifecycle import Workspace, CheckpointStore

store = CheckpointStore(Workspace("service-data"))
try:
    result = CaseBuilder(store).build("case-A", "stable-package")
except CaseBuildError as error:
    print(error.code, error.path, str(error))

Input must already be admitted. VALIDATED or REOPENED enters BUILDING_CASE through a start checkpoint; existing BUILDING_CASE work continues there. Artifacts use case/revisions/NNNN/case.json and case_summary.md. Revision paths preserve append-only history; manifest pointers case and case_summary select the current documents. Existing case files and unknown artifacts are never overwritten.

Case JSON, deterministic summary and the case-built completion checkpoint are published together through PackageWriter. State remains BUILDING_CASE; construction does not execute or start interpretation. Later phase orchestration advances it. Summary is generated only from canonical JSON, adds no interpretation and escapes supplied Markdown/HTML. render_summary is pure; CaseAssembler.assemble is deterministic for the same validated snapshot.

Completion uses a stable step ID per builder version and analysis revision. Repeats check the input request hash, case contract and summary, reuse output and repair local metadata. Crashes after publication do not create another generation; unconfirmed work retries from the same snapshot. Changed payloads after completion require reopening with a new analysis revision. The request hash includes explicit source roles and all unclassified payloads, excluding known generated case outputs and checkpoint artifacts. Analysis revisions and package generations stay separate.

Prepared output calls CheckpointStore.advance(expected_generation=...) to reject concurrent changes before committing. Identical confirmed requests remain replayable with the old expected generation. Locks and this optimistic check prevent stale prepared data from being committed over newer work. There are no external side effects in construction.

Configurable resource defaults

CaseBuilderLimits holds operational policy, not immutable format limits:

Limit Default
Individual index/report/reproduction JSON 1 MiB
Aggregate structured input JSON 8 MiB
Structured input documents 256
Prior/canonical case JSON 8 MiB
Summary bytes 8 MiB
Inline fact value 16 KiB

Prior case JSON is bounded separately from the structured input budget. Package limits still apply to the archive/artifacts. Context is hashed in chunks rather than loaded as prose. Invalid attempts preserve all source/previous case files; they may retain a confirmed start checkpoint in BUILDING_CASE, allowing resumption after corrected sources and a new index are appended. Changing resource defaults does not rewrite a previously confirmed case.