Files

153 lines
7.5 KiB
Markdown

# 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:
```json
{
"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.
```json
{
"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
```python
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.