From 6ad8f71809bf1ca5cd6f877d21b668b8732a7322 Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 08:24:01 -0300 Subject: [PATCH 1/8] feat: retain controlled fault evidence and inconclusive comparisons (#294) Add versioned offline controlled fault contexts, source-bound observation reports and deterministic immutable artifacts. Preserve expected, unexpected and inconclusive paired outcomes with exact elapsed-counter units and pinned diagnostics. Reuse native source caches, runner, manifests and checkpoints. Refs #261; source admission and the diversified benchmark program remain open. --- coleman/corpus/controlled.py | 78 ++++ coleman/corpus/controlled_contracts.py | 283 ++++++++++++ coleman/manifest.py | 1 + docs/benchmark-corpus.md | 9 + docs/controlled-faults.md | 218 +++++++++ docs/roadmap.md | 6 +- examples/controlled_faults/ci.py | 206 +++++++++ llms.txt | 239 +++++++++- .../fixtures/controlled-owned-pair-v1.json | 1 + tests/corpus/test_controlled.py | 430 ++++++++++++++++++ tests/corpus/test_installed_controlled.py | 76 ++++ zensical.toml | 1 + 12 files changed, 1544 insertions(+), 4 deletions(-) create mode 100644 coleman/corpus/controlled.py create mode 100644 coleman/corpus/controlled_contracts.py create mode 100644 docs/controlled-faults.md create mode 100644 examples/controlled_faults/ci.py create mode 100644 tests/corpus/fixtures/controlled-owned-pair-v1.json create mode 100644 tests/corpus/test_controlled.py create mode 100644 tests/corpus/test_installed_controlled.py diff --git a/coleman/corpus/controlled.py b/coleman/corpus/controlled.py new file mode 100644 index 00000000..1eea26d0 --- /dev/null +++ b/coleman/corpus/controlled.py @@ -0,0 +1,78 @@ +"""Offline controlled-fault conversion through existing source integrity and immutable artifact services.""" + +from __future__ import annotations + +import hashlib +from pathlib import Path + +from coleman.artifacts import ArtifactWriter +from coleman.corpus.controlled_contracts import ( + ControlledDataset, + ControlledObservation, + ControlledReport, + ControlledSpec, +) +from coleman.corpus.materialization import SourceCache, validate_cache_separation, validate_materialization + + +def convert_controlled_source(spec: ControlledSpec, cache: SourceCache) -> ControlledDataset: + """Verify pinned inputs/report and convert bounded observations without executing foreign code. + + Each input receipt is checked against actual offline cached bytes. Identical + role/test/trial repetitions are excluded with counts; conflicting repetitions + raise ValueError. Aborted/missing/unexpected outcomes remain evidence, not a + substituted pass or fault detection. Source/input terms remain independent of + the report's own terms. No source is fetched, extracted again or executed. + Schema/size/digest/context conflicts raise ValueError; I/O errors propagate. + """ + spec = ControlledSpec.model_validate(spec) + for item in spec.context.inputs: + validate_materialization(item.materialization, cache) + receipt = spec.report_materialization + validate_materialization(receipt, cache) + member = next(item for item in receipt.spec.members if item.name == spec.report_member) + path = cache.member_path(receipt, spec.report_member) + with path.open("rb") as stream: + payload = stream.read(member.size_bytes + 1) + if len(payload) != member.size_bytes or "sha256:" + hashlib.sha256(payload).hexdigest() != member.sha256: + raise ValueError("Parsed controlled report bytes disagree with pinned member") + report = ControlledReport.from_json(payload) + if report.context_fingerprint != spec.context.fingerprint: + raise ValueError("Controlled report context fingerprint mismatch") + unique: dict[tuple[str, str, str], ControlledObservation] = {} + for observation in report.observations: + prior = unique.setdefault(observation.logical_key, observation) + if prior != observation: + raise ValueError("Conflicting controlled execution duplicate") + return ControlledDataset( + schema_version=1, + spec=spec, + input_rows=len(report.observations), + duplicates_excluded=len(report.observations) - len(unique), + observations=tuple(unique.values()), + ) + + +def validate_controlled_dataset(dataset: ControlledDataset, cache: SourceCache) -> None: + """Reconvert actual source bytes; embedded metadata alone never proves correspondence or execution.""" + dataset = ControlledDataset.model_validate(dataset) + if convert_controlled_source(dataset.spec, cache) != dataset: + raise ValueError("Controlled dataset disagrees with pinned source observations") + + +def publish_controlled_dataset(dataset: ControlledDataset, cache: SourceCache, writer: ArtifactWriter) -> Path: + """Reverify before atomic immutable publication; interrupted work never becomes a completed experiment. + + Concurrent identical retries share one content-addressed artifact. Source cache + and output must be separate. This writes no learning checkpoint and grants no + evaluation admission. Recipe-only observations must remain local. A content + conflict raises ValueError; filesystem/integrity errors propagate. + """ + dataset = ControlledDataset.model_validate(dataset) + validate_cache_separation(cache.root, writer.run_root) + path = writer.run_root / "corpus-controlled" / (dataset.fingerprint.removeprefix("sha256:") + ".json") + if path.is_symlink() or not path.resolve().is_relative_to(writer.run_root.resolve()): + raise ValueError("Controlled artifacts must remain within their output tree") + validate_controlled_dataset(dataset, cache) + writer.write_immutable(path, dataset.to_json() + "\n") + return path diff --git a/coleman/corpus/controlled_contracts.py b/coleman/corpus/controlled_contracts.py new file mode 100644 index 00000000..5951cbe2 --- /dev/null +++ b/coleman/corpus/controlled_contracts.py @@ -0,0 +1,283 @@ +"""Controlled fault observations: paired functional evidence, never inferred CI chronology.""" + +from __future__ import annotations + +from typing import Annotated, Literal, Self + +from pydantic import Field, model_validator + +from coleman.corpus.materialization_contracts import MaterializationReceipt +from coleman.evaluation.protected.temporal import Timestamp +from coleman.results.domain import Fingerprint, Identifier, fingerprint +from coleman.results.versioned import VersionedContract +from coleman.selection.contracts import Immutable + +Label = Annotated[Identifier, Field(max_length=1024)] +Ticks = Annotated[int, Field(strict=True, ge=0, le=2**63 - 1)] +Role = Literal["buggy", "fixed"] +Outcome = Literal[ + "passed", "assertion_failed", "test_error", "skipped", "timeout", "cancelled", "infrastructure_error", "unavailable" +] + + +class ControlledInput(Immutable): + """A reviewed source input receipt; identity is its descriptive name, never an executable path. + + Receipts prove local byte correspondence only when validated against a cache. + They do not prove that a process consumed those bytes. Opaque archives can be + materialized as raw members without broadening extraction support. + """ + + name: Label + kind: Literal["buggy_source", "fixed_source", "test_fixture", "harness", "dependency"] + materialization: MaterializationReceipt + + +class ControlledRuntime(Immutable): + """Producer-attested execution conditions; commands are descriptions and are never run here. + + Image digest identifies a platform-specific container manifest, not a blanket + license for its components. Dependency receipts belong in the context inputs. + Setup/intervention descriptions must include derived build metadata and test + transplants. Environment identity is not measured performance or isolation proof. + """ + + implementation: Label + version: Label + platform: Label + execution_model: Literal["container", "host", "constructed"] + image_digest: Fingerprint | None + emulated: Annotated[bool, Field(strict=True)] + timezone: Label + setup: Annotated[tuple[Label, ...], Field(min_length=1, max_length=64)] + commands: Annotated[tuple[Label, ...], Field(min_length=1, max_length=64)] + interventions: Annotated[tuple[Label, ...], Field(max_length=64)] + + @model_validator(mode="after") + def _image(self) -> Self: + """Require an image identity exactly for container executions; do not invent one for host fixtures.""" + if (self.image_digest is not None) != (self.execution_model == "container"): + raise ValueError("Container runtime requires image digest; host/constructed runtime has none") + return self + + +class ControlledContext(VersionedContract): + """Freeze one fault, revisions, common test universe, inputs and execution recipe. + + ``fault_id`` is a curated subject label, not a verified unique-fault mapping. + Test fixtures are identical in both roles, including any declared transplant. + Source/input revisions are explicit labels and no external imports are performed. + Repeated trials retain the same dependence group; seeds never create new bugs. + """ + + recipe: Literal["controlled-fault-observations-v1"] = "controlled-fault-observations-v1" + project: Label + fault_id: Label + language: Label + fault_origin: Literal["real", "synthetic"] + buggy_revision: Label + fixed_revision: Label + fixture_revision: Label + dependence_group: Label + test_ids: Annotated[tuple[Label, ...], Field(min_length=1, max_length=10000)] + inputs: Annotated[tuple[ControlledInput, ...], Field(min_length=4, max_length=64)] + runtime: ControlledRuntime + limitations: Annotated[tuple[Label, ...], Field(min_length=1, max_length=64)] + + @model_validator(mode="after") + def _identities(self) -> Self: + """Require distinct revisions, unique inputs/tests and all four source/fixture/harness roles.""" + if self.buggy_revision == self.fixed_revision: + raise ValueError("Controlled pair requires distinct buggy/fixed revisions") + if len(set(self.test_ids)) != len(self.test_ids): + raise ValueError("Duplicate controlled test identity") + if len({item.name for item in self.inputs}) != len(self.inputs): + raise ValueError("Duplicate controlled input name") + for kind in ("buggy_source", "fixed_source", "test_fixture", "harness"): + if sum(item.kind == kind for item in self.inputs) != 1: + raise ValueError("Controlled context requires exactly one input of each source/fixture/harness kind") + revisions = { + "buggy_source": self.buggy_revision, + "fixed_source": self.fixed_revision, + "test_fixture": self.fixture_revision, + } + if any( + item.materialization.spec.source.version != revisions[item.kind] + for item in self.inputs + if item.kind in revisions + ): + raise ValueError("Controlled input source version disagrees with declared revision") + object.__setattr__(self, "test_ids", tuple(sorted(self.test_ids))) + object.__setattr__(self, "inputs", tuple(sorted(self.inputs, key=lambda item: item.name))) + return self + + +class ControlledElapsed(Immutable): + """Nonnegative monotonic elapsed ticks in nanoseconds; null is explicitly unavailable/inapplicable. + + Integer nanoseconds retain exact counter resolution, not physical accuracy. + No conversion to runner work, per-test removable cost or CI savings is allowed. + Genuine zero is observed. Negative, fractional, bool and nonfinite values reject. + """ + + value: Ticks | None + unit: Literal["ns"] = "ns" + meaning: Literal["observed-test-harness-monotonic-elapsed-v1"] = "observed-test-harness-monotonic-elapsed-v1" + status: Literal["observed", "unavailable", "not_applicable"] + + @model_validator(mode="after") + def _missingness(self) -> Self: + """Keep observed zero separate from an absent elapsed counter without imputing a value.""" + if (self.value is not None) != (self.status == "observed"): + raise ValueError("Controlled elapsed value/status disagree") + return self + + +class ControlledObservation(Immutable): + """One role/test/trial observation, including aborted and non-assertion outcomes. + + Trial IDs identify actual executions, not independent faults. Capture instants + are collection clocks, never historical CI events or verified feature clocks. + A timeout can have elapsed ticks; it cannot become an assertion failure. Raw + diagnostics remain in separate pinned report-package members, outside decision + features. A non-null digest must match such a member during conversion. + """ + + trial_id: Label + role: Role + test_id: Label + outcome: Outcome + elapsed: ControlledElapsed + capture_started_at: Timestamp + capture_finished_at: Timestamp + diagnostics_sha256: Fingerprint | None + + @model_validator(mode="after") + def _clock(self) -> Self: + """Reject reversed capture clocks; do not equate UTC interval with monotonic elapsed ticks.""" + if self.capture_finished_at < self.capture_started_at: + raise ValueError("Controlled capture finishes before it starts") + return self + + @property + def logical_key(self) -> tuple[str, str, str]: + """Return role/test/trial identity; context adds project/fault/runtime/input identity.""" + return self.trial_id, self.test_id, self.role + + def execution_id(self, context: ControlledContext) -> str: + """Hash stable context and logical key, excluding observations and capture values.""" + return fingerprint(["controlled-execution-v1", context.fingerprint, *self.logical_key]) + + +class ControlledReport(VersionedContract): + """Bounded producer observation interchange, bound to an exact frozen context. + + Duplicate physical observations remain visible for adapter accounting. Conflict + detection happens during conversion; this is not an executable test driver. + Missing, legacy and future schema versions reject without migration. + """ + + context_fingerprint: Fingerprint + observations: Annotated[tuple[ControlledObservation, ...], Field(max_length=20000)] + + +class ControlledSpec(VersionedContract): + """Bind a frozen context to a reviewed, pinned producer report in an external source cache.""" + + context: ControlledContext + report_materialization: MaterializationReceipt + report_member: Label + + @model_validator(mode="after") + def _member(self) -> Self: + """Require exactly one declared report member with an uncompressed 8-MiB ceiling.""" + members = [item for item in self.report_materialization.spec.members if item.name == self.report_member] + if len(members) != 1 or members[0].size_bytes > 8 * 1024**2: + raise ValueError("Controlled report member missing or exceeds 8 MiB") + return self + + +class ControlledPair(Immutable): + """Derived same-test/same-trial comparison; absent roles and non-assertion outcomes are inconclusive.""" + + trial_id: Label + test_id: Label + buggy: Outcome | None + fixed: Outcome | None + + @property + def classification(self) -> str: + """Return expected, both-pass, both-fail, reversed or inconclusive without dropping negatives.""" + classifications: dict[tuple[Outcome | None, Outcome | None], str] = { + ("assertion_failed", "passed"): "expected", + ("passed", "passed"): "both_pass", + ("assertion_failed", "assertion_failed"): "both_fail", + ("passed", "assertion_failed"): "reversed", + } + return classifications.get((self.buggy, self.fixed), "inconclusive") + + +class ControlledDataset(VersionedContract): + """Canonical functional observations, separate from historical CI and scientific admission. + + Producer attestations plus byte correspondence do not verify execution truth, + a complete original suite, independent fault counts or protected efficacy. + New collections have new trial IDs; retries of the same collection retain IDs. + The complete source report remains pinned even after duplicate exclusion. + """ + + spec: ControlledSpec + input_rows: Annotated[int, Field(strict=True, ge=0, le=20000)] + duplicates_excluded: Annotated[int, Field(strict=True, ge=0, le=20000)] + observations: Annotated[tuple[ControlledObservation, ...], Field(max_length=20000)] + history: Literal["constructed"] = "constructed" + scope: Literal["controlled-functional-observations-only"] = "controlled-functional-observations-only" + admission: Literal["not_evaluated"] = "not_evaluated" + generalization: Literal["insufficient_evidence"] = "insufficient_evidence" + + @model_validator(mode="after") + def _rows(self) -> Self: + """Conserve physical rows, prohibit duplicate keys and reject tests outside the declared universe.""" + if self.input_rows != len(self.observations) + self.duplicates_excluded: + raise ValueError("Controlled observation conservation failed") + if len({item.logical_key for item in self.observations}) != len(self.observations): + raise ValueError("Duplicate controlled execution identity") + test_ids = set(self.spec.context.test_ids) + if any(item.test_id not in test_ids for item in self.observations): + raise ValueError("Controlled observation test outside declared universe") + object.__setattr__(self, "observations", tuple(sorted(self.observations, key=lambda item: item.logical_key))) + return self + + @model_validator(mode="after") + def _diagnostics(self) -> Self: + """Bind optional diagnostic digests to separate declared report members on conversion and every read. + + This pure check validates declared membership only. Conversion/publication + separately verifies actual package/member bytes through the source cache. + """ + diagnostic_digests = { + item.sha256 + for item in self.spec.report_materialization.spec.members + if item.name != self.spec.report_member + } + if any( + item.diagnostics_sha256 is not None and item.diagnostics_sha256 not in diagnostic_digests + for item in self.observations + ): + raise ValueError("Controlled diagnostic digest must reference a validated report package member") + return self + + @property + def pairs(self) -> tuple[ControlledPair, ...]: + """Compare only explicitly collected test/trial groups; never invent missing observations.""" + groups: dict[tuple[str, str], dict[str, Outcome]] = {} + for item in self.observations: + groups.setdefault((item.trial_id, item.test_id), {})[item.role] = item.outcome + return tuple( + ControlledPair(trial_id=trial, test_id=test, buggy=roles.get("buggy"), fixed=roles.get("fixed")) + for (trial, test), roles in sorted(groups.items()) + ) + + def require_temporal_evaluation(self) -> None: + """Reject historical evaluation: capture clocks do not supply CI chronology or predecision features.""" + raise ValueError("Controlled observations are not historical CI; temporal evaluation is unavailable") diff --git a/coleman/manifest.py b/coleman/manifest.py index 51050bd7..7b71ca50 100644 --- a/coleman/manifest.py +++ b/coleman/manifest.py @@ -83,6 +83,7 @@ def generate_manifest(run_dir: str | Path, *, run_id: str) -> Path: "corpus_materialization": "corpus-materializations/*.json", "corpus_rtptorrent_dataset": "corpus-rtptorrent/*.json", "corpus_lrts_dataset": "corpus-lrts/*.json", + "corpus_controlled_dataset": "corpus-controlled/*.json", "observation_model": "observation-models/*.json", "decision_signal": "decision-signals/*.json", "resource_run": "resource-runs/*.json", diff --git a/docs/benchmark-corpus.md b/docs/benchmark-corpus.md index c4f498ac..f031052e 100644 --- a/docs/benchmark-corpus.md +++ b/docs/benchmark-corpus.md @@ -373,3 +373,12 @@ flowchart LR M --> R[Visible blocked sources and missing diversity cells] V --> R ``` + + +The next [controlled fault observation adapter](controlled-faults.md) retains +same-test buggy/fixed comparisons, exact elapsed-counter units and negative or +inconclusive outcomes. It verifies producer bytes through the existing source +cache and publishes through the same artifact writer. It does not grant source +admission or convert collection clocks into historical CI chronology. Direct +upstream Java/Python reproductions are documented separately from the owned +synthetic installed example; required diversity cells remain uncovered. diff --git a/docs/controlled-faults.md b/docs/controlled-faults.md new file mode 100644 index 00000000..2957673d --- /dev/null +++ b/docs/controlled-faults.md @@ -0,0 +1,218 @@ +# Controlled real-fault observations + +Controlled buggy/fixed pairs answer a narrow question: does the same selected +assertion fail against one source revision and pass against the corrected revision +under the declared execution conditions? COLEMAN can retain that evidence, +including unexpected and inconclusive results, without presenting a reconstructed +sequence as historical CI. + +This source slice of [#261](https://github.com/jacksonpradolima/coleman/issues/261) +adds an offline typed observation adapter. It does not complete source admission, +fault diversity, baseline comparisons or the cross-corpus benchmark. The registry's +seven required diversity cells remain uncovered. Source assessments for +[RTPTorrent](rtptorrent.md) and [LRTS](lrts.md) remain separate. + +## Architecture and trust boundary + +```mermaid +flowchart LR + producer[External subject execution] --> report[Pinned producer observation report] + inputs[Reviewed source / fixture / harness inputs] --> cache[Existing external source cache] + report --> cache + context[Frozen controlled context] --> adapter[Offline typed conversion] + cache --> adapter + adapter --> pairs[Expected / unexpected / inconclusive pairs] + adapter --> writer[Existing immutable artifact writer] + writer --> manifest[Native run artifact manifest] +``` + +The core reads and verifies cached bytes. It never starts a subject process, +container, compiler, CLI or network transport. A receipt proves byte correspondence, +not that a producer executed those bytes. Runtime and command descriptions remain +producer attestations. Review and execution of external subjects belong outside +this adapter, with their own component terms and resource limits. + +`ControlledContext` freezes project, curated fault label, language, fault origin, +source revisions, fixture revision, dependence group, declared test IDs, input +receipts and runtime conditions. Exactly one buggy source, fixed source, common +test fixture and harness input is required. Dependency inputs are separate. Source +versions must match the declared revisions. Input names and test IDs are unique; +permuting those declarations preserves context identity. Opaque source archives +can be cached as raw packages; this adds no TAR or ZIP64 extraction capability. + +`ControlledReport` binds observations to the context fingerprint. Each observation +has a trial ID, role, test ID, explicit outcome, capture instants, nullable diagnostic +digest and monotonic elapsed counter. A non-null diagnostic digest must match a +separate regular member of the validated report package; absent references reject. +Diagnostics are not predecision features. Capture instants are collection clocks, not +historical event or feature availability. No observed CI chronology is inferred. + +Execution identity hashes the context and `(trial_id, test_id, role)`, excluding +outcomes and capture values. A retry of the same collection retains its trial ID; +a genuinely new execution gets a new trial ID. Both remain in the same declared +dependence group. These IDs do not establish independent bugs or projects. + +## Outcomes, units and missingness + +| Buggy observation | Fixed observation | Comparison | +| --- | --- | --- | +| Assertion failed | Passed | Expected | +| Passed | Passed | Both pass | +| Assertion failed | Assertion failed | Both fail | +| Passed | Assertion failed | Reversed | +| Missing role, test error, skipped, timeout, cancellation, infrastructure error or unavailable | Any | Inconclusive | + +The same inconclusive rule applies when the fixed role has a non-assertion outcome. +Only actual test/trial groups are compared. An empty report has no comparisons; +missing observations are never fabricated. Unexpected and inconclusive results +are valid evidence and remain in the dataset. + +Elapsed values are strict nonnegative integer **nanoseconds**, at most `2**63-1`, +with meaning `observed-test-harness-monotonic-elapsed-v1`. Zero is observed. Null +requires `unavailable` or `not_applicable`; an observed null or absent-state zero +rejects. Negative, fractional, boolean, nonfinite and incompatible-unit values +reject. Counter resolution establishes no physical measurement accuracy. + +Elapsed harness time includes whatever that harness times. It is not independently +removable runner work, shared setup cost, queue delay or developer-visible CI +latency. It must not be substituted for native scheduling costs. This contract +does not claim that all negative numbers are invalid in other result families; +negative signed measurements remain governed by their existing contracts. + +## Installed package workflow + +Build and install the working branch's wheel in a separate environment. The +released 4.5 wheel predates this adapter. From the checkout: + +```bash +wheel_dir=$(mktemp -d /tmp/coleman-controlled-wheel.XXXXXX) +uv build --wheel --out-dir "$wheel_dir" +uv venv /tmp/coleman-controlled-installed --python 3.14 +uv pip install --python /tmp/coleman-controlled-installed/bin/python "$wheel_dir"/*.whl +mkdir -p /tmp/coleman-controlled-workspace +cp examples/controlled_faults/ci.py /tmp/coleman-controlled-workspace/ci.py +cd /tmp/coleman-controlled-workspace +/tmp/coleman-controlled-installed/bin/python ci.py owned-ci /tmp/coleman-controlled-source-cache +``` + +The example's pairs are **newly authored synthetic schema fixtures**, not external +real faults or measured executions. Their constructed capture instants and +unavailable elapsed counters are explicit. A separate complete owned serial CI +fixture runs real native Random/RNFail with budget 7 seconds, independently checked +NAPFD/APFDc and a second call through the learning checkpoint. No counter from the +controlled observations is projected into that serial fixture's costs. + +Re-running the command preserves the controlled artifact and committed native +result. The output includes the frozen `spec`, converted `dataset`, classifications +(`expected`, `inconclusive`), native directory and explicit insufficient-evidence +status. This demonstrates integration and recovery, not external effectiveness. + +The following complete SDK example reopens that specification offline. It runs +from the same external workspace and requires no CLI or MCP imports: + +```python +from pathlib import Path + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import SourceCache +from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset +from coleman.corpus.controlled_contracts import ControlledSpec + +cache = SourceCache("/tmp/coleman-controlled-source-cache") +spec = ControlledSpec.from_json(Path("owned-ci/controlled-spec.json").read_bytes()) +dataset = convert_controlled_source(spec, cache) +assert [pair.classification for pair in dataset.pairs] == ["expected", "inconclusive"] +path = publish_controlled_dataset(dataset, cache, ArtifactWriter("offline-assessment")) +assert dataset.admission == "not_evaluated" +assert dataset.history == "constructed" +print(path) +``` + +For another cache location, replace the SDK path with the same location supplied +to `ci.py`. Input/report materializations use the existing reviewed-license, +source-digest, bounded-byte and offline validation contracts. Reports have an +8-MiB ceiling and at most 20,000 physical observations; contexts permit at most +10,000 test IDs and 64 input packages. Every report is checked against the bytes +actually parsed, including EOF size/digest, after cache validation. + +## Compatibility, duplication and publication + +All new interchange models require integer `schema_version: 1`, reject unknown +fields, and reject missing, legacy and future versions. Existing native results, +source manifests, checkpoints and historical artifacts keep their existing +meaning. No migration or automatic reinterpretation occurs. A future converter +must declare any migration separately and preserve original bytes. + +Conversion conserves physical rows: `input_rows = observations + duplicates_excluded`. +Identical role/test/trial repeats are counted and excluded; conflicting repetitions +reject. Output observations are sorted by logical key. Permuting physical report +rows preserves normalized observations but changes the pinned source report bytes +and therefore the complete artifact fingerprint. This is deliberate provenance, +not an input-order-dependent policy comparison. + +Publication re-converts the actual cache before writing one +`corpus-controlled/.json` artifact. Identical concurrent publication +is idempotent through the existing immutable writer. Partial work is never a +completed experiment or learning checkpoint. A failed publication can be retried; +recipe-only content must remain local. Artifact metadata alone does not establish +source integrity, execution truth, scientific admission or independence. + +## Primary-source investigation and fresh local evidence + +The [Defects4J paper](https://homes.cs.washington.edu/~mernst/pubs/bug-database-issta2014.pdf) +and [pinned documentation](https://github.com/rjust/defects4j/tree/8c16da8230843cdc918eaf4ddb449637f02b83c6) +describe isolated buggy/fixed subjects, including reconstructed revisions. +The current documentation requires Java 11 and `America/Los_Angeles`; its current +corpus differs from the paper's original snapshot. Framework MIT terms do not +license every subject or dependency. Broad initialization downloads unrelated +repositories and tools; it was not used for the bounded case below. + +The [BugsInPy paper](https://arxiv.org/html/2401.15481v1) describes selected real +source revisions and common exposing tests, with manual isolation review. A later +[independent reproduction study](https://mir.cs.illinois.edu/~marinov/publications/AguilarETAL23ReproducingBugsInPy.pdf) +demonstrates why declared metadata is insufficient: dependency installation and +runtime selection can prevent paired reproduction, and both-pass/both-fail +outcomes must remain visible. Its corpus snapshot and results are that study's +observations, not COLEMAN measurements. + +At BugsInPy revision `11c5f1eea954a42132cfd06bf257766a7963e0fd`, no verified +framework license was found. The existing [upstream license question](https://github.com/soarsmu/BugsInPy/issues/94) +remains unresolved. The paper's license and a subject's license do not clear that +framework. No BugsInPy framework code or data is admitted by this increment. + +Two **direct upstream** selected-test pairs were freshly executed on 2026-10-16: + +| Subject | Buggy revision | Fixed / common test revision | Observed result | +| --- | --- | --- | --- | +| Apache Commons CLI, CLI-13 | `8f46f467a33ace44ccd9f394910940b6c48a3827` | `b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e` | One assertion failure / one pass; zero errors or skips | +| Black, process-pool fallback | `26c9465a22c732ab1e17b0dec578fa3432e9b558` | `c0a7582e3d4cc8bec3b7f5a6c52b36880dcb57d7` | One assertion failure / one pass; zero errors or skips | + +Commons CLI used the [official Apache fixed commit](https://github.com/apache/commons-cli/commit/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e), +Git-verified source blobs and its Apache-2.0 LICENSE/NOTICE, +common fixed-revision `BugCLI13Test.testCLI13`, Commons Lang 2.1 and JUnit 3.8.1 +(Maven Central bytes and checksums). It compiled directly with Java 11.0.32.1, +linux/arm64 Temurin manifest +`sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8`. +This was a direct source-pair experiment, not the complete Defects4J reconstruction +or a full original-suite reproduction. JUnit's component terms are CPL-1.0; +Commons Lang retains its own Apache terms. + +Black used the [official upstream fallback fix](https://github.com/psf/black/commit/c0a7582e3d4cc8bec3b7f5a6c52b36880dcb57d7), +MIT source notices, CPython 3.8.3 and 16 pinned offline wheels. +The common fixed-revision +`BlackTestCase.test_works_in_mono_process_only_environment` explicitly injects +`ProcessPoolExecutor` initialization `OSError`. Both roles use the same declared +derived SCM version label `controlled-upstream-source-v1`. The linux/amd64 image +manifest `sha256:13af390c7ababf48b675e151c354de224f2ae6ec17ee08fe04ad3df8d0736501` +was emulated on an arm64 host. Its elapsed counters are not native performance +measurements. This direct upstream experiment does not resolve BugsInPy licensing. + +Both used read-only subject/fixture/harness mounts, execution without network, +non-root UID, bounded memory/CPU/processes and per-case timeout. All source/dependency +bytes and raw observations remain outside Git. No third-party test code or rows +are bundled. These are two selected functional reproductions, not a randomized +sample, full corpus admission, fault-localization matrix, historical CI evidence +or an algorithm comparison. The typed reader does not independently certify this +external execution. A distributable pinned producer recipe, component-by-component +admission dossier and broader fresh test/fault matrix remain necessary before +claiming that the Java/non-Java diversity criteria are satisfied. diff --git a/docs/roadmap.md b/docs/roadmap.md index 7c6c7f41..e510f4bc 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -32,8 +32,10 @@ reuse the existing runner/artifacts/checkpoints. All ten existing native registr retain their admission blockers; all seven required diversity regimes remain uncovered. -The next sequential corpus slice is the version-pinned RTPTorrent adapter and -baseline slice. Later steps cover LRTS, controlled real faults, HCS/variant expansion +**4.5.0** publishes the reviewed RTPTorrent and LRTS source-assessment adapters, +with explicit missing temporal evidence and reproducible admission blockers. +The next sequential corpus slice adds [controlled fault observations](controlled-faults.md). +Later steps cover admitted real-fault matrices, HCS/variant expansion and synthetic stress, comparable baselines/statistics, frozen confirmatory execution and the final evidence report. Compatible deliveries continue in later **4.x** releases. #261 stays open until its admission, diversity, execution and evidence diff --git a/examples/controlled_faults/ci.py b/examples/controlled_faults/ci.py new file mode 100644 index 00000000..92b0d8d5 --- /dev/null +++ b/examples/controlled_faults/ci.py @@ -0,0 +1,206 @@ +"""Owned controlled-observation schema fixture beside a real native CI checkpoint workflow. + +Run outside checkout: python ci.py OUTPUT_DIRECTORY EXTERNAL_CACHE_DIRECTORY. +This synthetic correctness fixture does not execute foreign subject code, pretend +its constructed clocks are CI events, or project elapsed counters into runner costs. +""" + +import hashlib +import io +import json +import math +import sys +from pathlib import Path + +import polars as pl + +from coleman.api import run +from coleman.artifacts import ArtifactWriter +from coleman.corpus import MaterializationSpec, SourceCache, load_registry, materialize_source, validate_bundled_source +from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset +from coleman.corpus.controlled_contracts import ControlledContext, ControlledReport, ControlledSpec +from coleman.corpus.materialization import validate_cache_separation +from coleman.corpus.reference import tiny_ci_reference +from coleman.manifest import generate_manifest +from coleman.pilot import SECONDS +from coleman.selection import Quantity +from coleman.spec.models import RunSpec + + +def materialized(cache, name, payload, version): + """Cache only these newly authored bytes using the existing verified source-package contract.""" + digest = "sha256:" + hashlib.sha256(payload).hexdigest() + spec = MaterializationSpec.model_validate( + { + "schema_version": 1, + "package_id": name, + "archive": "raw", + "source": { + "uri": "urn:coleman:owned:" + name, + "version": version, + "citation": "Repository-authored controlled CI fixture; no third-party data", + "sha256": digest, + "size_bytes": len(payload), + "availability": "not_verified", + }, + "license": load_registry().card("ci-serial-boundary-v1").manifest.license.model_dump(), + "members": [{"name": name + ".json", "sha256": digest, "size_bytes": len(payload)}], + } + ) + return materialize_source(spec, cache, lambda: io.BytesIO(payload)) + + +def owned_dataset(cache): + """Construct explicit same-test pairs, including inconclusive and repeated-trial observations.""" + inputs = [] + for kind, revision in [ + ("buggy_source", "buggy-v1"), + ("fixed_source", "fixed-v1"), + ("test_fixture", "fixed-v1"), + ("harness", "harness-v1"), + ]: + receipt = materialized(cache, kind, json.dumps({"owned": kind}).encode(), revision) + inputs.append({"name": kind, "kind": kind, "materialization": receipt.model_dump()}) + context = ControlledContext.model_validate( + { + "schema_version": 1, + "project": "owned-ci", + "fault_id": "owned-fault", + "language": "Python", + "fault_origin": "synthetic", + "buggy_revision": "buggy-v1", + "fixed_revision": "fixed-v1", + "fixture_revision": "fixed-v1", + "dependence_group": "owned-ci-single-fixture", + "test_ids": ["ci.parse"], + "inputs": inputs, + "runtime": { + "implementation": "schema-fixture", + "version": "1", + "platform": "constructed", + "execution_model": "constructed", + "image_digest": None, + "emulated": False, + "timezone": "UTC", + "setup": ["No subject process is executed by this schema fixture"], + "commands": ["Construct schema-only observations"], + "interventions": [], + }, + "limitations": ["Synthetic schema-only observations; no fault diversity or historical CI claim"], + } + ) + rows = [] + for trial, role, outcome in [ + ("trial-1", "buggy", "assertion_failed"), + ("trial-1", "fixed", "passed"), + ("trial-2", "buggy", "timeout"), + ]: + rows.append( + { + "trial_id": trial, + "role": role, + "test_id": "ci.parse", + "outcome": outcome, + "elapsed": {"value": None, "status": "unavailable"}, + "capture_started_at": "2026-01-01T00:00:00Z", + "capture_finished_at": "2026-01-01T00:00:00Z", + "diagnostics_sha256": None, + } + ) + report = ControlledReport.model_validate( + {"schema_version": 1, "context_fingerprint": context.fingerprint, "observations": rows} + ) + receipt = materialized(cache, "controlled-report", report.to_json().encode(), "owned-report-v1") + spec = ControlledSpec( + schema_version=1, context=context, report_materialization=receipt, report_member="controlled-report.json" + ) + return convert_controlled_source(spec, cache) + + +def main(output, cache_directory): + """Reuse native CI/policies/artifacts/checkpoints; independently verify one complete owned serial suite.""" + workspace = Path.cwd().resolve() + root = (workspace / output).resolve() + if not root.is_relative_to(workspace): + raise ValueError("Owned output must remain within the current workspace") + for name in ("inputs/owned-ci/features-engineered.parquet", "native"): + target = root / name + if target.is_symlink() or not target.resolve().is_relative_to(root): + raise ValueError("Owned output descendants must remain inside their output tree") + validate_cache_separation(cache_directory, root) + cache = SourceCache(cache_directory) + dataset = owned_dataset(cache) + source_spec_path = root / "controlled-spec.json" + ArtifactWriter(root).write_immutable(source_spec_path, dataset.spec.to_json() + "\n") + fixture = validate_bundled_source("ci-serial-boundary-v1").fixture + rows = [ + { + "BuildId": 1, + "Name": test.test_id, + "Duration": float(test.duration.value), + "Verdict": int(test.outcome == "failed"), + "CalcPrio": 0, + "LastRun": "", + } + for test in fixture.build.tests + ] + buffer = io.BytesIO() + pl.DataFrame(rows).write_parquet(buffer) + payload = buffer.getvalue() + ArtifactWriter(root).write_immutable_stream( + root / "inputs/owned-ci/features-engineered.parquet", (payload,), maximum_bytes=len(payload) + ) + spec = RunSpec.model_validate( + { + "execution": {"independent_executions": 1, "parallel_pool_size": 1, "seed": 42, "verbose": False}, + "experiment": { + "datasets_dir": str(root / "inputs"), + "datasets": ["owned-ci"], + "policies": ["Random"], + "rewards": ["RNFail"], + "budget": {"mode": "fixed_time", "values": [7]}, + }, + "checkpoint": {"enabled": True, "interval": 1}, + "results": {"out_dir": str(root / "native"), "top_k_prioritization": 3}, + "extensions": { + "controlled": {"dataset_fingerprint": dataset.fingerprint, "scope": "synthetic-schema-fixture"} + }, + } + ) + first = run(spec) + second = run(spec) + if first.run_id != second.run_id or second.artifacts_dir is None: + raise ValueError("Native checkpoint continuation lost its identity") + directory = Path(second.artifacts_dir) + native = pl.read_parquet(str(directory / "results/**/*.parquet"), hive_partitioning=True) + if native.height != 1: + raise ValueError("Native checkpoint must retain exactly one committed result") + row = native.row(0, named=True) + reference = tiny_ci_reference( + fixture.build, tuple(json.loads(row["prioritization_order_top_k"])), Quantity(value=7, semantics=SECONDS) + ) + for actual, expected in ((row["fitness"], reference.napfd.value), (row["cost"], reference.apfdc.value)): + if expected is None or not math.isclose(actual, float(expected), rel_tol=0, abs_tol=1e-12): + raise ValueError("Native metric disagrees with independent exact CI reference") + path = publish_controlled_dataset(dataset, cache, ArtifactWriter(directory)) + manifest = json.loads(generate_manifest(directory, run_id=second.run_id).read_bytes()) + if not any(item["type"] == "corpus_controlled_dataset" for item in manifest["artifacts"]): + raise ValueError("Native manifest omitted controlled provenance") + print( + json.dumps( + { + "spec": str(source_spec_path), + "dataset": str(path), + "native_root": str(directory), + "native_rows": native.height, + "classifications": [pair.classification for pair in dataset.pairs], + "admission": dataset.admission, + "generalization": dataset.generalization, + }, + sort_keys=True, + ) + ) + + +if __name__ == "__main__": + main(*sys.argv[1:]) diff --git a/llms.txt b/llms.txt index 64a8e4d2..9e6ac1b8 100644 --- a/llms.txt +++ b/llms.txt @@ -33,6 +33,7 @@ parallel execution, and extensibility via hooks and namespaced custom config. - docs/benchmark-corpus.md - docs/code-cost.md - docs/configuration.md +- docs/controlled-faults.md - docs/corpus-materialization.md - docs/decision-benchmarks.md - docs/decisions/001-point-in-time-observations.md @@ -2174,6 +2175,15 @@ flowchart LR ``` +The next [controlled fault observation adapter](controlled-faults.md) retains +same-test buggy/fixed comparisons, exact elapsed-counter units and negative or +inconclusive outcomes. It verifies producer bytes through the existing source +cache and publishes through the same artifact writer. It does not grant source +admission or convert collection clocks into historical CI chronology. Direct +upstream Java/Python reproductions are documented separately from the owned +synthetic installed example; required diversity cells remain uncovered. + + ### FILE: docs/code-cost.md @@ -3089,6 +3099,229 @@ coleman validate --config my-experiment.yaml --resolve resolved.json +### FILE: docs/controlled-faults.md + +# Controlled real-fault observations + +Controlled buggy/fixed pairs answer a narrow question: does the same selected +assertion fail against one source revision and pass against the corrected revision +under the declared execution conditions? COLEMAN can retain that evidence, +including unexpected and inconclusive results, without presenting a reconstructed +sequence as historical CI. + +This source slice of [#261](https://github.com/jacksonpradolima/coleman/issues/261) +adds an offline typed observation adapter. It does not complete source admission, +fault diversity, baseline comparisons or the cross-corpus benchmark. The registry's +seven required diversity cells remain uncovered. Source assessments for +[RTPTorrent](rtptorrent.md) and [LRTS](lrts.md) remain separate. + +## Architecture and trust boundary + +```mermaid +flowchart LR + producer[External subject execution] --> report[Pinned producer observation report] + inputs[Reviewed source / fixture / harness inputs] --> cache[Existing external source cache] + report --> cache + context[Frozen controlled context] --> adapter[Offline typed conversion] + cache --> adapter + adapter --> pairs[Expected / unexpected / inconclusive pairs] + adapter --> writer[Existing immutable artifact writer] + writer --> manifest[Native run artifact manifest] +``` + +The core reads and verifies cached bytes. It never starts a subject process, +container, compiler, CLI or network transport. A receipt proves byte correspondence, +not that a producer executed those bytes. Runtime and command descriptions remain +producer attestations. Review and execution of external subjects belong outside +this adapter, with their own component terms and resource limits. + +`ControlledContext` freezes project, curated fault label, language, fault origin, +source revisions, fixture revision, dependence group, declared test IDs, input +receipts and runtime conditions. Exactly one buggy source, fixed source, common +test fixture and harness input is required. Dependency inputs are separate. Source +versions must match the declared revisions. Input names and test IDs are unique; +permuting those declarations preserves context identity. Opaque source archives +can be cached as raw packages; this adds no TAR or ZIP64 extraction capability. + +`ControlledReport` binds observations to the context fingerprint. Each observation +has a trial ID, role, test ID, explicit outcome, capture instants, nullable diagnostic +digest and monotonic elapsed counter. A non-null diagnostic digest must match a +separate regular member of the validated report package; absent references reject. +Diagnostics are not predecision features. Capture instants are collection clocks, not +historical event or feature availability. No observed CI chronology is inferred. + +Execution identity hashes the context and `(trial_id, test_id, role)`, excluding +outcomes and capture values. A retry of the same collection retains its trial ID; +a genuinely new execution gets a new trial ID. Both remain in the same declared +dependence group. These IDs do not establish independent bugs or projects. + +## Outcomes, units and missingness + +| Buggy observation | Fixed observation | Comparison | +| --- | --- | --- | +| Assertion failed | Passed | Expected | +| Passed | Passed | Both pass | +| Assertion failed | Assertion failed | Both fail | +| Passed | Assertion failed | Reversed | +| Missing role, test error, skipped, timeout, cancellation, infrastructure error or unavailable | Any | Inconclusive | + +The same inconclusive rule applies when the fixed role has a non-assertion outcome. +Only actual test/trial groups are compared. An empty report has no comparisons; +missing observations are never fabricated. Unexpected and inconclusive results +are valid evidence and remain in the dataset. + +Elapsed values are strict nonnegative integer **nanoseconds**, at most `2**63-1`, +with meaning `observed-test-harness-monotonic-elapsed-v1`. Zero is observed. Null +requires `unavailable` or `not_applicable`; an observed null or absent-state zero +rejects. Negative, fractional, boolean, nonfinite and incompatible-unit values +reject. Counter resolution establishes no physical measurement accuracy. + +Elapsed harness time includes whatever that harness times. It is not independently +removable runner work, shared setup cost, queue delay or developer-visible CI +latency. It must not be substituted for native scheduling costs. This contract +does not claim that all negative numbers are invalid in other result families; +negative signed measurements remain governed by their existing contracts. + +## Installed package workflow + +Build and install the working branch's wheel in a separate environment. The +released 4.5 wheel predates this adapter. From the checkout: + +```bash +wheel_dir=$(mktemp -d /tmp/coleman-controlled-wheel.XXXXXX) +uv build --wheel --out-dir "$wheel_dir" +uv venv /tmp/coleman-controlled-installed --python 3.14 +uv pip install --python /tmp/coleman-controlled-installed/bin/python "$wheel_dir"/*.whl +mkdir -p /tmp/coleman-controlled-workspace +cp examples/controlled_faults/ci.py /tmp/coleman-controlled-workspace/ci.py +cd /tmp/coleman-controlled-workspace +/tmp/coleman-controlled-installed/bin/python ci.py owned-ci /tmp/coleman-controlled-source-cache +``` + +The example's pairs are **newly authored synthetic schema fixtures**, not external +real faults or measured executions. Their constructed capture instants and +unavailable elapsed counters are explicit. A separate complete owned serial CI +fixture runs real native Random/RNFail with budget 7 seconds, independently checked +NAPFD/APFDc and a second call through the learning checkpoint. No counter from the +controlled observations is projected into that serial fixture's costs. + +Re-running the command preserves the controlled artifact and committed native +result. The output includes the frozen `spec`, converted `dataset`, classifications +(`expected`, `inconclusive`), native directory and explicit insufficient-evidence +status. This demonstrates integration and recovery, not external effectiveness. + +The following complete SDK example reopens that specification offline. It runs +from the same external workspace and requires no CLI or MCP imports: + +```python +from pathlib import Path + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import SourceCache +from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset +from coleman.corpus.controlled_contracts import ControlledSpec + +cache = SourceCache("/tmp/coleman-controlled-source-cache") +spec = ControlledSpec.from_json(Path("owned-ci/controlled-spec.json").read_bytes()) +dataset = convert_controlled_source(spec, cache) +assert [pair.classification for pair in dataset.pairs] == ["expected", "inconclusive"] +path = publish_controlled_dataset(dataset, cache, ArtifactWriter("offline-assessment")) +assert dataset.admission == "not_evaluated" +assert dataset.history == "constructed" +print(path) +``` + +For another cache location, replace the SDK path with the same location supplied +to `ci.py`. Input/report materializations use the existing reviewed-license, +source-digest, bounded-byte and offline validation contracts. Reports have an +8-MiB ceiling and at most 20,000 physical observations; contexts permit at most +10,000 test IDs and 64 input packages. Every report is checked against the bytes +actually parsed, including EOF size/digest, after cache validation. + +## Compatibility, duplication and publication + +All new interchange models require integer `schema_version: 1`, reject unknown +fields, and reject missing, legacy and future versions. Existing native results, +source manifests, checkpoints and historical artifacts keep their existing +meaning. No migration or automatic reinterpretation occurs. A future converter +must declare any migration separately and preserve original bytes. + +Conversion conserves physical rows: `input_rows = observations + duplicates_excluded`. +Identical role/test/trial repeats are counted and excluded; conflicting repetitions +reject. Output observations are sorted by logical key. Permuting physical report +rows preserves normalized observations but changes the pinned source report bytes +and therefore the complete artifact fingerprint. This is deliberate provenance, +not an input-order-dependent policy comparison. + +Publication re-converts the actual cache before writing one +`corpus-controlled/.json` artifact. Identical concurrent publication +is idempotent through the existing immutable writer. Partial work is never a +completed experiment or learning checkpoint. A failed publication can be retried; +recipe-only content must remain local. Artifact metadata alone does not establish +source integrity, execution truth, scientific admission or independence. + +## Primary-source investigation and fresh local evidence + +The [Defects4J paper](https://homes.cs.washington.edu/~mernst/pubs/bug-database-issta2014.pdf) +and [pinned documentation](https://github.com/rjust/defects4j/tree/8c16da8230843cdc918eaf4ddb449637f02b83c6) +describe isolated buggy/fixed subjects, including reconstructed revisions. +The current documentation requires Java 11 and `America/Los_Angeles`; its current +corpus differs from the paper's original snapshot. Framework MIT terms do not +license every subject or dependency. Broad initialization downloads unrelated +repositories and tools; it was not used for the bounded case below. + +The [BugsInPy paper](https://arxiv.org/html/2401.15481v1) describes selected real +source revisions and common exposing tests, with manual isolation review. A later +[independent reproduction study](https://mir.cs.illinois.edu/~marinov/publications/AguilarETAL23ReproducingBugsInPy.pdf) +demonstrates why declared metadata is insufficient: dependency installation and +runtime selection can prevent paired reproduction, and both-pass/both-fail +outcomes must remain visible. Its corpus snapshot and results are that study's +observations, not COLEMAN measurements. + +At BugsInPy revision `11c5f1eea954a42132cfd06bf257766a7963e0fd`, no verified +framework license was found. The existing [upstream license question](https://github.com/soarsmu/BugsInPy/issues/94) +remains unresolved. The paper's license and a subject's license do not clear that +framework. No BugsInPy framework code or data is admitted by this increment. + +Two **direct upstream** selected-test pairs were freshly executed on 2026-10-16: + +| Subject | Buggy revision | Fixed / common test revision | Observed result | +| --- | --- | --- | --- | +| Apache Commons CLI, CLI-13 | `8f46f467a33ace44ccd9f394910940b6c48a3827` | `b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e` | One assertion failure / one pass; zero errors or skips | +| Black, process-pool fallback | `26c9465a22c732ab1e17b0dec578fa3432e9b558` | `c0a7582e3d4cc8bec3b7f5a6c52b36880dcb57d7` | One assertion failure / one pass; zero errors or skips | + +Commons CLI used the [official Apache fixed commit](https://github.com/apache/commons-cli/commit/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e), +Git-verified source blobs and its Apache-2.0 LICENSE/NOTICE, +common fixed-revision `BugCLI13Test.testCLI13`, Commons Lang 2.1 and JUnit 3.8.1 +(Maven Central bytes and checksums). It compiled directly with Java 11.0.32.1, +linux/arm64 Temurin manifest +`sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8`. +This was a direct source-pair experiment, not the complete Defects4J reconstruction +or a full original-suite reproduction. JUnit's component terms are CPL-1.0; +Commons Lang retains its own Apache terms. + +Black used the [official upstream fallback fix](https://github.com/psf/black/commit/c0a7582e3d4cc8bec3b7f5a6c52b36880dcb57d7), +MIT source notices, CPython 3.8.3 and 16 pinned offline wheels. +The common fixed-revision +`BlackTestCase.test_works_in_mono_process_only_environment` explicitly injects +`ProcessPoolExecutor` initialization `OSError`. Both roles use the same declared +derived SCM version label `controlled-upstream-source-v1`. The linux/amd64 image +manifest `sha256:13af390c7ababf48b675e151c354de224f2ae6ec17ee08fe04ad3df8d0736501` +was emulated on an arm64 host. Its elapsed counters are not native performance +measurements. This direct upstream experiment does not resolve BugsInPy licensing. + +Both used read-only subject/fixture/harness mounts, execution without network, +non-root UID, bounded memory/CPU/processes and per-case timeout. All source/dependency +bytes and raw observations remain outside Git. No third-party test code or rows +are bundled. These are two selected functional reproductions, not a randomized +sample, full corpus admission, fault-localization matrix, historical CI evidence +or an algorithm comparison. The typed reader does not independently certify this +external execution. A distributable pinned producer recipe, component-by-component +admission dossier and broader fresh test/fault matrix remain necessary before +claiming that the Java/non-Java diversity criteria are satisfied. + + + ### FILE: docs/corpus-materialization.md # Verified source packages for CI benchmarks @@ -7803,8 +8036,10 @@ reuse the existing runner/artifacts/checkpoints. All ten existing native registr retain their admission blockers; all seven required diversity regimes remain uncovered. -The next sequential corpus slice is the version-pinned RTPTorrent adapter and -baseline slice. Later steps cover LRTS, controlled real faults, HCS/variant expansion +**4.5.0** publishes the reviewed RTPTorrent and LRTS source-assessment adapters, +with explicit missing temporal evidence and reproducible admission blockers. +The next sequential corpus slice adds [controlled fault observations](controlled-faults.md). +Later steps cover admitted real-fault matrices, HCS/variant expansion and synthetic stress, comparable baselines/statistics, frozen confirmatory execution and the final evidence report. Compatible deliveries continue in later **4.x** releases. #261 stays open until its admission, diversity, execution and evidence diff --git a/tests/corpus/fixtures/controlled-owned-pair-v1.json b/tests/corpus/fixtures/controlled-owned-pair-v1.json new file mode 100644 index 00000000..32b6de5a --- /dev/null +++ b/tests/corpus/fixtures/controlled-owned-pair-v1.json @@ -0,0 +1 @@ +{"admission":"not_evaluated","duplicates_excluded":0,"generalization":"insufficient_evidence","history":"constructed","input_rows":2,"observations":[{"capture_finished_at":"2026-01-01T00:00:00Z","capture_started_at":"2026-01-01T00:00:00Z","diagnostics_sha256":null,"elapsed":{"meaning":"observed-test-harness-monotonic-elapsed-v1","status":"observed","unit":"ns","value":0},"outcome":"assertion_failed","role":"buggy","test_id":"ci.parse","trial_id":"trial-1"},{"capture_finished_at":"2026-01-01T00:00:00Z","capture_started_at":"2026-01-01T00:00:00Z","diagnostics_sha256":null,"elapsed":{"meaning":"observed-test-harness-monotonic-elapsed-v1","status":"observed","unit":"ns","value":0},"outcome":"passed","role":"fixed","test_id":"ci.parse","trial_id":"trial-1"}],"schema_version":1,"scope":"controlled-functional-observations-only","spec":{"context":{"buggy_revision":"buggy-v1","dependence_group":"owned-ci-single-fixture","fault_id":"owned-parser-fault","fault_origin":"synthetic","fixed_revision":"fixed-v1","fixture_revision":"fixed-v1","inputs":[{"kind":"buggy_source","materialization":{"admission":"not_evaluated","schema_version":1,"scope":"source-integrity-only","spec":{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"buggy_source.json","sha256":"sha256:510fe12d18e4873529c93a075a5651f53de1b89355006825f73e3df19dd15b43","size_bytes":25}],"package_id":"buggy_source","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Repository-authored CI correctness fixture; no foreign rows","sha256":"sha256:510fe12d18e4873529c93a075a5651f53de1b89355006825f73e3df19dd15b43","size_bytes":25,"uri":"urn:coleman:owned:buggy_source","version":"buggy-v1"}}},"name":"buggy_source"},{"kind":"fixed_source","materialization":{"admission":"not_evaluated","schema_version":1,"scope":"source-integrity-only","spec":{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"fixed_source.json","sha256":"sha256:c5c6909276fc1075e9ab78fd772467833e34f9e87bac5f49662dce95e8029850","size_bytes":25}],"package_id":"fixed_source","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Repository-authored CI correctness fixture; no foreign rows","sha256":"sha256:c5c6909276fc1075e9ab78fd772467833e34f9e87bac5f49662dce95e8029850","size_bytes":25,"uri":"urn:coleman:owned:fixed_source","version":"fixed-v1"}}},"name":"fixed_source"},{"kind":"harness","materialization":{"admission":"not_evaluated","schema_version":1,"scope":"source-integrity-only","spec":{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"harness.json","sha256":"sha256:b3991ceb444e0f5c12991da477aa6d0ce3c108a17289a567346ccea3946ad41c","size_bytes":20}],"package_id":"harness","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Repository-authored CI correctness fixture; no foreign rows","sha256":"sha256:b3991ceb444e0f5c12991da477aa6d0ce3c108a17289a567346ccea3946ad41c","size_bytes":20,"uri":"urn:coleman:owned:harness","version":"harness-v1"}}},"name":"harness"},{"kind":"test_fixture","materialization":{"admission":"not_evaluated","schema_version":1,"scope":"source-integrity-only","spec":{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"test_fixture.json","sha256":"sha256:b2185d292e1692a81c7d654518933059d64b5fc32ad5d2bc76304ce0f01a0906","size_bytes":25}],"package_id":"test_fixture","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Repository-authored CI correctness fixture; no foreign rows","sha256":"sha256:b2185d292e1692a81c7d654518933059d64b5fc32ad5d2bc76304ce0f01a0906","size_bytes":25,"uri":"urn:coleman:owned:test_fixture","version":"fixed-v1"}}},"name":"test_fixture"}],"language":"Python","limitations":["Synthetic schema-only evidence; no historical CI or fault independence"],"project":"owned-ci","recipe":"controlled-fault-observations-v1","runtime":{"commands":["Descriptive owned fixture; no commands executed"],"emulated":false,"execution_model":"constructed","image_digest":null,"implementation":"owned-runtime-description","interventions":[],"platform":"constructed","setup":["Constructed schema-only observations; no source execution claimed"],"timezone":"UTC","version":"1"},"schema_version":1,"test_ids":["ci.parse"]},"report_materialization":{"admission":"not_evaluated","schema_version":1,"scope":"source-integrity-only","spec":{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"observations.json","sha256":"sha256:b911d7fbbcf44ce82c789edfb292c943045dee14ceb68b6453e9755b6abc9c7e","size_bytes":747}],"package_id":"observations","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Repository-authored CI correctness fixture; no foreign rows","sha256":"sha256:b911d7fbbcf44ce82c789edfb292c943045dee14ceb68b6453e9755b6abc9c7e","size_bytes":747,"uri":"urn:coleman:owned:observations","version":"owned-v1"}}},"report_member":"observations.json","schema_version":1}} diff --git a/tests/corpus/test_controlled.py b/tests/corpus/test_controlled.py new file mode 100644 index 00000000..359336a3 --- /dev/null +++ b/tests/corpus/test_controlled.py @@ -0,0 +1,430 @@ +"""Owned controlled-source observations: exact identities, negative outcomes and cache integrity.""" + +import hashlib +import io +import json +import zipfile +from concurrent.futures import ThreadPoolExecutor +from datetime import UTC, datetime +from pathlib import Path + +import pytest + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import MaterializationSpec, SourceCache, load_registry, materialize_source +from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset, validate_controlled_dataset +from coleman.corpus.controlled_contracts import ( + ControlledContext, + ControlledDataset, + ControlledElapsed, + ControlledInput, + ControlledObservation, + ControlledPair, + ControlledReport, + ControlledRuntime, + ControlledSpec, +) +from coleman.manifest import generate_manifest + + +def digest(data): + return "sha256:" + hashlib.sha256(data).hexdigest() + + +def changed(model, **values): + return type(model).model_validate({**model.model_dump(), **values}) + + +def materialized(cache, name, payload, version="owned-v1"): + spec = MaterializationSpec.model_validate( + { + "schema_version": 1, + "package_id": name, + "archive": "raw", + "source": { + "uri": "urn:coleman:owned:" + name, + "version": version, + "citation": "Repository-authored CI correctness fixture; no foreign rows", + "sha256": digest(payload), + "size_bytes": len(payload), + "availability": "not_verified", + }, + "license": load_registry().card("ci-serial-boundary-v1").manifest.license.model_dump(), + "members": [{"name": name + ".json", "sha256": digest(payload), "size_bytes": len(payload)}], + } + ) + return materialize_source(spec, cache, lambda: io.BytesIO(payload)) + + +def context(cache): + inputs = [] + for kind, revision in [ + ("buggy_source", "buggy-v1"), + ("fixed_source", "fixed-v1"), + ("test_fixture", "fixed-v1"), + ("harness", "harness-v1"), + ]: + receipt = materialized(cache, kind, json.dumps({"owned": kind}).encode(), revision) + inputs.append(ControlledInput.model_validate({"name": kind, "kind": kind, "materialization": receipt})) + return ControlledContext( + schema_version=1, + project="owned-ci", + fault_id="owned-parser-fault", + language="Python", + fault_origin="synthetic", + buggy_revision="buggy-v1", + fixed_revision="fixed-v1", + fixture_revision="fixed-v1", + dependence_group="owned-ci-single-fixture", + test_ids=("ci.parse",), + inputs=tuple(inputs), + runtime=ControlledRuntime( + implementation="owned-runtime-description", + version="1", + platform="constructed", + execution_model="constructed", + image_digest=None, + emulated=False, + timezone="UTC", + setup=("Constructed schema-only observations; no source execution claimed",), + commands=("Descriptive owned fixture; no commands executed",), + interventions=(), + ), + limitations=("Synthetic schema-only evidence; no historical CI or fault independence",), + ) + + +def observation(role="buggy", outcome="assertion_failed", trial="trial-1"): + return ControlledObservation( + trial_id=trial, + role=role, + test_id="ci.parse", + outcome=outcome, + elapsed=ControlledElapsed(value=0, status="observed"), + capture_started_at=datetime(2026, 1, 1, tzinfo=UTC), + capture_finished_at=datetime(2026, 1, 1, tzinfo=UTC), + diagnostics_sha256=None, + ) + + +def source(cache, rows=None, ctx=None): + ctx = context(cache) if ctx is None else ctx + rows = (observation(), observation("fixed", "passed")) if rows is None else rows + report = ControlledReport(schema_version=1, context_fingerprint=ctx.fingerprint, observations=rows) + receipt = materialized(cache, "observations", report.to_json().encode()) + return ControlledSpec( + schema_version=1, context=ctx, report_materialization=receipt, report_member="observations.json" + ) + + +def test_roundtrip_golden_cache_source_and_manifest(tmp_path): + cache = SourceCache(tmp_path / "cache") + spec = source(cache) + result = convert_controlled_source(spec, cache) + for item in (spec, spec.context, result): + assert type(item).from_json(item.to_json()) == item + golden = Path(__file__).with_name("fixtures") / "controlled-owned-pair-v1.json" + assert result.to_json() + "\n" == golden.read_text() + validate_controlled_dataset(result, cache) + assert [p.classification for p in result.pairs] == ["expected"] + assert result.history == "constructed" + assert result.admission == "not_evaluated" + with pytest.raises(ValueError, match="not historical CI"): + result.require_temporal_evaluation() + writer = ArtifactWriter(tmp_path / "out") + path = publish_controlled_dataset(result, cache, writer) + manifest = json.loads(generate_manifest(writer.run_root, run_id="owned-ci").read_bytes()) + assert any(a["type"] == "corpus_controlled_dataset" for a in manifest["artifacts"]) + assert ControlledDataset.from_json(path.read_bytes()) == result + + +@pytest.mark.parametrize("kind", [ControlledSpec, ControlledContext, ControlledDataset, ControlledReport]) +@pytest.mark.parametrize("version", [None, 0, 2, True, "1"]) +def test_unknown_versions_reject_without_legacy_migration(tmp_path, kind, version): + cache = SourceCache(tmp_path / "cache") + spec = source(cache) + report = ControlledReport(schema_version=1, context_fingerprint=spec.context.fingerprint, observations=()) + objects = { + ControlledSpec: spec, + ControlledContext: spec.context, + ControlledDataset: convert_controlled_source(spec, cache), + ControlledReport: report, + } + payload = objects[kind].model_dump(mode="json") + if version is None: + del payload["schema_version"] + else: + payload["schema_version"] = version + encoded = json.dumps(payload) + with pytest.raises(ValueError): + kind.from_json(encoded) + + +@pytest.mark.parametrize( + "outcomes,expected", + [ + (("assertion_failed", "passed"), "expected"), + (("passed", "passed"), "both_pass"), + (("assertion_failed", "assertion_failed"), "both_fail"), + (("passed", "assertion_failed"), "reversed"), + ((None, "passed"), "inconclusive"), + (("timeout", "passed"), "inconclusive"), + (("test_error", "passed"), "inconclusive"), + (("infrastructure_error", "passed"), "inconclusive"), + (("skipped", "passed"), "inconclusive"), + (("cancelled", "passed"), "inconclusive"), + (("unavailable", "passed"), "inconclusive"), + ], +) +def test_classification_preserves_negative_and_inconclusive_results(outcomes, expected): + assert ControlledPair(trial_id="t", test_id="case", buggy=outcomes[0], fixed=outcomes[1]).classification == expected + + +@pytest.mark.parametrize("value", [-1, 1.1, True, float("inf"), float("nan"), "1"]) +def test_ticks_are_exact_nonnegative_integer_nanoseconds(value): + with pytest.raises(ValueError): + ControlledElapsed(value=value, status="observed") + + +def test_zero_null_unavailable_not_applicable_and_units(): + assert ControlledElapsed(value=0, status="observed").value == 0 + for status in ("unavailable", "not_applicable"): + assert ControlledElapsed(value=None, status=status).value is None + with pytest.raises(ValueError): + ControlledElapsed(value=0, status=status) + with pytest.raises(ValueError): + ControlledElapsed(value=None, status="observed") + for change in ({"unit": "s"}, {"meaning": "runner-work"}, {"status": "unknown"}): + with pytest.raises(ValueError): + ControlledElapsed.model_validate({"value": 0, "status": "observed", **change}) + + +@pytest.mark.parametrize("value", [0, 1, 10**9, 2**53 + 1, 2**63 - 1]) +def test_integer_elapsed_roundtrip_metamorphic(value): + item = ControlledElapsed(value=value, status="observed") + assert ControlledElapsed.model_validate_json(item.model_dump_json()) == item + + +def test_duplicate_accounting_conflicts_input_order_and_logical_identity(tmp_path): + cache = SourceCache(tmp_path / "cache") + ctx = context(cache) + a = observation() + b = observation("fixed", "passed") + first = convert_controlled_source(source(cache, (a, b, a), ctx), cache) + second = convert_controlled_source(source(cache, (b, a, a), ctx), cache) + assert first.observations == second.observations + assert first.input_rows == 3 + assert first.duplicates_excluded == 1 + assert first.spec.context.fingerprint == second.spec.context.fingerprint + assert changed(a, outcome="passed").execution_id(ctx) == a.execution_id(ctx) + assert changed(a, trial_id="trial-2").execution_id(ctx) != a.execution_id(ctx) + assert changed(ctx, inputs=tuple(reversed(ctx.inputs)), test_ids=tuple(reversed(ctx.test_ids))) == ctx + conflicting = source(cache, (a, changed(a, outcome="passed")), ctx) + with pytest.raises(ValueError, match="Conflicting"): + convert_controlled_source(conflicting, cache) + single = convert_controlled_source(source(cache, (a,), ctx), cache) + assert single.pairs[0].fixed is None + assert single.pairs[0].classification == "inconclusive" + assert convert_controlled_source(source(cache, (), ctx), cache).pairs == () + + +def test_context_binding_missing_inputs_revisions_and_universe(tmp_path): + cache = SourceCache(tmp_path / "cache") + ctx = context(cache) + for updates in ( + {"buggy_revision": "fixed-v1"}, + {"fixture_revision": "other"}, + {"test_ids": ("same", "same")}, + {"inputs": ctx.inputs[:-1]}, + {"inputs": (*ctx.inputs, ctx.inputs[0])}, + ): + with pytest.raises(ValueError): + changed(ctx, **updates) + spec = source(cache, ctx=ctx) + mismatched = changed(spec, context=changed(ctx, project="other")) + with pytest.raises(ValueError, match="fingerprint mismatch"): + convert_controlled_source(mismatched, cache) + outside_universe = source(cache, (changed(observation(), test_id="other"),), ctx) + with pytest.raises(ValueError, match="outside declared universe"): + convert_controlled_source(outside_universe, cache) + valid_observation = observation() + with pytest.raises(ValueError, match="finishes before"): + changed(valid_observation, capture_finished_at="2025-12-31T23:59:59Z") + with pytest.raises(ValueError): + changed(valid_observation, capture_started_at="2026-01-01T00:00:00") + with pytest.raises(ValueError, match="member missing"): + changed(spec, report_member="missing") + + +def test_tampering_conservation_and_duplicate_dataset_reject(tmp_path): + cache = SourceCache(tmp_path / "cache") + spec = source(cache) + result = convert_controlled_source(spec, cache) + for updates in ({"input_rows": 0}, {"duplicates_excluded": 1}, {"observations": (result.observations[0],) * 2}): + with pytest.raises(ValueError): + changed(result, **updates) + altered = changed(result, observations=(changed(result.observations[0], outcome="passed"), result.observations[1])) + with pytest.raises(ValueError, match="disagrees"): + validate_controlled_dataset(altered, cache) + path = cache.member_path(spec.report_materialization, spec.report_member) + path.write_bytes(b"{}") + with pytest.raises(ValueError): + convert_controlled_source(spec, cache) + + +def test_concurrent_publication_replay_and_interruption(tmp_path, monkeypatch): + cache = SourceCache(tmp_path / "cache") + result = convert_controlled_source(source(cache), cache) + writer = ArtifactWriter(tmp_path / "out") + with ThreadPoolExecutor(max_workers=4) as pool: + paths = list(pool.map(lambda _: publish_controlled_dataset(result, cache, writer), range(8))) + assert len(set(paths)) == 1 + assert len(list(writer.run_root.rglob("*.json"))) == 1 + other = ArtifactWriter(tmp_path / "interrupted") + import coleman.artifacts as artifacts + + original = artifacts.os.link + + def interrupted(*args, **kwargs): + raise OSError("interrupted before publication") + + monkeypatch.setattr(artifacts.os, "link", interrupted) + with pytest.raises(OSError, match="interrupted"): + publish_controlled_dataset(result, cache, other) + assert not list(other.run_root.rglob("*.json")) + assert not list(other.run_root.rglob("*.tmp")) + monkeypatch.setattr(artifacts.os, "link", original) + assert publish_controlled_dataset(result, cache, other).exists() + overlapping = ArtifactWriter(cache.root) + with pytest.raises(ValueError): + publish_controlled_dataset(result, cache, overlapping) + + +def test_runtime_container_identity_and_revision_kind_cardinality(tmp_path): + cache = SourceCache(tmp_path / "cache") + ctx = context(cache) + with pytest.raises(ValueError, match="image digest"): + changed(ctx.runtime, execution_model="container") + runtime = changed(ctx.runtime, execution_model="container", image_digest=digest(b"owned-container-manifest")) + assert runtime.image_digest is not None + with pytest.raises(ValueError, match="image digest"): + changed(runtime, execution_model="host") + renamed = changed(ctx.inputs[0], name="extra-unique-name") + with pytest.raises(ValueError, match="exactly one input"): + changed(ctx, inputs=(*ctx.inputs, renamed)) + + +def test_report_member_limit_and_context_source_tampering(tmp_path): + cache = SourceCache(tmp_path / "cache") + spec = source(cache) + receipt = spec.report_materialization + member = changed(receipt.spec.members[0], size_bytes=8 * 1024**2 + 1) + raw = changed(receipt.spec, source=changed(receipt.spec.source, size_bytes=member.size_bytes), members=(member,)) + oversized = changed(receipt, spec=raw) + with pytest.raises(ValueError, match="exceeds 8 MiB"): + changed(spec, report_materialization=oversized) + source_receipt = spec.context.inputs[0].materialization + cache.member_path(source_receipt, source_receipt.spec.members[0].name).write_bytes(b"changed input") + with pytest.raises(ValueError): + convert_controlled_source(spec, cache) + + +def test_actual_parsed_bytes_are_rechecked_after_cache_validation(tmp_path, monkeypatch): + cache = SourceCache(tmp_path / "cache") + spec = source(cache) + original = cache.member_path + + def mutated(receipt, name): + path = original(receipt, name) + if receipt == spec.report_materialization: + path.write_bytes(b"{}") + return path + + monkeypatch.setattr(cache, "member_path", mutated) + with pytest.raises(ValueError, match="Parsed controlled report bytes"): + convert_controlled_source(spec, cache) + + +def test_unchecked_dataset_and_unsafe_publication_cannot_bypass_validation(tmp_path): + cache = SourceCache(tmp_path / "cache") + result = convert_controlled_source(source(cache), cache) + unchecked = result.model_copy(update={"input_rows": -1}) + invalid_output = ArtifactWriter(tmp_path / "out") + with pytest.raises(ValueError): + publish_controlled_dataset(unchecked, cache, invalid_output) + writer = ArtifactWriter(tmp_path / "unsafe") + outside = tmp_path / "elsewhere" + outside.mkdir() + writer.run_root.mkdir() + (writer.run_root / "corpus-controlled").symlink_to(outside, target_is_directory=True) + with pytest.raises(ValueError, match="within their output tree"): + publish_controlled_dataset(result, cache, writer) + assert not list(outside.iterdir()) + + +def test_unpinned_diagnostic_digest_rejects(tmp_path): + cache = SourceCache(tmp_path / "cache") + ctx = context(cache) + spec = source(cache, (changed(observation(), diagnostics_sha256=digest(b"absent diagnostics")),), ctx) + with pytest.raises(ValueError, match="diagnostic digest"): + convert_controlled_source(spec, cache) + + +def diagnostic_source(cache, diagnostic_digest=None): + """Own a pinned report/diagnostic package, independent of raw-format or real subject code.""" + ctx = context(cache) + diagnostic = b"Owned assertion diagnostic. No foreign trace.\n" + observed = changed( + observation(), diagnostics_sha256=digest(diagnostic) if diagnostic_digest is None else diagnostic_digest + ) + report = ControlledReport(schema_version=1, context_fingerprint=ctx.fingerprint, observations=(observed,)) + payload = report.to_json().encode() + buffer = io.BytesIO() + entries = {"report.json": payload, "diagnostics.log": diagnostic} + with zipfile.ZipFile(buffer, "w") as archive: + for name, data in entries.items(): + archive.writestr(zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)), data) + packaged = buffer.getvalue() + base = materialized(cache, "diagnostic-envelope", packaged) + spec = changed( + base.spec, + archive="zip", + members=tuple( + {"name": name, "sha256": digest(data), "size_bytes": len(data)} for name, data in entries.items() + ), + ) + receipt = materialize_source(spec, cache, lambda: io.BytesIO(packaged)) + return ControlledSpec(schema_version=1, context=ctx, report_materialization=receipt, report_member="report.json") + + +def test_packaged_diagnostics_validate_roundtrip_publication_and_tampering(tmp_path): + cache = SourceCache(tmp_path / "cache") + spec = diagnostic_source(cache) + result = convert_controlled_source(spec, cache) + assert result.observations[0].diagnostics_sha256 is not None + assert ControlledDataset.from_json(result.to_json()) == result + writer = ArtifactWriter(tmp_path / "out") + assert publish_controlled_dataset(result, cache, writer).exists() + path = cache.member_path(spec.report_materialization, "diagnostics.log") + path.write_bytes(b"changed diagnostics") + with pytest.raises(ValueError): + validate_controlled_dataset(result, cache) + + +def test_cached_context_input_does_not_substitute_for_report_diagnostics(tmp_path): + cache = SourceCache(tmp_path / "cache") + ctx = context(cache) + other_digest = ctx.inputs[0].materialization.spec.members[0].sha256 + spec = diagnostic_source(cache, other_digest) + with pytest.raises(ValueError, match="diagnostic digest"): + convert_controlled_source(spec, cache) + + +def test_diagnostic_binding_is_also_enforced_on_dataset_reads(tmp_path): + cache = SourceCache(tmp_path / "cache") + result = convert_controlled_source(diagnostic_source(cache), cache) + payload = json.loads(result.to_json()) + payload["observations"][0]["diagnostics_sha256"] = digest(b"not in evidence package") + encoded = json.dumps(payload) + with pytest.raises(ValueError, match="diagnostic digest"): + ControlledDataset.from_json(encoded) diff --git a/tests/corpus/test_installed_controlled.py b/tests/corpus/test_installed_controlled.py new file mode 100644 index 00000000..adc53363 --- /dev/null +++ b/tests/corpus/test_installed_controlled.py @@ -0,0 +1,76 @@ +"""Installed offline controlled source reader, native CI replay and checkpoint continuation.""" + +import json +import os +import re +import shutil +import subprocess +import sys +from pathlib import Path + +from coleman.corpus.controlled_contracts import ControlledDataset + +ROOT = Path(__file__).parents[2] + + +def command(args, cwd, env): + """Run a bounded installed-package command and preserve independent process failures.""" + return subprocess.run(args, cwd=cwd, env=env, capture_output=True, text=True, check=True, timeout=240) + + +def test_installed_offline_sources_import_boundary_native_checkpoint_and_sdk(tmp_path): + uv = shutil.which("uv") + assert uv is not None + env = {k: v for k, v in os.environ.items() if k not in {"PYTHONPATH", "PYTHONHOME"}} + env.update({"UV_LINK_MODE": "copy", "UV_NO_PROGRESS": "1"}) + dist = tmp_path / "dist" + command([uv, "build", "--out-dir", str(dist)], ROOT, env) + virtual = tmp_path / "installed" + command([uv, "venv", str(virtual), "--python", sys.executable], tmp_path, env) + python = virtual / "bin/python" + command([uv, "pip", "install", "--offline", "--python", str(python), str(next(dist.glob("*.whl")))], tmp_path, env) + outside = tmp_path / "outside" + outside.mkdir() + code = """ +import importlib.abc, importlib.util, sys +assert importlib.util.find_spec('mcp') is None +class Boundary(importlib.abc.MetaPathFinder): + def find_spec(self, fullname, path=None, target=None): + if fullname == 'coleman.cli' or fullname.startswith(('coleman.transports','mcp')): + raise AssertionError('Controlled domain imported transport: '+fullname) +sys.meta_path.insert(0, Boundary()) +import coleman.corpus.controlled as adapter +import coleman.corpus.controlled_contracts +print(adapter.__file__) +""" + origin = command([str(python), "-c", code], outside, env) + assert Path(origin.stdout.strip()).resolve().is_relative_to(virtual.resolve()) + script = outside / "ci.py" + shutil.copyfile(ROOT / "examples/controlled_faults/ci.py", script) + observations = [] + for _ in range(2): + outcome = json.loads( + command([str(python), str(script), "owned-ci", str(tmp_path / "cache")], outside, env) + .stdout.strip() + .splitlines()[-1] + ) + observations.append(Path(outcome["dataset"]).read_bytes()) + assert outcome["native_rows"] == 1 + assert outcome["classifications"] == ["expected", "inconclusive"] + dataset = ControlledDataset.from_json(observations[-1]) + assert dataset.spec.context.fault_origin == "synthetic" + assert dataset.admission == "not_evaluated" + assert dataset.generalization == "insufficient_evidence" + assert len(dataset.observations) == 3 + assert all(item.elapsed.value is None for item in dataset.observations) + root = Path(outcome["native_root"]) + checkpoints = list((root / "checkpoints").rglob("progress_*.json")) + assert checkpoints + assert all(json.loads(p.read_bytes())["step_committed"] == 1 for p in checkpoints) + manifest = json.loads((root / "manifest.json").read_bytes()) + assert sum(a["type"] == "corpus_controlled_dataset" for a in manifest["artifacts"]) == 1 + assert observations[0] == observations[1] + snippets = re.findall(r"```python\n(.*?)```", (ROOT / "docs/controlled-faults.md").read_text(), flags=re.S) + assert len(snippets) == 1 + snippet = snippets[0].replace("/tmp/coleman-controlled-source-cache", str(tmp_path / "cache")) + command([str(python), "-c", snippet], outside, env) diff --git a/zensical.toml b/zensical.toml index 3f42a5d9..c4624483 100644 --- a/zensical.toml +++ b/zensical.toml @@ -26,6 +26,7 @@ nav = [ { "Verified Corpus Materialization" = "corpus-materialization.md" }, { "RTPTorrent Source Assessment" = "rtptorrent.md" }, { "LRTS Source Assessment" = "lrts.md" }, + { "Controlled Fault Observations" = "controlled-faults.md" }, { "Point-in-time CI Observations" = "point-in-time-observations.md" }, { "ADR 001: Point-in-time Boundary" = "decisions/001-point-in-time-observations.md" }, { "Operational CI Pilot" = "operational-pilot.md" }, From 72d7467c11746f5c1ee80b310af2ba182f131a5a Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 10:57:25 -0300 Subject: [PATCH 2/8] feat(corpus): reproduce pinned JUnit3 faults with recoverable evidence (#295) Refs #261. Preserve controlled negative observations, explicit units and complete provenance through pinned source reproduction, bounded capture and validated checkpoint recovery. --- .../resources/ColemanJunit3Capture.java | 138 +++++ .../apache-cli13-junit3-arm64-v1.json | 1 + coleman/corpus/source_views.py | 130 +++++ coleman/transports/corpus_http.py | 4 +- coleman/transports/junit.py | 71 +++ coleman/transports/junit_capture.py | 485 ++++++++++++++++++ coleman/transports/junit_contracts.py | 332 ++++++++++++ coleman/transports/junit_process.py | 95 ++++ coleman/transports/junit_protocol.py | 148 ++++++ coleman/transports/junit_source.py | 196 +++++++ docs/controlled-faults.md | 3 + docs/junit-source-capture.md | 163 ++++++ docs/roadmap.md | 5 +- llms.txt | 177 ++++++- .../fixtures/junit-recipe-owned-v1.json | 1 + .../corpus/fixtures/junit-role-owned-v1.json | 1 + .../corpus/fixtures/source-view-owned-v1.json | 1 + tests/corpus/test_http_source.py | 7 +- tests/corpus/test_installed_junit.py | 68 +++ tests/corpus/test_junit_capture.py | 463 +++++++++++++++++ tests/corpus/test_junit_process.py | 82 +++ tests/corpus/test_junit_protocol.py | 235 +++++++++ tests/corpus/test_source_views.py | 170 ++++++ zensical.toml | 1 + 24 files changed, 2970 insertions(+), 7 deletions(-) create mode 100644 coleman/corpus/resources/ColemanJunit3Capture.java create mode 100644 coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json create mode 100644 coleman/corpus/source_views.py create mode 100644 coleman/transports/junit.py create mode 100644 coleman/transports/junit_capture.py create mode 100644 coleman/transports/junit_contracts.py create mode 100644 coleman/transports/junit_process.py create mode 100644 coleman/transports/junit_protocol.py create mode 100644 coleman/transports/junit_source.py create mode 100644 docs/junit-source-capture.md create mode 100644 tests/corpus/fixtures/junit-recipe-owned-v1.json create mode 100644 tests/corpus/fixtures/junit-role-owned-v1.json create mode 100644 tests/corpus/fixtures/source-view-owned-v1.json create mode 100644 tests/corpus/test_installed_junit.py create mode 100644 tests/corpus/test_junit_capture.py create mode 100644 tests/corpus/test_junit_process.py create mode 100644 tests/corpus/test_junit_protocol.py create mode 100644 tests/corpus/test_source_views.py diff --git a/coleman/corpus/resources/ColemanJunit3Capture.java b/coleman/corpus/resources/ColemanJunit3Capture.java new file mode 100644 index 00000000..05a1770b --- /dev/null +++ b/coleman/corpus/resources/ColemanJunit3Capture.java @@ -0,0 +1,138 @@ +/* COLEMAN-authored JUnit3 observation harness, distributed under the repository MIT license. */ +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestFailure; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +/** Observe a pinned common test tree; success means collection, never an all-green suite. */ +public final class ColemanJunit3Capture { + private static final int DIAGNOSTIC_BYTES = 65536; + + private static final class LimitedBytes extends OutputStream { + private final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + private boolean truncated; + @Override public void write(int value) { + if (bytes.size() < DIAGNOSTIC_BYTES) bytes.write(value); else truncated = true; + } + @Override public void write(byte[] value, int offset, int length) { + int accepted = Math.min(length, DIAGNOSTIC_BYTES - bytes.size()); + bytes.write(value, offset, accepted); + if (accepted != length) truncated = true; + } + private String text() { return new String(bytes.toByteArray(), StandardCharsets.UTF_8); } + } + + private static String quote(String value) { + StringBuilder out = new StringBuilder("\""); + for (char c : value.toCharArray()) { + switch (c) { + case '\\': out.append("\\\\"); break; + case '"': out.append("\\\""); break; + case '\n': out.append("\\n"); break; + case '\r': out.append("\\r"); break; + case '\t': out.append("\\t"); break; + default: + if (c < 32) out.append(String.format("\\u%04x", (int)c)); else out.append(c); + } + } + return out.append('"').toString(); + } + + private static String array(List values) { + StringBuilder out = new StringBuilder("["); + for (int i = 0; i < values.size(); i++) { + if (i != 0) out.append(','); + out.append(quote(values.get(i))); + } + return out.append(']').toString(); + } + + private static String identity(TestCase test) { + return test.getClass().getName() + "::" + test.getName(); + } + + @SuppressWarnings("unchecked") + private static List discover(List excluded) throws Exception { + List cases = new ArrayList<>(); + for (String name : Files.readAllLines(Paths.get("/harness/classes.txt"), StandardCharsets.UTF_8)) { + Class type = Class.forName(name); + if (!TestCase.class.isAssignableFrom(type) || Modifier.isAbstract(type.getModifiers())) { + excluded.add(name); + continue; + } + TestSuite suite = new TestSuite((Class)type); + Enumeration tests = suite.tests(); + while (tests.hasMoreElements()) { + Test test = tests.nextElement(); + if (!(test instanceof TestCase)) throw new IllegalStateException("Unexpected nested suite"); + cases.add((TestCase)test); + if (cases.size() > 10000) throw new IllegalStateException("Discovery exceeds case limit"); + } + } + cases.sort(Comparator.comparing(ColemanJunit3Capture::identity)); + Set identities = new HashSet<>(); + for (TestCase test : cases) { + if (!identities.add(identity(test))) throw new IllegalStateException("Duplicate discovered identity"); + } + excluded.sort(String::compareTo); + return cases; + } + + private static void observe(TestCase test, PrintStream output, PrintStream error) throws Exception { + LimitedBytes diagnostics = new LimitedBytes(); + TestResult result = new TestResult(); + String started = Instant.now().truncatedTo(ChronoUnit.MICROS).toString(); + long begin = System.nanoTime(); + try (PrintStream capture = new PrintStream(diagnostics, true, "UTF-8")) { + System.setOut(capture); + System.setErr(capture); + try { test.run(result); } + finally { System.setOut(output); System.setErr(error); } + long elapsed = System.nanoTime() - begin; + String finished = Instant.now().truncatedTo(ChronoUnit.MICROS).toString(); + for (Enumeration e = result.failures(); e.hasMoreElements();) capture.print(e.nextElement().trace()); + for (Enumeration e = result.errors(); e.hasMoreElements();) capture.print(e.nextElement().trace()); + capture.flush(); + output.println("{\"schema_version\":1,\"record_type\":\"case\",\"test_id\":" + quote(identity(test)) + + ",\"tests_run\":" + result.runCount() + ",\"failures\":" + result.failureCount() + + ",\"errors\":" + result.errorCount() + ",\"elapsed_ns\":" + elapsed + + ",\"capture_started_at\":" + quote(started) + ",\"capture_finished_at\":" + quote(finished) + + ",\"diagnostics\":" + quote(diagnostics.text()) + + ",\"diagnostics_truncated\":" + diagnostics.truncated + "}"); + } + } + + /** Emit one header, every lexical shared-JVM case and a completion trailer as UTF-8 JSON lines. */ + public static void main(String[] args) throws Exception { + PrintStream output = System.out; + PrintStream error = System.err; + List excluded = new ArrayList<>(); + List cases = discover(excluded); + List identities = new ArrayList<>(); + for (TestCase test : cases) identities.add(identity(test)); + output.println("{\"schema_version\":1,\"record_type\":\"header\",\"java_version\":" + + quote(System.getProperty("java.version")) + ",\"architecture\":" + quote(System.getProperty("os.arch")) + + ",\"timezone\":" + quote(TimeZone.getDefault().getID()) + + ",\"capture_clock\":\"producer-truncated-utc-microsecond-v1\"" + + ",\"test_ids\":" + array(identities) + ",\"excluded_classes\":" + array(excluded) + "}"); + for (TestCase test : cases) observe(test, output, error); + output.println("{\"schema_version\":1,\"record_type\":\"trailer\",\"case_count\":" + cases.size() + "}"); + } +} diff --git a/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json b/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json new file mode 100644 index 00000000..db92759e --- /dev/null +++ b/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json @@ -0,0 +1 @@ +{"buggy":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-buggy-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-buggy-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/NOTICE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-buggy-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-buggy-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/BasicParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348}],"package_id":"commons-cli-buggy-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLine.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-buggy-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLineParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-buggy-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/GnuParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-buggy-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/HelpFormatter.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-buggy-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-buggy-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529}],"package_id":"commons-cli-buggy-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Option.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-buggy-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-buggy-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionGroup.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-buggy-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionValidator.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-buggy-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Options.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-buggy-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/ParseException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-buggy-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Parser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-buggy-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-buggy-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PosixParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-buggy-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/TypeHandler.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-buggy-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-buggy-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Util.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-buggy-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/overview.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/package.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:090dde1611fe8048b0e4e012c8b2c4cf24e885112ca7cb9c5ddec5729a59307e","size_bytes":147265,"uri":"urn:coleman:derived-source-view:commons-cli-buggy-v1","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"dependence_group":"commons-cli-cli13-upstream-pair","dependencies":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","terms_uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"commons-lang-2.1.jar","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723}],"package_id":"commons-lang-2.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723,"uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar","version":"2.1"}},{"archive":"raw","license":{"license_id":"CPL-1.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:0113c91fc99f8eec673ad5d0a75369b60a5cc7a6318b3354e511bbafeb40beb1","terms_uri":"https://opensource.org/license/CPL-1.0"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"junit-3.8.1.jar","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070}],"package_id":"junit-3.8.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070,"uri":"https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.jar","version":"3.8.1"}}],"fault_id":"CLI-13","fault_origin":"real","fixed":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixed-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixed-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-fixed-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-fixed-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/BasicParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462}],"package_id":"commons-cli-fixed-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLine.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-fixed-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLineParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-fixed-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/GnuParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-fixed-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/HelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-fixed-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-fixed-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287}],"package_id":"commons-cli-fixed-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Option.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-fixed-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-fixed-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionGroup.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-fixed-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionValidator.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-fixed-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Options.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-fixed-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/ParseException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-fixed-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Parser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-fixed-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-fixed-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PosixParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-fixed-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/TypeHandler.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-fixed-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-fixed-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Util.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-fixed-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/overview.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/package.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:a0d2077c23d2a4bef4fe339ecfbbf919c1e95fff4ba1a00d9dad923a59ef2f4a","size_bytes":148137,"uri":"urn:coleman:derived-source-view:commons-cli-fixed-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixture-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixture-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19}],"package_id":"commons-cli-fixture-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/.hidden.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21}],"package_id":"commons-cli-fixture-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/readable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21}],"package_id":"commons-cli-fixture-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/writable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123}],"package_id":"commons-cli-fixture-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ApplicationTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094}],"package_id":"commons-cli-fixture-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386}],"package_id":"commons-cli-fixture-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BugsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464}],"package_id":"commons-cli-fixture-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BuildTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653}],"package_id":"commons-cli-fixture-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/GnuParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074}],"package_id":"commons-cli-fixture-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/HelpFormatterExamples.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249}],"package_id":"commons-cli-fixture-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/LongOptionWithShort.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866}],"package_id":"commons-cli-fixture-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937}],"package_id":"commons-cli-fixture-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionGroupTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658}],"package_id":"commons-cli-fixture-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363}],"package_id":"commons-cli-fixture-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseRequiredTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359}],"package_id":"commons-cli-fixture-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738}],"package_id":"commons-cli-fixture-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253}],"package_id":"commons-cli-fixture-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/TestHelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754}],"package_id":"commons-cli-fixture-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValueTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779}],"package_id":"commons-cli-fixture-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValuesTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948}],"package_id":"commons-cli-fixture-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI13Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI18Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19},{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21},{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21},{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123},{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094},{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386},{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464},{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653},{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074},{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249},{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866},{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937},{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658},{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363},{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359},{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738},{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253},{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754},{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779},{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948},{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:becc2f662b4262776537cceeb27707732070998d5858090209f30a4695400489","size_bytes":128691,"uri":"urn:coleman:derived-source-view:commons-cli-fixture-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture_prefix":"src/test","harness_sha256":"sha256:e8e900c6ecf426282bfcfee5cb9749cad0ae7411f315e5cbe54ba5a0e3190891","limitations":["One public upstream Java fault pair, not a complete Defects4J reconstruction or corpus admission","Common fixed-tree test fixture transplanted to both source revisions","Shared JVM and lexical test order; order independence has not been established","Repeated tests and trials are not independent projects or unique faults","Two assertions fail in both revisions and remain negative evidence","Collection clocks are not historical CI timestamps; elapsed counters are not runner-removable costs","JUnit 3.8.1 CPL-1.0 declaration: https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.pom","Commons Lang license digest identifies META-INF/LICENSE.txt inside the separately pinned JAR; preserve NOTICE.txt"],"limits":{"maximum_output_bytes":1048576,"memory_bytes":1073741824,"timeout_seconds":60},"production_prefix":"src/java","project":"Apache Commons CLI","recipe":"junit3-fixed-tree-capture-v1","recipe_id":"apache-cli13-junit3-arm64-v1","runtime":{"emulated":false,"image_digest":"sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8","implementation":"Temurin","platform":"linux/arm64","timezone":"America/Los_Angeles","version":"11.0.32.1"},"schema_version":1,"test_ids":["org.apache.commons.cli.ApplicationTest::testAnt","org.apache.commons.cli.ApplicationTest::testLs","org.apache.commons.cli.ArgumentIsOptionTest::testOption","org.apache.commons.cli.ArgumentIsOptionTest::testOptionAndOptionWithArgument","org.apache.commons.cli.ArgumentIsOptionTest::testOptionWithArgument","org.apache.commons.cli.BugsTest::test11456","org.apache.commons.cli.BugsTest::test11457","org.apache.commons.cli.BugsTest::test11458","org.apache.commons.cli.BugsTest::test11680","org.apache.commons.cli.BugsTest::test12210","org.apache.commons.cli.BugsTest::test13425","org.apache.commons.cli.BugsTest::test13666","org.apache.commons.cli.BugsTest::test13935","org.apache.commons.cli.BugsTest::test14786","org.apache.commons.cli.BugsTest::test15046","org.apache.commons.cli.BugsTest::test15648","org.apache.commons.cli.BugsTest::test19383","org.apache.commons.cli.BugsTest::test21215","org.apache.commons.cli.BugsTest::test27635","org.apache.commons.cli.BugsTest::test31148","org.apache.commons.cli.BuildTest::testDuplicateLong","org.apache.commons.cli.BuildTest::testDuplicateSimple","org.apache.commons.cli.BuildTest::testLong","org.apache.commons.cli.BuildTest::testSimple","org.apache.commons.cli.GnuParseTest::testDoubleDash","org.apache.commons.cli.GnuParseTest::testExtraOption","org.apache.commons.cli.GnuParseTest::testMissingArg","org.apache.commons.cli.GnuParseTest::testMultiple","org.apache.commons.cli.GnuParseTest::testMultipleWithLong","org.apache.commons.cli.GnuParseTest::testSimpleLong","org.apache.commons.cli.GnuParseTest::testSimpleShort","org.apache.commons.cli.GnuParseTest::testSingleDash","org.apache.commons.cli.GnuParseTest::testStop","org.apache.commons.cli.LongOptionWithShort::testLongOptionWithShort","org.apache.commons.cli.OptionBuilderTest::testBaseOptionCharOpt","org.apache.commons.cli.OptionBuilderTest::testBaseOptionStringOpt","org.apache.commons.cli.OptionBuilderTest::testCompleteOption","org.apache.commons.cli.OptionBuilderTest::testIllegalOptions","org.apache.commons.cli.OptionBuilderTest::testOptionArgNumbers","org.apache.commons.cli.OptionBuilderTest::testSpecialOptChars","org.apache.commons.cli.OptionBuilderTest::testTwoCompleteOptions","org.apache.commons.cli.OptionGroupTest::testNoOptionsExtraArgs","org.apache.commons.cli.OptionGroupTest::testSingleLongOption","org.apache.commons.cli.OptionGroupTest::testSingleOption","org.apache.commons.cli.OptionGroupTest::testSingleOptionFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoLongOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromDifferentGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoValidLongOptions","org.apache.commons.cli.OptionGroupTest::testTwoValidOptions","org.apache.commons.cli.OptionGroupTest::testValidLongOnlyOptions","org.apache.commons.cli.OptionsTest::testHelpOptions","org.apache.commons.cli.ParseRequiredTest::testMissingRequiredOption","org.apache.commons.cli.ParseRequiredTest::testOptionAndRequiredOption","org.apache.commons.cli.ParseRequiredTest::testWithRequiredOption","org.apache.commons.cli.ParseTest::testComplexShort","org.apache.commons.cli.ParseTest::testDoubleDash","org.apache.commons.cli.ParseTest::testExtraOption","org.apache.commons.cli.ParseTest::testMissingArg","org.apache.commons.cli.ParseTest::testMultiple","org.apache.commons.cli.ParseTest::testMultipleWithLong","org.apache.commons.cli.ParseTest::testSimpleLong","org.apache.commons.cli.ParseTest::testSimpleShort","org.apache.commons.cli.ParseTest::testSingleDash","org.apache.commons.cli.ParseTest::testStop","org.apache.commons.cli.PatternOptionBuilderTest::testSimplePattern","org.apache.commons.cli.TestHelpFormatter::testAutomaticUsage","org.apache.commons.cli.TestHelpFormatter::testFindWrapPos","org.apache.commons.cli.TestHelpFormatter::testPrintOptions","org.apache.commons.cli.TestHelpFormatter::testPrintWrapped","org.apache.commons.cli.ValueTest::testLongNoArg","org.apache.commons.cli.ValueTest::testLongOptionalArgValue","org.apache.commons.cli.ValueTest::testLongOptionalArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNoValue","org.apache.commons.cli.ValueTest::testLongWithArg","org.apache.commons.cli.ValueTest::testPropertyOptionFlags","org.apache.commons.cli.ValueTest::testPropertyOptionMultipleValues","org.apache.commons.cli.ValueTest::testPropertyOptionSingularValue","org.apache.commons.cli.ValueTest::testPropertyOverrideValues","org.apache.commons.cli.ValueTest::testShortNoArg","org.apache.commons.cli.ValueTest::testShortOptionalArgNoValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValues","org.apache.commons.cli.ValueTest::testShortOptionalNArgValues","org.apache.commons.cli.ValueTest::testShortWithArg","org.apache.commons.cli.ValuesTest::testCharSeparator","org.apache.commons.cli.ValuesTest::testComplexValues","org.apache.commons.cli.ValuesTest::testExtraArgs","org.apache.commons.cli.ValuesTest::testMultipleArgValues","org.apache.commons.cli.ValuesTest::testShortArgs","org.apache.commons.cli.ValuesTest::testShortArgsWithValue","org.apache.commons.cli.ValuesTest::testTwoArgValues","org.apache.commons.cli.bug.BugCLI13Test::testCLI13","org.apache.commons.cli.bug.BugCLI18Test::testCLI18"]} diff --git a/coleman/corpus/source_views.py b/coleman/corpus/source_views.py new file mode 100644 index 00000000..3f451c87 --- /dev/null +++ b/coleman/corpus/source_views.py @@ -0,0 +1,130 @@ +"""Deterministic source views assembled from individually pinned, licensed raw packages.""" + +from __future__ import annotations + +import io +import stat +import zipfile +from collections.abc import Callable +from typing import Annotated, Literal, Self + +from pydantic import Field, model_validator + +from coleman.corpus.materialization import ReaderFactory, SourceCache, materialize_source, validate_materialization +from coleman.corpus.materialization_contracts import MaterializationReceipt, MaterializationSpec +from coleman.results.versioned import VersionedContract + + +class SourceViewSpec(VersionedContract): + """Bind homogeneous reviewed raw inputs to an expected deterministic ZIP source view. + + Each input contains exactly one regular member. Logical names, bytes, source + versions, terms and the resulting archive are frozen before acquisition. + At most 128 members, 8 MiB per file and 16 MiB total decoded input are allowed; + output ZIP bytes cannot exceed 32 MiB. These limits do not expand v1 archive + support. A view preserves file bytes and never compiles or executes them. + Terms must match exactly across inputs/output; heterogeneous component terms + require separately reviewed packages rather than an inferred umbrella license. + """ + + recipe: Literal["deterministic-raw-source-view-v1"] = "deterministic-raw-source-view-v1" + inputs: Annotated[tuple[MaterializationSpec, ...], Field(min_length=1, max_length=128)] + output: MaterializationSpec + + @model_validator(mode="after") + def _bindings(self) -> Self: + """Reject unsupported recipes, mixed terms, ambiguous members and weakened byte bounds.""" + if self.output.archive != "zip" or any(item.archive != "raw" for item in self.inputs): + raise ValueError("Source views require raw inputs and one ZIP output") + names = [item.members[0].name for item in self.inputs] + if len(names) != len(set(names)): + raise ValueError("Duplicate source view member") + if len({item.package_id for item in self.inputs}) != len(self.inputs): + raise ValueError("Duplicate source view input package identity") + members = tuple(sorted((item.members[0] for item in self.inputs), key=lambda item: item.name)) + if members != self.output.members: + raise ValueError("Source view output must preserve every input member without additions/exclusions") + if any(item.license != self.output.license for item in self.inputs): + raise ValueError("Source view input/output terms must match exactly") + if any(item.source.version != self.output.source.version for item in self.inputs): + raise ValueError("Source view input/output versions disagree") + object.__setattr__(self, "inputs", tuple(sorted(self.inputs, key=lambda item: item.members[0].name))) + return self + + @model_validator(mode="after") + def _bounds(self) -> Self: + """Enforce decoded and archive byte ceilings independently of caller-supplied package limits.""" + members = self.output.members + if ( + any(item.size_bytes > 8 * 1024**2 for item in members) + or sum(item.size_bytes for item in members) > 16 * 1024**2 + ): + raise ValueError("Source view decoded inputs exceed their byte budget") + if self.output.source.size_bytes is None or self.output.source.size_bytes > 32 * 1024**2: + raise ValueError("Source view ZIP exceeds 32 MiB") + return self + + +def source_view_bytes(entries: tuple[tuple[str, bytes], ...]) -> bytes: + """Encode a bounded sorted regular-file ZIP recipe, without deriving or changing source content. + + All names must be conservative portable materialization member names. Fixed + DOS epoch, Unix regular-file permissions, stored bytes and empty comments + remove host/time/compressor variability. Duplicate names, non-bytes, limits + and unsafe names raise ValueError/TypeError. No files or network are accessed. + This format is COLEMAN's ZIP recipe, not a claim about upstream archive bytes. + """ + from coleman.corpus.materialization_contracts import safe_member_name + + if not 1 <= len(entries) <= 128 or len({name for name, _ in entries}) != len(entries): + raise ValueError("Source view requires 1..128 uniquely named files") + total = 0 + for name, payload in entries: + safe_member_name(name) + if not isinstance(payload, bytes): + raise TypeError("Source view payload must be bytes") + total += len(payload) + if len(payload) > 8 * 1024**2 or total > 16 * 1024**2: + raise ValueError("Source view payload exceeds decoded-byte bounds") + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, "w", allowZip64=False) as archive: + for name, payload in sorted(entries): + info = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) + info.create_system = 3 + info.create_version = 20 + info.extract_version = 20 + info.compress_type = zipfile.ZIP_STORED + info.external_attr = (stat.S_IFREG | 0o644) << 16 + archive.writestr(info, payload) + return buffer.getvalue() + + +def materialize_source_view( + spec: SourceViewSpec, + cache: SourceCache, + reader_for: Callable[[MaterializationSpec], ReaderFactory] | None = None, +) -> MaterializationReceipt: + """Acquire/verify raw inputs and a deterministic derived ZIP through the existing cache. + + With no factory this operates offline. A supplied factory is explicit, lazy on + verified raw cache hits and responsible for transport; no URI is opened here. + Only individually completed blobs survive interruption. The complete returned + receipt pins the derived view, not an upstream download archive or scientific + admission. Invalid/mutated bytes, mismatched generation pins and unsupported + terms fail closed; I/O errors propagate. No subject process is started. + """ + spec = SourceViewSpec.model_validate(spec) + entries = [] + for package in spec.inputs: + source = None if reader_for is None else reader_for(package) + receipt = materialize_source(package, cache, source) + validate_materialization(receipt, cache) + member = package.members[0] + path = cache.member_path(receipt, member.name) + with path.open("rb") as stream: + payload = stream.read(member.size_bytes + 1) + if len(payload) != member.size_bytes: + raise ValueError("Source view input changed after verification") + entries.append((member.name, payload)) + payload = source_view_bytes(tuple(entries)) + return materialize_source(spec.output, cache, lambda: io.BytesIO(payload), refresh_source=True) diff --git a/coleman/transports/corpus_http.py b/coleman/transports/corpus_http.py index a603ae88..f6ad557a 100644 --- a/coleman/transports/corpus_http.py +++ b/coleman/transports/corpus_http.py @@ -13,7 +13,7 @@ from coleman.corpus.materialization_contracts import ByteReader # Provider expansion requires an explicitly reviewed public-source integration. -_PUBLIC_HOSTS = frozenset({"raw.githubusercontent.com"}) +_PUBLIC_HOSTS = frozenset({"raw.githubusercontent.com", "repo.maven.apache.org"}) def _public_target(url: str) -> tuple[str, str]: @@ -74,7 +74,7 @@ def public_https_source( """Open a reviewed public source with certificate verification and no ambient authentication/proxy state. The adapter never follows redirects or requests private/authenticated sources. - Only raw.githubusercontent.com is supported in v1. The caller separately + Only raw.githubusercontent.com and repo.maven.apache.org are supported. The caller separately supplies a licensed, digest-pinned materialization spec. Size is the HTTP entity byte count, not packet/TLS/header overhead. Socket inactivity timeouts and elapsed checks between reads are not a hard OS deadline for DNS or headers. diff --git a/coleman/transports/junit.py b/coleman/transports/junit.py new file mode 100644 index 00000000..626a12e8 --- /dev/null +++ b/coleman/transports/junit.py @@ -0,0 +1,71 @@ +"""Optional local entry point for pinned JUnit3 source collection, separate from native TCPCI execution.""" + +from __future__ import annotations + +import argparse +import json +from collections import Counter +from importlib.resources import files +from pathlib import Path + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import SourceCache +from coleman.transports.junit_capture import capture_junit_source +from coleman.transports.junit_contracts import JunitCaptureRecipe + + +def load_junit_recipe(path: Path | None = None) -> JunitCaptureRecipe: + """Read a bounded versioned recipe or the bundled arm64 CLI-13 preset; never acquire/execute inputs. + + Missing files, unsupported versions, unsafe declarations and files over + 2 MiB reject. The preset contains public integrity metadata, not subject code. + Runtime preparation and optional acquisition remain explicit caller actions. + """ + resource = path or files("coleman.corpus.resources").joinpath("apache-cli13-junit3-arm64-v1.json") + with resource.open("rb") as stream: + payload = stream.read(2 * 1024**2 + 1) + if len(payload) > 2 * 1024**2: + raise ValueError("JUnit recipe exceeds 2 MiB") + return JunitCaptureRecipe.from_json(payload) + + +def main(argv: list[str] | None = None) -> int: + """Collect a local source trial and print paths/counts; source failures stay outcomes rather than successes. + + Requires a preinstalled pinned Docker image; fetch is opt-in and only for + declared public source/dependency packages. Errors propagate with a nonzero + process exit. Incomplete role collection returns 2 after evidence publication. + No learning experiment, historical evaluation or image pull is performed. + """ + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--recipe", type=Path) + parser.add_argument("--cache", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--trial", required=True) + parser.add_argument("--fetch", action="store_true") + args = parser.parse_args(argv) + result = capture_junit_source( + load_junit_recipe(args.recipe), + SourceCache(args.cache), + ArtifactWriter(args.output), + args.trial, + fetch=args.fetch, + ) + print( + json.dumps( + { + "dataset": str(result.dataset_path), + "state": str(result.state_directory), + "role_statuses": {capture.role: capture.status for capture in result.captures}, + "pairs": dict(sorted(Counter(pair.classification for pair in result.dataset.pairs).items())), + "admission": result.dataset.admission, + "generalization": result.dataset.generalization, + }, + sort_keys=True, + ) + ) + return 0 if all(capture.status == "collected" for capture in result.captures) else 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/coleman/transports/junit_capture.py b/coleman/transports/junit_capture.py new file mode 100644 index 00000000..9ffcef40 --- /dev/null +++ b/coleman/transports/junit_capture.py @@ -0,0 +1,485 @@ +"""Optional local Docker/JUnit producer; native TCPCI experiments continue to use the existing runner.""" + +from __future__ import annotations + +import csv +import io +import os +import platform +import shutil +import tempfile +from collections.abc import Iterator +from contextlib import contextmanager +from datetime import UTC, datetime +from importlib.metadata import version +from pathlib import Path +from typing import NamedTuple + +from pydantic import TypeAdapter + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import MaterializationReceipt, SourceCache +from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset +from coleman.corpus.controlled_contracts import ( + ControlledDataset, + ControlledElapsed, + ControlledObservation, + ControlledReport, + ControlledSpec, + Label, +) +from coleman.corpus.materialization import materialize_source, validate_cache_separation +from coleman.corpus.materialization_contracts import MaterializationSpec, PackageMember +from coleman.corpus.source_views import source_view_bytes +from coleman.results.domain import decode_json, fingerprint +from coleman.transports.junit_contracts import ( + JunitCaptureRecipe, + JunitEnvironment, + JunitRoleCapture, + JunitRoleStart, + ProducerElapsed, +) +from coleman.transports.junit_process import collect_process +from coleman.transports.junit_protocol import role_capture, validate_role_bytes +from coleman.transports.junit_source import ( + HARNESS_NAME, + PreparedJunitInputs, + digest, + java_commands, + owned_package, + prepare_junit_inputs, +) + +_JAVA_SUFFIX = ".java" + + +def _contained(root: Path, path: Path) -> Path: + """Require a cooperative trusted-local output path; no symlink or resolved parent escape is adopted.""" + if path.is_symlink() or not path.resolve().is_relative_to(root.resolve()): + raise ValueError("JUnit output must remain within its trusted output tree") + return path + + +@contextmanager +def _single_producer(root: Path) -> Iterator[None]: + """Serialize one context/trial producer across POSIX processes; crash releases the advisory lock. + + Lock files are neither completed captures nor native learning checkpoints. + This assumes trusted local parent directories, like the existing source cache. + """ + if os.name != "posix": + raise OSError("JUnit producer requires POSIX advisory locks") + import fcntl + + root.mkdir(parents=True, exist_ok=True) + path = _contained(root, root / "producer.lock") + with path.open("a+b") as lock: + try: + fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) + except BlockingIOError as exc: + raise ValueError( + "Another producer owns this context/trial; no duplicate source execution was started" + ) from exc + try: + yield + finally: + fcntl.flock(lock, fcntl.LOCK_UN) + + +def _docker_query(base: tuple[str, ...], args: tuple[str, ...]): + """Read only specifically selected public runtime metadata, never tags, containers, contexts or credentials.""" + result = collect_process(base + args, timeout_seconds=15, maximum_output_bytes=256 * 1024) + if result.termination != "exited" or result.exit_code != 0: + raise OSError("Pinned local Docker runtime unavailable; prepare the documented image before capture") + return decode_json(result.stdout) + + +def _runtime_environment( + base: tuple[str, ...], recipe: JunitCaptureRecipe, cache: SourceCache +) -> MaterializationReceipt: + """Verify an already installed image and record filtered architecture/version facts; never pull an image.""" + image = "eclipse-temurin@" + recipe.runtime.image_digest + info = _docker_query( + base, + ("image", "inspect", image, "--format", "[{{json .Os}},{{json .Architecture}},{{json .Size}},{{json .Id}}]"), + ) + versions = _docker_query( + base, ("version", "--format", "[{{json .Client.Version}},{{json .Server.Version}},{{json .Server.Arch}}]") + ) + kernel = _docker_query(base, ("info", "--format", "{{json .KernelVersion}}")) + if not isinstance(info, list) or len(info) != 4 or not isinstance(versions, list) or len(versions) != 3: + raise ValueError("Unexpected filtered Docker runtime metadata") + target = recipe.runtime.platform.split("/")[1] + aliases = {"arm64": "arm64", "aarch64": "arm64", "x86_64": "amd64", "amd64": "amd64", "AMD64": "amd64"} + host = aliases.get(platform.machine()) + if not all(isinstance(value, str) for value in versions): + raise ValueError("Unexpected Docker version/architecture scalar") + server = aliases.get(versions[2]) + if info[0] != "linux" or info[1] != target or host is None or server is None: + raise ValueError("Local image/host architecture does not satisfy the reviewed runtime recipe") + if recipe.runtime.emulated != (len({host, server, target}) != 1): + raise ValueError("Visible architecture translation disagrees with the declared emulation profile") + environment = JunitEnvironment.model_validate( + { + "schema_version": 1, + "kind": "filtered-local-junit-runtime-v1", + "host_os": platform.system(), + "host_architecture": platform.machine(), + "host_release": platform.release(), + "producer_python_version": platform.python_version(), + "producer_package_version": version("coleman"), + "docker_client_version": versions[0], + "docker_server_version": versions[1], + "docker_server_architecture": versions[2], + "container_kernel": kernel, + "image_os": info[0], + "image_architecture": info[1], + "image_size_bytes": info[2], + "image_config_digest": info[3], + } + ) + return owned_package( + cache, "execution-environment.json", environment.to_json().encode(), "filtered-local-junit-runtime-v1" + ) + + +def _member_bytes(cache: SourceCache, receipt: MaterializationReceipt, name: str) -> bytes: + """Rehash the actual bounded bytes copied to the compiler, after the cache's own verification.""" + member = next(item for item in receipt.spec.members if item.name == name) + if member.size_bytes > 32 * 1024**2: + raise ValueError("JUnit staging member exceeds its byte bound") + path = cache.member_path(receipt, name) + with path.open("rb") as stream: + payload = stream.read(member.size_bytes + 1) + if len(payload) != member.size_bytes or digest(payload) != member.sha256: + raise ValueError("JUnit staged bytes disagree with the pinned member") + return payload + + +def _stage_view(cache: SourceCache, receipt: MaterializationReceipt, root: Path) -> None: + """Stage only declared regular-file bytes in a fresh private temporary tree, never extracting arbitrary paths.""" + root.mkdir(mode=0o755) + root.chmod(0o755) + for member in receipt.spec.members: + path = _contained(root, root / member.name) + path.parent.mkdir(parents=True, exist_ok=True, mode=0o755) + for directory in (path.parent, *path.parent.parents): + if directory == root.parent: + break + directory.chmod(0o755) + path.write_bytes(_member_bytes(cache, receipt, member.name)) + path.chmod(0o644) + + +def _mount(source: Path, target: str) -> str: + """Encode Docker's CSV mount argument, including an explicit temporary path containing commas.""" + output = io.StringIO(newline="") + csv.writer(output, lineterminator="").writerow(["type=bind", f"source={source}", f"target={target}", "readonly"]) + return output.getvalue() + + +def _source_arguments(receipt: MaterializationReceipt, prefix: str, target: str) -> str: + """Return quoted javac argument-file entries; safe materialization names cannot contain quotes/control syntax.""" + names = [ + item.name + for item in receipt.spec.members + if item.name.startswith(prefix + "/") and item.name.endswith(_JAVA_SUFFIX) + ] + return "".join(f'"{target}/{name}"\n' for name in sorted(names)) + + +def _run_role( + base: tuple[str, ...], + recipe: JunitCaptureRecipe, + prepared: PreparedJunitInputs, + cache: SourceCache, + role: str, + container_name: str, +): + """Execute one offline, non-root, read-only common-fixture JVM under container/parent guards.""" + source = prepared.buggy if role == "buggy" else prepared.fixed + with tempfile.TemporaryDirectory(prefix="coleman-junit-stage-") as temporary: + stage = Path(temporary) + _stage_view(cache, source, stage / "source") + _stage_view(cache, prepared.fixture, stage / "fixture") + dependencies = stage / "deps" + dependencies.mkdir(mode=0o755) + dependencies.chmod(0o755) + for index, receipt in enumerate(prepared.dependencies): + path = dependencies / f"{index}.jar" + path.write_bytes(_member_bytes(cache, receipt, receipt.spec.members[0].name)) + path.chmod(0o644) + harness = stage / "harness" + harness.mkdir(mode=0o755) + harness.chmod(0o755) + (harness / HARNESS_NAME).write_bytes(prepared.harness) + (harness / "production-sources.txt").write_text(_source_arguments(source, recipe.production_prefix, "/source")) + (harness / "fixture-sources.txt").write_text( + _source_arguments(prepared.fixture, recipe.fixture_prefix, "/fixture") + ) + classes = [ + item.name.removeprefix(recipe.fixture_prefix + "/").removesuffix(_JAVA_SUFFIX).replace("/", ".") + for item in prepared.fixture.spec.members + if item.name.startswith(recipe.fixture_prefix + "/") and item.name.endswith(_JAVA_SUFFIX) + ] + (harness / "classes.txt").write_text("\n".join(sorted(classes)) + "\n") + for path in harness.iterdir(): + path.chmod(0o644) + uid, gid = (os.getuid(), os.getgid()) if os.getuid() else (65534, 65534) + args = base + ( + "run", + "--pull=never", + "--rm", + "--name", + container_name, + "--platform", + recipe.runtime.platform, + "--network", + "none", + "--cap-drop", + "ALL", + "--security-opt", + "no-new-privileges", + "--pids-limit", + "64", + "--cpus", + "2", + "--memory", + str(recipe.limits.memory_bytes), + "--read-only", + "--tmpfs", + "/tmp:rw,nosuid,nodev,size=134217728,mode=1777", + "--user", + f"{uid}:{gid}", + "--env", + "TZ=" + recipe.runtime.timezone, + "--env", + "LANG=C.UTF-8", + "--env", + "LC_ALL=C.UTF-8", + ) + for name in ("source", "fixture", "deps", "harness"): + args += ("--mount", _mount(stage / name, "/" + name)) + compile_command, observe_command = java_commands(len(prepared.dependencies)) + script = "mkdir /tmp/classes && cd /fixture && " + compile_command + " && exec " + observe_command + try: + return collect_process( + args + ("eclipse-temurin@" + recipe.runtime.image_digest, "sh", "-c", script), + timeout_seconds=recipe.limits.timeout_seconds, + maximum_output_bytes=recipe.limits.maximum_output_bytes, + ) + finally: + _cleanup(base, container_name) + + +class _CleanupError(OSError): + """Leave a start marker recoverable when producer-owned container cleanup cannot be confirmed.""" + + +def _cleanup(base: tuple[str, ...], name: str) -> None: + """Remove only this deterministic producer-owned container name; an absent container is normal.""" + try: + result = collect_process(base + ("rm", "-f", name), timeout_seconds=15, maximum_output_bytes=65536) + except OSError as exc: + raise _CleanupError("Producer-owned container cleanup failed before acknowledgment") from exc + absent = result.stderr.decode("utf-8", errors="replace").strip() == ( + "Error response from daemon: No such container: " + name + ) + if result.termination != "exited" or (result.exit_code != 0 and not absent): + raise _CleanupError("Producer-owned container cleanup failed; recover its deterministic context/trial role") + + +def _load_role(path: Path, recipe: JunitCaptureRecipe) -> JunitRoleCapture: + """Read a bounded role checkpoint and revalidate its actual raw stream/case correspondence offline.""" + with path.open("rb") as stream: + payload = stream.read(16 * 1024**2 + 1) + if len(payload) > 16 * 1024**2: + raise ValueError("JUnit role checkpoint exceeds 16 MiB") + capture = JunitRoleCapture.from_json(payload) + validate_role_bytes(capture, recipe) + return capture + + +def _capture_role( + base: tuple[str, ...], + recipe: JunitCaptureRecipe, + prepared: PreparedJunitInputs, + cache: SourceCache, + writer: ArtifactWriter, + state: Path, + trial_id: str, + role: str, +) -> JunitRoleCapture: + """Reuse completed captures; recover started/uncommitted roles as interrupted without silent source reruns.""" + path = _contained(writer.run_root, state / (role + ".json")) + marker = _contained(writer.run_root, state / (role + ".started.json")) + expected = (prepared.context.fingerprint, trial_id, role) + if path.exists(): + capture = _load_role(path, recipe) + if (capture.context_fingerprint, capture.trial_id, capture.role) != expected: + raise ValueError("JUnit role checkpoint identity mismatch") + return capture + container_name = "coleman-junit-" + state.name[:24] + "-" + role + if marker.exists(): + with marker.open("rb") as stream: + payload = stream.read(4097) + if len(payload) > 4096: + raise ValueError("JUnit start marker exceeds 4 KiB") + started = JunitRoleStart.from_json(payload) + if (started.context_fingerprint, started.trial_id, started.role) != expected: + raise ValueError("JUnit start marker identity mismatch") + _cleanup(base, container_name) + capture = JunitRoleCapture.model_validate( + { + "schema_version": 1, + "context_fingerprint": expected[0], + "trial_id": trial_id, + "role": role, + "status": "interrupted", + "exit_code": None, + "capture_started_at": started.capture_started_at, + "capture_finished_at": datetime.now(UTC), + "producer_elapsed": ProducerElapsed(value=None, status="unavailable"), + "stdout_base64": None, + "stderr_base64": None, + "header": None, + "cases": (), + "problem": "Recovered a started but uncommitted source capture; no outcomes or elapsed ticks inferred", + } + ) + else: + now = datetime.now(UTC) + started = JunitRoleStart.model_validate( + { + "schema_version": 1, + "context_fingerprint": expected[0], + "trial_id": trial_id, + "role": role, + "capture_started_at": now, + } + ) + writer.write_immutable(marker, started.to_json() + "\n") + try: + streams = _run_role(base, recipe, prepared, cache, role, container_name) + except _CleanupError: + raise + except OSError as exc: + capture = JunitRoleCapture.model_validate( + { + "schema_version": 1, + "context_fingerprint": expected[0], + "trial_id": trial_id, + "role": role, + "status": "process_error", + "exit_code": None, + "capture_started_at": now, + "capture_finished_at": datetime.now(UTC), + "producer_elapsed": ProducerElapsed(value=None, status="unavailable"), + "stdout_base64": None, + "stderr_base64": None, + "header": None, + "cases": (), + "problem": (type(exc).__name__ + ": " + str(exc)).replace("\n", " ").replace("\r", " ")[:1024], + } + ) + else: + capture = role_capture(recipe, expected[0], trial_id, role, now, datetime.now(UTC), streams) + writer.write_immutable(path, capture.to_json() + "\n") + return capture + + +class JunitCaptureOutcome(NamedTuple): + """Typed local paths/results; source packets and domain dataset retain their independent v1 contracts.""" + + dataset: ControlledDataset + captures: tuple[JunitRoleCapture, ...] + dataset_path: Path + state_directory: Path + + +def _publish_capture( + recipe: JunitCaptureRecipe, + prepared: PreparedJunitInputs, + captures: tuple[JunitRoleCapture, ...], + cache: SourceCache, + writer: ArtifactWriter, +) -> tuple[ControlledDataset, Path]: + """Package normalized observations plus both raw role packets; source diagnostics always have pinned members.""" + entries = tuple((capture.role + "-capture.json", capture.to_json().encode()) for capture in captures) + pins = {name: digest(payload) for name, payload in entries} + observations = tuple( + ControlledObservation( + trial_id=capture.trial_id, + role=capture.role, + test_id=case.test_id, + outcome=case.outcome, + elapsed=ControlledElapsed(value=case.elapsed_ns, status="observed"), + capture_started_at=case.capture_started_at, + capture_finished_at=case.capture_finished_at, + diagnostics_sha256=pins[capture.role + "-capture.json"], + ) + for capture in captures + for case in capture.cases + ) + report = ControlledReport( + schema_version=1, context_fingerprint=prepared.context.fingerprint, observations=observations + ) + entries += (("report.json", report.to_json().encode()),) + payload = source_view_bytes(entries) + owner = owned_package(cache, "capture-envelope.zip", payload, recipe.recipe) + spec = MaterializationSpec.model_validate( + { + **owner.spec.model_dump(), + "archive": "zip", + "members": tuple( + PackageMember(name=name, sha256=digest(data), size_bytes=len(data)) for name, data in entries + ), + } + ) + receipt = materialize_source(spec, cache, lambda: io.BytesIO(payload)) + source = ControlledSpec( + schema_version=1, context=prepared.context, report_materialization=receipt, report_member="report.json" + ) + dataset = convert_controlled_source(source, cache) + return dataset, publish_controlled_dataset(dataset, cache, writer) + + +def capture_junit_source( + recipe: JunitCaptureRecipe, cache: SourceCache, writer: ArtifactWriter, trial_id: str, *, fetch: bool = False +) -> JunitCaptureOutcome: + """Collect one paired source trial with verified inputs, filtered runtime provenance and immutable recovery. + + Default acquisition is offline and the public pinned runtime image must + already exist locally. No image is pulled and no network is available to the + subject. Concurrent same-trial producers fail before execution. Completed + roles replay; a started/uncommitted role becomes interrupted/inconclusive, + requiring a new trial ID for fresh collection. Neither source capture nor + unexpected assertions establish CI chronology, independent faults or admission. + Native learning checkpoints and TCPCI experiments remain the native runner's + responsibility. Invalid source/schema/output states raise; OS failures outside + a role propagate. Role failures remain versioned raw evidence, never passes. + """ + recipe = JunitCaptureRecipe.model_validate(recipe) + trial_id = TypeAdapter(Label).validate_python(trial_id) + validate_cache_separation(cache.root, writer.run_root) + docker = shutil.which("docker") + if docker is None: + raise OSError("JUnit capture requires the documented local Docker runtime") + with tempfile.TemporaryDirectory(prefix="coleman-junit-client-") as temporary: + config = Path(temporary) + (config / "config.json").write_text("{}\n") + base = (docker, "--config", str(config)) + environment = _runtime_environment(base, recipe, cache) + prepared = prepare_junit_inputs(recipe, cache, environment, fetch=fetch) + session = fingerprint(["junit-capture-session-v1", prepared.context.fingerprint, trial_id]).removeprefix( + "sha256:" + ) + state = _contained(writer.run_root, writer.run_root / "junit-captures" / session) + with _single_producer(state): + writer.write_immutable(state / "context.json", prepared.context.to_json() + "\n") + captures = tuple( + _capture_role(base, recipe, prepared, cache, writer, state, trial_id, role) + for role in ("buggy", "fixed") + ) + dataset, path = _publish_capture(recipe, prepared, captures, cache, writer) + return JunitCaptureOutcome(dataset, captures, path, state) diff --git a/coleman/transports/junit_contracts.py b/coleman/transports/junit_contracts.py new file mode 100644 index 00000000..e2697571 --- /dev/null +++ b/coleman/transports/junit_contracts.py @@ -0,0 +1,332 @@ +"""Typed optional JUnit3 source-capture transport; no domain module imports this adapter.""" + +from __future__ import annotations + +import re +from datetime import datetime +from typing import Annotated, Literal, Self + +from pydantic import BeforeValidator, Field, model_validator + +from coleman.corpus.controlled_contracts import Label, Ticks +from coleman.corpus.materialization_contracts import MaterializationSpec, safe_member_name +from coleman.corpus.source_views import SourceViewSpec +from coleman.evaluation.protected.temporal import Timestamp +from coleman.results.domain import Fingerprint +from coleman.results.versioned import VersionedContract +from coleman.selection.contracts import Immutable + +JavaClass = Annotated[str, Field(strict=True, pattern=r"^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$")] +JavaTest = Annotated[ + str, + Field( + strict=True, + max_length=1024, + pattern=r"^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*::[A-Za-z_$][A-Za-z0-9_$]*$", + ), +] +Count = Annotated[int, Field(strict=True, ge=0, le=10000)] + + +def _capture_instant(value): + """Reject sub-microsecond or ambiguous string instants before Python datetime could truncate them.""" + if ( + isinstance(value, str) + and re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?Z", value, flags=re.ASCII) is None + ): + raise ValueError("JUnit capture instants require UTC Z and at most six fractional digits") + if not isinstance(value, str | datetime): + raise ValueError("JUnit capture instant must be an explicitly zoned value") + return value + + +CaptureInstant = Annotated[Timestamp, BeforeValidator(_capture_instant)] + + +class JunitCaptureLimits(Immutable): + """Per-role monotonic seconds, combined stdout/stderr bytes and container memory bytes. + + Network is disabled during execution; two CPUs, 64 PIDs and a 128-MiB tmpfs + are fixed by this v1 producer. These are execution guards, not benchmark costs. + Captures remain trusted-code experiments, not a hostile-code security sandbox. + """ + + timeout_seconds: Annotated[int, Field(strict=True, ge=1, le=120)] = 60 + maximum_output_bytes: Annotated[int, Field(strict=True, ge=1024, le=4 * 1024**2)] = 1024**2 + memory_bytes: Annotated[int, Field(strict=True, ge=128 * 1024**2, le=2 * 1024**3)] = 1024**3 + + +class JunitRuntimeImage(Immutable): + """Pinned public Temurin platform image and expected actual JVM facts; no executable commands.""" + + implementation: Literal["Temurin"] = "Temurin" + version: Label + platform: Literal["linux/arm64", "linux/amd64"] + image_digest: Fingerprint + emulated: Annotated[bool, Field(strict=True)] + timezone: Label + + +class JunitCaptureRecipe(VersionedContract): + """Freeze reviewed source views, a common test universe and a pinned Linux Java image. + + No URI, command or source code is executed by this model. Java/JUnit3 is an + optional producer boundary; generic controlled observation models stay free + of it. Source revisions label one focal fix, not universal correctness. All + same-test negative outcomes remain evidence and no unique-fault map is inferred. + """ + + recipe: Literal["junit3-fixed-tree-capture-v1"] = "junit3-fixed-tree-capture-v1" + recipe_id: Label + project: Label + fault_id: Label + fault_origin: Literal["real", "synthetic"] + dependence_group: Label + buggy: SourceViewSpec + fixed: SourceViewSpec + fixture: SourceViewSpec + dependencies: Annotated[tuple[MaterializationSpec, ...], Field(min_length=1, max_length=16)] + runtime: JunitRuntimeImage + production_prefix: Label + fixture_prefix: Label + test_ids: Annotated[tuple[JavaTest, ...], Field(min_length=1, max_length=10000)] + harness_sha256: Fingerprint + limits: JunitCaptureLimits = Field(default_factory=JunitCaptureLimits) + limitations: Annotated[tuple[Label, ...], Field(min_length=1, max_length=64)] + + @model_validator(mode="after") + def _bindings(self) -> Self: + """Reject incompatible runtime, revisions, classpaths and unsafe/empty source prefixes.""" + if self.buggy.output.source.version == self.fixed.output.source.version: + raise ValueError("JUnit source roles require distinct revisions") + if self.fixture.output.source.version != self.fixed.output.source.version: + raise ValueError("V1 common JUnit fixture must come from the fixed revision") + for prefix in (self.production_prefix, self.fixture_prefix): + safe_member_name(prefix) + for view, prefix in ( + (self.buggy, self.production_prefix), + (self.fixed, self.production_prefix), + (self.fixture, self.fixture_prefix), + ): + if not any( + item.name.startswith(prefix + "/") and item.name.endswith(".java") for item in view.output.members + ): + raise ValueError("JUnit view contains no Java file under its declared prefix") + return self + + @model_validator(mode="after") + def _dependencies(self) -> Self: + """Require distinct bounded raw JARs and a canonical test universe.""" + if len(self.test_ids) != len(set(self.test_ids)): + raise ValueError("Duplicate declared JUnit test ID") + if len({item.package_id for item in self.dependencies}) != len(self.dependencies): + raise ValueError("Duplicate JUnit dependency package identity") + if any(item.archive != "raw" or not item.members[0].name.endswith(".jar") for item in self.dependencies): + raise ValueError("JUnit classpath requires pinned raw JAR packages") + if ( + any(item.source.size_bytes is None or item.source.size_bytes > 32 * 1024**2 for item in self.dependencies) + or sum(item.source.size_bytes or 0 for item in self.dependencies) > 64 * 1024**2 + ): + raise ValueError("JUnit dependencies exceed per-file or total byte bounds") + object.__setattr__(self, "test_ids", tuple(sorted(self.test_ids))) + object.__setattr__(self, "dependencies", tuple(sorted(self.dependencies, key=lambda item: item.package_id))) + return self + + +class JunitHeader(VersionedContract): + """Actual runtime/discovery facts emitted before cases; collection is not observed CI history.""" + + record_type: Literal["header"] + java_version: Label + architecture: Literal["aarch64", "amd64", "x86_64"] + timezone: Label + capture_clock: Literal["producer-truncated-utc-microsecond-v1"] + test_ids: Annotated[tuple[JavaTest, ...], Field(min_length=1, max_length=10000)] + excluded_classes: Annotated[tuple[JavaClass, ...], Field(max_length=128)] + + @model_validator(mode="after") + def _universe(self) -> Self: + """Reject duplicate runtime discoveries and canonicalize declaration order only.""" + if len(self.test_ids) != len(set(self.test_ids)) or len(self.excluded_classes) != len( + set(self.excluded_classes) + ): + raise ValueError("Duplicate JUnit runtime discovery") + object.__setattr__(self, "test_ids", tuple(sorted(self.test_ids))) + object.__setattr__(self, "excluded_classes", tuple(sorted(self.excluded_classes))) + return self + + +class JunitCase(VersionedContract): + """One observed JUnit3 case, including setup/teardown in a monotonic harness counter. + + Truncated diagnostics force an infrastructure outcome rather than a successful + reproduction claim. Test errors are distinct from assertion failures. Counter + values are not CI scheduling costs and no full-suite green state is inferred. + """ + + record_type: Literal["case"] + test_id: JavaTest + tests_run: Annotated[int, Field(strict=True, ge=1, le=1)] + failures: Count + errors: Count + elapsed_ns: Ticks + capture_started_at: CaptureInstant + capture_finished_at: CaptureInstant + diagnostics: Annotated[str, Field(strict=True, max_length=1024**2)] + diagnostics_truncated: Annotated[bool, Field(strict=True)] + + @model_validator(mode="after") + def _clock(self) -> Self: + """Reject reversed capture instants without equating UTC and monotonic clocks.""" + if self.capture_finished_at < self.capture_started_at: + raise ValueError("JUnit capture finishes before it starts") + return self + + @property + def outcome(self) -> Literal["passed", "assertion_failed", "test_error", "infrastructure_error"]: + """Classify actual counters; incomplete diagnostics cannot certify a fault reproduction.""" + if self.diagnostics_truncated: + return "infrastructure_error" + if self.errors: + return "test_error" + return "assertion_failed" if self.failures else "passed" + + +class JunitTrailer(VersionedContract): + """Explicit process-level case completion; failures remain successful evidence collection.""" + + record_type: Literal["trailer"] + case_count: Count + + +class ProducerElapsed(Immutable): + """Exact producer-process monotonic nanoseconds, including local container startup/observation overhead. + + This is distinct from per-test harness ticks, runner occupancy and CI latency. + Interrupted recovery has unavailable null rather than an invented zero. + """ + + value: Ticks | None + unit: Literal["ns"] = "ns" + meaning: Literal["observed-producer-process-monotonic-elapsed-v1"] = ( + "observed-producer-process-monotonic-elapsed-v1" + ) + status: Literal["observed", "unavailable"] + + @model_validator(mode="after") + def _value(self) -> Self: + """Reject observed null and unavailable numeric values; perform no clock access.""" + if (self.value is not None) != (self.status == "observed"): + raise ValueError("Producer elapsed value/status disagree") + return self + + +class JunitRoleCapture(VersionedContract): + """Bounded raw role capture, separate from normalized observations and scientific admission. + + Base64 stores exact bounded stream bytes, including invalid/truncated output. + A started but uncommitted role recovers as interrupted with no invented cases. + Same-trial replay never silently reruns an interrupted role. A fresh collection + requires a new trial ID and remains in the same declared dependence group. + """ + + context_fingerprint: Fingerprint + trial_id: Label + role: Literal["buggy", "fixed"] + status: Literal["collected", "process_error", "timeout", "output_limit", "protocol_error", "interrupted"] + exit_code: Annotated[int, Field(strict=True, ge=-255, le=255)] | None + capture_started_at: CaptureInstant + capture_finished_at: CaptureInstant + producer_elapsed: ProducerElapsed + stdout_base64: Annotated[str, Field(strict=True, max_length=6 * 1024**2)] | None + stderr_base64: Annotated[str, Field(strict=True, max_length=6 * 1024**2)] | None + problem: Label | None = None + header: JunitHeader | None + cases: Annotated[tuple[JunitCase, ...], Field(max_length=10000)] + + @model_validator(mode="after") + def _capture(self) -> Self: + """Require collected captures to have a successful process, header and matching unique universe.""" + if self.capture_finished_at < self.capture_started_at: + raise ValueError("Role capture finishes before it starts") + if (self.stdout_base64 is None) != (self.stderr_base64 is None): + raise ValueError("Role stream availability must agree") + if self.status == "interrupted" and ( + self.exit_code is not None + or self.stdout_base64 is not None + or self.header is not None + or self.producer_elapsed.status != "unavailable" + ): + raise ValueError("Interrupted role has unavailable streams, runtime facts and elapsed counter") + if self.stdout_base64 is None and self.status not in {"interrupted", "process_error"}: + raise ValueError("Role status requires observed stream bytes") + if self.status == "collected": + if self.exit_code != 0 or self.header is None: + raise ValueError("Collected JUnit capture requires process success and runtime header") + ids = tuple(item.test_id for item in self.cases) + if len(ids) != len(set(ids)) or set(ids) != set(self.header.test_ids): + raise ValueError("Collected JUnit cases disagree with declared runtime discovery") + return self + + @model_validator(mode="after") + def _incomplete(self) -> Self: + """Keep incomplete raw packets separate from validated case/runtime observations.""" + if self.status != "collected": + if self.cases: + raise ValueError("Incomplete JUnit captures cannot promote partial/invalid streams into observations") + if self.header is not None: + raise ValueError("Incomplete JUnit captures cannot claim a validated runtime header") + return self + + @model_validator(mode="after") + def _process_facts(self) -> Self: + """Bind raw-stream availability to observed process facts, including explicit unavailable counters. + + Missing streams cannot retain a known exit code or measured parent time. + Observed streams require both. This does not prove whether an interrupted + or failed process started; it only prohibits contradictory saved evidence. + """ + if self.stdout_base64 is None: + if self.exit_code is not None or self.producer_elapsed.status != "unavailable": + raise ValueError("Unavailable role streams require unknown exit code and unavailable elapsed") + elif self.exit_code is None or self.producer_elapsed.status != "observed": + raise ValueError("Observed role streams require exit code and observed elapsed") + return self + + +class JunitRoleStart(VersionedContract): + """Immutable pre-execution acknowledgment, never a completed capture or experiment checkpoint. + + After process interruption this marker supplies identity and the collection + start instant only. It cannot certify test outcomes or elapsed time. + """ + + phase: Literal["source-capture-started"] = "source-capture-started" + context_fingerprint: Fingerprint + trial_id: Label + role: Literal["buggy", "fixed"] + capture_started_at: CaptureInstant + + +class JunitEnvironment(VersionedContract): + """Filtered local runtime facts; excludes image tags, containers, contexts, credentials and hostnames. + + Image size is observed Docker image storage bytes, not process memory or a + source-cache quota. The kernel belongs to the execution environment, not the + immutable image. These fields establish conditions, never native performance. + """ + + kind: Literal["filtered-local-junit-runtime-v1"] = "filtered-local-junit-runtime-v1" + host_os: Label + host_architecture: Label + host_release: Label + producer_python_version: Label + producer_package_version: Label + docker_client_version: Label + docker_server_version: Label + docker_server_architecture: Literal["arm64", "aarch64", "amd64", "x86_64"] + container_kernel: Label + image_os: Literal["linux"] + image_architecture: Literal["arm64", "amd64"] + image_size_bytes: Annotated[int, Field(strict=True, ge=0, le=64 * 1024**3)] + image_config_digest: Fingerprint diff --git a/coleman/transports/junit_process.py b/coleman/transports/junit_process.py new file mode 100644 index 00000000..c74c2871 --- /dev/null +++ b/coleman/transports/junit_process.py @@ -0,0 +1,95 @@ +"""Optional POSIX bounded process stream collector used only by the JUnit source producer.""" + +from __future__ import annotations + +import os +import selectors +import signal +import subprocess +import time +from contextlib import suppress +from typing import Literal, NamedTuple + + +class ProcessStreams(NamedTuple): + """Exact bounded stream prefixes, actual exit code and monotonic producer-process nanoseconds. + + A limit/timeout identifies incomplete collection. These bytes must never be + parsed as a successfully completed test experiment. The caller owns cleanup + of an external container; this helper owns only its child process group. + """ + + stdout: bytes + stderr: bytes + exit_code: int + elapsed_ns: int + termination: Literal["exited", "timeout", "output_limit"] + + +def _drain(selector, streams, deadline, maximum): + """Read ready bounded pipe prefixes until EOF, deadline or the first excess byte.""" + total = 0 + while selector.get_map(): + remaining = deadline - time.monotonic() + if remaining <= 0: + return "timeout" + for key, _ in selector.select(min(remaining, 0.1)): + chunk = os.read(key.fd, min(65536, maximum - total + 1)) + if not chunk: + selector.unregister(key.fileobj) + continue + accepted = min(len(chunk), maximum - total) + streams[key.data].extend(chunk[:accepted]) + total += accepted + if accepted != len(chunk): + return "output_limit" + return "exited" + + +def collect_process(args: tuple[str, ...], *, timeout_seconds: int, maximum_output_bytes: int) -> ProcessStreams: + """Collect a trusted command without a shell, with a combined byte cap and parent execution timeout. + + Only POSIX is supported. No ambient authentication, proxy or Python settings + are inherited; PATH is retained solely for executable/helper resolution. + The process gets a new group, killed on timeout/oversized output/error so + inherited pipe writers cannot keep collection alive indefinitely. Output + prefixes remain available for an explicit incomplete evidence packet. Exit + codes alone are never interpreted as assertion failures. OS failures propagate. + """ + if os.name != "posix": + raise OSError("Bounded JUnit process collection requires POSIX") + if type(timeout_seconds) is not int or not 1 <= timeout_seconds <= 120: + raise ValueError("Process timeout must be 1..120 seconds") + if type(maximum_output_bytes) is not int or not 1 <= maximum_output_bytes <= 4 * 1024**2: + raise ValueError("Process output limit must be 1..4 MiB") + if not args or any(not isinstance(arg, str) or "\x00" in arg for arg in args): + raise ValueError("Process requires nonempty NUL-free string arguments") + begin = time.monotonic_ns() + deadline = time.monotonic() + timeout_seconds + streams = {"stdout": bytearray(), "stderr": bytearray()} + termination: Literal["exited", "timeout", "output_limit"] = "exited" + env = {"PATH": os.environ.get("PATH", os.defpath)} + with subprocess.Popen( + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True, env=env + ) as process: + try: + with selectors.DefaultSelector() as selector: + for pipe, name in ((process.stdout, "stdout"), (process.stderr, "stderr")): + if pipe is None: + raise OSError("Process stream unavailable") + os.set_blocking(pipe.fileno(), False) + selector.register(pipe, selectors.EVENT_READ, name) + termination = _drain(selector, streams, deadline, maximum_output_bytes) + if termination == "exited": + try: + process.wait(timeout=max(0.001, deadline - time.monotonic())) + except subprocess.TimeoutExpired: + termination = "timeout" + finally: + if process.returncode is None: + with suppress(ProcessLookupError): + os.killpg(process.pid, signal.SIGKILL) + exit_code = process.wait(timeout=10) + return ProcessStreams( + bytes(streams["stdout"]), bytes(streams["stderr"]), exit_code, time.monotonic_ns() - begin, termination + ) diff --git a/coleman/transports/junit_protocol.py b/coleman/transports/junit_protocol.py new file mode 100644 index 00000000..ced3e6f3 --- /dev/null +++ b/coleman/transports/junit_protocol.py @@ -0,0 +1,148 @@ +"""Strict bounded protocol interpretation for the optional JUnit source producer.""" + +from __future__ import annotations + +import base64 +from datetime import datetime + +from coleman.transports.junit_contracts import ( + JunitCaptureRecipe, + JunitCase, + JunitHeader, + JunitRoleCapture, + JunitTrailer, + ProducerElapsed, +) +from coleman.transports.junit_process import ProcessStreams + + +def parsed_junit_stream(payload: bytes, recipe: JunitCaptureRecipe) -> tuple[JunitHeader, tuple[JunitCase, ...]]: + """Require one header, all declared cases and one trailer; do not interpret incomplete output. + + LF framing is byte-based so a Unicode line separator inside a JSON diagnostic + cannot split a record. Duplicate keys, missing/future versions, unknown fields, + wrong clocks/runtime/universe, repeated/missing cases and absent trailers + reject with ValueError. The caller first applies the combined stream byte cap. + No source/process/file/network access occurs and test failures remain outcomes. + """ + recipe = JunitCaptureRecipe.model_validate(recipe) + if len(payload) > recipe.limits.maximum_output_bytes or not payload.endswith(b"\n"): + raise ValueError("JUnit stream is oversized or lacks its final LF") + lines = payload.split(b"\n")[:-1] + if not 3 <= len(lines) <= 10002: + raise ValueError("JUnit stream record count is outside the declared bound") + header = JunitHeader.from_json(lines[0]) + trailer = JunitTrailer.from_json(lines[-1]) + cases = tuple(JunitCase.from_json(line) for line in lines[1:-1]) + expected_architecture = {"linux/arm64": {"aarch64"}, "linux/amd64": {"amd64", "x86_64"}} + if ( + header.java_version != recipe.runtime.version + or header.architecture not in expected_architecture[recipe.runtime.platform] + or header.timezone != recipe.runtime.timezone + ): + raise ValueError("JUnit actual runtime disagrees with the frozen recipe") + identities = tuple(item.test_id for item in cases) + if header.test_ids != recipe.test_ids or identities != recipe.test_ids or trailer.case_count != len(cases): + raise ValueError("JUnit actual discovery/case sequence disagrees with the frozen universe") + return header, cases + + +def _completed_protocol( + payload: bytes, exit_code: int, recipe: JunitCaptureRecipe +) -> tuple[str, JunitHeader | None, tuple[JunitCase, ...]]: + """Derive an exited process's status and cases from the actual code/bytes, including negative evidence.""" + if exit_code != 0: + return "process_error", None, () + try: + header, cases = parsed_junit_stream(payload, recipe) + except (ValueError, RecursionError): + return "protocol_error", None, () + return "collected", header, cases + + +def role_capture( + recipe: JunitCaptureRecipe, + context_fingerprint: str, + trial_id: str, + role: str, + started_at: datetime, + finished_at: datetime, + streams: ProcessStreams, +) -> JunitRoleCapture: + """Retain exact bounded raw bytes and distinguish process/timeout/protocol failures from assertions. + + Failed collection retains no promoted partial case observations; the raw + packet remains auditable and the other role can still supply observations. + Incomplete pairs therefore remain visible in generic controlled results. + The producer timer includes container/compile overhead and is not a test cost. + """ + header = None + cases: tuple[JunitCase, ...] = () + if streams.termination != "exited": + status = streams.termination + else: + status, header, cases = _completed_protocol(streams.stdout, streams.exit_code, recipe) + return JunitRoleCapture.model_validate( + { + "schema_version": 1, + "context_fingerprint": context_fingerprint, + "trial_id": trial_id, + "role": role, + "status": status, + "exit_code": streams.exit_code, + "capture_started_at": started_at, + "capture_finished_at": finished_at, + "producer_elapsed": ProducerElapsed(value=streams.elapsed_ns, status="observed"), + "stdout_base64": base64.b64encode(streams.stdout).decode("ascii"), + "stderr_base64": base64.b64encode(streams.stderr).decode("ascii"), + "header": header, + "cases": cases, + } + ) + + +def _guard_evidence(capture: JunitRoleCapture, size: int, recipe: JunitCaptureRecipe) -> None: + """Reject impossible parent-guard claims; coherent bounds still do not authenticate execution truth.""" + if capture.status == "output_limit" and size != recipe.limits.maximum_output_bytes: + raise ValueError("Output-limit capture must retain the complete bounded stream prefix") + if capture.status == "timeout" and ( + capture.producer_elapsed.value is None or capture.producer_elapsed.value < recipe.limits.timeout_seconds * 10**9 + ): + raise ValueError("Timeout capture elapsed must reach the declared parent deadline") + + +def validate_role_bytes(capture: JunitRoleCapture, recipe: JunitCaptureRecipe) -> None: + """Reparse actual stored streams; typed metadata alone cannot substitute declared cases for raw evidence. + + Canonical base64, combined byte limits and successful record/runtime bindings + are rechecked on resume. Exited process/protocol error statuses must agree + with the actual exit code and protocol, preventing silent observation loss. + Timeout/output-limit claims require the corresponding elapsed/prefix bounds. + They remain producer attestations: coherent facts do not authenticate which + parent guard actually stopped collection. + Schema errors raise ValueError; no files or source processes are accessed. + """ + capture = JunitRoleCapture.model_validate(capture) + recipe = JunitCaptureRecipe.model_validate(recipe) + if capture.stdout_base64 is None or capture.stderr_base64 is None: + if capture.status not in {"interrupted", "process_error"}: + raise ValueError("Stored role claims unavailable streams for a collected process") + return + try: + stdout = base64.b64decode(capture.stdout_base64, validate=True) + stderr = base64.b64decode(capture.stderr_base64, validate=True) + except (ValueError, TypeError) as exc: + raise ValueError("Invalid JUnit capture base64") from exc + if ( + base64.b64encode(stdout).decode("ascii") != capture.stdout_base64 + or base64.b64encode(stderr).decode("ascii") != capture.stderr_base64 + or len(stdout) + len(stderr) > recipe.limits.maximum_output_bytes + ): + raise ValueError("Noncanonical or oversized stored JUnit streams") + _guard_evidence(capture, len(stdout) + len(stderr), recipe) + if capture.status in {"collected", "protocol_error", "process_error"}: + if capture.exit_code is None: + raise ValueError("Stored exited role requires an observed exit code") + expected = _completed_protocol(stdout, capture.exit_code, recipe) + if (capture.status, capture.header, capture.cases) != expected: + raise ValueError("Stored JUnit status or observations disagree with raw streams and exit code") diff --git a/coleman/transports/junit_source.py b/coleman/transports/junit_source.py new file mode 100644 index 00000000..2a0408b0 --- /dev/null +++ b/coleman/transports/junit_source.py @@ -0,0 +1,196 @@ +"""Optional JUnit producer input preparation; source acquisition stays explicit and verified.""" + +from __future__ import annotations + +import hashlib +import io +from functools import partial +from importlib.resources import files +from typing import NamedTuple + +from coleman.corpus import ( + LicenseReview, + MaterializationReceipt, + MaterializationSpec, + SourceArtifact, + SourceCache, + load_registry, +) +from coleman.corpus.controlled_contracts import ControlledContext, ControlledInput, ControlledRuntime +from coleman.corpus.materialization import ReaderFactory, materialize_source, validate_materialization +from coleman.corpus.materialization_contracts import PackageMember +from coleman.corpus.source_views import materialize_source_view +from coleman.transports.corpus_http import public_https_source +from coleman.transports.junit_contracts import JunitCaptureRecipe + +HARNESS_NAME = "ColemanJunit3Capture.java" + + +def digest(payload: bytes) -> str: + """Return the explicit SHA-256 identity of actual bytes, without file/network access.""" + return "sha256:" + hashlib.sha256(payload).hexdigest() + + +def harness_bytes() -> bytes: + """Load the packaged COLEMAN-authored source harness; no subject/JVM code is executed.""" + return files("coleman.corpus.resources").joinpath(HARNESS_NAME).read_bytes() + + +def owned_package(cache: SourceCache, name: str, payload: bytes, version: str) -> MaterializationReceipt: + """Cache new producer-owned bytes with explicit recipe-only terms, not a foreign-code blanket license. + + Foreign subject and dependency inputs retain their independent reviewed terms. + This helper only describes newly authored harness/recipe/code/evidence records. + It uses the existing source cache and never publishes the data to Git/network. + """ + terms = load_registry().card("ci-serial-boundary-v1").manifest.license + terms = LicenseReview.model_validate({**terms.model_dump(), "redistribution": "recipe_only"}) + pin = digest(payload) + spec = MaterializationSpec( + schema_version=1, + package_id=name, + source=SourceArtifact( + uri="urn:coleman:controlled-junit-owned:" + name, + version=version, + citation="COLEMAN-authored producer record; foreign inputs have separate source/terms receipts", + sha256=pin, + size_bytes=len(payload), + availability="verified_local", + ), + license=terms, + archive="raw", + members=(PackageMember(name=name, sha256=pin, size_bytes=len(payload)),), + ) + return materialize_source(spec, cache, lambda: io.BytesIO(payload)) + + +def public_reader(package: MaterializationSpec) -> ReaderFactory: + """Return an unopened explicit public reader; host/size/TLS/redirect checks remain in the existing transport.""" + if package.source.size_bytes is None: + raise ValueError("JUnit acquisition requires a pinned source byte count") + return partial(public_https_source, package.source.uri, package.source.size_bytes) + + +def classpath(count: int) -> str: + """Return only producer-generated numeric dependency paths; no user text becomes shell syntax.""" + if not 1 <= count <= 16: + raise ValueError("JUnit classpath requires 1..16 dependencies") + return ":".join(f"/deps/{index}.jar" for index in range(count)) + + +def java_commands(count: int) -> tuple[str, str]: + """Return the exact fixed in-container compile/observe commands; subject paths live in argument files.""" + jars = classpath(count) + compile_command = ( + "javac -encoding UTF-8 -cp " + jars + " -d /tmp/classes @/harness/production-sources.txt " + "@/harness/fixture-sources.txt /harness/" + HARNESS_NAME + ) + observe_command = "java -Dfile.encoding=UTF-8 -cp /tmp/classes:" + jars + " ColemanJunit3Capture" + return compile_command, observe_command + + +class PreparedJunitInputs(NamedTuple): + """Verified source-view/dependency receipts and frozen context; no process is started here.""" + + context: ControlledContext + buggy: MaterializationReceipt + fixed: MaterializationReceipt + fixture: MaterializationReceipt + dependencies: tuple[MaterializationReceipt, ...] + harness: bytes + + +def prepare_junit_inputs( + recipe: JunitCaptureRecipe, cache: SourceCache, environment: MaterializationReceipt, *, fetch: bool = False +) -> PreparedJunitInputs: + """Materialize a frozen source recipe offline by default and bind actual producer implementation bytes. + + Explicit fetch uses only the reviewed public transport. Source views preserve + all raw bytes and their homogeneous terms. No image is pulled or code executed. + Changed harness pins, invalid inputs and missing offline bytes fail closed; + I/O failures propagate. Recipe/controller/harness receipts retain provenance. + """ + recipe = JunitCaptureRecipe.model_validate(recipe) + if type(fetch) is not bool: + raise ValueError("JUnit fetch flag must be boolean") + validate_materialization(environment, cache) + harness = harness_bytes() + if digest(harness) != recipe.harness_sha256: + raise ValueError("Installed JUnit harness disagrees with frozen recipe; a reviewed recipe update is required") + reader = public_reader if fetch else None + views = tuple(materialize_source_view(view, cache, reader) for view in (recipe.buggy, recipe.fixed, recipe.fixture)) + dependencies = tuple( + materialize_source(package, cache, public_reader(package) if fetch else None) for package in recipe.dependencies + ) + harness_receipt = owned_package(cache, HARNESS_NAME, harness, "coleman-junit3-harness-v1") + plan = owned_package(cache, "producer-recipe.json", recipe.to_json().encode(), recipe.recipe) + inputs = [ + ControlledInput.model_validate({"name": name, "kind": kind, "materialization": receipt}) + for name, kind, receipt in ( + ("buggy-source", "buggy_source", views[0]), + ("fixed-source", "fixed_source", views[1]), + ("common-fixture", "test_fixture", views[2]), + ("observation-harness", "harness", harness_receipt), + ("producer-recipe", "dependency", plan), + ("execution-environment", "dependency", environment), + ) + ] + inputs.extend( + ControlledInput(name=f"classpath-{index}", kind="dependency", materialization=receipt) + for index, receipt in enumerate(dependencies) + ) + for module in ( + "junit_contracts.py", + "junit_process.py", + "junit_source.py", + "junit_protocol.py", + "junit_capture.py", + ): + payload = files("coleman.transports").joinpath(module).read_bytes() + receipt = owned_package(cache, module, payload, "coleman-junit3-producer-code-v1") + inputs.append(ControlledInput(name=module, kind="dependency", materialization=receipt)) + view_code = files("coleman.corpus").joinpath("source_views.py").read_bytes() + inputs.append( + ControlledInput( + name="source-view-code", + kind="dependency", + materialization=owned_package(cache, "source_views.py", view_code, "coleman-source-view-code-v1"), + ) + ) + runtime = ControlledRuntime( + implementation=recipe.runtime.implementation, + version=recipe.runtime.version, + platform=recipe.runtime.platform, + execution_model="container", + image_digest=recipe.runtime.image_digest, + emulated=recipe.runtime.emulated, + timezone=recipe.runtime.timezone, + setup=( + "Pinned source views and a common fixed-revision test fixture; no original build bootstrap", + "Shared JVM per role; lexical test order; order independence is not established", + "Per-case elapsed ticks include JUnit setup/teardown; not removable CI runner work", + "Producer UTC capture instants explicitly use microsecond resolution; monotonic counters retain integer ns", + f"Container: memory_bytes={recipe.limits.memory_bytes}; " + "CPUs=2; PIDs=64; tmpfs_bytes=134217728; network=none", + f"Parent guards: timeout_seconds={recipe.limits.timeout_seconds}; " + f"output_bytes={recipe.limits.maximum_output_bytes}", + ), + commands=java_commands(len(dependencies)), + interventions=("Use the same declared fixed-tree test fixture against both source revisions",), + ) + context = ControlledContext( + schema_version=1, + project=recipe.project, + fault_id=recipe.fault_id, + fault_origin=recipe.fault_origin, + language="Java", + buggy_revision=recipe.buggy.output.source.version, + fixed_revision=recipe.fixed.output.source.version, + fixture_revision=recipe.fixture.output.source.version, + dependence_group=recipe.dependence_group, + test_ids=recipe.test_ids, + inputs=tuple(inputs), + runtime=runtime, + limitations=recipe.limitations, + ) + return PreparedJunitInputs(context, views[0], views[1], views[2], dependencies, harness) diff --git a/docs/controlled-faults.md b/docs/controlled-faults.md index 2957673d..1041042c 100644 --- a/docs/controlled-faults.md +++ b/docs/controlled-faults.md @@ -12,6 +12,9 @@ fault diversity, baseline comparisons or the cross-corpus benchmark. The registr seven required diversity cells remain uncovered. Source assessments for [RTPTorrent](rtptorrent.md) and [LRTS](lrts.md) remain separate. +The optional [pinned JUnit3 producer](junit-source-capture.md) now provides a +reproducible public Java source recipe, with bounded execution and raw-role recovery. + ## Architecture and trust boundary ```mermaid diff --git a/docs/junit-source-capture.md b/docs/junit-source-capture.md new file mode 100644 index 00000000..e350a153 --- /dev/null +++ b/docs/junit-source-capture.md @@ -0,0 +1,163 @@ +# Reproduce a pinned Java fault pair + +COLEMAN's optional JUnit3 producer collects source evidence before benchmark +admission. Its packaged Apache Commons CLI recipe compiles two pinned upstream +revisions against the same fixed-tree test fixture and records all 95 discovered +tests. It reuses the existing source cache, controlled-observation contracts and +immutable artifact writer. Native TCPCI experiments still use the existing runner. + +The recipe contains integrity metadata only. Subject sources, dependencies, +container images and raw captures remain outside the repository. It does not +execute Defects4J or claim its complete reconstruction protocol. The generic +[controlled domain](controlled-faults.md) imports no Docker, CLI or MCP adapter. + +## Prepare and run + +Build and install this branch's wheel as shown in the controlled-observation guide. +The released 4.5 wheel predates this producer. The bundled preset requires POSIX, +Docker, an arm64 host and arm64 Docker engine. It pins Temurin `11.0.32.1` and +`America/Los_Angeles`. Other platforms require a separately reviewed recipe; +changing a platform label does not validate a different image. + +Prepare the public image explicitly: + +```bash +docker pull --platform linux/arm64 eclipse-temurin@sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8 +``` + +From an external workspace, using the installed environment: + +```bash +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 --fetch +``` + +`--fetch` permits only the individually pinned public source/JAR downloads from +`raw.githubusercontent.com` and `repo.maven.apache.org`. The HTTPS adapter verifies +TLS and exact entity lengths, and rejects redirects, credentials, queries, partial +responses and encoded transfers. It uses no ambient authentication or proxy +configuration. The producer never pulls an image. Once cached, omit `--fetch` for +offline acquisition; subject execution has no network even during the first run. +Source-cache and output directories must be separate. + +The JSON summary includes dataset/state paths, role collection statuses, pair +counts, admission and generalization. Exit 0 means both role protocols completed; +assertion failures remain recorded outcomes. Incomplete collection publishes its +evidence and returns 2. Validation, infrastructure or publication exceptions exit +nonzero. Neither exit status certifies benchmark admission or algorithm efficacy. + +To supply another frozen recipe, add `--recipe /absolute/path/recipe.json`. +Recipes are bounded to 2 MiB, require schema version 1 and pin the installed +COLEMAN-authored harness. Missing, future or unknown versions reject. Updating the +harness requires an explicit reviewed recipe update, never silent migration. +Existing native results, learning checkpoints and older source artifacts retain +their meaning and require no migration. + +## What the recipe freezes + +The [buggy revision](https://github.com/apache/commons-cli/tree/8f46f467a33ace44ccd9f394910940b6c48a3827) +and [fixed revision](https://github.com/apache/commons-cli/tree/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e) +are the selected public CLI-13 pair. Each production view includes all `src/java` +blobs plus `LICENSE.txt` and `NOTICE.txt`; the common fixture includes all fixed-tree +`src/test` blobs plus those notices. Every raw file and derived ZIP is separately +size/digest pinned. The deterministic ZIP fixes member order, epoch, regular-file +permissions and stored bytes; it is a COLEMAN-derived view, not upstream archive +bytes. Its contract permits at most 128 homogeneous-license members, 8 MiB per +file, 16 MiB decoded total and 32 MiB output. It adds no TAR or ZIP64 support. + +The dependencies are Commons Lang 2.1 and JUnit 3.8.1. Apache subject and Commons +Lang Apache-2.0 terms remain separate from JUnit's CPL-1.0 terms. The version-specific +[JUnit POM](https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.pom) +declares CPL-1.0; the recipe records the reviewed [full terms](https://opensource.org/license/CPL-1.0). +Commons Lang's terms digest identifies `META-INF/LICENSE.txt` inside its independently +pinned JAR; its `NOTICE.txt` is retained. The COLEMAN MIT license does not replace +these terms. The recipe-only policy keeps foreign content in the external cache. + +```mermaid +flowchart LR + recipe[Pinned Java source recipe] --> raw[Reviewed raw source and dependency cache] + raw --> views[Deterministic source views] + views --> producer[Optional bounded Docker producer] + harness[Packaged COLEMAN JUnit3 harness] --> producer + producer --> packets[Versioned raw role packets and start markers] + packets --> report[Controlled report plus diagnostic members] + report --> domain[Existing offline controlled conversion] + domain --> artifact[Immutable controlled artifact] +``` + +Each role uses a fresh non-root, read-only container, four explicit read-only +input mounts, no network, no added capabilities, no privilege escalation, two +CPUs, 64 PIDs, a 128-MiB temporary filesystem and a 1-GiB memory default. The +parent bounds collection to 60 seconds and 1 MiB combined stdout/stderr by default; +recipes may select only the contract's bounded ranges. These guards support +trusted public-source reproduction; they are not a hostile-code security sandbox. + +The filtered runtime receipt retains host/Python/package versions, Docker +client/server architecture and versions, kernel and target image config digest +and size. It excludes credentials, context names, unrelated containers, image +tags and hostnames. Actual producer module bytes, recipe and harness are input +receipts, so modified implementation bytes change context identity. + +## Evidence and recovery + +A fresh local execution collected 190 observations: 92 same-test pairs passed in +both revisions, two failed in both and CLI-13 failed then passed. The two other +failures (`BugsTest::test19383`, `BugsTest::test27635`) remain visible. No causal +explanation or extra unique-fault count is inferred. These are observations of +this runtime and fixture, not a promise that every future run has the same result. + +Each case runs in the role's shared JVM in lexical test-ID order, including JUnit +setup/teardown. Independence from test order has not been established. Its strict +integer monotonic nanoseconds mean harness elapsed time, never removable runner +cost or wall-clock CI savings. Zero is observed; unavailable counters are null. +The separate parent timer includes startup and compilation. UTC capture instants +are explicitly quantized by the producer to microseconds; higher-precision input +strings reject rather than silently truncate. No collection clock becomes +historical CI chronology or a predecision feature. + +An immutable start marker precedes each role execution. A completed raw packet +replays without executing that role again. A start marker without a committed +packet recovers as `interrupted`: streams and counters remain unavailable, no +partial cases are promoted. Use a new trial ID for a fresh execution. Both trials +remain in the same dependence group. A POSIX advisory lock rejects concurrent +producers for the same context/trial; a process crash releases it. Cleanup targets +only the producer's deterministic container name. A cleanup failure propagates +without committing a role packet; the next call retries cleanup and retains the +interrupted observation state. Source acquisition, staging and +publication failures never certify a completed learning checkpoint. + +Successful protocols require the exact discovered test sequence and a final +trailer. Malformed/partial protocols, timeouts, output limits and process errors +retain bounded raw evidence without promoting partial cases into assertions. +On replay, exited process/protocol error labels are rederived from the stored +exit code and raw protocol; relabeling a valid complete packet cannot silently +discard its observations. Unavailable streams require an unknown exit code and +unavailable parent elapsed counter; observed streams require both observed process +facts. A timeout must reach its declared parent deadline, and an output-limit +packet must retain the complete bounded prefix. These checks reject contradictory +evidence; coherent timeout/output-limit labels remain producer attestations rather +than authenticated proof of which guard fired. +Both role packets are separately digest-pinned report members; normalized +observations reference their diagnostic member digest. An entirely unobserved +trial has no invented pairs. Negative, reversed and inconclusive comparisons +remain valid. All outputs retain `not_evaluated` and `insufficient_evidence`. + +## Validate the installed flow + +The normal suite exercises owned fixtures without external downloads. To repeat +the actual source flow from a wheel installed outside the checkout, first populate +the source cache with the command above and prepare the pinned image, then run: + +```bash +COLEMAN_JUNIT_REAL_CACHE=/tmp/coleman-junit-cache \ + uv run pytest tests/corpus/test_installed_junit.py --no-cov -q +``` + +This explicit source reproduction checks all 190 observations and the observed +pair counts, then repeats the same trial to verify byte-identical recovery. It +mocks no source compiler, JVM, cache, converter or artifact writer. It establishes +functional reproduction only. Chronological benchmark admission, additional +languages/faults, independent observations, fair baselines and all seven diversity +regimes remain work in [#261](https://github.com/jacksonpradolima/coleman/issues/261). diff --git a/docs/roadmap.md b/docs/roadmap.md index e510f4bc..014a0c86 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -34,7 +34,10 @@ uncovered. **4.5.0** publishes the reviewed RTPTorrent and LRTS source-assessment adapters, with explicit missing temporal evidence and reproducible admission blockers. -The next sequential corpus slice adds [controlled fault observations](controlled-faults.md). +The reviewed 4.6 integration branch adds [controlled fault observations](controlled-faults.md). +Its next sequential slice supplies [pinned JUnit3 source capture](junit-source-capture.md) +with raw evidence, interruption recovery and negative outcomes. This is source +reproduction, not completed benchmark admission. Later steps cover admitted real-fault matrices, HCS/variant expansion and synthetic stress, comparable baselines/statistics, frozen confirmatory execution and the final evidence report. Compatible deliveries continue in later **4.x** diff --git a/llms.txt b/llms.txt index 9e6ac1b8..ff42b4db 100644 --- a/llms.txt +++ b/llms.txt @@ -43,6 +43,7 @@ parallel execution, and extensibility via hooks and namespaced custom config. - docs/finite-coverage.md - docs/getting-started.md - docs/index.md +- docs/junit-source-capture.md - docs/lrts.md - docs/observability.md - docs/operational-pilot.md @@ -3115,6 +3116,9 @@ fault diversity, baseline comparisons or the cross-corpus benchmark. The registr seven required diversity cells remain uncovered. Source assessments for [RTPTorrent](rtptorrent.md) and [LRTS](lrts.md) remain separate. +The optional [pinned JUnit3 producer](junit-source-capture.md) now provides a +reproducible public Java source recipe, with bounded execution and raw-role recovery. + ## Architecture and trust boundary ```mermaid @@ -5653,6 +5657,174 @@ For advanced customization and parallel extension contracts, see +### FILE: docs/junit-source-capture.md + +# Reproduce a pinned Java fault pair + +COLEMAN's optional JUnit3 producer collects source evidence before benchmark +admission. Its packaged Apache Commons CLI recipe compiles two pinned upstream +revisions against the same fixed-tree test fixture and records all 95 discovered +tests. It reuses the existing source cache, controlled-observation contracts and +immutable artifact writer. Native TCPCI experiments still use the existing runner. + +The recipe contains integrity metadata only. Subject sources, dependencies, +container images and raw captures remain outside the repository. It does not +execute Defects4J or claim its complete reconstruction protocol. The generic +[controlled domain](controlled-faults.md) imports no Docker, CLI or MCP adapter. + +## Prepare and run + +Build and install this branch's wheel as shown in the controlled-observation guide. +The released 4.5 wheel predates this producer. The bundled preset requires POSIX, +Docker, an arm64 host and arm64 Docker engine. It pins Temurin `11.0.32.1` and +`America/Los_Angeles`. Other platforms require a separately reviewed recipe; +changing a platform label does not validate a different image. + +Prepare the public image explicitly: + +```bash +docker pull --platform linux/arm64 eclipse-temurin@sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8 +``` + +From an external workspace, using the installed environment: + +```bash +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 --fetch +``` + +`--fetch` permits only the individually pinned public source/JAR downloads from +`raw.githubusercontent.com` and `repo.maven.apache.org`. The HTTPS adapter verifies +TLS and exact entity lengths, and rejects redirects, credentials, queries, partial +responses and encoded transfers. It uses no ambient authentication or proxy +configuration. The producer never pulls an image. Once cached, omit `--fetch` for +offline acquisition; subject execution has no network even during the first run. +Source-cache and output directories must be separate. + +The JSON summary includes dataset/state paths, role collection statuses, pair +counts, admission and generalization. Exit 0 means both role protocols completed; +assertion failures remain recorded outcomes. Incomplete collection publishes its +evidence and returns 2. Validation, infrastructure or publication exceptions exit +nonzero. Neither exit status certifies benchmark admission or algorithm efficacy. + +To supply another frozen recipe, add `--recipe /absolute/path/recipe.json`. +Recipes are bounded to 2 MiB, require schema version 1 and pin the installed +COLEMAN-authored harness. Missing, future or unknown versions reject. Updating the +harness requires an explicit reviewed recipe update, never silent migration. +Existing native results, learning checkpoints and older source artifacts retain +their meaning and require no migration. + +## What the recipe freezes + +The [buggy revision](https://github.com/apache/commons-cli/tree/8f46f467a33ace44ccd9f394910940b6c48a3827) +and [fixed revision](https://github.com/apache/commons-cli/tree/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e) +are the selected public CLI-13 pair. Each production view includes all `src/java` +blobs plus `LICENSE.txt` and `NOTICE.txt`; the common fixture includes all fixed-tree +`src/test` blobs plus those notices. Every raw file and derived ZIP is separately +size/digest pinned. The deterministic ZIP fixes member order, epoch, regular-file +permissions and stored bytes; it is a COLEMAN-derived view, not upstream archive +bytes. Its contract permits at most 128 homogeneous-license members, 8 MiB per +file, 16 MiB decoded total and 32 MiB output. It adds no TAR or ZIP64 support. + +The dependencies are Commons Lang 2.1 and JUnit 3.8.1. Apache subject and Commons +Lang Apache-2.0 terms remain separate from JUnit's CPL-1.0 terms. The version-specific +[JUnit POM](https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.pom) +declares CPL-1.0; the recipe records the reviewed [full terms](https://opensource.org/license/CPL-1.0). +Commons Lang's terms digest identifies `META-INF/LICENSE.txt` inside its independently +pinned JAR; its `NOTICE.txt` is retained. The COLEMAN MIT license does not replace +these terms. The recipe-only policy keeps foreign content in the external cache. + +```mermaid +flowchart LR + recipe[Pinned Java source recipe] --> raw[Reviewed raw source and dependency cache] + raw --> views[Deterministic source views] + views --> producer[Optional bounded Docker producer] + harness[Packaged COLEMAN JUnit3 harness] --> producer + producer --> packets[Versioned raw role packets and start markers] + packets --> report[Controlled report plus diagnostic members] + report --> domain[Existing offline controlled conversion] + domain --> artifact[Immutable controlled artifact] +``` + +Each role uses a fresh non-root, read-only container, four explicit read-only +input mounts, no network, no added capabilities, no privilege escalation, two +CPUs, 64 PIDs, a 128-MiB temporary filesystem and a 1-GiB memory default. The +parent bounds collection to 60 seconds and 1 MiB combined stdout/stderr by default; +recipes may select only the contract's bounded ranges. These guards support +trusted public-source reproduction; they are not a hostile-code security sandbox. + +The filtered runtime receipt retains host/Python/package versions, Docker +client/server architecture and versions, kernel and target image config digest +and size. It excludes credentials, context names, unrelated containers, image +tags and hostnames. Actual producer module bytes, recipe and harness are input +receipts, so modified implementation bytes change context identity. + +## Evidence and recovery + +A fresh local execution collected 190 observations: 92 same-test pairs passed in +both revisions, two failed in both and CLI-13 failed then passed. The two other +failures (`BugsTest::test19383`, `BugsTest::test27635`) remain visible. No causal +explanation or extra unique-fault count is inferred. These are observations of +this runtime and fixture, not a promise that every future run has the same result. + +Each case runs in the role's shared JVM in lexical test-ID order, including JUnit +setup/teardown. Independence from test order has not been established. Its strict +integer monotonic nanoseconds mean harness elapsed time, never removable runner +cost or wall-clock CI savings. Zero is observed; unavailable counters are null. +The separate parent timer includes startup and compilation. UTC capture instants +are explicitly quantized by the producer to microseconds; higher-precision input +strings reject rather than silently truncate. No collection clock becomes +historical CI chronology or a predecision feature. + +An immutable start marker precedes each role execution. A completed raw packet +replays without executing that role again. A start marker without a committed +packet recovers as `interrupted`: streams and counters remain unavailable, no +partial cases are promoted. Use a new trial ID for a fresh execution. Both trials +remain in the same dependence group. A POSIX advisory lock rejects concurrent +producers for the same context/trial; a process crash releases it. Cleanup targets +only the producer's deterministic container name. A cleanup failure propagates +without committing a role packet; the next call retries cleanup and retains the +interrupted observation state. Source acquisition, staging and +publication failures never certify a completed learning checkpoint. + +Successful protocols require the exact discovered test sequence and a final +trailer. Malformed/partial protocols, timeouts, output limits and process errors +retain bounded raw evidence without promoting partial cases into assertions. +On replay, exited process/protocol error labels are rederived from the stored +exit code and raw protocol; relabeling a valid complete packet cannot silently +discard its observations. Unavailable streams require an unknown exit code and +unavailable parent elapsed counter; observed streams require both observed process +facts. A timeout must reach its declared parent deadline, and an output-limit +packet must retain the complete bounded prefix. These checks reject contradictory +evidence; coherent timeout/output-limit labels remain producer attestations rather +than authenticated proof of which guard fired. +Both role packets are separately digest-pinned report members; normalized +observations reference their diagnostic member digest. An entirely unobserved +trial has no invented pairs. Negative, reversed and inconclusive comparisons +remain valid. All outputs retain `not_evaluated` and `insufficient_evidence`. + +## Validate the installed flow + +The normal suite exercises owned fixtures without external downloads. To repeat +the actual source flow from a wheel installed outside the checkout, first populate +the source cache with the command above and prepare the pinned image, then run: + +```bash +COLEMAN_JUNIT_REAL_CACHE=/tmp/coleman-junit-cache \ + uv run pytest tests/corpus/test_installed_junit.py --no-cov -q +``` + +This explicit source reproduction checks all 190 observations and the observed +pair counts, then repeats the same trial to verify byte-identical recovery. It +mocks no source compiler, JVM, cache, converter or artifact writer. It establishes +functional reproduction only. Chronological benchmark admission, additional +languages/faults, independent observations, fair baselines and all seven diversity +regimes remain work in [#261](https://github.com/jacksonpradolima/coleman/issues/261). + + + ### FILE: docs/lrts.md # LRTS: preserve raw method evidence and processed metadata @@ -8038,7 +8210,10 @@ uncovered. **4.5.0** publishes the reviewed RTPTorrent and LRTS source-assessment adapters, with explicit missing temporal evidence and reproducible admission blockers. -The next sequential corpus slice adds [controlled fault observations](controlled-faults.md). +The reviewed 4.6 integration branch adds [controlled fault observations](controlled-faults.md). +Its next sequential slice supplies [pinned JUnit3 source capture](junit-source-capture.md) +with raw evidence, interruption recovery and negative outcomes. This is source +reproduction, not completed benchmark admission. Later steps cover admitted real-fault matrices, HCS/variant expansion and synthetic stress, comparable baselines/statistics, frozen confirmatory execution and the final evidence report. Compatible deliveries continue in later **4.x** diff --git a/tests/corpus/fixtures/junit-recipe-owned-v1.json b/tests/corpus/fixtures/junit-recipe-owned-v1.json new file mode 100644 index 00000000..5b196925 --- /dev/null +++ b/tests/corpus/fixtures/junit-recipe-owned-v1.json @@ -0,0 +1 @@ +{"buggy":{"inputs":[{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"src/java/owned/CheckCase.java","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34,"uri":"urn:coleman:owned-source-view:src/java/owned/CheckCase.java","version":"buggy-v1"}}],"output":{"archive":"zip","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"buggy","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:991f9df151b0e688f1604853b67c3d6d70dc014b33885160897dd50107bcb58c","size_bytes":190,"uri":"urn:coleman:owned-source-view:buggy","version":"buggy-v1"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"dependence_group":"owned-ci-single-fixture","dependencies":[{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"junit.jar","sha256":"sha256:534de3e70785b8e6aa4e82f7f984a58f08d2b937e2fe1b91ac661c37accc4d53","size_bytes":44}],"package_id":"junit.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:534de3e70785b8e6aa4e82f7f984a58f08d2b937e2fe1b91ac661c37accc4d53","size_bytes":44,"uri":"urn:coleman:owned-source-view:junit.jar","version":"owned-v1"}}],"fault_id":"owned-case","fault_origin":"synthetic","fixed":{"inputs":[{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"src/java/owned/CheckCase.java","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34,"uri":"urn:coleman:owned-source-view:src/java/owned/CheckCase.java","version":"fixed-v1"}}],"output":{"archive":"zip","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"fixed","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:991f9df151b0e688f1604853b67c3d6d70dc014b33885160897dd50107bcb58c","size_bytes":190,"uri":"urn:coleman:owned-source-view:fixed","version":"fixed-v1"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture":{"inputs":[{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"src/test/owned/CheckCase.java","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34,"uri":"urn:coleman:owned-source-view:src/test/owned/CheckCase.java","version":"fixed-v1"}}],"output":{"archive":"zip","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/owned/CheckCase.java","sha256":"sha256:bfee489d22f60fed22ba0e74332bd4cdf090453813e41f83e5e3c3373675bed8","size_bytes":34}],"package_id":"fixture","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:a6418f0ab524b2685fe90dad26aa4e0ad9e4f8d6aee87d51f46bd1b46ced337c","size_bytes":190,"uri":"urn:coleman:owned-source-view:fixture","version":"fixed-v1"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture_prefix":"src/test","harness_sha256":"sha256:09f53ce24694ee4152d1a5ffe3c5279563be4ef2a306169ead675764da80ce2e","limitations":["Schema-only fixture; no foreign runtime, source or independent faults claimed"],"limits":{"maximum_output_bytes":1048576,"memory_bytes":1073741824,"timeout_seconds":60},"production_prefix":"src/java","project":"owned-ci","recipe":"junit3-fixed-tree-capture-v1","recipe_id":"owned-junit-schema-v1","runtime":{"emulated":false,"image_digest":"sha256:64c4ecbca71fa33006a489109a2a50a3a6baa33f553ff43ca4f334f3537e4b2d","implementation":"Temurin","platform":"linux/arm64","timezone":"UTC","version":"11.0.32.1"},"schema_version":1,"test_ids":["owned.CheckCase::test_ci"]} diff --git a/tests/corpus/fixtures/junit-role-owned-v1.json b/tests/corpus/fixtures/junit-role-owned-v1.json new file mode 100644 index 00000000..4df4efc4 --- /dev/null +++ b/tests/corpus/fixtures/junit-role-owned-v1.json @@ -0,0 +1 @@ +{"capture_finished_at":"2026-01-01T00:00:00Z","capture_started_at":"2026-01-01T00:00:00Z","cases":[{"capture_finished_at":"2026-01-01T00:00:00Z","capture_started_at":"2026-01-01T00:00:00Z","diagnostics":"Owned diagnostic
retains its Unicode separator","diagnostics_truncated":false,"elapsed_ns":0,"errors":0,"failures":1,"record_type":"case","schema_version":1,"test_id":"owned.CheckCase::test_ci","tests_run":1}],"context_fingerprint":"sha256:ea7792a26f405e2ae9c6f49ca93bbe6076ceac0a1fc53d83426c7d7f2d9377e4","exit_code":0,"header":{"architecture":"aarch64","capture_clock":"producer-truncated-utc-microsecond-v1","excluded_classes":["owned.Example"],"java_version":"11.0.32.1","record_type":"header","schema_version":1,"test_ids":["owned.CheckCase::test_ci"],"timezone":"UTC"},"problem":null,"producer_elapsed":{"meaning":"observed-producer-process-monotonic-elapsed-v1","status":"observed","unit":"ns","value":0},"role":"buggy","schema_version":1,"status":"collected","stderr_base64":"b3duZWQgY29tcGlsZXIgZGlhZ25vc3RpYw==","stdout_base64":"eyJzY2hlbWFfdmVyc2lvbiI6IDEsICJyZWNvcmRfdHlwZSI6ICJoZWFkZXIiLCAiamF2YV92ZXJzaW9uIjogIjExLjAuMzIuMSIsICJhcmNoaXRlY3R1cmUiOiAiYWFyY2g2NCIsICJ0aW1lem9uZSI6ICJVVEMiLCAiY2FwdHVyZV9jbG9jayI6ICJwcm9kdWNlci10cnVuY2F0ZWQtdXRjLW1pY3Jvc2Vjb25kLXYxIiwgInRlc3RfaWRzIjogWyJvd25lZC5DaGVja0Nhc2U6OnRlc3RfY2kiXSwgImV4Y2x1ZGVkX2NsYXNzZXMiOiBbIm93bmVkLkV4YW1wbGUiXX0KeyJzY2hlbWFfdmVyc2lvbiI6IDEsICJyZWNvcmRfdHlwZSI6ICJjYXNlIiwgInRlc3RfaWQiOiAib3duZWQuQ2hlY2tDYXNlOjp0ZXN0X2NpIiwgInRlc3RzX3J1biI6IDEsICJmYWlsdXJlcyI6IDEsICJlcnJvcnMiOiAwLCAiZWxhcHNlZF9ucyI6IDAsICJjYXB0dXJlX3N0YXJ0ZWRfYXQiOiAiMjAyNi0wMS0wMVQwMDowMDowMFoiLCAiY2FwdHVyZV9maW5pc2hlZF9hdCI6ICIyMDI2LTAxLTAxVDAwOjAwOjAwWiIsICJkaWFnbm9zdGljcyI6ICJPd25lZCBkaWFnbm9zdGlj4oCocmV0YWlucyBpdHMgVW5pY29kZSBzZXBhcmF0b3IiLCAiZGlhZ25vc3RpY3NfdHJ1bmNhdGVkIjogZmFsc2V9Cnsic2NoZW1hX3ZlcnNpb24iOiAxLCAicmVjb3JkX3R5cGUiOiAidHJhaWxlciIsICJjYXNlX2NvdW50IjogMX0K","trial_id":"owned-trial"} diff --git a/tests/corpus/fixtures/source-view-owned-v1.json b/tests/corpus/fixtures/source-view-owned-v1.json new file mode 100644 index 00000000..be0acd92 --- /dev/null +++ b/tests/corpus/fixtures/source-view-owned-v1.json @@ -0,0 +1 @@ +{"inputs":[{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE","sha256":"sha256:35e413c482729013a296aeb57c1b838300c20b700d1ccacb7928bde1090655c3","size_bytes":27}],"package_id":"LICENSE","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:35e413c482729013a296aeb57c1b838300c20b700d1ccacb7928bde1090655c3","size_bytes":27,"uri":"urn:coleman:owned-source-view:LICENSE","version":"owned-v1"}},{"archive":"raw","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/owned.txt","sha256":"sha256:3868f829f7aeb64f19aa5e83f3d331863ec0006e22951ce6f6665dfa5eda7861","size_bytes":17}],"package_id":"src/owned.txt","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:3868f829f7aeb64f19aa5e83f3d331863ec0006e22951ce6f6665dfa5eda7861","size_bytes":17,"uri":"urn:coleman:owned-source-view:src/owned.txt","version":"owned-v1"}}],"output":{"archive":"zip","license":{"license_id":"MIT","redistribution":"permitted","reviewed_at":"2026-10-15T04:51:46Z","status":"verified","terms_sha256":"sha256:42f4c2f2ecff6df389cf65a7b4a63ba252c4e0322365905f80a31af9ab959761","terms_uri":"https://github.com/jacksonpradolima/coleman/blob/b743f51d5ba444410b32f2c0e318b2587b882c43/LICENSE"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE","sha256":"sha256:35e413c482729013a296aeb57c1b838300c20b700d1ccacb7928bde1090655c3","size_bytes":27},{"name":"src/owned.txt","sha256":"sha256:3868f829f7aeb64f19aa5e83f3d331863ec0006e22951ce6f6665dfa5eda7861","size_bytes":17}],"package_id":"owned-source-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"not_verified","citation":"Owned synthetic source-view fixture, not foreign code","sha256":"sha256:e56201cf2843385fa05adee1934e3d455d932c7d0fb0c03c02fac92502f5ac7f","size_bytes":258,"uri":"urn:coleman:owned-source-view:owned-source-view-v1","version":"owned-v1"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1} diff --git a/tests/corpus/test_http_source.py b/tests/corpus/test_http_source.py index 28a1b38b..08da9fd6 100644 --- a/tests/corpus/test_http_source.py +++ b/tests/corpus/test_http_source.py @@ -51,13 +51,14 @@ def connection(monkeypatch, reply): return client, constructor -def test_approved_origin_uses_verified_tls_no_ambient_headers_and_closes(monkeypatch): +@pytest.mark.parametrize("host", ["raw.githubusercontent.com", "repo.maven.apache.org"]) +def test_approved_origin_uses_verified_tls_no_ambient_headers_and_closes(monkeypatch, host): reply = response() client, constructor = connection(monkeypatch, reply) - with corpus_http.public_https_source("https://raw.githubusercontent.com/owner/ci/pinned/data", 3) as source: + with corpus_http.public_https_source(f"https://{host}/owner/ci/pinned/data", 3) as source: assert source.read(3) == b"abc" args, kwargs = constructor.call_args - assert args == ("raw.githubusercontent.com",) + assert args == (host,) assert kwargs["context"].check_hostname assert kwargs["context"].verify_mode == corpus_http.ssl.CERT_REQUIRED request = client.request.call_args diff --git a/tests/corpus/test_installed_junit.py b/tests/corpus/test_installed_junit.py new file mode 100644 index 00000000..aadf100f --- /dev/null +++ b/tests/corpus/test_installed_junit.py @@ -0,0 +1,68 @@ +"""Installed JUnit resources/import boundaries plus an explicitly enabled real offline source reproduction.""" + +import json +import os +import shutil +import sys + +from tests.corpus.test_installed_controlled import ROOT, command + + +def test_installed_producer_resources_domain_boundary_and_optional_real_pair(tmp_path): + uv = shutil.which("uv") + assert uv is not None + env = {k: v for k, v in os.environ.items() if k not in {"PYTHONPATH", "PYTHONHOME"}} + env.update({"UV_LINK_MODE": "copy", "UV_NO_PROGRESS": "1"}) + dist = tmp_path / "dist" + command([uv, "build", "--wheel", "--out-dir", str(dist)], ROOT, env) + virtual = tmp_path / "installed" + command([uv, "venv", str(virtual), "--python", sys.executable], tmp_path, env) + python = virtual / "bin/python" + command([uv, "pip", "install", "--offline", "--python", str(python), str(next(dist.glob("*.whl")))], tmp_path, env) + outside = tmp_path / "outside" + outside.mkdir() + script = """ +import importlib.abc, json, sys +from collections import Counter +from pathlib import Path +class Boundary(importlib.abc.MetaPathFinder): + def find_spec(self, fullname, path=None, target=None): + if fullname == 'coleman.cli' or fullname.startswith(('coleman.transports','mcp')): + raise AssertionError('Source domain imported transport: '+fullname) +boundary = Boundary() +sys.meta_path.insert(0, boundary) +from coleman.corpus.source_views import SourceViewSpec, source_view_bytes +assert source_view_bytes((('owned.txt',b'owned'),)) +sys.meta_path.remove(boundary) +from coleman.transports.junit import load_junit_recipe +from coleman.transports.junit_source import digest, harness_bytes +recipe = load_junit_recipe() +assert recipe.harness_sha256 == digest(harness_bytes()) +assert len(recipe.test_ids) == 95 +assert Path(sys.modules['coleman.transports.junit'].__file__).resolve().is_relative_to(Path(sys.prefix)) +proof = {'installed': True, 'tests': len(recipe.test_ids), 'real_source_capture': False} +if sys.argv[1] != '-': + from coleman.artifacts import ArtifactWriter + from coleman.corpus import SourceCache + from coleman.transports.junit_capture import capture_junit_source + cache = SourceCache(sys.argv[1]) + writer = ArtifactWriter('real-junit-source') + first = capture_junit_source(recipe, cache, writer, 'installed-source-001') + second = capture_junit_source(recipe, cache, writer, 'installed-source-001') + assert first == second + assert [item.status for item in first.captures] == ['collected','collected'] + pairs = dict(Counter(pair.classification for pair in first.dataset.pairs)) + assert pairs == {'both_pass':92,'both_fail':2,'expected':1} + assert len(first.dataset.observations) == 190 + assert first.dataset.admission == 'not_evaluated' + assert first.dataset.generalization == 'insufficient_evidence' + proof.update(real_source_capture=True, pairs=pairs, dataset=str(first.dataset_path.resolve())) +print(json.dumps(proof,sort_keys=True)) +""" + source_cache = env.get("COLEMAN_JUNIT_REAL_CACHE", "-") + completed = command([str(python), "-c", script, source_cache], outside, env) + proof = json.loads(completed.stdout) + assert proof["installed"] + assert proof["tests"] == 95 + assert proof["real_source_capture"] == (source_cache != "-") + (tmp_path / "installed-junit-proof.json").write_text(json.dumps(proof, indent=2) + "\n") diff --git a/tests/corpus/test_junit_capture.py b/tests/corpus/test_junit_capture.py new file mode 100644 index 00000000..07a53dc9 --- /dev/null +++ b/tests/corpus/test_junit_capture.py @@ -0,0 +1,463 @@ +"""Owned producer tests exercise actual cache/contracts/publication; only the external Docker process is substituted.""" + +import io +import json +from collections import Counter +from datetime import UTC, datetime + +import pytest + +from coleman.artifacts import ArtifactWriter +from coleman.corpus import SourceCache, validate_materialization +from coleman.corpus.controlled_contracts import ControlledDataset +from coleman.corpus.materialization import materialize_source +from coleman.transports import junit +from coleman.transports import junit_capture as capture +from coleman.transports.junit_contracts import JunitCaptureRecipe, JunitRoleCapture, JunitRoleStart +from coleman.transports.junit_process import ProcessStreams +from coleman.transports.junit_source import classpath, digest, harness_bytes, owned_package, prepare_junit_inputs +from tests.corpus.test_junit_protocol import changed, encoded, recipe, records + + +def prepared_inputs(tmp_path): + spec = changed(recipe(), harness_sha256=digest(harness_bytes())) + cache = SourceCache(tmp_path / "cache") + for view in (spec.buggy, spec.fixed, spec.fixture): + for package in view.inputs: + materialize_source(package, cache, lambda: io.BytesIO(b"Owned schema-only source fixture.\n")) + materialize_source(spec.dependencies[0], cache, lambda: io.BytesIO(b"Owned schema-only dependency, not a real JAR")) + environment = owned_package(cache, "environment.json", b"Owned environment fixture", "owned-v1") + return spec, cache, environment + + +def substitute_docker(monkeypatch, environment, run): + monkeypatch.setattr(capture.shutil, "which", lambda _: "/owned/docker") + monkeypatch.setattr(capture, "_runtime_environment", lambda *args: environment) + monkeypatch.setattr(capture, "_run_role", run) + monkeypatch.setattr(capture, "_cleanup", lambda *args: None) + + +def test_offline_inputs_bind_actual_implementation_and_reject_changed_harness(tmp_path): + spec, cache, environment = prepared_inputs(tmp_path) + prepared = prepare_junit_inputs(spec, cache, environment) + assert prepared.context.test_ids == spec.test_ids + assert prepared.context.runtime.execution_model == "container" + assert prepared.harness == harness_bytes() + assert len(prepared.context.inputs) == 13 + for item in prepared.context.inputs: + validate_materialization(item.materialization, cache) + wrong = changed(spec, harness_sha256=digest(b"another harness")) + with pytest.raises(ValueError, match="harness disagrees"): + prepare_junit_inputs(wrong, cache, environment) + invalid_fetch = json.loads("1") + with pytest.raises(ValueError, match="boolean"): + prepare_junit_inputs(spec, cache, environment, fetch=invalid_fetch) + + +def test_paired_collection_checkpoint_replay_actual_core_and_cli(tmp_path, monkeypatch, capsys): + spec, cache, environment = prepared_inputs(tmp_path) + calls = [] + + def run(*args): + role = args[-2] + calls.append(role) + rows = records() + rows[1]["failures"] = int(role == "buggy") + return ProcessStreams(encoded(rows), b"compiler diagnostic", 0, 0, "exited") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(tmp_path / "results") + first = capture.capture_junit_source(spec, cache, writer, "owned-trial") + replay = capture.capture_junit_source(spec, cache, writer, "owned-trial") + assert first == replay + assert calls == ["buggy", "fixed"] + assert first.dataset.pairs[0].classification == "expected" + assert first.dataset.admission == "not_evaluated" + assert first.dataset.generalization == "insufficient_evidence" + assert ControlledDataset.from_json(first.dataset_path.read_bytes()) == first.dataset + assert first.dataset.observations[0].elapsed.value == 0 + recipe_path = tmp_path / "recipe.json" + recipe_path.write_text(spec.to_json()) + code = junit.main( + [ + "--recipe", + str(recipe_path), + "--cache", + str(cache.root), + "--output", + str(writer.run_root), + "--trial", + "owned-trial", + ] + ) + assert code == 0 + summary = json.loads(capsys.readouterr().out) + assert summary["pairs"] == {"expected": 1} + assert calls == ["buggy", "fixed"] + with pytest.raises(ValueError, match="not historical CI"): + first.dataset.require_temporal_evaluation() + packet_path = first.state_directory / "buggy.json" + packet = JunitRoleCapture.from_json(packet_path.read_bytes()) + packet_path.write_text(changed(packet, trial_id="wrong-trial").to_json()) + with pytest.raises(ValueError, match="identity mismatch"): + capture.capture_junit_source(spec, cache, writer, "owned-trial") + + +def test_process_interruption_has_no_false_completion_and_recovers_without_rerun(tmp_path, monkeypatch): + spec, cache, environment = prepared_inputs(tmp_path) + calls = [] + + def run(*args): + calls.append(args[-2]) + if len(calls) == 1: + raise KeyboardInterrupt + return ProcessStreams(encoded(records()), b"", 0, 1, "exited") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(tmp_path / "results") + with pytest.raises(KeyboardInterrupt): + capture.capture_junit_source(spec, cache, writer, "interrupted-trial") + assert not list(writer.run_root.glob("corpus-controlled/*.json")) + assert not list(writer.run_root.glob("junit-captures/*/buggy.json")) + result = capture.capture_junit_source(spec, cache, writer, "interrupted-trial") + assert calls == ["buggy", "fixed"] + assert [item.status for item in result.captures] == ["interrupted", "collected"] + interrupted = result.captures[0] + assert interrupted.stdout_base64 is None + assert interrupted.stderr_base64 is None + assert interrupted.producer_elapsed.value is None + assert result.dataset.pairs[0].classification == "inconclusive" + assert len(result.dataset.observations) == 1 + assert capture.capture_junit_source(spec, cache, writer, "interrupted-trial") == result + marker = result.state_directory / "buggy.started.json" + started = JunitRoleStart.from_json(marker.read_bytes()) + (result.state_directory / "buggy.json").unlink() + marker.write_text(changed(started, trial_id="wrong").to_json()) + with pytest.raises(ValueError, match="marker identity mismatch"): + capture.capture_junit_source(spec, cache, writer, "interrupted-trial") + + +def test_launch_failure_preserves_unavailable_values_and_cli_reports_incomplete(tmp_path, monkeypatch, capsys): + spec, cache, environment = prepared_inputs(tmp_path) + + def run(*args): + raise OSError("Owned launch failure") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(tmp_path / "results") + result = capture.capture_junit_source(spec, cache, writer, "failed-launch") + assert result.dataset.observations == () + assert result.dataset.pairs == () + assert all(item.status == "process_error" for item in result.captures) + assert all(item.stdout_base64 is None for item in result.captures) + path = tmp_path / "recipe.json" + path.write_text(spec.to_json()) + assert ( + junit.main( + [ + "--recipe", + str(path), + "--cache", + str(cache.root), + "--output", + str(writer.run_root), + "--trial", + "failed-launch", + ] + ) + == 2 + ) + assert json.loads(capsys.readouterr().out)["pairs"] == {} + + +def test_staging_exact_bytes_javac_arguments_and_postverification_tamper(tmp_path): + spec, cache, environment = prepared_inputs(tmp_path) + prepared = prepare_junit_inputs(spec, cache, environment) + root = tmp_path / "stage" + capture._stage_view(cache, prepared.buggy, root) + assert (root / "src/java/owned/CheckCase.java").read_bytes() == b"Owned schema-only source fixture.\n" + assert (root / "src/java").stat().st_mode & 0o777 == 0o755 + assert ( + capture._source_arguments(prepared.buggy, "src/java", "/source") == '"/source/src/java/owned/CheckCase.java"\n' + ) + cache.member_path(prepared.buggy, "src/java/owned/CheckCase.java").write_bytes(b"tampered") + with pytest.raises(ValueError, match="disagrees"): + capture._member_bytes(cache, prepared.buggy, "src/java/owned/CheckCase.java") + + +def test_concurrent_producer_lock_release_and_containment(tmp_path): + state = tmp_path / "state" + with ( + capture._single_producer(state), + pytest.raises((ValueError, OSError), match="producer"), + capture._single_producer(state), + ): + pytest.fail("Concurrent writer acquired the same trial") + with capture._single_producer(state): + pass + with pytest.raises(ValueError, match="trusted output"): + capture._contained(tmp_path, tmp_path / ".." / "escape") + link = tmp_path / "link" + link.symlink_to(state) + with pytest.raises(ValueError, match="trusted output"): + capture._contained(tmp_path, link) + + +def test_preset_is_metadata_only_and_current_harness_pinned(): + spec = junit.load_junit_recipe() + assert len(spec.test_ids) == 95 + assert spec.harness_sha256 == digest(harness_bytes()) + assert len(spec.fixture.inputs) == 23 + assert spec.dependencies[0].source.sha256 is not None + assert JunitCaptureRecipe.from_json(spec.to_json()) == spec + assert Counter(item.license.license_id for item in spec.dependencies) == {"Apache-2.0": 1, "CPL-1.0": 1} + + +@pytest.mark.parametrize("count", [0, 17]) +def test_classpath_limits(count): + with pytest.raises(ValueError, match="1..16"): + classpath(count) + + +def test_cleanup_is_scoped_and_does_not_hide_daemon_failure(monkeypatch): + calls = [] + + def collect(args, **kwargs): + calls.append(args) + return ProcessStreams(b"", b"Error response from daemon: No such container: owned-name\n", 1, 1, "exited") + + monkeypatch.setattr(capture, "collect_process", collect) + capture._cleanup(("docker",), "owned-name") + assert calls == [("docker", "rm", "-f", "owned-name")] + monkeypatch.setattr( + capture, "collect_process", lambda *args, **kwargs: ProcessStreams(b"", b"daemon unavailable", 1, 1, "exited") + ) + with pytest.raises(OSError, match="cleanup failed"): + capture._cleanup(("docker",), "owned-name") + + +def test_missing_runtime_rejects_before_collection(tmp_path, monkeypatch): + spec, cache, _ = prepared_inputs(tmp_path) + monkeypatch.setattr(capture.shutil, "which", lambda _: None) + writer = ArtifactWriter(tmp_path / "results") + with pytest.raises(OSError, match="local Docker"): + capture.capture_junit_source(spec, cache, writer, "owned-trial") + + +def test_bounded_recipe_and_checkpoint_reads(tmp_path): + path = tmp_path / "too-large.json" + path.write_bytes(b" " * (2 * 1024**2 + 1)) + with pytest.raises(ValueError, match="recipe exceeds"): + junit.load_junit_recipe(path) + path.write_bytes(b" " * (16 * 1024**2 + 1)) + spec = recipe() + with pytest.raises(ValueError, match="checkpoint exceeds"): + capture._load_role(path, spec) + + +def test_filtered_runtime_provenance_has_no_ambient_metadata(tmp_path, monkeypatch): + spec = recipe() + calls = [] + + def query(base, args): + calls.append(args) + if args[0] == "image": + return ["linux", "arm64", 1234, digest(b"owned image config")] + if args[0] == "version": + return ["24.0.2", "24.0.2", "arm64"] + return "owned-kernel" + + monkeypatch.setattr(capture, "_docker_query", query) + monkeypatch.setattr(capture.platform, "machine", lambda: "arm64") + cache = SourceCache(tmp_path / "cache") + receipt = capture._runtime_environment(("docker",), spec, cache) + payload = cache.member_path(receipt, "execution-environment.json").read_bytes() + metadata = json.loads(payload) + assert metadata["image_size_bytes"] == 1234 + assert metadata["producer_python_version"] + assert "RepoTags" not in str(calls) + assert "RepoDigests" not in str(calls) + assert "hostname" not in metadata + wrong = changed(spec, runtime=changed(spec.runtime, emulated=True)) + with pytest.raises(ValueError, match="emulation profile"): + capture._runtime_environment(("docker",), wrong, cache) + monkeypatch.setattr(capture, "_docker_query", lambda *args: []) + with pytest.raises(ValueError, match="runtime metadata"): + capture._runtime_environment(("docker",), spec, cache) + + +def test_docker_query_checks_process_and_strict_json(monkeypatch): + monkeypatch.setattr( + capture, "collect_process", lambda *args, **kwargs: ProcessStreams(b'{"owned":1}\n', b"", 0, 1, "exited") + ) + assert capture._docker_query(("docker",), ("version",)) == {"owned": 1} + monkeypatch.setattr(capture, "collect_process", lambda *args, **kwargs: ProcessStreams(b"", b"", 1, 1, "exited")) + with pytest.raises(OSError, match="runtime unavailable"): + capture._docker_query(("docker",), ("version",)) + + +def test_actual_role_command_stages_only_declared_inputs_and_guards(tmp_path, monkeypatch): + spec, cache, environment = prepared_inputs(tmp_path) + prepared = prepare_junit_inputs(spec, cache, environment) + calls = [] + + def collect(args, **kwargs): + calls.append((args, kwargs)) + if "run" in args: + assert "--network" in args + assert args[args.index("--network") + 1] == "none" + assert "--read-only" in args + assert "--pull=never" in args + assert args[args.index("--cap-drop") + 1] == "ALL" + mounts = [args[index + 1] for index, value in enumerate(args) if value == "--mount"] + assert len(mounts) == 4 + assert all("readonly" in value for value in mounts) + return ProcessStreams(encoded(records()), b"", 0, 123, "exited") + return ProcessStreams(b"owned-name", b"", 0, 1, "exited") + + monkeypatch.setattr(capture, "collect_process", collect) + streams = capture._run_role(("docker",), spec, prepared, cache, "buggy", "owned-name") + assert streams.elapsed_ns == 123 + assert calls[-1][0] == ("docker", "rm", "-f", "owned-name") + assert calls[0][1]["maximum_output_bytes"] == spec.limits.maximum_output_bytes + + +@pytest.mark.parametrize( + "instant", + ["2026-01-01T00:00:00.123456789Z", "٢٠٢٦-01-01T00:00:00Z", "2026-01-01T00:00:00+00:00"], +) +def test_role_precision_and_unknown_schema_reject_before_truncation(instant): + row = records()[1] + row["capture_started_at"] = instant + from coleman.transports.junit_contracts import JunitCase + + with pytest.raises(ValueError, match="six fractional digits"): + JunitCase.model_validate(row) + row["capture_started_at"] = "2026-01-01T00:00:00Z" + row["schema_version"] = 2 + with pytest.raises(ValueError, match="version"): + JunitCase.model_validate(row) + + +@pytest.mark.parametrize("launch_error", [False, True]) +def test_cleanup_failure_leaves_recoverable_start_without_committing_a_role(tmp_path, monkeypatch, launch_error): + spec, cache, environment = prepared_inputs(tmp_path) + monkeypatch.setattr(capture.shutil, "which", lambda _: "/owned/docker") + monkeypatch.setattr(capture, "_runtime_environment", lambda *args: environment) + executions = [] + fail_cleanup = True + + def collect(args, **kwargs): + if "run" in args: + executions.append(args) + return ProcessStreams(encoded(records()), b"", 0, 1, "exited") + if fail_cleanup: + if launch_error: + raise OSError("Owned cleanup process could not start") + return ProcessStreams(b"", b"owned daemon unavailable during cleanup", 1, 1, "exited") + return ProcessStreams(b"", b"", 0, 1, "exited") + + monkeypatch.setattr(capture, "collect_process", collect) + writer = ArtifactWriter(tmp_path / "results") + with pytest.raises(OSError, match="cleanup failed"): + capture.capture_junit_source(spec, cache, writer, "cleanup-trial") + assert len(executions) == 1 + assert not list(writer.run_root.glob("junit-captures/*/buggy.json")) + assert not list(writer.run_root.glob("corpus-controlled/*.json")) + assert len(list(writer.run_root.glob("junit-captures/*/buggy.started.json"))) == 1 + fail_cleanup = False + recovered = capture.capture_junit_source(spec, cache, writer, "cleanup-trial") + assert len(executions) == 2 + assert [item.status for item in recovered.captures] == ["interrupted", "collected"] + assert recovered.dataset.pairs[0].classification == "inconclusive" + + +@pytest.mark.parametrize("status", ["protocol_error", "process_error"]) +def test_checkpoint_cannot_discard_complete_raw_observations_by_changing_status(tmp_path, status): + spec = recipe() + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = capture.role_capture( + spec, + digest(b"context"), + "owned-trial", + "buggy", + now, + now, + ProcessStreams(encoded(records()), b"", 0, 1, "exited"), + ) + payload = packet.model_dump(mode="json") + payload.update(status=status, header=None, cases=[]) + path = tmp_path / "edited-role.json" + path.write_text(json.dumps(payload)) + with pytest.raises(ValueError): + capture._load_role(path, spec) + + +@pytest.mark.parametrize("known_exit,known_elapsed", [(True, False), (False, True), (True, True)]) +def test_streamless_checkpoint_cannot_retain_observed_process_facts(tmp_path, known_exit, known_elapsed): + spec = recipe() + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = capture.role_capture( + spec, + digest(b"context"), + "owned-trial", + "buggy", + now, + now, + ProcessStreams(encoded(records()), b"", 0, 1, "exited"), + ) + payload = packet.model_dump(mode="json") + payload.update(status="process_error", stdout_base64=None, stderr_base64=None, header=None, cases=[]) + if not known_exit: + payload["exit_code"] = None + if not known_elapsed: + payload["producer_elapsed"].update(value=None, status="unavailable") + path = tmp_path / "edited-streamless-role.json" + path.write_text(json.dumps(payload)) + with pytest.raises(ValueError): + capture._load_role(path, spec) + + +@pytest.mark.parametrize("missing_fact", ["exit_code", "producer_elapsed"]) +def test_observed_streams_cannot_discard_process_facts(tmp_path, missing_fact): + spec = recipe() + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = capture.role_capture( + spec, + digest(b"context"), + "owned-trial", + "buggy", + now, + now, + ProcessStreams(b"owned process failure", b"", 7, 0, "exited"), + ) + payload = packet.model_dump(mode="json") + if missing_fact == "exit_code": + payload[missing_fact] = None + else: + payload[missing_fact].update(value=None, status="unavailable") + path = tmp_path / "edited-observed-role.json" + path.write_text(json.dumps(payload)) + with pytest.raises(ValueError): + capture._load_role(path, spec) + + +@pytest.mark.parametrize("status", ["timeout", "output_limit"]) +def test_checkpoint_guard_labels_must_agree_with_observed_bounds(tmp_path, status): + spec = recipe() + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = capture.role_capture( + spec, + digest(b"context"), + "owned-trial", + "buggy", + now, + now, + ProcessStreams(encoded(records()), b"", 0, 0, "exited"), + ) + payload = packet.model_dump(mode="json") + payload.update(status=status, header=None, cases=[]) + path = tmp_path / "edited-guard-role.json" + path.write_text(json.dumps(payload)) + with pytest.raises(ValueError): + capture._load_role(path, spec) diff --git a/tests/corpus/test_junit_process.py b/tests/corpus/test_junit_process.py new file mode 100644 index 00000000..d6d94554 --- /dev/null +++ b/tests/corpus/test_junit_process.py @@ -0,0 +1,82 @@ +"""Real owned child processes verify bounded collection without Docker or external network.""" + +import sys + +import pytest + +from coleman.transports.junit_process import collect_process + + +def command(code): + return (sys.executable, "-I", "-c", code) + + +def test_real_child_exit_streams_and_environment_are_explicit(monkeypatch): + monkeypatch.setenv("COLEMAN_OWNED_PARENT_VALUE", "must not reach child") + result = collect_process( + command( + "import os,sys; assert 'COLEMAN_OWNED_PARENT_VALUE' not in os.environ; " + "sys.stdout.buffer.write(b'owned CI output'); " + "sys.stderr.buffer.write(b'owned diagnostic'); sys.exit(7)" + ), + timeout_seconds=5, + maximum_output_bytes=1024, + ) + assert result.stdout == b"owned CI output" + assert result.stderr == b"owned diagnostic" + assert result.exit_code == 7 + assert result.termination == "exited" + assert result.elapsed_ns > 0 + + +def test_exact_byte_limit_succeeds_and_overflow_preserves_a_bounded_prefix(): + exact = collect_process( + command("import sys; sys.stdout.buffer.write(b'x'*1024)"), timeout_seconds=5, maximum_output_bytes=1024 + ) + assert exact.termination == "exited" + assert len(exact.stdout) == 1024 + exceeded = collect_process( + command("import sys,time; sys.stdout.buffer.write(b'x'*1000000); sys.stdout.flush(); time.sleep(10)"), + timeout_seconds=5, + maximum_output_bytes=1024, + ) + assert exceeded.termination == "output_limit" + assert len(exceeded.stdout) + len(exceeded.stderr) == 1024 + + +def test_timeout_kills_the_actual_child_process_group(): + result = collect_process( + command("import time; print('partial evidence',flush=True); time.sleep(10)"), + timeout_seconds=1, + maximum_output_bytes=1024, + ) + assert result.termination == "timeout" + assert result.stdout == b"partial evidence\n" + assert result.exit_code < 0 + + +def test_a_child_that_closes_pipes_cannot_escape_the_deadline(): + result = collect_process( + command("import os,time; os.close(1); os.close(2); time.sleep(10)"), + timeout_seconds=1, + maximum_output_bytes=1024, + ) + assert result.termination == "timeout" + + +@pytest.mark.parametrize( + "seconds,maximum", [(0, 1024), (True, 1024), (121, 1024), (5, 0), (5, True), (5, 4 * 1024**2 + 1)] +) +def test_invalid_guards_reject_before_execution(seconds, maximum): + args = command('raise RuntimeError("must not execute")') + with pytest.raises(ValueError): + collect_process(args, timeout_seconds=seconds, maximum_output_bytes=maximum) + + +def test_invalid_command_and_missing_executable_reject(tmp_path): + with pytest.raises(ValueError): + collect_process((), timeout_seconds=1, maximum_output_bytes=1) + with pytest.raises(ValueError): + collect_process(("bad\x00command",), timeout_seconds=1, maximum_output_bytes=1) + with pytest.raises(OSError): + collect_process((str(tmp_path / "not-created" / "command"),), timeout_seconds=1, maximum_output_bytes=1) diff --git a/tests/corpus/test_junit_protocol.py b/tests/corpus/test_junit_protocol.py new file mode 100644 index 00000000..da998680 --- /dev/null +++ b/tests/corpus/test_junit_protocol.py @@ -0,0 +1,235 @@ +"""Owned JUnit protocol fixtures retain negative evidence without executing foreign source.""" + +import base64 +import json +import sys +from datetime import UTC, datetime +from pathlib import Path + +import pytest + +from coleman.corpus.source_views import SourceViewSpec, source_view_bytes +from coleman.transports.junit_contracts import JunitCaptureRecipe, JunitCase, JunitRoleCapture, ProducerElapsed +from coleman.transports.junit_process import ProcessStreams, collect_process +from coleman.transports.junit_protocol import parsed_junit_stream, role_capture, validate_role_bytes +from tests.corpus.test_source_views import changed, digest, source_spec + + +def view(label, prefix, version): + name = prefix + "/owned/CheckCase.java" + payload = b"Owned schema-only source fixture.\n" + raw = source_spec(name, payload) + raw = changed(raw, source=changed(raw.source, version=version)) + output = source_spec(label, source_view_bytes(((name, payload),)), "zip", [raw.members[0].model_dump()]) + output = changed(output, source=changed(output.source, version=version)) + return SourceViewSpec(schema_version=1, inputs=(raw,), output=output) + + +def recipe(): + return JunitCaptureRecipe.model_validate( + { + "schema_version": 1, + "recipe_id": "owned-junit-schema-v1", + "project": "owned-ci", + "fault_id": "owned-case", + "fault_origin": "synthetic", + "dependence_group": "owned-ci-single-fixture", + "buggy": view("buggy", "src/java", "buggy-v1"), + "fixed": view("fixed", "src/java", "fixed-v1"), + "fixture": view("fixture", "src/test", "fixed-v1"), + "dependencies": [source_spec("junit.jar", b"Owned schema-only dependency, not a real JAR")], + "runtime": { + "version": "11.0.32.1", + "platform": "linux/arm64", + "image_digest": digest(b"owned schema-only image"), + "emulated": False, + "timezone": "UTC", + }, + "production_prefix": "src/java", + "fixture_prefix": "src/test", + "test_ids": ["owned.CheckCase::test_ci"], + "harness_sha256": digest(b"owned schema-only harness"), + "limitations": ["Schema-only fixture; no foreign runtime, source or independent faults claimed"], + } + ) + + +def records(): + return [ + { + "schema_version": 1, + "record_type": "header", + "java_version": "11.0.32.1", + "architecture": "aarch64", + "timezone": "UTC", + "capture_clock": "producer-truncated-utc-microsecond-v1", + "test_ids": ["owned.CheckCase::test_ci"], + "excluded_classes": ["owned.Example"], + }, + { + "schema_version": 1, + "record_type": "case", + "test_id": "owned.CheckCase::test_ci", + "tests_run": 1, + "failures": 1, + "errors": 0, + "elapsed_ns": 0, + "capture_started_at": "2026-01-01T00:00:00Z", + "capture_finished_at": "2026-01-01T00:00:00Z", + "diagnostics": "Owned diagnostic\u2028retains its Unicode separator", + "diagnostics_truncated": False, + }, + {"schema_version": 1, "record_type": "trailer", "case_count": 1}, + ] + + +def encoded(rows): + return b"".join(json.dumps(row, ensure_ascii=False).encode() + b"\n" for row in rows) + + +def test_protocol_runtime_unicode_framing_counters_and_packet_roundtrip(): + spec = recipe() + raw = encoded(records()) + header, cases = parsed_junit_stream(raw, spec) + assert header.test_ids == spec.test_ids + assert cases[0].outcome == "assertion_failed" + assert cases[0].elapsed_ns == 0 + assert "\u2028" in cases[0].diagnostics + now = datetime(2026, 1, 1, tzinfo=UTC) + streams = ProcessStreams(raw, b"owned compiler diagnostic", 0, 0, "exited") + packet = role_capture(spec, digest(b"context"), "owned-trial", "buggy", now, now, streams) + assert packet.status == "collected" + assert packet.producer_elapsed.value == 0 + assert packet.producer_elapsed.meaning != "observed-test-harness-monotonic-elapsed-v1" + assert JunitRoleCapture.from_json(packet.to_json()) == packet + fixtures = Path(__file__).with_name("fixtures") + assert packet.to_json() + "\n" == (fixtures / "junit-role-owned-v1.json").read_text() + assert spec.to_json() + "\n" == (fixtures / "junit-recipe-owned-v1.json").read_text() + validate_role_bytes(packet, spec) + altered_case = changed(packet.cases[0], failures=0) + altered = changed(packet, cases=(altered_case,)) + with pytest.raises(ValueError, match="disagree with raw streams"): + validate_role_bytes(altered, spec) + + +@pytest.mark.parametrize( + "change", + [ + {"java_version": "other"}, + {"architecture": "amd64"}, + {"timezone": "other"}, + {"test_ids": ["owned.CheckCase::different"]}, + {"schema_version": 2}, + {"extra": "unknown"}, + ], +) +def test_bad_header_and_future_versions_reject(change): + rows = records() + rows[0].update(change) + raw = encoded(rows) + spec = recipe() + with pytest.raises(ValueError): + parsed_junit_stream(raw, spec) + + +@pytest.mark.parametrize( + "change", + [ + {"elapsed_ns": -1}, + {"elapsed_ns": float("inf")}, + {"elapsed_ns": True}, + {"failures": None}, + {"tests_run": 0}, + {"schema_version": 2}, + ], +) +def test_invalid_case_quantities_and_future_versions_reject(change): + data = {**records()[1], **change} + payload = json.dumps(data) + with pytest.raises(ValueError): + JunitCase.from_json(payload) + + +def test_missing_final_marker_duplicates_and_incompatible_case_universe_reject(): + spec = recipe() + rows = records() + candidates = [ + encoded(rows)[:-1], + encoded(rows[:-1]), + encoded([rows[0], rows[1], rows[1], rows[2]]), + encoded([rows[0], {**rows[1], "test_id": "owned.CheckCase::different"}, rows[2]]), + encoded([rows[0], rows[1], {**rows[2], "case_count": 2}]), + ] + for raw in candidates: + with pytest.raises(ValueError): + parsed_junit_stream(raw, spec) + + +@pytest.mark.parametrize( + "updates,expected", + [ + ({"errors": 1}, "test_error"), + ({"failures": 0}, "passed"), + ({"diagnostics_truncated": True}, "infrastructure_error"), + ], +) +def test_test_error_pass_and_truncation_remain_distinct(updates, expected): + data = {**records()[1], **updates} + assert JunitCase.model_validate(data).outcome == expected + + +@pytest.mark.parametrize( + "termination,exit_code,stdout,status", + [ + ("timeout", -9, b"partial output", "timeout"), + ("output_limit", -9, b"clipped", "output_limit"), + ("exited", 2, b"compile failed", "process_error"), + ("exited", 0, b"not JSON\n", "protocol_error"), + ], +) +def test_incomplete_process_does_not_promote_partial_cases(termination, exit_code, stdout, status): + now = datetime(2026, 1, 1, tzinfo=UTC) + spec = recipe() + stderr = b"raw stderr" + elapsed = 1 + if termination == "timeout": + elapsed = spec.limits.timeout_seconds * 10**9 + if termination == "output_limit": + stdout = stdout.ljust(spec.limits.maximum_output_bytes - len(stderr), b"x") + streams = ProcessStreams(stdout, stderr, exit_code, elapsed, termination) + packet = role_capture(spec, digest(b"context"), "owned-trial", "buggy", now, now, streams) + assert packet.status == status + assert packet.cases == () + assert packet.stdout_base64 is not None + assert base64.b64decode(packet.stdout_base64) == stdout + validate_role_bytes(packet, spec) + + +def test_producer_counter_has_explicit_units_and_missingness(): + assert ProducerElapsed(value=None, status="unavailable").value is None + for data in ( + {"value": None, "status": "observed"}, + {"value": 0, "status": "unavailable"}, + {"value": -1, "status": "observed"}, + {"value": 0, "status": "observed", "unit": "s"}, + ): + with pytest.raises(ValueError): + ProducerElapsed.model_validate(data) + + +@pytest.mark.parametrize("termination", ["timeout", "output_limit"]) +def test_actual_child_guard_facts_validate_without_promoting_cases(termination): + seconds = 1 if termination == "timeout" else 5 + spec = recipe() + spec = changed(spec, limits=changed(spec.limits, timeout_seconds=seconds, maximum_output_bytes=1024)) + code = ( + "import time; time.sleep(10)" + if termination == "timeout" + else "import sys; sys.stdout.buffer.write(b'x'*100000)" + ) + streams = collect_process((sys.executable, "-I", "-c", code), timeout_seconds=seconds, maximum_output_bytes=1024) + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = role_capture(spec, digest(b"context"), "owned-trial", "buggy", now, now, streams) + assert packet.status == termination + assert packet.cases == () + validate_role_bytes(packet, spec) diff --git a/tests/corpus/test_source_views.py b/tests/corpus/test_source_views.py new file mode 100644 index 00000000..b1251d13 --- /dev/null +++ b/tests/corpus/test_source_views.py @@ -0,0 +1,170 @@ +"""Owned source views: immutable raw acquisition, explicit provenance and deterministic assembly.""" + +import hashlib +import io +import json +import zipfile +from concurrent.futures import ThreadPoolExecutor +from pathlib import Path + +import pytest + +from coleman.corpus import MaterializationSpec, SourceCache, load_registry, validate_materialization +from coleman.corpus.source_views import SourceViewSpec, materialize_source_view, source_view_bytes + + +def digest(payload): + return "sha256:" + hashlib.sha256(payload).hexdigest() + + +def changed(model, **values): + return type(model).model_validate({**model.model_dump(), **values}) + + +def source_spec(name, payload, archive="raw", members=None): + if members is None: + members = [{"name": name, "sha256": digest(payload), "size_bytes": len(payload)}] + return MaterializationSpec.model_validate( + { + "schema_version": 1, + "package_id": name, + "archive": archive, + "source": { + "uri": "urn:coleman:owned-source-view:" + name, + "version": "owned-v1", + "citation": "Owned synthetic source-view fixture, not foreign code", + "sha256": digest(payload), + "size_bytes": len(payload), + "availability": "not_verified", + }, + "license": load_registry().card("ci-serial-boundary-v1").manifest.license.model_dump(), + "members": members, + } + ) + + +def recipe(): + entries = (("src/owned.txt", b"Owned CI source.\n"), ("LICENSE", b"Owned schema fixture only.\n")) + inputs = tuple(source_spec(name, payload) for name, payload in entries) + payload = source_view_bytes(entries) + output = source_spec( + "owned-source-view-v1", + payload, + "zip", + [p.members[0].model_dump() for p in sorted(inputs, key=lambda p: p.members[0].name)], + ) + return SourceViewSpec(schema_version=1, inputs=inputs, output=output), dict(entries) + + +def test_roundtrip_golden_real_cache_offline_recovery_and_concurrent_replay(tmp_path): + spec, data = recipe() + cache = SourceCache(tmp_path / "cache") + calls = [] + + def reader_for(package): + name = package.members[0].name + + def factory(): + calls.append(name) + return io.BytesIO(data[name]) + + return factory + + receipt = materialize_source_view(spec, cache, reader_for) + assert set(calls) == set(data) + assert SourceViewSpec.from_json(spec.to_json()) == spec + golden = Path(__file__).with_name("fixtures") / "source-view-owned-v1.json" + assert spec.to_json() + "\n" == golden.read_text() + validate_materialization(receipt, cache) + assert materialize_source_view(spec, cache) == receipt + materialize_source_view(spec, cache, reader_for) + assert len(calls) == 2 + with ThreadPoolExecutor(max_workers=4) as pool: + results = list(pool.map(lambda _: materialize_source_view(spec, cache), range(8))) + assert all(result == receipt for result in results) + assert cache.member_path(receipt, "src/owned.txt").read_bytes() == data["src/owned.txt"] + + +def test_zip_metadata_order_metamorphism_empty_file_and_exact_pins(): + entries = (("z.txt", b"Z"), ("a.txt", b"")) + first = source_view_bytes(entries) + assert source_view_bytes(tuple(reversed(entries))) == first + with zipfile.ZipFile(io.BytesIO(first)) as archive: + assert archive.namelist() == ["a.txt", "z.txt"] + for member in archive.infolist(): + assert member.date_time == (1980, 1, 1, 0, 0, 0) + assert member.compress_type == zipfile.ZIP_STORED + assert member.create_system == 3 + assert member.external_attr >> 16 == 0o100644 + assert archive.read("a.txt") == b"" + spec, _ = recipe() + assert changed(spec, inputs=tuple(reversed(spec.inputs))) == spec + + +@pytest.mark.parametrize("entries", [(), (("a", b"a"), ("a", b"b")), (("../escape", b"a"),), (("a", bytearray(b"x")),)]) +def test_invalid_entries_reject_before_writing(entries): + with pytest.raises((ValueError, TypeError)): + source_view_bytes(entries) + + +@pytest.mark.parametrize("version", [None, 0, 2, True, "1"]) +def test_source_view_versions_fail_closed(version): + spec, _ = recipe() + payload = spec.model_dump(mode="json") + if version is None: + del payload["schema_version"] + else: + payload["schema_version"] = version + encoded = json.dumps(payload) + with pytest.raises(ValueError): + SourceViewSpec.from_json(encoded) + + +def test_member_names_package_ids_licence_and_versions_are_bound(): + spec, _ = recipe() + for updates in ({"recipe": "future"}, {"inputs": (spec.inputs[0],) * 2}, {"output": spec.inputs[0]}): + with pytest.raises(ValueError): + changed(spec, **updates) + duplicated_id = changed(spec.inputs[0], package_id=spec.inputs[1].package_id) + with pytest.raises(ValueError, match="package identity"): + changed(spec, inputs=(duplicated_id, spec.inputs[1])) + altered_terms = changed(spec.inputs[0].license, redistribution="recipe_only") + input_terms = changed(spec.inputs[0], license=altered_terms) + with pytest.raises(ValueError, match="terms must match"): + changed(spec, inputs=(input_terms, spec.inputs[1])) + input_version = changed(spec.inputs[0], source=changed(spec.inputs[0].source, version="other")) + with pytest.raises(ValueError, match="versions disagree"): + changed(spec, inputs=(input_version, spec.inputs[1])) + missing = changed(spec.output, members=spec.output.members[:-1]) + with pytest.raises(ValueError, match="preserve every input"): + changed(spec, output=missing) + + +def test_interrupted_input_retry_output_pins_and_byte_tampering(tmp_path): + spec, data = recipe() + cache = SourceCache(tmp_path / "cache") + seen = [] + + def interrupted(package): + name = package.members[0].name + seen.append(name) + if len(seen) == 2: + + def fail(): + raise OSError("interrupted source acquisition") + + return fail + return lambda: io.BytesIO(data[name]) + + with pytest.raises(OSError, match="interrupted"): + materialize_source_view(spec, cache, interrupted) + assert len(list((cache.root / "blobs").iterdir())) == 1 + receipt = materialize_source_view(spec, cache, lambda p: lambda: io.BytesIO(data[p.members[0].name])) + wrong_output = changed(spec.output, source=changed(spec.output.source, sha256=digest(b"wrong archive"))) + wrong = changed(spec, output=wrong_output) + with pytest.raises(ValueError): + materialize_source_view(wrong, cache) + path = cache.member_path(receipt, "src/owned.txt") + path.write_bytes(b"changed cached input") + with pytest.raises(ValueError): + materialize_source_view(spec, cache) diff --git a/zensical.toml b/zensical.toml index c4624483..8905ae3f 100644 --- a/zensical.toml +++ b/zensical.toml @@ -27,6 +27,7 @@ nav = [ { "RTPTorrent Source Assessment" = "rtptorrent.md" }, { "LRTS Source Assessment" = "lrts.md" }, { "Controlled Fault Observations" = "controlled-faults.md" }, + { "Pinned JUnit Source Capture" = "junit-source-capture.md" }, { "Point-in-time CI Observations" = "point-in-time-observations.md" }, { "ADR 001: Point-in-time Boundary" = "decisions/001-point-in-time-observations.md" }, { "Operational CI Pilot" = "operational-pilot.md" }, From 8de339e8b4de95c7877b9af93255086f380978ca Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 11:04:13 -0300 Subject: [PATCH 3/8] test(corpus): isolate fresh installed source collection identities --- tests/corpus/test_installed_junit.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/corpus/test_installed_junit.py b/tests/corpus/test_installed_junit.py index aadf100f..5a86d9eb 100644 --- a/tests/corpus/test_installed_junit.py +++ b/tests/corpus/test_installed_junit.py @@ -42,13 +42,15 @@ def find_spec(self, fullname, path=None, target=None): assert Path(sys.modules['coleman.transports.junit'].__file__).resolve().is_relative_to(Path(sys.prefix)) proof = {'installed': True, 'tests': len(recipe.test_ids), 'real_source_capture': False} if sys.argv[1] != '-': + from uuid import uuid4 from coleman.artifacts import ArtifactWriter from coleman.corpus import SourceCache from coleman.transports.junit_capture import capture_junit_source cache = SourceCache(sys.argv[1]) writer = ArtifactWriter('real-junit-source') - first = capture_junit_source(recipe, cache, writer, 'installed-source-001') - second = capture_junit_source(recipe, cache, writer, 'installed-source-001') + trial = 'installed-source-' + uuid4().hex + first = capture_junit_source(recipe, cache, writer, trial) + second = capture_junit_source(recipe, cache, writer, trial) assert first == second assert [item.status for item in first.captures] == ['collected','collected'] pairs = dict(Counter(pair.classification for pair in first.dataset.pairs)) From 1283fba534cf0cded90b0ab3323b2953c52c7afc Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 11:04:13 -0300 Subject: [PATCH 4/8] docs: prepare reviewed COLEMAN 4.6 release notes --- docs/releases.md | 7 +- docs/releases/4.6.0.md | 128 +++++++++++++++++++++++++++++++++++++ llms.txt | 141 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 docs/releases/4.6.0.md diff --git a/docs/releases.md b/docs/releases.md index 273f377d..9aba792a 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -6,7 +6,12 @@ should explain the value to CI users before listing internal implementation work ## Versioning and integration -[COLEMAN 4.5](releases/4.5.0.md) adds bounded RTPTorrent and LRTS source readers, +[COLEMAN 4.6](releases/4.6.0.md) adds versioned controlled fault observations, +a pinned offline JUnit3 source recipe and recoverable raw evidence. Existing +native TCPCI experiments and learning checkpoints keep their contracts. Controlled +source reproduction remains separate from benchmark admission. + +[COLEMAN 4.5](releases/4.5.0.md) added bounded RTPTorrent and LRTS source readers, explicit units/provenance and installed native CI/checkpoint workflows. It retains the exact numeric safeguards from 4.4.1, corpus profiles and secure source cache. Both external sources remain blocked for protected temporal evaluation. diff --git a/docs/releases/4.6.0.md b/docs/releases/4.6.0.md new file mode 100644 index 00000000..e471dac2 --- /dev/null +++ b/docs/releases/4.6.0.md @@ -0,0 +1,128 @@ +# COLEMAN 4.6 — Reproducible fault evidence for CI + +A CI prioritization decision needs evidence you can inspect and reproduce. +COLEMAN 4.6 connects pinned buggy/fixed source revisions to versioned test +observations, retained diagnostics and immutable artifacts. You can rerun a +controlled fault recipe, recover interrupted collection and keep unexpected +outcomes visible before considering a source for a benchmark. + +This release brings together the reviewed controlled-observation foundation and +an optional Java/JUnit3 producer. The existing TCPCI runner continues to execute +learning experiments, write results and resume its own checkpoints. + +## From a source revision to an auditable result + +The new controlled records retain the project, curated fault label, common test +fixture, source revisions, runtime, component receipts and actual producer bytes. +Each observation has a stable logical identity, explicit outcome and integer +monotonic nanoseconds. Zero, unavailable and not applicable keep distinct meanings. +Parent-process timing and per-test harness timing have separate semantics. +Neither becomes an invented CI completion time or removable scheduling cost. + +Same-test comparisons preserve expected, both-pass, both-fail, reversed and +inconclusive outcomes. Missing observations stay missing. Diagnostic digests bind +to separately verified report members; schemas, source bytes and duplicate +identities are validated before immutable publication. + +The bundled Apache Commons CLI-13 recipe pins both public source revisions, a +common fixed-tree fixture, component dependencies, the COLEMAN-authored harness +and a platform-specific Temurin image. Individually pinned files form bounded, +deterministic source views. Foreign source code and datasets are not bundled in +the package or mirrored into the repository. + +A real installed-wheel execution collected **190 observations across 95 tests per +revision**: 92 pairs passed in both revisions, two failed in both and one failed +then passed. The two additional failures remain in the evidence. These are +functional reproduction results for this declared runtime and fixture, not an +independent-fault count or a policy-performance comparison. + +## Try the pinned recipe + +Use Python 3.14+, a local arm64 Docker engine and an external workspace. Install +the wheel attached to this release and explicitly prepare its public image: + +```bash +python -m pip install https://github.com/jacksonpradolima/coleman/releases/download/v4.6.0/coleman-4.6.0-py3-none-any.whl +docker pull --platform linux/arm64 eclipse-temurin@sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8 +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 --fetch +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 +``` + +The first call explicitly permits reviewed, size/digest-pinned public GitHub and +Maven downloads. The second reopens the same committed observations without +executing those roles again. Acquisition is offline by default; subject execution +has no network and the producer never pulls an image implicitly. + +The JSON summary provides artifact paths, role statuses, pair counts and explicit +admission/generalization fields. Exit 0 means the collection protocols completed; +assertion failures remain outcomes. Incomplete collection retains its evidence +and returns 2. Exceptions remain nonzero failures. + +The [complete Java guide](https://github.com/jacksonpradolima/coleman/blob/v4.6.0/docs/junit-source-capture.md) +explains source/component terms, resource limits and the runtime profile. The +[controlled-observation guide](https://github.com/jacksonpradolima/coleman/blob/v4.6.0/docs/controlled-faults.md) +provides an offline SDK example and a complete owned native TCPCI workflow with +independently checked metrics and learning-checkpoint continuation. + +## Recover without inventing success + +An immutable start marker precedes each role. Completed packets replay; a started +but uncommitted role recovers as interrupted, with unavailable streams/counters +and no fabricated cases. Failed container cleanup leaves that start recoverable. +A POSIX lock prevents duplicate producers for the same context/trial/output tree. +Use a new trial ID for a new execution; repeated trials retain their dependence +group and do not become independent projects or faults. + +The collector bounds process time and combined output bytes. Containers are +non-root and read-only, with explicit input mounts and CPU, memory, PID and +temporary-storage limits. These guards support trusted-source reproduction. + +Resume validates raw protocol bytes, exit status, discovered test IDs and the +completion trailer. Unavailable streams cannot retain observed process facts; +observed streams require them. Timeout/prefix claims must agree with their bounds. +Contradictory negative labels cannot silently erase complete observations. +Coherent producer attestations still do not authenticate execution truth. + +## Compatibility and validation + +This is an additive **4.x** release. Existing native results, artifacts, sinks, +checkpoints and source readers retain their meaning. New contracts require schema +v1 and reject missing, unknown and future versions. No automatic migration or +reinterpretation of old results occurs. Harness changes require a reviewed recipe +update. The domain remains independent of CLI, Docker and MCP imports. + +The reviewed implementation passed **2,243 tests** with **95.26% combined +statement/branch coverage**, including a real paired source reproduction from a +wheel installed outside the checkout. Versioned golden/round-trip fixtures, +compatibility, units/missingness, nonfinite values, deterministic identities, +concurrent publication, interrupted writes, genuine child-process guards and +checkpoint recovery are covered. All lint/format/type/Pylint/docstring/structural, +strict documentation and package checks passed. Local-only OpenCodeReview and +manual review covered every changed file; confirmed findings were reproduced and +fixed with regressions before integration. + +## What remains open + +The records retain `admission=not_evaluated` and +`generalization=insufficient_evidence`. The shared JVM uses lexical test order; +order independence is not established. Collection clocks are not historical CI. +The recipe is one direct upstream pair, not a full Defects4J reconstruction. +Component terms remain separate from COLEMAN's MIT license; recipe-only content +stays in external caches. + +The diversified benchmark program in +[#261](https://github.com/jacksonpradolima/coleman/issues/261) remains open. Source +admission, independent projects/faults, all seven diversity regimes, comparable +baselines, protected chronological evidence and cross-corpus reports remain +sequential work. Negative and inconclusive results remain valid evidence. + +Implemented in [#294](https://github.com/jacksonpradolima/coleman/pull/294) and +[#295](https://github.com/jacksonpradolima/coleman/pull/295). + +[Full changes from 4.5.0](https://github.com/jacksonpradolima/coleman/compare/v4.5.0...v4.6.0). diff --git a/llms.txt b/llms.txt index ff42b4db..ee801e8e 100644 --- a/llms.txt +++ b/llms.txt @@ -58,6 +58,7 @@ parallel execution, and extensibility via hooks and namespaced custom config. - docs/releases/4.4.0.md - docs/releases/4.4.1.md - docs/releases/4.5.0.md +- docs/releases/4.6.0.md - docs/releases.md - docs/resource-replay.md - docs/roadmap.md @@ -7903,6 +7904,139 @@ Implemented in [#290](https://github.com/jacksonpradolima/coleman/pull/290) and +### FILE: docs/releases/4.6.0.md + +# COLEMAN 4.6 — Reproducible fault evidence for CI + +A CI prioritization decision needs evidence you can inspect and reproduce. +COLEMAN 4.6 connects pinned buggy/fixed source revisions to versioned test +observations, retained diagnostics and immutable artifacts. You can rerun a +controlled fault recipe, recover interrupted collection and keep unexpected +outcomes visible before considering a source for a benchmark. + +This release brings together the reviewed controlled-observation foundation and +an optional Java/JUnit3 producer. The existing TCPCI runner continues to execute +learning experiments, write results and resume its own checkpoints. + +## From a source revision to an auditable result + +The new controlled records retain the project, curated fault label, common test +fixture, source revisions, runtime, component receipts and actual producer bytes. +Each observation has a stable logical identity, explicit outcome and integer +monotonic nanoseconds. Zero, unavailable and not applicable keep distinct meanings. +Parent-process timing and per-test harness timing have separate semantics. +Neither becomes an invented CI completion time or removable scheduling cost. + +Same-test comparisons preserve expected, both-pass, both-fail, reversed and +inconclusive outcomes. Missing observations stay missing. Diagnostic digests bind +to separately verified report members; schemas, source bytes and duplicate +identities are validated before immutable publication. + +The bundled Apache Commons CLI-13 recipe pins both public source revisions, a +common fixed-tree fixture, component dependencies, the COLEMAN-authored harness +and a platform-specific Temurin image. Individually pinned files form bounded, +deterministic source views. Foreign source code and datasets are not bundled in +the package or mirrored into the repository. + +A real installed-wheel execution collected **190 observations across 95 tests per +revision**: 92 pairs passed in both revisions, two failed in both and one failed +then passed. The two additional failures remain in the evidence. These are +functional reproduction results for this declared runtime and fixture, not an +independent-fault count or a policy-performance comparison. + +## Try the pinned recipe + +Use Python 3.14+, a local arm64 Docker engine and an external workspace. Install +the wheel attached to this release and explicitly prepare its public image: + +```bash +python -m pip install https://github.com/jacksonpradolima/coleman/releases/download/v4.6.0/coleman-4.6.0-py3-none-any.whl +docker pull --platform linux/arm64 eclipse-temurin@sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8 +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 --fetch +python -m coleman.transports.junit \ + --cache /tmp/coleman-junit-cache \ + --output /tmp/coleman-junit-results \ + --trial source-001 +``` + +The first call explicitly permits reviewed, size/digest-pinned public GitHub and +Maven downloads. The second reopens the same committed observations without +executing those roles again. Acquisition is offline by default; subject execution +has no network and the producer never pulls an image implicitly. + +The JSON summary provides artifact paths, role statuses, pair counts and explicit +admission/generalization fields. Exit 0 means the collection protocols completed; +assertion failures remain outcomes. Incomplete collection retains its evidence +and returns 2. Exceptions remain nonzero failures. + +The [complete Java guide](https://github.com/jacksonpradolima/coleman/blob/v4.6.0/docs/junit-source-capture.md) +explains source/component terms, resource limits and the runtime profile. The +[controlled-observation guide](https://github.com/jacksonpradolima/coleman/blob/v4.6.0/docs/controlled-faults.md) +provides an offline SDK example and a complete owned native TCPCI workflow with +independently checked metrics and learning-checkpoint continuation. + +## Recover without inventing success + +An immutable start marker precedes each role. Completed packets replay; a started +but uncommitted role recovers as interrupted, with unavailable streams/counters +and no fabricated cases. Failed container cleanup leaves that start recoverable. +A POSIX lock prevents duplicate producers for the same context/trial/output tree. +Use a new trial ID for a new execution; repeated trials retain their dependence +group and do not become independent projects or faults. + +The collector bounds process time and combined output bytes. Containers are +non-root and read-only, with explicit input mounts and CPU, memory, PID and +temporary-storage limits. These guards support trusted-source reproduction. + +Resume validates raw protocol bytes, exit status, discovered test IDs and the +completion trailer. Unavailable streams cannot retain observed process facts; +observed streams require them. Timeout/prefix claims must agree with their bounds. +Contradictory negative labels cannot silently erase complete observations. +Coherent producer attestations still do not authenticate execution truth. + +## Compatibility and validation + +This is an additive **4.x** release. Existing native results, artifacts, sinks, +checkpoints and source readers retain their meaning. New contracts require schema +v1 and reject missing, unknown and future versions. No automatic migration or +reinterpretation of old results occurs. Harness changes require a reviewed recipe +update. The domain remains independent of CLI, Docker and MCP imports. + +The reviewed implementation passed **2,243 tests** with **95.26% combined +statement/branch coverage**, including a real paired source reproduction from a +wheel installed outside the checkout. Versioned golden/round-trip fixtures, +compatibility, units/missingness, nonfinite values, deterministic identities, +concurrent publication, interrupted writes, genuine child-process guards and +checkpoint recovery are covered. All lint/format/type/Pylint/docstring/structural, +strict documentation and package checks passed. Local-only OpenCodeReview and +manual review covered every changed file; confirmed findings were reproduced and +fixed with regressions before integration. + +## What remains open + +The records retain `admission=not_evaluated` and +`generalization=insufficient_evidence`. The shared JVM uses lexical test order; +order independence is not established. Collection clocks are not historical CI. +The recipe is one direct upstream pair, not a full Defects4J reconstruction. +Component terms remain separate from COLEMAN's MIT license; recipe-only content +stays in external caches. + +The diversified benchmark program in +[#261](https://github.com/jacksonpradolima/coleman/issues/261) remains open. Source +admission, independent projects/faults, all seven diversity regimes, comparable +baselines, protected chronological evidence and cross-corpus reports remain +sequential work. Negative and inconclusive results remain valid evidence. + +Implemented in [#294](https://github.com/jacksonpradolima/coleman/pull/294) and +[#295](https://github.com/jacksonpradolima/coleman/pull/295). + +[Full changes from 4.5.0](https://github.com/jacksonpradolima/coleman/compare/v4.5.0...v4.6.0). + + + ### FILE: docs/releases.md # Release preparation @@ -7913,7 +8047,12 @@ should explain the value to CI users before listing internal implementation work ## Versioning and integration -[COLEMAN 4.5](releases/4.5.0.md) adds bounded RTPTorrent and LRTS source readers, +[COLEMAN 4.6](releases/4.6.0.md) adds versioned controlled fault observations, +a pinned offline JUnit3 source recipe and recoverable raw evidence. Existing +native TCPCI experiments and learning checkpoints keep their contracts. Controlled +source reproduction remains separate from benchmark admission. + +[COLEMAN 4.5](releases/4.5.0.md) added bounded RTPTorrent and LRTS source readers, explicit units/provenance and installed native CI/checkpoint workflows. It retains the exact numeric safeguards from 4.4.1, corpus profiles and secure source cache. Both external sources remain blocked for protected temporal evaluation. From 0572fad75d2902da563e69d4718594d6dfdcd26e Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 11:27:03 -0300 Subject: [PATCH 5/8] fix(corpus): protect raw output storage and terminal case counts --- coleman/corpus/__init__.py | 2 ++ coleman/corpus/materialization.py | 17 ++++++++++++---- coleman/transports/junit_capture.py | 7 +++++-- coleman/transports/junit_contracts.py | 7 +++++++ docs/junit-source-capture.md | 10 +++++++-- docs/releases/4.6.0.md | 12 +++++++---- llms.txt | 22 ++++++++++++++------ tests/corpus/test_junit_capture.py | 29 +++++++++++++++++++++++++++ tests/corpus/test_junit_protocol.py | 19 +++++++++++++++++- 9 files changed, 106 insertions(+), 19 deletions(-) diff --git a/coleman/corpus/__init__.py b/coleman/corpus/__init__.py index 18f7402a..1603ed2b 100644 --- a/coleman/corpus/__init__.py +++ b/coleman/corpus/__init__.py @@ -33,6 +33,7 @@ publish_materialization, validate_cache_separation, validate_materialization, + validate_source_storage, ) from coleman.corpus.materialization_contracts import ( MaterializationLimits, @@ -112,4 +113,5 @@ "validate_fixture_source", "validate_cache_separation", "validate_materialization", + "validate_source_storage", ] diff --git a/coleman/corpus/materialization.py b/coleman/corpus/materialization.py index 2e6f0eaf..b22ec52a 100644 --- a/coleman/corpus/materialization.py +++ b/coleman/corpus/materialization.py @@ -30,10 +30,19 @@ class _CacheFormat(VersionedContract): kind: Literal["coleman-source-cache-v1"] = "coleman-source-cache-v1" -def _outside_repository(root: Path) -> None: - """Reject cache paths physically under a Git worktree marker, without invoking Git or scanning siblings.""" +def validate_source_storage(root: str | Path) -> None: + """Reject source-content storage physically inside a Git worktree, without creating files. + + Resolve existing symlink parents and inspect only ancestor Git directory/file + markers; no Git process, marker content or sibling tree is read. Cache bytes + and raw producer diagnostics need this guard; metadata-only exports retain + their existing rules. Invalid roots raise ValueError and filesystem failures + propagate. Trusted local parents are required: future Git initialization or + concurrent hostile filesystem mutation is outside this preflight's guarantee. + """ + root = Path(root).resolve() if any(parent.name == ".git" or (parent / ".git").exists() for parent in (root, *root.parents)): - raise ValueError("Source cache must be outside a repository") + raise ValueError("Source content storage must be outside a repository") def _verified_chunks(reader: ByteReader, digest: str, size: int) -> Iterator[bytes]: @@ -73,7 +82,7 @@ class SourceCache: def __init__(self, root: str | Path) -> None: """Validate the physical root before creating a deterministic version marker; I/O failures propagate.""" self._root = Path(root).resolve() - _outside_repository(self.root) + validate_source_storage(self.root) self._writer = ArtifactWriter(self.root) marker = self._contained("cache-format.json") if marker.exists(): diff --git a/coleman/transports/junit_capture.py b/coleman/transports/junit_capture.py index 9ffcef40..dd773575 100644 --- a/coleman/transports/junit_capture.py +++ b/coleman/transports/junit_capture.py @@ -28,7 +28,7 @@ ControlledSpec, Label, ) -from coleman.corpus.materialization import materialize_source, validate_cache_separation +from coleman.corpus.materialization import materialize_source, validate_cache_separation, validate_source_storage from coleman.corpus.materialization_contracts import MaterializationSpec, PackageMember from coleman.corpus.source_views import source_view_bytes from coleman.results.domain import decode_json, fingerprint @@ -450,7 +450,9 @@ def capture_junit_source( """Collect one paired source trial with verified inputs, filtered runtime provenance and immutable recovery. Default acquisition is offline and the public pinned runtime image must - already exist locally. No image is pulled and no network is available to the + already exist locally. Raw output roots must be physically outside Git + worktrees, checked by the shared cache guard before runtime/source access. + No image is pulled and no network is available to the subject. Concurrent same-trial producers fail before execution. Completed roles replay; a started/uncommitted role becomes interrupted/inconclusive, requiring a new trial ID for fresh collection. Neither source capture nor @@ -461,6 +463,7 @@ def capture_junit_source( """ recipe = JunitCaptureRecipe.model_validate(recipe) trial_id = TypeAdapter(Label).validate_python(trial_id) + validate_source_storage(writer.run_root) validate_cache_separation(cache.root, writer.run_root) docker = shutil.which("docker") if docker is None: diff --git a/coleman/transports/junit_contracts.py b/coleman/transports/junit_contracts.py index e2697571..cf4a04f6 100644 --- a/coleman/transports/junit_contracts.py +++ b/coleman/transports/junit_contracts.py @@ -182,6 +182,13 @@ def _clock(self) -> Self: raise ValueError("JUnit capture finishes before it starts") return self + @model_validator(mode="after") + def _terminal_counters(self) -> Self: + """Require at most one terminal failure/error for the single executed JUnit3 case.""" + if self.failures + self.errors > self.tests_run: + raise ValueError("JUnit terminal counters cannot exceed tests_run") + return self + @property def outcome(self) -> Literal["passed", "assertion_failed", "test_error", "infrastructure_error"]: """Classify actual counters; incomplete diagnostics cannot certify a fault reproduction.""" diff --git a/docs/junit-source-capture.md b/docs/junit-source-capture.md index e350a153..c34e4d77 100644 --- a/docs/junit-source-capture.md +++ b/docs/junit-source-capture.md @@ -40,7 +40,11 @@ TLS and exact entity lengths, and rejects redirects, credentials, queries, parti responses and encoded transfers. It uses no ambient authentication or proxy configuration. The producer never pulls an image. Once cached, omit `--fetch` for offline acquisition; subject execution has no network even during the first run. -Source-cache and output directories must be separate. +Source-cache and output directories must be separate and physically outside +Git worktrees. The producer reuses the cache's shared storage guard to reject +repository directories, linked-worktree marker files and symlink aliases before +runtime queries, source acquisition or raw-capture writes. Metadata-only source +exports retain their existing publication rules. The JSON summary includes dataset/state paths, role collection statuses, pair counts, admission and generalization. Exit 0 means both role protocols completed; @@ -129,7 +133,9 @@ interrupted observation state. Source acquisition, staging and publication failures never certify a completed learning checkpoint. Successful protocols require the exact discovered test sequence and a final -trailer. Malformed/partial protocols, timeouts, output limits and process errors +trailer. Each case declares exactly one run and at most one terminal failure or +error; contradictory counters cause a protocol error rather than a normalized +test outcome. Malformed/partial protocols, timeouts, output limits and process errors retain bounded raw evidence without promoting partial cases into assertions. On replay, exited process/protocol error labels are rederived from the stored exit code and raw protocol; relabeling a valid complete packet cannot silently diff --git a/docs/releases/4.6.0.md b/docs/releases/4.6.0.md index e471dac2..58f82ed0 100644 --- a/docs/releases/4.6.0.md +++ b/docs/releases/4.6.0.md @@ -75,7 +75,10 @@ independently checked metrics and learning-checkpoint continuation. An immutable start marker precedes each role. Completed packets replay; a started but uncommitted role recovers as interrupted, with unavailable streams/counters and no fabricated cases. Failed container cleanup leaves that start recoverable. -A POSIX lock prevents duplicate producers for the same context/trial/output tree. +Raw-capture output roots are checked outside Git worktrees before source execution, +using the same guard as the external source cache. Linked-worktree markers and +symlink aliases cannot bypass that preflight. A POSIX lock prevents duplicate +producers for the same context/trial/output tree. Use a new trial ID for a new execution; repeated trials retain their dependence group and do not become independent projects or faults. @@ -84,7 +87,8 @@ non-root and read-only, with explicit input mounts and CPU, memory, PID and temporary-storage limits. These guards support trusted-source reproduction. Resume validates raw protocol bytes, exit status, discovered test IDs and the -completion trailer. Unavailable streams cannot retain observed process facts; +completion trailer. Single-case terminal counters cannot exceed the one declared +run. Unavailable streams cannot retain observed process facts; observed streams require them. Timeout/prefix claims must agree with their bounds. Contradictory negative labels cannot silently erase complete observations. Coherent producer attestations still do not authenticate execution truth. @@ -97,8 +101,8 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,243 tests** with **95.26% combined -statement/branch coverage**, including a real paired source reproduction from a +The reviewed implementation passed **2,250 tests** and the **95% combined +statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, concurrent publication, interrupted writes, genuine child-process guards and diff --git a/llms.txt b/llms.txt index ee801e8e..4d4a183c 100644 --- a/llms.txt +++ b/llms.txt @@ -5702,7 +5702,11 @@ TLS and exact entity lengths, and rejects redirects, credentials, queries, parti responses and encoded transfers. It uses no ambient authentication or proxy configuration. The producer never pulls an image. Once cached, omit `--fetch` for offline acquisition; subject execution has no network even during the first run. -Source-cache and output directories must be separate. +Source-cache and output directories must be separate and physically outside +Git worktrees. The producer reuses the cache's shared storage guard to reject +repository directories, linked-worktree marker files and symlink aliases before +runtime queries, source acquisition or raw-capture writes. Metadata-only source +exports retain their existing publication rules. The JSON summary includes dataset/state paths, role collection statuses, pair counts, admission and generalization. Exit 0 means both role protocols completed; @@ -5791,7 +5795,9 @@ interrupted observation state. Source acquisition, staging and publication failures never certify a completed learning checkpoint. Successful protocols require the exact discovered test sequence and a final -trailer. Malformed/partial protocols, timeouts, output limits and process errors +trailer. Each case declares exactly one run and at most one terminal failure or +error; contradictory counters cause a protocol error rather than a normalized +test outcome. Malformed/partial protocols, timeouts, output limits and process errors retain bounded raw evidence without promoting partial cases into assertions. On replay, exited process/protocol error labels are rederived from the stored exit code and raw protocol; relabeling a valid complete packet cannot silently @@ -7983,7 +7989,10 @@ independently checked metrics and learning-checkpoint continuation. An immutable start marker precedes each role. Completed packets replay; a started but uncommitted role recovers as interrupted, with unavailable streams/counters and no fabricated cases. Failed container cleanup leaves that start recoverable. -A POSIX lock prevents duplicate producers for the same context/trial/output tree. +Raw-capture output roots are checked outside Git worktrees before source execution, +using the same guard as the external source cache. Linked-worktree markers and +symlink aliases cannot bypass that preflight. A POSIX lock prevents duplicate +producers for the same context/trial/output tree. Use a new trial ID for a new execution; repeated trials retain their dependence group and do not become independent projects or faults. @@ -7992,7 +8001,8 @@ non-root and read-only, with explicit input mounts and CPU, memory, PID and temporary-storage limits. These guards support trusted-source reproduction. Resume validates raw protocol bytes, exit status, discovered test IDs and the -completion trailer. Unavailable streams cannot retain observed process facts; +completion trailer. Single-case terminal counters cannot exceed the one declared +run. Unavailable streams cannot retain observed process facts; observed streams require them. Timeout/prefix claims must agree with their bounds. Contradictory negative labels cannot silently erase complete observations. Coherent producer attestations still do not authenticate execution truth. @@ -8005,8 +8015,8 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,243 tests** with **95.26% combined -statement/branch coverage**, including a real paired source reproduction from a +The reviewed implementation passed **2,250 tests** and the **95% combined +statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, concurrent publication, interrupted writes, genuine child-process guards and diff --git a/tests/corpus/test_junit_capture.py b/tests/corpus/test_junit_capture.py index 07a53dc9..2cd8e27d 100644 --- a/tests/corpus/test_junit_capture.py +++ b/tests/corpus/test_junit_capture.py @@ -461,3 +461,32 @@ def test_checkpoint_guard_labels_must_agree_with_observed_bounds(tmp_path, statu path.write_text(json.dumps(payload)) with pytest.raises(ValueError): capture._load_role(path, spec) + + +@pytest.mark.parametrize("layout", ["directory", "linked-worktree", "symlink"]) +def test_raw_capture_output_rejects_git_worktrees_before_any_output(tmp_path, monkeypatch, layout): + spec, cache, environment = prepared_inputs(tmp_path) + repository = tmp_path / "repository" + repository.mkdir() + marker = repository / ".git" + if layout == "linked-worktree": + marker.write_text("gitdir: /owned/external/git-metadata\n") + else: + marker.mkdir() + output = repository / "raw-captures" + if layout == "symlink": + alias = tmp_path / "repository-alias" + alias.symlink_to(repository, target_is_directory=True) + output = alias / "raw-captures" + calls = [] + + def run(*args): + calls.append(args) + return ProcessStreams(encoded(records()), b"Owned raw diagnostic", 0, 1, "exited") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(output) + with pytest.raises(ValueError, match="outside.*repository"): + capture.capture_junit_source(spec, cache, writer, "outside-git-trial") + assert calls == [] + assert not output.exists() diff --git a/tests/corpus/test_junit_protocol.py b/tests/corpus/test_junit_protocol.py index da998680..d8a2cdd3 100644 --- a/tests/corpus/test_junit_protocol.py +++ b/tests/corpus/test_junit_protocol.py @@ -168,7 +168,7 @@ def test_missing_final_marker_duplicates_and_incompatible_case_universe_reject() @pytest.mark.parametrize( "updates,expected", [ - ({"errors": 1}, "test_error"), + ({"errors": 1, "failures": 0}, "test_error"), ({"failures": 0}, "passed"), ({"diagnostics_truncated": True}, "infrastructure_error"), ], @@ -233,3 +233,20 @@ def test_actual_child_guard_facts_validate_without_promoting_cases(termination): assert packet.status == termination assert packet.cases == () validate_role_bytes(packet, spec) + + +@pytest.mark.parametrize("failures,errors", [(2, 0), (0, 2), (1, 1), (10000, 10000)]) +def test_terminal_counters_cannot_exceed_one_executed_case(failures, errors): + spec = recipe() + rows = records() + rows[1].update(failures=failures, errors=errors) + raw = encoded(rows) + with pytest.raises(ValueError, match="terminal counters"): + parsed_junit_stream(raw, spec) + now = datetime(2026, 1, 1, tzinfo=UTC) + packet = role_capture( + spec, digest(b"context"), "owned-trial", "buggy", now, now, ProcessStreams(raw, b"", 0, 1, "exited") + ) + assert packet.status == "protocol_error" + assert packet.cases == () + validate_role_bytes(packet, spec) From d3f804d2eb5467493291d290e04038b15752f046 Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 11:44:21 -0300 Subject: [PATCH 6/8] fix(corpus): guard concrete raw storage and staging destinations --- coleman/corpus/materialization.py | 9 +++-- coleman/transports/junit_capture.py | 3 ++ docs/junit-source-capture.md | 7 +++- docs/releases/4.6.0.md | 8 ++-- llms.txt | 15 +++++--- tests/corpus/test_junit_capture.py | 56 ++++++++++++++++++++++++++++ tests/corpus/test_materialization.py | 18 +++++++++ 7 files changed, 101 insertions(+), 15 deletions(-) diff --git a/coleman/corpus/materialization.py b/coleman/corpus/materialization.py index b22ec52a..291b1796 100644 --- a/coleman/corpus/materialization.py +++ b/coleman/corpus/materialization.py @@ -34,14 +34,16 @@ def validate_source_storage(root: str | Path) -> None: """Reject source-content storage physically inside a Git worktree, without creating files. Resolve existing symlink parents and inspect only ancestor Git directory/file - markers; no Git process, marker content or sibling tree is read. Cache bytes + markers; reserved .git path components reject case-insensitively before + staging can introduce them. No Git process, marker content or sibling tree is + read. Cache bytes and raw producer diagnostics need this guard; metadata-only exports retain their existing rules. Invalid roots raise ValueError and filesystem failures propagate. Trusted local parents are required: future Git initialization or concurrent hostile filesystem mutation is outside this preflight's guarantee. """ root = Path(root).resolve() - if any(parent.name == ".git" or (parent / ".git").exists() for parent in (root, *root.parents)): + if any(parent.name.casefold() == ".git" or (parent / ".git").exists() for parent in (root, *root.parents)): raise ValueError("Source content storage must be outside a repository") @@ -99,10 +101,11 @@ def root(self) -> Path: return self._root def _contained(self, relative: str) -> Path: - """Reject existing symlink escapes/files; cooperative writers may only create normal content paths.""" + """Reject symlink escapes and Git-backed content paths before reading/writing cooperative cache bytes.""" path = self.root / relative if path.is_symlink() or not path.resolve().is_relative_to(self.root): raise ValueError("Source cache path escapes its trusted root") + validate_source_storage(path) return path def _blob(self, digest: str) -> Path: diff --git a/coleman/transports/junit_capture.py b/coleman/transports/junit_capture.py index dd773575..4a881761 100644 --- a/coleman/transports/junit_capture.py +++ b/coleman/transports/junit_capture.py @@ -158,10 +158,12 @@ def _member_bytes(cache: SourceCache, receipt: MaterializationReceipt, name: str def _stage_view(cache: SourceCache, receipt: MaterializationReceipt, root: Path) -> None: """Stage only declared regular-file bytes in a fresh private temporary tree, never extracting arbitrary paths.""" + validate_source_storage(root) root.mkdir(mode=0o755) root.chmod(0o755) for member in receipt.spec.members: path = _contained(root, root / member.name) + validate_source_storage(path) path.parent.mkdir(parents=True, exist_ok=True, mode=0o755) for directory in (path.parent, *path.parent.parents): if directory == root.parent: @@ -478,6 +480,7 @@ def capture_junit_source( "sha256:" ) state = _contained(writer.run_root, writer.run_root / "junit-captures" / session) + validate_source_storage(state) with _single_producer(state): writer.write_immutable(state / "context.json", prepared.context.to_json() + "\n") captures = tuple( diff --git a/docs/junit-source-capture.md b/docs/junit-source-capture.md index c34e4d77..1f8d95af 100644 --- a/docs/junit-source-capture.md +++ b/docs/junit-source-capture.md @@ -42,8 +42,11 @@ configuration. The producer never pulls an image. Once cached, omit `--fetch` fo offline acquisition; subject execution has no network even during the first run. Source-cache and output directories must be separate and physically outside Git worktrees. The producer reuses the cache's shared storage guard to reject -repository directories, linked-worktree marker files and symlink aliases before -runtime queries, source acquisition or raw-capture writes. Metadata-only source +repository directories, linked-worktree marker files and symlink aliases. Provided +output roots are checked before runtime queries/source acquisition; concrete cache +blob, capture-session and staging paths are rechecked before content writes. +Staged members cannot introduce case-insensitive `.git` path components. The system +temporary directory must also be outside Git for source staging. Metadata-only exports retain their existing publication rules. The JSON summary includes dataset/state paths, role collection statuses, pair diff --git a/docs/releases/4.6.0.md b/docs/releases/4.6.0.md index 58f82ed0..46a1fb4d 100644 --- a/docs/releases/4.6.0.md +++ b/docs/releases/4.6.0.md @@ -75,9 +75,9 @@ independently checked metrics and learning-checkpoint continuation. An immutable start marker precedes each role. Completed packets replay; a started but uncommitted role recovers as interrupted, with unavailable streams/counters and no fabricated cases. Failed container cleanup leaves that start recoverable. -Raw-capture output roots are checked outside Git worktrees before source execution, -using the same guard as the external source cache. Linked-worktree markers and -symlink aliases cannot bypass that preflight. A POSIX lock prevents duplicate +Raw output roots, concrete cache/session paths and source staging destinations +are checked outside Git worktrees with one shared storage guard. Linked-worktree +markers, symlink aliases and staged Git-marker names are covered. A POSIX lock prevents duplicate producers for the same context/trial/output tree. Use a new trial ID for a new execution; repeated trials retain their dependence group and do not become independent projects or faults. @@ -101,7 +101,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,250 tests** and the **95% combined +The reviewed implementation passed **2,258 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/llms.txt b/llms.txt index 4d4a183c..682040dc 100644 --- a/llms.txt +++ b/llms.txt @@ -5704,8 +5704,11 @@ configuration. The producer never pulls an image. Once cached, omit `--fetch` fo offline acquisition; subject execution has no network even during the first run. Source-cache and output directories must be separate and physically outside Git worktrees. The producer reuses the cache's shared storage guard to reject -repository directories, linked-worktree marker files and symlink aliases before -runtime queries, source acquisition or raw-capture writes. Metadata-only source +repository directories, linked-worktree marker files and symlink aliases. Provided +output roots are checked before runtime queries/source acquisition; concrete cache +blob, capture-session and staging paths are rechecked before content writes. +Staged members cannot introduce case-insensitive `.git` path components. The system +temporary directory must also be outside Git for source staging. Metadata-only exports retain their existing publication rules. The JSON summary includes dataset/state paths, role collection statuses, pair @@ -7989,9 +7992,9 @@ independently checked metrics and learning-checkpoint continuation. An immutable start marker precedes each role. Completed packets replay; a started but uncommitted role recovers as interrupted, with unavailable streams/counters and no fabricated cases. Failed container cleanup leaves that start recoverable. -Raw-capture output roots are checked outside Git worktrees before source execution, -using the same guard as the external source cache. Linked-worktree markers and -symlink aliases cannot bypass that preflight. A POSIX lock prevents duplicate +Raw output roots, concrete cache/session paths and source staging destinations +are checked outside Git worktrees with one shared storage guard. Linked-worktree +markers, symlink aliases and staged Git-marker names are covered. A POSIX lock prevents duplicate producers for the same context/trial/output tree. Use a new trial ID for a new execution; repeated trials retain their dependence group and do not become independent projects or faults. @@ -8015,7 +8018,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,250 tests** and the **95% combined +The reviewed implementation passed **2,258 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/tests/corpus/test_junit_capture.py b/tests/corpus/test_junit_capture.py index 2cd8e27d..ecc20746 100644 --- a/tests/corpus/test_junit_capture.py +++ b/tests/corpus/test_junit_capture.py @@ -490,3 +490,59 @@ def run(*args): capture.capture_junit_source(spec, cache, writer, "outside-git-trial") assert calls == [] assert not output.exists() + + +@pytest.mark.parametrize("marker_kind", ["directory", "file"]) +def test_nested_capture_worktree_rejects_before_role_writes(tmp_path, monkeypatch, marker_kind): + spec, cache, environment = prepared_inputs(tmp_path) + output = tmp_path / "external-output" + namespace = output / "junit-captures" + namespace.mkdir(parents=True) + marker = namespace / ".git" + if marker_kind == "directory": + marker.mkdir() + else: + marker.write_text("gitdir: /owned/external/git-metadata\n") + calls = [] + + def run(*args): + calls.append(args) + return ProcessStreams(encoded(records()), b"Owned raw diagnostic", 0, 1, "exited") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(output) + with pytest.raises(ValueError, match="outside.*repository"): + capture.capture_junit_source(spec, cache, writer, "nested-worktree-trial") + assert calls == [] + assert not list(namespace.glob("*/context.json")) + assert not (output / "corpus-controlled").exists() + + +def test_source_staging_rejects_git_selected_as_system_temporary_directory(tmp_path, monkeypatch): + spec, cache, environment = prepared_inputs(tmp_path) + repository = tmp_path / "repository" + (repository / ".git").mkdir(parents=True) + monkeypatch.setattr(capture.tempfile, "tempdir", str(repository)) + monkeypatch.setattr(capture.shutil, "which", lambda _: "/owned/docker") + monkeypatch.setattr(capture, "_runtime_environment", lambda *args: environment) + + def collect(*args, **kwargs): + pytest.fail("Raw source staging must reject before container execution") + + monkeypatch.setattr(capture, "collect_process", collect) + writer = ArtifactWriter(tmp_path / "external-output") + with pytest.raises(ValueError, match="outside.*repository"): + capture.capture_junit_source(spec, cache, writer, "git-temporary-trial") + assert [path.name for path in repository.iterdir()] == [".git"] + assert not (writer.run_root / "corpus-controlled").exists() + + +@pytest.mark.parametrize("name", [".git", ".GIT", "nested/.Git/config"]) +def test_source_staging_cannot_introduce_git_markers(tmp_path, name): + cache = SourceCache(tmp_path / "cache") + receipt = owned_package(cache, name, b"Owned Git marker fixture", "owned-v1") + root = tmp_path / "stage" + with pytest.raises(ValueError, match="outside.*repository"): + capture._stage_view(cache, receipt, root) + assert not list(root.rglob("config")) + assert not (root / name).exists() diff --git a/tests/corpus/test_materialization.py b/tests/corpus/test_materialization.py index 7f9a92b6..603b39f5 100644 --- a/tests/corpus/test_materialization.py +++ b/tests/corpus/test_materialization.py @@ -1116,3 +1116,21 @@ def forbid_allocation(*args, **kwargs): with pytest.raises(ValueError, match="ZIP64 end locator"): materialize_source(spec, cache, lambda: reader(bytes(payload))) assert not list(tmp_path.rglob("corpus-materializations/*.json")) + + +@pytest.mark.parametrize("marker_kind", ["directory", "file"]) +def test_raw_blob_namespace_cannot_be_a_nested_git_worktree(tmp_path, marker_kind): + cache = SourceCache(tmp_path / "cache") + directory = cache.root / "blobs" + directory.mkdir() + marker = directory / ".git" + if marker_kind == "directory": + marker.mkdir() + else: + marker.write_text("gitdir: /owned/external/git-metadata\n") + payload = b"Owned source storage fixture" + pin = "sha256:" + hashlib.sha256(payload).hexdigest() + reader = io.BytesIO(payload) + with pytest.raises(ValueError, match="outside.*repository"): + cache.store_blob(pin, len(payload), reader) + assert not (directory / pin.removeprefix("sha256:")).exists() From 80e668164b6be68d6760769e94c67cd05ec802b0 Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 12:22:18 -0300 Subject: [PATCH 7/8] fix(corpus): size diagnostic envelopes for supported capture limits --- coleman/corpus/archives.py | 41 +++++++++++++++++++++ coleman/corpus/controlled_contracts.py | 6 ++-- coleman/corpus/source_views.py | 27 ++------------ coleman/transports/junit_capture.py | 14 +++++--- coleman/transports/junit_contracts.py | 4 ++- coleman/transports/junit_source.py | 49 +++++++++++++++++++++++++- docs/junit-source-capture.md | 11 ++++++ docs/releases/4.6.0.md | 5 ++- llms.txt | 16 ++++++++- tests/corpus/test_installed_junit.py | 10 ++++++ tests/corpus/test_junit_capture.py | 44 +++++++++++++++++++++++ tests/corpus/test_source_views.py | 29 +++++++++++++++ 12 files changed, 221 insertions(+), 35 deletions(-) diff --git a/coleman/corpus/archives.py b/coleman/corpus/archives.py index 60bea16f..e0581d50 100644 --- a/coleman/corpus/archives.py +++ b/coleman/corpus/archives.py @@ -2,6 +2,7 @@ from __future__ import annotations +import io import stat import struct import zipfile @@ -16,6 +17,46 @@ _DEFLATE_LEVEL_FLAGS = 0x0006 +def deterministic_zip_bytes( + entries: tuple[tuple[str, bytes], ...], *, maximum_member_bytes: int, maximum_total_bytes: int +) -> bytes: + """Encode deterministic regular-file ZIP bytes under explicit decoded-byte budgets. + + Budgets are strict positive integers at most 64 MiB; at most 128 unique safe + names are supported. Stored bytes, fixed DOS epoch/Unix permissions and empty + metadata remove host/time/compressor variability. ZIP64 remains disabled. + Encoded size includes bounded ZIP headers beyond the decoded total. No files + or network are accessed. Invalid names/budgets/duplicates/sizes raise ValueError; + non-bytes raise TypeError. Callers retain their own narrower format limits. + """ + if any( + type(value) is not int or not 1 <= value <= 64 * 1024**2 + for value in (maximum_member_bytes, maximum_total_bytes) + ): + raise ValueError("Deterministic ZIP requires positive byte budgets at most 64 MiB") + if not 1 <= len(entries) <= 128 or len({name for name, _ in entries}) != len(entries): + raise ValueError("Deterministic ZIP requires 1..128 uniquely named files") + total = 0 + for name, payload in entries: + safe_member_name(name) + if not isinstance(payload, bytes): + raise TypeError("Deterministic ZIP payload must be bytes") + total += len(payload) + if len(payload) > maximum_member_bytes or total > maximum_total_bytes: + raise ValueError("Deterministic ZIP payload exceeds decoded-byte bounds") + buffer = io.BytesIO() + with zipfile.ZipFile(buffer, "w", allowZip64=False) as archive: + for name, payload in sorted(entries): + info = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) + info.create_system = 3 + info.create_version = 20 + info.extract_version = 20 + info.compress_type = zipfile.ZIP_STORED + info.external_attr = (stat.S_IFREG | 0o644) << 16 + archive.writestr(info, payload) + return buffer.getvalue() + + def _zip_footer(path: Path, spec: MaterializationSpec) -> int: """Bound central-directory bytes/entries before ZipFile allocates its metadata structures. diff --git a/coleman/corpus/controlled_contracts.py b/coleman/corpus/controlled_contracts.py index 5951cbe2..f2feac82 100644 --- a/coleman/corpus/controlled_contracts.py +++ b/coleman/corpus/controlled_contracts.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Annotated, Literal, Self +from typing import Annotated, ClassVar, Literal, Self from pydantic import Field, model_validator @@ -177,6 +177,8 @@ class ControlledReport(VersionedContract): Missing, legacy and future schema versions reject without migration. """ + MAXIMUM_BYTES: ClassVar[int] = 8 * 1024**2 + context_fingerprint: Fingerprint observations: Annotated[tuple[ControlledObservation, ...], Field(max_length=20000)] @@ -192,7 +194,7 @@ class ControlledSpec(VersionedContract): def _member(self) -> Self: """Require exactly one declared report member with an uncompressed 8-MiB ceiling.""" members = [item for item in self.report_materialization.spec.members if item.name == self.report_member] - if len(members) != 1 or members[0].size_bytes > 8 * 1024**2: + if len(members) != 1 or members[0].size_bytes > ControlledReport.MAXIMUM_BYTES: raise ValueError("Controlled report member missing or exceeds 8 MiB") return self diff --git a/coleman/corpus/source_views.py b/coleman/corpus/source_views.py index 3f451c87..fbd48ca4 100644 --- a/coleman/corpus/source_views.py +++ b/coleman/corpus/source_views.py @@ -3,13 +3,12 @@ from __future__ import annotations import io -import stat -import zipfile from collections.abc import Callable from typing import Annotated, Literal, Self from pydantic import Field, model_validator +from coleman.corpus.archives import deterministic_zip_bytes from coleman.corpus.materialization import ReaderFactory, SourceCache, materialize_source, validate_materialization from coleman.corpus.materialization_contracts import MaterializationReceipt, MaterializationSpec from coleman.results.versioned import VersionedContract @@ -74,29 +73,7 @@ def source_view_bytes(entries: tuple[tuple[str, bytes], ...]) -> bytes: and unsafe names raise ValueError/TypeError. No files or network are accessed. This format is COLEMAN's ZIP recipe, not a claim about upstream archive bytes. """ - from coleman.corpus.materialization_contracts import safe_member_name - - if not 1 <= len(entries) <= 128 or len({name for name, _ in entries}) != len(entries): - raise ValueError("Source view requires 1..128 uniquely named files") - total = 0 - for name, payload in entries: - safe_member_name(name) - if not isinstance(payload, bytes): - raise TypeError("Source view payload must be bytes") - total += len(payload) - if len(payload) > 8 * 1024**2 or total > 16 * 1024**2: - raise ValueError("Source view payload exceeds decoded-byte bounds") - buffer = io.BytesIO() - with zipfile.ZipFile(buffer, "w", allowZip64=False) as archive: - for name, payload in sorted(entries): - info = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) - info.create_system = 3 - info.create_version = 20 - info.extract_version = 20 - info.compress_type = zipfile.ZIP_STORED - info.external_attr = (stat.S_IFREG | 0o644) << 16 - archive.writestr(info, payload) - return buffer.getvalue() + return deterministic_zip_bytes(entries, maximum_member_bytes=8 * 1024**2, maximum_total_bytes=16 * 1024**2) def materialize_source_view( diff --git a/coleman/transports/junit_capture.py b/coleman/transports/junit_capture.py index 4a881761..8c0a65d2 100644 --- a/coleman/transports/junit_capture.py +++ b/coleman/transports/junit_capture.py @@ -19,6 +19,7 @@ from coleman.artifacts import ArtifactWriter from coleman.corpus import MaterializationReceipt, SourceCache +from coleman.corpus.archives import deterministic_zip_bytes from coleman.corpus.controlled import convert_controlled_source, publish_controlled_dataset from coleman.corpus.controlled_contracts import ( ControlledDataset, @@ -30,7 +31,6 @@ ) from coleman.corpus.materialization import materialize_source, validate_cache_separation, validate_source_storage from coleman.corpus.materialization_contracts import MaterializationSpec, PackageMember -from coleman.corpus.source_views import source_view_bytes from coleman.results.domain import decode_json, fingerprint from coleman.transports.junit_contracts import ( JunitCaptureRecipe, @@ -48,6 +48,7 @@ java_commands, owned_package, prepare_junit_inputs, + validate_junit_report_budget, ) _JAVA_SUFFIX = ".java" @@ -294,8 +295,8 @@ def _cleanup(base: tuple[str, ...], name: str) -> None: def _load_role(path: Path, recipe: JunitCaptureRecipe) -> JunitRoleCapture: """Read a bounded role checkpoint and revalidate its actual raw stream/case correspondence offline.""" with path.open("rb") as stream: - payload = stream.read(16 * 1024**2 + 1) - if len(payload) > 16 * 1024**2: + payload = stream.read(JunitRoleCapture.MAXIMUM_BYTES + 1) + if len(payload) > JunitRoleCapture.MAXIMUM_BYTES: raise ValueError("JUnit role checkpoint exceeds 16 MiB") capture = JunitRoleCapture.from_json(payload) validate_role_bytes(capture, recipe) @@ -427,7 +428,11 @@ def _publish_capture( schema_version=1, context_fingerprint=prepared.context.fingerprint, observations=observations ) entries += (("report.json", report.to_json().encode()),) - payload = source_view_bytes(entries) + payload = deterministic_zip_bytes( + entries, + maximum_member_bytes=JunitRoleCapture.MAXIMUM_BYTES, + maximum_total_bytes=2 * JunitRoleCapture.MAXIMUM_BYTES + ControlledReport.MAXIMUM_BYTES, + ) owner = owned_package(cache, "capture-envelope.zip", payload, recipe.recipe) spec = MaterializationSpec.model_validate( { @@ -467,6 +472,7 @@ def capture_junit_source( trial_id = TypeAdapter(Label).validate_python(trial_id) validate_source_storage(writer.run_root) validate_cache_separation(cache.root, writer.run_root) + validate_junit_report_budget(recipe, trial_id) docker = shutil.which("docker") if docker is None: raise OSError("JUnit capture requires the documented local Docker runtime") diff --git a/coleman/transports/junit_contracts.py b/coleman/transports/junit_contracts.py index cf4a04f6..1a45058c 100644 --- a/coleman/transports/junit_contracts.py +++ b/coleman/transports/junit_contracts.py @@ -4,7 +4,7 @@ import re from datetime import datetime -from typing import Annotated, Literal, Self +from typing import Annotated, ClassVar, Literal, Self from pydantic import BeforeValidator, Field, model_validator @@ -237,6 +237,8 @@ class JunitRoleCapture(VersionedContract): requires a new trial ID and remains in the same declared dependence group. """ + MAXIMUM_BYTES: ClassVar[int] = 16 * 1024**2 + context_fingerprint: Fingerprint trial_id: Label role: Literal["buggy", "fixed"] diff --git a/coleman/transports/junit_source.py b/coleman/transports/junit_source.py index 2a0408b0..b61dea28 100644 --- a/coleman/transports/junit_source.py +++ b/coleman/transports/junit_source.py @@ -4,6 +4,7 @@ import hashlib import io +from datetime import UTC, datetime from functools import partial from importlib.resources import files from typing import NamedTuple @@ -16,10 +17,18 @@ SourceCache, load_registry, ) -from coleman.corpus.controlled_contracts import ControlledContext, ControlledInput, ControlledRuntime +from coleman.corpus.controlled_contracts import ( + ControlledContext, + ControlledElapsed, + ControlledInput, + ControlledObservation, + ControlledReport, + ControlledRuntime, +) from coleman.corpus.materialization import ReaderFactory, materialize_source, validate_materialization from coleman.corpus.materialization_contracts import PackageMember from coleman.corpus.source_views import materialize_source_view +from coleman.results.domain import canonical_json from coleman.transports.corpus_http import public_https_source from coleman.transports.junit_contracts import JunitCaptureRecipe @@ -100,6 +109,44 @@ class PreparedJunitInputs(NamedTuple): harness: bytes +def validate_junit_report_budget(recipe: JunitCaptureRecipe, trial_id: str) -> None: + """Reject a declared complete trial whose conservative normalized report cannot fit the core's byte limit. + + Only sizing records are constructed, never stored or presented as observations. + Actual trial/test labels, maximal integer ticks, longest outcomes and UTC + instants bound the same DTO serializer used at publication. This pure check + raises ValueError before acquisition/execution for unsupported combinations; + per-field test/label maxima alone do not guarantee a complete report fits. + """ + instant = datetime.max.replace(tzinfo=UTC) + placeholder = "sha256:" + "f" * 64 + empty = ControlledReport( + schema_version=1, + context_fingerprint=placeholder, + observations=(), + ) + total = len(empty.to_json().encode()) + count = 0 + for role in ("buggy", "fixed"): + for test_id in recipe.test_ids: + observation = ControlledObservation( + trial_id=trial_id, + role=role, + test_id=test_id, + outcome="infrastructure_error", + elapsed=ControlledElapsed(value=2**63 - 1, status="observed"), + capture_started_at=instant, + capture_finished_at=instant, + diagnostics_sha256=placeholder, + ) + total += len(canonical_json(observation.model_dump(mode="json")).encode()) + bool(count) + count += 1 + if total > ControlledReport.MAXIMUM_BYTES: + raise ValueError( + "Declared normalized report exceeds its 8 MiB budget; shorten trial labels or declare fewer tests" + ) + + def prepare_junit_inputs( recipe: JunitCaptureRecipe, cache: SourceCache, environment: MaterializationReceipt, *, fetch: bool = False ) -> PreparedJunitInputs: diff --git a/docs/junit-source-capture.md b/docs/junit-source-capture.md index 1f8d95af..1ed5d20e 100644 --- a/docs/junit-source-capture.md +++ b/docs/junit-source-capture.md @@ -101,6 +101,17 @@ parent bounds collection to 60 seconds and 1 MiB combined stdout/stderr by defau recipes may select only the contract's bounded ranges. These guards support trusted public-source reproduction; they are not a hostile-code security sandbox. +Diagnostic packaging has its own explicit budget: each complete role packet is +bounded to 16 MiB, the normalized report remains bounded to 8 MiB, and the decoded +envelope total is at most 40 MiB. The shared deterministic ZIP encoder preserves +stored bytes and existing ZIP64/entry policies; source-view limits remain +8 MiB per file and 16 MiB total. This accommodates the permitted 4-MiB output +profile without dropping raw streams or parsed diagnostics. Before acquisition +or execution, the producer computes a conservative normalized-report size bound +from declared test/trial labels and maximal field sizes. Unsupported combinations +reject before a source trial can create unpublishable completed role checkpoints. +The sizing records are never published as observations. + The filtered runtime receipt retains host/Python/package versions, Docker client/server architecture and versions, kernel and target image config digest and size. It excludes credentials, context names, unrelated containers, image diff --git a/docs/releases/4.6.0.md b/docs/releases/4.6.0.md index 46a1fb4d..298aa93b 100644 --- a/docs/releases/4.6.0.md +++ b/docs/releases/4.6.0.md @@ -91,6 +91,9 @@ completion trailer. Single-case terminal counters cannot exceed the one declared run. Unavailable streams cannot retain observed process facts; observed streams require them. Timeout/prefix claims must agree with their bounds. Contradictory negative labels cannot silently erase complete observations. +Diagnostic envelopes use a separate bounded profile, preserving complete raw +packets for the supported 4-MiB output limit. Oversized normalized-report +configurations reject before source execution; source-view limits stay unchanged. Coherent producer attestations still do not authenticate execution truth. ## Compatibility and validation @@ -101,7 +104,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,258 tests** and the **95% combined +The reviewed implementation passed **2,268 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/llms.txt b/llms.txt index 682040dc..586c87d2 100644 --- a/llms.txt +++ b/llms.txt @@ -5763,6 +5763,17 @@ parent bounds collection to 60 seconds and 1 MiB combined stdout/stderr by defau recipes may select only the contract's bounded ranges. These guards support trusted public-source reproduction; they are not a hostile-code security sandbox. +Diagnostic packaging has its own explicit budget: each complete role packet is +bounded to 16 MiB, the normalized report remains bounded to 8 MiB, and the decoded +envelope total is at most 40 MiB. The shared deterministic ZIP encoder preserves +stored bytes and existing ZIP64/entry policies; source-view limits remain +8 MiB per file and 16 MiB total. This accommodates the permitted 4-MiB output +profile without dropping raw streams or parsed diagnostics. Before acquisition +or execution, the producer computes a conservative normalized-report size bound +from declared test/trial labels and maximal field sizes. Unsupported combinations +reject before a source trial can create unpublishable completed role checkpoints. +The sizing records are never published as observations. + The filtered runtime receipt retains host/Python/package versions, Docker client/server architecture and versions, kernel and target image config digest and size. It excludes credentials, context names, unrelated containers, image @@ -8008,6 +8019,9 @@ completion trailer. Single-case terminal counters cannot exceed the one declared run. Unavailable streams cannot retain observed process facts; observed streams require them. Timeout/prefix claims must agree with their bounds. Contradictory negative labels cannot silently erase complete observations. +Diagnostic envelopes use a separate bounded profile, preserving complete raw +packets for the supported 4-MiB output limit. Oversized normalized-report +configurations reject before source execution; source-view limits stay unchanged. Coherent producer attestations still do not authenticate execution truth. ## Compatibility and validation @@ -8018,7 +8032,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,258 tests** and the **95% combined +The reviewed implementation passed **2,268 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/tests/corpus/test_installed_junit.py b/tests/corpus/test_installed_junit.py index 5a86d9eb..c3248094 100644 --- a/tests/corpus/test_installed_junit.py +++ b/tests/corpus/test_installed_junit.py @@ -33,6 +33,16 @@ def find_spec(self, fullname, path=None, target=None): sys.meta_path.insert(0, boundary) from coleman.corpus.source_views import SourceViewSpec, source_view_bytes assert source_view_bytes((('owned.txt',b'owned'),)) +from coleman.corpus.archives import deterministic_zip_bytes +import io, zipfile +large = b'x'*(8*1024**2+1) +entries = (('diagnostic.json',large),) +try: source_view_bytes(entries) +except ValueError: pass +else: raise AssertionError('Installed source-view limits were widened') +envelope = deterministic_zip_bytes(entries,maximum_member_bytes=16*1024**2,maximum_total_bytes=40*1024**2) +with zipfile.ZipFile(io.BytesIO(envelope)) as archive: + assert archive.read('diagnostic.json') == large sys.meta_path.remove(boundary) from coleman.transports.junit import load_junit_recipe from coleman.transports.junit_source import digest, harness_bytes diff --git a/tests/corpus/test_junit_capture.py b/tests/corpus/test_junit_capture.py index ecc20746..e2171214 100644 --- a/tests/corpus/test_junit_capture.py +++ b/tests/corpus/test_junit_capture.py @@ -546,3 +546,47 @@ def test_source_staging_cannot_introduce_git_markers(tmp_path, name): capture._stage_view(cache, receipt, root) assert not list(root.rglob("config")) assert not (root / name).exists() + + +def test_four_mib_diagnostics_publish_and_replay_complete_large_role_packets(tmp_path, monkeypatch): + spec, cache, environment = prepared_inputs(tmp_path) + ids = tuple(sorted(f"owned.CheckCase::test_ci_{index}" for index in range(64))) + spec = changed(spec, test_ids=ids, limits=changed(spec.limits, maximum_output_bytes=4 * 1024**2)) + original = records() + rows = [{**original[0], "test_ids": ids}] + rows.extend({**original[1], "test_id": name, "diagnostics": "x" * 64000} for name in ids) + rows.append({**original[-1], "case_count": len(ids)}) + raw = encoded(rows) + assert len(raw) <= spec.limits.maximum_output_bytes + calls = [] + + def run(*args): + calls.append(args[-2]) + return ProcessStreams(raw, b"", 0, 1, "exited") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(tmp_path / "results") + first = capture.capture_junit_source(spec, cache, writer, "large-diagnostics-trial") + assert len(first.dataset.observations) == 128 + assert (first.state_directory / "buggy.json").stat().st_size > 8 * 1024**2 + assert (first.state_directory / "fixed.json").stat().st_size > 8 * 1024**2 + source_size = first.dataset.spec.report_materialization.spec.source.size_bytes + assert source_size is not None + assert source_size > 16 * 1024**2 + assert capture.capture_junit_source(spec, cache, writer, "large-diagnostics-trial") == first + assert calls == ["buggy", "fixed"] + + +def test_declared_report_budget_rejects_before_any_source_execution(tmp_path, monkeypatch): + spec, cache, environment = prepared_inputs(tmp_path) + ids = tuple(sorted(f"owned.CheckCase::test_ci_{index}" for index in range(7000))) + spec = changed(spec, test_ids=ids, limits=changed(spec.limits, maximum_output_bytes=4 * 1024**2)) + + def run(*args): + pytest.fail("Oversized normalized report must reject before source execution") + + substitute_docker(monkeypatch, environment, run) + writer = ArtifactWriter(tmp_path / "results") + with pytest.raises(ValueError, match="normalized report"): + capture.capture_junit_source(spec, cache, writer, "t" * 1024) + assert not writer.run_root.exists() diff --git a/tests/corpus/test_source_views.py b/tests/corpus/test_source_views.py index b1251d13..c1be0465 100644 --- a/tests/corpus/test_source_views.py +++ b/tests/corpus/test_source_views.py @@ -10,6 +10,7 @@ import pytest from coleman.corpus import MaterializationSpec, SourceCache, load_registry, validate_materialization +from coleman.corpus.archives import deterministic_zip_bytes from coleman.corpus.source_views import SourceViewSpec, materialize_source_view, source_view_bytes @@ -168,3 +169,31 @@ def fail(): path.write_bytes(b"changed cached input") with pytest.raises(ValueError): materialize_source_view(spec, cache) + + +@pytest.mark.parametrize("member,total", [(0, 16), (True, 16), (-1, 16), (16, 0), (16, True), (16, 64 * 1024**2 + 1)]) +def test_shared_zip_encoder_rejects_invalid_explicit_byte_budgets(member, total): + entries = (("owned.txt", b"owned"),) + with pytest.raises(ValueError, match="byte budgets"): + deterministic_zip_bytes(entries, maximum_member_bytes=member, maximum_total_bytes=total) + + +def test_shared_zip_encoder_exact_bounds_order_and_source_view_byte_compatibility(): + entries = (("b.txt", b"bb"), ("a.txt", b"aa")) + encoded = deterministic_zip_bytes(entries, maximum_member_bytes=2, maximum_total_bytes=4) + assert source_view_bytes(entries) == encoded + assert deterministic_zip_bytes(tuple(reversed(entries)), maximum_member_bytes=2, maximum_total_bytes=4) == encoded + with pytest.raises(ValueError, match="decoded-byte bounds"): + deterministic_zip_bytes(entries, maximum_member_bytes=1, maximum_total_bytes=4) + with pytest.raises(ValueError, match="decoded-byte bounds"): + deterministic_zip_bytes(entries, maximum_member_bytes=2, maximum_total_bytes=3) + + +def test_diagnostic_profile_does_not_widen_source_view_limits(): + payload = b"x" * (8 * 1024**2 + 1) + entries = (("diagnostic.json", payload),) + with pytest.raises(ValueError, match="decoded-byte bounds"): + source_view_bytes(entries) + encoded = deterministic_zip_bytes(entries, maximum_member_bytes=16 * 1024**2, maximum_total_bytes=40 * 1024**2) + with zipfile.ZipFile(io.BytesIO(encoded)) as archive: + assert archive.read("diagnostic.json") == payload From d1d0a1e0fcf1373d2b2eafa28981d8e98b422d92 Mon Sep 17 00:00:00 2001 From: Jackson Antonio do Prado Lima Date: Fri, 16 Oct 2026 13:07:26 -0300 Subject: [PATCH 8/8] fix(corpus): isolate Java discovery output from observation protocol --- .../resources/ColemanJunit3Capture.java | 18 ++++- .../apache-cli13-junit3-arm64-v1.json | 2 +- docs/junit-source-capture.md | 6 +- docs/releases/4.6.0.md | 2 +- llms.txt | 8 ++- tests/corpus/test_junit_harness.py | 69 +++++++++++++++++++ 6 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 tests/corpus/test_junit_harness.py diff --git a/coleman/corpus/resources/ColemanJunit3Capture.java b/coleman/corpus/resources/ColemanJunit3Capture.java index 05a1770b..9112bd4d 100644 --- a/coleman/corpus/resources/ColemanJunit3Capture.java +++ b/coleman/corpus/resources/ColemanJunit3Capture.java @@ -72,7 +72,7 @@ private static String identity(TestCase test) { private static List discover(List excluded) throws Exception { List cases = new ArrayList<>(); for (String name : Files.readAllLines(Paths.get("/harness/classes.txt"), StandardCharsets.UTF_8)) { - Class type = Class.forName(name); + Class type = Class.forName(name, false, ColemanJunit3Capture.class.getClassLoader()); if (!TestCase.class.isAssignableFrom(type) || Modifier.isAbstract(type.getModifiers())) { excluded.add(name); continue; @@ -119,12 +119,24 @@ private static void observe(TestCase test, PrintStream output, PrintStream error } } - /** Emit one header, every lexical shared-JVM case and a completion trailer as UTF-8 JSON lines. */ + /** + * Emit UTF-8 protocol lines only on the original stdout. Discovery can initialize + * test classes and invoke constructors; their output is retained on bounded raw + * stderr, outside case timing/diagnostics. Excluded classes are not initialized. + * Discovery errors propagate after restoring streams and produce no complete protocol. + */ public static void main(String[] args) throws Exception { PrintStream output = System.out; PrintStream error = System.err; List excluded = new ArrayList<>(); - List cases = discover(excluded); + List cases; + try { + System.setOut(error); + cases = discover(excluded); + } finally { + System.setOut(output); + System.setErr(error); + } List identities = new ArrayList<>(); for (TestCase test : cases) identities.add(identity(test)); output.println("{\"schema_version\":1,\"record_type\":\"header\",\"java_version\":" diff --git a/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json b/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json index db92759e..66ba665e 100644 --- a/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json +++ b/coleman/corpus/resources/apache-cli13-junit3-arm64-v1.json @@ -1 +1 @@ -{"buggy":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-buggy-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-buggy-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/NOTICE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-buggy-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-buggy-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/BasicParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348}],"package_id":"commons-cli-buggy-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLine.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-buggy-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLineParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-buggy-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/GnuParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-buggy-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/HelpFormatter.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-buggy-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-buggy-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529}],"package_id":"commons-cli-buggy-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Option.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-buggy-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-buggy-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionGroup.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-buggy-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionValidator.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-buggy-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Options.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-buggy-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/ParseException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-buggy-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Parser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-buggy-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-buggy-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PosixParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-buggy-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/TypeHandler.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-buggy-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-buggy-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Util.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-buggy-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/overview.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/package.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:090dde1611fe8048b0e4e012c8b2c4cf24e885112ca7cb9c5ddec5729a59307e","size_bytes":147265,"uri":"urn:coleman:derived-source-view:commons-cli-buggy-v1","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"dependence_group":"commons-cli-cli13-upstream-pair","dependencies":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","terms_uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"commons-lang-2.1.jar","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723}],"package_id":"commons-lang-2.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723,"uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar","version":"2.1"}},{"archive":"raw","license":{"license_id":"CPL-1.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:0113c91fc99f8eec673ad5d0a75369b60a5cc7a6318b3354e511bbafeb40beb1","terms_uri":"https://opensource.org/license/CPL-1.0"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"junit-3.8.1.jar","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070}],"package_id":"junit-3.8.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070,"uri":"https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.jar","version":"3.8.1"}}],"fault_id":"CLI-13","fault_origin":"real","fixed":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixed-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixed-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-fixed-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-fixed-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/BasicParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462}],"package_id":"commons-cli-fixed-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLine.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-fixed-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLineParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-fixed-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/GnuParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-fixed-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/HelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-fixed-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-fixed-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287}],"package_id":"commons-cli-fixed-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Option.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-fixed-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-fixed-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionGroup.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-fixed-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionValidator.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-fixed-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Options.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-fixed-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/ParseException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-fixed-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Parser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-fixed-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-fixed-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PosixParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-fixed-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/TypeHandler.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-fixed-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-fixed-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Util.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-fixed-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/overview.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/package.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:a0d2077c23d2a4bef4fe339ecfbbf919c1e95fff4ba1a00d9dad923a59ef2f4a","size_bytes":148137,"uri":"urn:coleman:derived-source-view:commons-cli-fixed-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixture-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixture-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19}],"package_id":"commons-cli-fixture-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/.hidden.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21}],"package_id":"commons-cli-fixture-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/readable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21}],"package_id":"commons-cli-fixture-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/writable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123}],"package_id":"commons-cli-fixture-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ApplicationTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094}],"package_id":"commons-cli-fixture-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386}],"package_id":"commons-cli-fixture-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BugsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464}],"package_id":"commons-cli-fixture-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BuildTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653}],"package_id":"commons-cli-fixture-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/GnuParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074}],"package_id":"commons-cli-fixture-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/HelpFormatterExamples.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249}],"package_id":"commons-cli-fixture-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/LongOptionWithShort.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866}],"package_id":"commons-cli-fixture-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937}],"package_id":"commons-cli-fixture-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionGroupTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658}],"package_id":"commons-cli-fixture-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363}],"package_id":"commons-cli-fixture-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseRequiredTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359}],"package_id":"commons-cli-fixture-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738}],"package_id":"commons-cli-fixture-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253}],"package_id":"commons-cli-fixture-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/TestHelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754}],"package_id":"commons-cli-fixture-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValueTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779}],"package_id":"commons-cli-fixture-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValuesTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948}],"package_id":"commons-cli-fixture-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI13Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI18Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19},{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21},{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21},{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123},{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094},{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386},{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464},{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653},{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074},{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249},{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866},{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937},{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658},{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363},{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359},{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738},{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253},{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754},{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779},{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948},{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:becc2f662b4262776537cceeb27707732070998d5858090209f30a4695400489","size_bytes":128691,"uri":"urn:coleman:derived-source-view:commons-cli-fixture-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture_prefix":"src/test","harness_sha256":"sha256:e8e900c6ecf426282bfcfee5cb9749cad0ae7411f315e5cbe54ba5a0e3190891","limitations":["One public upstream Java fault pair, not a complete Defects4J reconstruction or corpus admission","Common fixed-tree test fixture transplanted to both source revisions","Shared JVM and lexical test order; order independence has not been established","Repeated tests and trials are not independent projects or unique faults","Two assertions fail in both revisions and remain negative evidence","Collection clocks are not historical CI timestamps; elapsed counters are not runner-removable costs","JUnit 3.8.1 CPL-1.0 declaration: https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.pom","Commons Lang license digest identifies META-INF/LICENSE.txt inside the separately pinned JAR; preserve NOTICE.txt"],"limits":{"maximum_output_bytes":1048576,"memory_bytes":1073741824,"timeout_seconds":60},"production_prefix":"src/java","project":"Apache Commons CLI","recipe":"junit3-fixed-tree-capture-v1","recipe_id":"apache-cli13-junit3-arm64-v1","runtime":{"emulated":false,"image_digest":"sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8","implementation":"Temurin","platform":"linux/arm64","timezone":"America/Los_Angeles","version":"11.0.32.1"},"schema_version":1,"test_ids":["org.apache.commons.cli.ApplicationTest::testAnt","org.apache.commons.cli.ApplicationTest::testLs","org.apache.commons.cli.ArgumentIsOptionTest::testOption","org.apache.commons.cli.ArgumentIsOptionTest::testOptionAndOptionWithArgument","org.apache.commons.cli.ArgumentIsOptionTest::testOptionWithArgument","org.apache.commons.cli.BugsTest::test11456","org.apache.commons.cli.BugsTest::test11457","org.apache.commons.cli.BugsTest::test11458","org.apache.commons.cli.BugsTest::test11680","org.apache.commons.cli.BugsTest::test12210","org.apache.commons.cli.BugsTest::test13425","org.apache.commons.cli.BugsTest::test13666","org.apache.commons.cli.BugsTest::test13935","org.apache.commons.cli.BugsTest::test14786","org.apache.commons.cli.BugsTest::test15046","org.apache.commons.cli.BugsTest::test15648","org.apache.commons.cli.BugsTest::test19383","org.apache.commons.cli.BugsTest::test21215","org.apache.commons.cli.BugsTest::test27635","org.apache.commons.cli.BugsTest::test31148","org.apache.commons.cli.BuildTest::testDuplicateLong","org.apache.commons.cli.BuildTest::testDuplicateSimple","org.apache.commons.cli.BuildTest::testLong","org.apache.commons.cli.BuildTest::testSimple","org.apache.commons.cli.GnuParseTest::testDoubleDash","org.apache.commons.cli.GnuParseTest::testExtraOption","org.apache.commons.cli.GnuParseTest::testMissingArg","org.apache.commons.cli.GnuParseTest::testMultiple","org.apache.commons.cli.GnuParseTest::testMultipleWithLong","org.apache.commons.cli.GnuParseTest::testSimpleLong","org.apache.commons.cli.GnuParseTest::testSimpleShort","org.apache.commons.cli.GnuParseTest::testSingleDash","org.apache.commons.cli.GnuParseTest::testStop","org.apache.commons.cli.LongOptionWithShort::testLongOptionWithShort","org.apache.commons.cli.OptionBuilderTest::testBaseOptionCharOpt","org.apache.commons.cli.OptionBuilderTest::testBaseOptionStringOpt","org.apache.commons.cli.OptionBuilderTest::testCompleteOption","org.apache.commons.cli.OptionBuilderTest::testIllegalOptions","org.apache.commons.cli.OptionBuilderTest::testOptionArgNumbers","org.apache.commons.cli.OptionBuilderTest::testSpecialOptChars","org.apache.commons.cli.OptionBuilderTest::testTwoCompleteOptions","org.apache.commons.cli.OptionGroupTest::testNoOptionsExtraArgs","org.apache.commons.cli.OptionGroupTest::testSingleLongOption","org.apache.commons.cli.OptionGroupTest::testSingleOption","org.apache.commons.cli.OptionGroupTest::testSingleOptionFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoLongOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromDifferentGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoValidLongOptions","org.apache.commons.cli.OptionGroupTest::testTwoValidOptions","org.apache.commons.cli.OptionGroupTest::testValidLongOnlyOptions","org.apache.commons.cli.OptionsTest::testHelpOptions","org.apache.commons.cli.ParseRequiredTest::testMissingRequiredOption","org.apache.commons.cli.ParseRequiredTest::testOptionAndRequiredOption","org.apache.commons.cli.ParseRequiredTest::testWithRequiredOption","org.apache.commons.cli.ParseTest::testComplexShort","org.apache.commons.cli.ParseTest::testDoubleDash","org.apache.commons.cli.ParseTest::testExtraOption","org.apache.commons.cli.ParseTest::testMissingArg","org.apache.commons.cli.ParseTest::testMultiple","org.apache.commons.cli.ParseTest::testMultipleWithLong","org.apache.commons.cli.ParseTest::testSimpleLong","org.apache.commons.cli.ParseTest::testSimpleShort","org.apache.commons.cli.ParseTest::testSingleDash","org.apache.commons.cli.ParseTest::testStop","org.apache.commons.cli.PatternOptionBuilderTest::testSimplePattern","org.apache.commons.cli.TestHelpFormatter::testAutomaticUsage","org.apache.commons.cli.TestHelpFormatter::testFindWrapPos","org.apache.commons.cli.TestHelpFormatter::testPrintOptions","org.apache.commons.cli.TestHelpFormatter::testPrintWrapped","org.apache.commons.cli.ValueTest::testLongNoArg","org.apache.commons.cli.ValueTest::testLongOptionalArgValue","org.apache.commons.cli.ValueTest::testLongOptionalArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNoValue","org.apache.commons.cli.ValueTest::testLongWithArg","org.apache.commons.cli.ValueTest::testPropertyOptionFlags","org.apache.commons.cli.ValueTest::testPropertyOptionMultipleValues","org.apache.commons.cli.ValueTest::testPropertyOptionSingularValue","org.apache.commons.cli.ValueTest::testPropertyOverrideValues","org.apache.commons.cli.ValueTest::testShortNoArg","org.apache.commons.cli.ValueTest::testShortOptionalArgNoValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValues","org.apache.commons.cli.ValueTest::testShortOptionalNArgValues","org.apache.commons.cli.ValueTest::testShortWithArg","org.apache.commons.cli.ValuesTest::testCharSeparator","org.apache.commons.cli.ValuesTest::testComplexValues","org.apache.commons.cli.ValuesTest::testExtraArgs","org.apache.commons.cli.ValuesTest::testMultipleArgValues","org.apache.commons.cli.ValuesTest::testShortArgs","org.apache.commons.cli.ValuesTest::testShortArgsWithValue","org.apache.commons.cli.ValuesTest::testTwoArgValues","org.apache.commons.cli.bug.BugCLI13Test::testCLI13","org.apache.commons.cli.bug.BugCLI18Test::testCLI18"]} +{"buggy":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-buggy-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-buggy-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/NOTICE.txt","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-buggy-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-buggy-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/BasicParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348}],"package_id":"commons-cli-buggy-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLine.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-buggy-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/CommandLineParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-buggy-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/GnuParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-buggy-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/HelpFormatter.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-buggy-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-buggy-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/MissingOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529}],"package_id":"commons-cli-buggy-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Option.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-buggy-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-buggy-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionGroup.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-buggy-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/OptionValidator.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-buggy-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Options.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-buggy-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/ParseException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-buggy-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Parser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-buggy-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-buggy-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/PosixParser.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-buggy-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/TypeHandler.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-buggy-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-buggy-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/Util.java","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-buggy-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/overview.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/src/java/org/apache/commons/cli/package.html","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/8f46f467a33ace44ccd9f394910940b6c48a3827/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:ba6f8cb7d474856c67b53f825b486d1bdef2affa391fb46b7071bfb08f038cd6","size_bytes":8348},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:b849d7f14564ab36fa91ba54930d4bde00cb4eb5950c1493ce72a9bbdc4a8e7f","size_bytes":15529},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-buggy-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:090dde1611fe8048b0e4e012c8b2c4cf24e885112ca7cb9c5ddec5729a59307e","size_bytes":147265,"uri":"urn:coleman:derived-source-view:commons-cli-buggy-v1","version":"8f46f467a33ace44ccd9f394910940b6c48a3827"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"dependence_group":"commons-cli-cli13-upstream-pair","dependencies":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5","terms_uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"commons-lang-2.1.jar","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723}],"package_id":"commons-lang-2.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:2ded7343dc8e57decd5e6302337139be020fdd885a2935925e8d575975e480b9","size_bytes":207723,"uri":"https://repo.maven.apache.org/maven2/commons-lang/commons-lang/2.1/commons-lang-2.1.jar","version":"2.1"}},{"archive":"raw","license":{"license_id":"CPL-1.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:0113c91fc99f8eec673ad5d0a75369b60a5cc7a6318b3354e511bbafeb40beb1","terms_uri":"https://opensource.org/license/CPL-1.0"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"junit-3.8.1.jar","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070}],"package_id":"junit-3.8.1.jar","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:b58e459509e190bed737f3592bc1950485322846cf10e78ded1d065153012d70","size_bytes":121070,"uri":"https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.jar","version":"3.8.1"}}],"fault_id":"CLI-13","fault_origin":"real","fixed":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixed-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixed-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164}],"package_id":"commons-cli-fixed-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/AlreadySelectedException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701}],"package_id":"commons-cli-fixed-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/BasicParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462}],"package_id":"commons-cli-fixed-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLine.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328}],"package_id":"commons-cli-fixed-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/CommandLineParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799}],"package_id":"commons-cli-fixed-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/GnuParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863}],"package_id":"commons-cli-fixed-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/HelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169}],"package_id":"commons-cli-fixed-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingArgumentException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139}],"package_id":"commons-cli-fixed-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/MissingOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287}],"package_id":"commons-cli-fixed-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Option.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818}],"package_id":"commons-cli-fixed-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242}],"package_id":"commons-cli-fixed-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionGroup.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029}],"package_id":"commons-cli-fixed-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/OptionValidator.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632}],"package_id":"commons-cli-fixed-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Options.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103}],"package_id":"commons-cli-fixed-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/ParseException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349}],"package_id":"commons-cli-fixed-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Parser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096}],"package_id":"commons-cli-fixed-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PatternOptionBuilder.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518}],"package_id":"commons-cli-fixed-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/PosixParser.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799}],"package_id":"commons-cli-fixed-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/TypeHandler.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169}],"package_id":"commons-cli-fixed-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/UnrecognizedOptionException.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949}],"package_id":"commons-cli-fixed-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/Util.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926}],"package_id":"commons-cli-fixed-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/overview.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-file-023","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/java/org/apache/commons/cli/package.html","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/java/org/apache/commons/cli/AlreadySelectedException.java","sha256":"sha256:746dd4650cc5b71730003298d2d08bfb519abb0680af549a057156f0a3f03e23","size_bytes":1164},{"name":"src/java/org/apache/commons/cli/BasicParser.java","sha256":"sha256:17f0ac5cd9f976c9266140dbe39d9a560f8b7d34ad52e3925b26e66f3ae3de68","size_bytes":1701},{"name":"src/java/org/apache/commons/cli/CommandLine.java","sha256":"sha256:4000f382a138b952dbfc784318dbff32d21219c6b04ca5f22ee37396da944d35","size_bytes":8462},{"name":"src/java/org/apache/commons/cli/CommandLineParser.java","sha256":"sha256:4aba3fc879b0f9a757454e48f6d5fdff953355133e1aadc80096e5de330ca21e","size_bytes":3328},{"name":"src/java/org/apache/commons/cli/GnuParser.java","sha256":"sha256:3627631bfbae3fb9d335544da48e4aa7dfc2d0a766a0662dc1d28ed6c638cb1b","size_bytes":5799},{"name":"src/java/org/apache/commons/cli/HelpFormatter.java","sha256":"sha256:e3d5d82ee027d0f537f7e6f8c9d4affce7abf218639b6733f74bb3da9b63cfb9","size_bytes":27863},{"name":"src/java/org/apache/commons/cli/MissingArgumentException.java","sha256":"sha256:379b8d713ebd507789deb3e1341eae0b24ec798a9140cb7d1dd1d8c97cb8402f","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/MissingOptionException.java","sha256":"sha256:83cbde92157cf57f8216986af30d89ee46240f5768ecb4d724fd710312c6af89","size_bytes":1139},{"name":"src/java/org/apache/commons/cli/Option.java","sha256":"sha256:4643b81e0898e91e2094a201291e5575d7c8f6ccaf03fa1b8518d9878414206e","size_bytes":16287},{"name":"src/java/org/apache/commons/cli/OptionBuilder.java","sha256":"sha256:de314f50a8028940cbe6cb70975b6b9e02cd0e495ec2826826bf5389e0ffd6e1","size_bytes":9818},{"name":"src/java/org/apache/commons/cli/OptionGroup.java","sha256":"sha256:fe9e709d95c0c675cf979e6ae133d60241fb784f8e7d772baef964bf669610f4","size_bytes":4242},{"name":"src/java/org/apache/commons/cli/OptionValidator.java","sha256":"sha256:e757d3f12ecd2a8fc5e24055dd05ba4b550fe8085da8f84a30d4180c274a01c7","size_bytes":3029},{"name":"src/java/org/apache/commons/cli/Options.java","sha256":"sha256:951c4a5b2c87b9e47188a1329310e8e115bebb4a91634eaf7443bfdd6b2679fa","size_bytes":7632},{"name":"src/java/org/apache/commons/cli/ParseException.java","sha256":"sha256:703c31885c017b43843d071d71229a3e752a571c7f5d301ddbab1b6c822462ed","size_bytes":1103},{"name":"src/java/org/apache/commons/cli/Parser.java","sha256":"sha256:da13231b6076e01ad25700bef237956ad8a761d3dcbc81aadb5a2ff978997f7b","size_bytes":12349},{"name":"src/java/org/apache/commons/cli/PatternOptionBuilder.java","sha256":"sha256:543e1c09adca4a80d1d650505e9939599b227c544d0ecdca0fdd5e05adea3430","size_bytes":6096},{"name":"src/java/org/apache/commons/cli/PosixParser.java","sha256":"sha256:4f6d24e21c4853e4a03b84c01495ad85e32b0791d8af05fa34ee94b7685cc263","size_bytes":10518},{"name":"src/java/org/apache/commons/cli/TypeHandler.java","sha256":"sha256:f32cce992af813788511e53cffee9715350e434f0516cc64efdce5a2b5bb447f","size_bytes":6799},{"name":"src/java/org/apache/commons/cli/UnrecognizedOptionException.java","sha256":"sha256:bef5d7849b1d4b0d3bd44d396cf11776ecc4fe2a9b4c0140b63fab96c1088b75","size_bytes":1169},{"name":"src/java/org/apache/commons/cli/Util.java","sha256":"sha256:8b6612870250e8e334204dc36f758c7cdd7aeb7b81d8179a3c0d64e1cde026e1","size_bytes":1949},{"name":"src/java/org/apache/commons/cli/overview.html","sha256":"sha256:fd5d4bffb43bf9862d4d2acd07ca998672cd1d761b45d9c2b01bfc3eed066080","size_bytes":926},{"name":"src/java/org/apache/commons/cli/package.html","sha256":"sha256:0af288cf35c17ff9dab4affa3b8716596836478e503e2bbeb13a73dfa1aaaca4","size_bytes":38}],"package_id":"commons-cli-fixed-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:a0d2077c23d2a4bef4fe339ecfbbf919c1e95fff4ba1a00d9dad923a59ef2f4a","size_bytes":148137,"uri":"urn:coleman:derived-source-view:commons-cli-fixed-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture":{"inputs":[{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358}],"package_id":"commons-cli-fixture-file-000","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101}],"package_id":"commons-cli-fixture-file-001","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/NOTICE.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19}],"package_id":"commons-cli-fixture-file-002","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/.hidden.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21}],"package_id":"commons-cli-fixture-file-003","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/readable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21}],"package_id":"commons-cli-fixture-file-004","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/data/writable.txt","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123}],"package_id":"commons-cli-fixture-file-005","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ApplicationTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094}],"package_id":"commons-cli-fixture-file-006","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386}],"package_id":"commons-cli-fixture-file-007","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BugsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464}],"package_id":"commons-cli-fixture-file-008","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/BuildTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653}],"package_id":"commons-cli-fixture-file-009","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/GnuParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074}],"package_id":"commons-cli-fixture-file-010","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/HelpFormatterExamples.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249}],"package_id":"commons-cli-fixture-file-011","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/LongOptionWithShort.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866}],"package_id":"commons-cli-fixture-file-012","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937}],"package_id":"commons-cli-fixture-file-013","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionGroupTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658}],"package_id":"commons-cli-fixture-file-014","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/OptionsTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363}],"package_id":"commons-cli-fixture-file-015","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseRequiredTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359}],"package_id":"commons-cli-fixture-file-016","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ParseTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738}],"package_id":"commons-cli-fixture-file-017","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253}],"package_id":"commons-cli-fixture-file-018","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/TestHelpFormatter.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754}],"package_id":"commons-cli-fixture-file-019","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValueTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779}],"package_id":"commons-cli-fixture-file-020","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/ValuesTest.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948}],"package_id":"commons-cli-fixture-file-021","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI13Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},{"archive":"raw","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-file-022","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645,"uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/src/test/org/apache/commons/cli/bug/BugCLI18Test.java","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}}],"output":{"archive":"zip","license":{"license_id":"Apache-2.0","redistribution":"recipe_only","reviewed_at":"2026-10-16T12:00:00Z","status":"verified","terms_sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","terms_uri":"https://raw.githubusercontent.com/apache/commons-cli/b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e/LICENSE.txt"},"limits":{"maximum_archive_entries":128,"maximum_extracted_bytes":268435456,"maximum_member_bytes":134217728,"maximum_source_bytes":67108864,"maximum_zip_metadata_bytes":1048576},"members":[{"name":"LICENSE.txt","sha256":"sha256:c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c","size_bytes":11358},{"name":"NOTICE.txt","sha256":"sha256:c53634c960163f00ba0b0147cc3dee5caf0e6a47bc9909a2fe94b7adcf5d983e","size_bytes":101},{"name":"src/test/data/.hidden.txt","sha256":"sha256:8dee3521f6a8b69db0e0e089cef0bb334a8de211a4691aecff7f9db3c32e9e82","size_bytes":19},{"name":"src/test/data/readable.txt","sha256":"sha256:44b2225a397cba928f256cf0cc35d91a2ba32497222ae2d998e29d5d11f0916f","size_bytes":21},{"name":"src/test/data/writable.txt","sha256":"sha256:3bfd07bc9a56a5b44c24e4449cfaddc244b4004f64206f77f944e0325a91cb0d","size_bytes":21},{"name":"src/test/org/apache/commons/cli/ApplicationTest.java","sha256":"sha256:96810e5ef1c4b1b80f7a4339e5520383a09947e0ea167272df93c110a268f098","size_bytes":5123},{"name":"src/test/org/apache/commons/cli/ArgumentIsOptionTest.java","sha256":"sha256:de41b68b53990a73af590992bd5a372a663fe7471c606f894f756767184a4481","size_bytes":3094},{"name":"src/test/org/apache/commons/cli/BugsTest.java","sha256":"sha256:486f9568938f9321b668f80cd5b9b46c2c2b9ea4ddf62ca3aa84ddbec5948821","size_bytes":19386},{"name":"src/test/org/apache/commons/cli/BuildTest.java","sha256":"sha256:8ceafeba8f2e285ba0a377d09079a51e267580ad3ee300893a3ea381fe3ab164","size_bytes":2464},{"name":"src/test/org/apache/commons/cli/GnuParseTest.java","sha256":"sha256:9b4fbabf09a4593b3dd8b4f5b14d98c4ea67efbbb03ad0b3a7f3d0195228bde7","size_bytes":8653},{"name":"src/test/org/apache/commons/cli/HelpFormatterExamples.java","sha256":"sha256:d726a975e767c238068dc61fc4523439583f7e74e4695a5c785d2fa438150abc","size_bytes":5074},{"name":"src/test/org/apache/commons/cli/LongOptionWithShort.java","sha256":"sha256:0a16a1911972539f179641f27c5136c3c011fd798c2482a26dafdc41fa628668","size_bytes":4249},{"name":"src/test/org/apache/commons/cli/OptionBuilderTest.java","sha256":"sha256:8ea2c63346028b0e7356fcdbd492ece1ca71f3fd3c04d345b217f0371000edc6","size_bytes":5866},{"name":"src/test/org/apache/commons/cli/OptionGroupTest.java","sha256":"sha256:da14e682e174feba908496061abf5b8c2741feb9b89b5d5c18dbbddcda5b91b6","size_bytes":8937},{"name":"src/test/org/apache/commons/cli/OptionsTest.java","sha256":"sha256:4e5eefd12d8a9aae1eb0e3b33617bb3c1364207e6ca718398e235e7ce59d80df","size_bytes":2658},{"name":"src/test/org/apache/commons/cli/ParseRequiredTest.java","sha256":"sha256:5e4c1283d837fb22f270dbedf228c38381b1247721cac713619f90bceba23afa","size_bytes":3363},{"name":"src/test/org/apache/commons/cli/ParseTest.java","sha256":"sha256:dcbe557c9964027ec4041726aa0ab91180049c0cd29cbbc155cbca05f3e76d34","size_bytes":9359},{"name":"src/test/org/apache/commons/cli/PatternOptionBuilderTest.java","sha256":"sha256:c81086f5e12cfe3d4393e838ac84c86269d9a5348c8573f896a801f29a5c50a0","size_bytes":3738},{"name":"src/test/org/apache/commons/cli/TestHelpFormatter.java","sha256":"sha256:c19da017899e3d7136eb697f104b5cd315839f192898865c8309a323f77bc0b4","size_bytes":6253},{"name":"src/test/org/apache/commons/cli/ValueTest.java","sha256":"sha256:c367dd8cc3d48058808c2b6f97ac8831963838cc904ae851ac5d5a6c0a3a3d7d","size_bytes":12754},{"name":"src/test/org/apache/commons/cli/ValuesTest.java","sha256":"sha256:cf1b755f7d86510bd355e8ca3f968e39d61a0d990f2f55cf37a98090289b7de7","size_bytes":8779},{"name":"src/test/org/apache/commons/cli/bug/BugCLI13Test.java","sha256":"sha256:46d2854c12ea2137aac196dc68b69b2fb4882f71f0d01d6b27475363dd15bd06","size_bytes":1948},{"name":"src/test/org/apache/commons/cli/bug/BugCLI18Test.java","sha256":"sha256:3112153c70961fc85bb9c3b56bea2e6a24ef92d3ac7c14596080a0641fa3b56c","size_bytes":1645}],"package_id":"commons-cli-fixture-view-v1","recipe":"bounded-source-package-v1","schema_version":1,"source":{"availability":"verified_local","citation":"Pinned public upstream component; source-only local reproduction, not benchmark admission","sha256":"sha256:becc2f662b4262776537cceeb27707732070998d5858090209f30a4695400489","size_bytes":128691,"uri":"urn:coleman:derived-source-view:commons-cli-fixture-v1","version":"b0e1b80b6d4a10a9c9f46539bc4c7a3cce55886e"}},"recipe":"deterministic-raw-source-view-v1","schema_version":1},"fixture_prefix":"src/test","harness_sha256":"sha256:d82676d24eb4b2683f8f0ccb1ccebc2a06ea771d8053e43d8f43b57a700dba7c","limitations":["One public upstream Java fault pair, not a complete Defects4J reconstruction or corpus admission","Common fixed-tree test fixture transplanted to both source revisions","Shared JVM and lexical test order; order independence has not been established","Repeated tests and trials are not independent projects or unique faults","Two assertions fail in both revisions and remain negative evidence","Collection clocks are not historical CI timestamps; elapsed counters are not runner-removable costs","JUnit 3.8.1 CPL-1.0 declaration: https://repo.maven.apache.org/maven2/junit/junit/3.8.1/junit-3.8.1.pom","Commons Lang license digest identifies META-INF/LICENSE.txt inside the separately pinned JAR; preserve NOTICE.txt"],"limits":{"maximum_output_bytes":1048576,"memory_bytes":1073741824,"timeout_seconds":60},"production_prefix":"src/java","project":"Apache Commons CLI","recipe":"junit3-fixed-tree-capture-v1","recipe_id":"apache-cli13-junit3-arm64-v1","runtime":{"emulated":false,"image_digest":"sha256:e4b3ff0f1a427efb2deb02b092ff8316d58573480260720d767d6ecdd69999d8","implementation":"Temurin","platform":"linux/arm64","timezone":"America/Los_Angeles","version":"11.0.32.1"},"schema_version":1,"test_ids":["org.apache.commons.cli.ApplicationTest::testAnt","org.apache.commons.cli.ApplicationTest::testLs","org.apache.commons.cli.ArgumentIsOptionTest::testOption","org.apache.commons.cli.ArgumentIsOptionTest::testOptionAndOptionWithArgument","org.apache.commons.cli.ArgumentIsOptionTest::testOptionWithArgument","org.apache.commons.cli.BugsTest::test11456","org.apache.commons.cli.BugsTest::test11457","org.apache.commons.cli.BugsTest::test11458","org.apache.commons.cli.BugsTest::test11680","org.apache.commons.cli.BugsTest::test12210","org.apache.commons.cli.BugsTest::test13425","org.apache.commons.cli.BugsTest::test13666","org.apache.commons.cli.BugsTest::test13935","org.apache.commons.cli.BugsTest::test14786","org.apache.commons.cli.BugsTest::test15046","org.apache.commons.cli.BugsTest::test15648","org.apache.commons.cli.BugsTest::test19383","org.apache.commons.cli.BugsTest::test21215","org.apache.commons.cli.BugsTest::test27635","org.apache.commons.cli.BugsTest::test31148","org.apache.commons.cli.BuildTest::testDuplicateLong","org.apache.commons.cli.BuildTest::testDuplicateSimple","org.apache.commons.cli.BuildTest::testLong","org.apache.commons.cli.BuildTest::testSimple","org.apache.commons.cli.GnuParseTest::testDoubleDash","org.apache.commons.cli.GnuParseTest::testExtraOption","org.apache.commons.cli.GnuParseTest::testMissingArg","org.apache.commons.cli.GnuParseTest::testMultiple","org.apache.commons.cli.GnuParseTest::testMultipleWithLong","org.apache.commons.cli.GnuParseTest::testSimpleLong","org.apache.commons.cli.GnuParseTest::testSimpleShort","org.apache.commons.cli.GnuParseTest::testSingleDash","org.apache.commons.cli.GnuParseTest::testStop","org.apache.commons.cli.LongOptionWithShort::testLongOptionWithShort","org.apache.commons.cli.OptionBuilderTest::testBaseOptionCharOpt","org.apache.commons.cli.OptionBuilderTest::testBaseOptionStringOpt","org.apache.commons.cli.OptionBuilderTest::testCompleteOption","org.apache.commons.cli.OptionBuilderTest::testIllegalOptions","org.apache.commons.cli.OptionBuilderTest::testOptionArgNumbers","org.apache.commons.cli.OptionBuilderTest::testSpecialOptChars","org.apache.commons.cli.OptionBuilderTest::testTwoCompleteOptions","org.apache.commons.cli.OptionGroupTest::testNoOptionsExtraArgs","org.apache.commons.cli.OptionGroupTest::testSingleLongOption","org.apache.commons.cli.OptionGroupTest::testSingleOption","org.apache.commons.cli.OptionGroupTest::testSingleOptionFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoLongOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromDifferentGroup","org.apache.commons.cli.OptionGroupTest::testTwoOptionsFromGroup","org.apache.commons.cli.OptionGroupTest::testTwoValidLongOptions","org.apache.commons.cli.OptionGroupTest::testTwoValidOptions","org.apache.commons.cli.OptionGroupTest::testValidLongOnlyOptions","org.apache.commons.cli.OptionsTest::testHelpOptions","org.apache.commons.cli.ParseRequiredTest::testMissingRequiredOption","org.apache.commons.cli.ParseRequiredTest::testOptionAndRequiredOption","org.apache.commons.cli.ParseRequiredTest::testWithRequiredOption","org.apache.commons.cli.ParseTest::testComplexShort","org.apache.commons.cli.ParseTest::testDoubleDash","org.apache.commons.cli.ParseTest::testExtraOption","org.apache.commons.cli.ParseTest::testMissingArg","org.apache.commons.cli.ParseTest::testMultiple","org.apache.commons.cli.ParseTest::testMultipleWithLong","org.apache.commons.cli.ParseTest::testSimpleLong","org.apache.commons.cli.ParseTest::testSimpleShort","org.apache.commons.cli.ParseTest::testSingleDash","org.apache.commons.cli.ParseTest::testStop","org.apache.commons.cli.PatternOptionBuilderTest::testSimplePattern","org.apache.commons.cli.TestHelpFormatter::testAutomaticUsage","org.apache.commons.cli.TestHelpFormatter::testFindWrapPos","org.apache.commons.cli.TestHelpFormatter::testPrintOptions","org.apache.commons.cli.TestHelpFormatter::testPrintWrapped","org.apache.commons.cli.ValueTest::testLongNoArg","org.apache.commons.cli.ValueTest::testLongOptionalArgValue","org.apache.commons.cli.ValueTest::testLongOptionalArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNArgValues","org.apache.commons.cli.ValueTest::testLongOptionalNoValue","org.apache.commons.cli.ValueTest::testLongWithArg","org.apache.commons.cli.ValueTest::testPropertyOptionFlags","org.apache.commons.cli.ValueTest::testPropertyOptionMultipleValues","org.apache.commons.cli.ValueTest::testPropertyOptionSingularValue","org.apache.commons.cli.ValueTest::testPropertyOverrideValues","org.apache.commons.cli.ValueTest::testShortNoArg","org.apache.commons.cli.ValueTest::testShortOptionalArgNoValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValue","org.apache.commons.cli.ValueTest::testShortOptionalArgValues","org.apache.commons.cli.ValueTest::testShortOptionalNArgValues","org.apache.commons.cli.ValueTest::testShortWithArg","org.apache.commons.cli.ValuesTest::testCharSeparator","org.apache.commons.cli.ValuesTest::testComplexValues","org.apache.commons.cli.ValuesTest::testExtraArgs","org.apache.commons.cli.ValuesTest::testMultipleArgValues","org.apache.commons.cli.ValuesTest::testShortArgs","org.apache.commons.cli.ValuesTest::testShortArgsWithValue","org.apache.commons.cli.ValuesTest::testTwoArgValues","org.apache.commons.cli.bug.BugCLI13Test::testCLI13","org.apache.commons.cli.bug.BugCLI18Test::testCLI18"]} diff --git a/docs/junit-source-capture.md b/docs/junit-source-capture.md index 1ed5d20e..1a3d4a5d 100644 --- a/docs/junit-source-capture.md +++ b/docs/junit-source-capture.md @@ -147,7 +147,11 @@ interrupted observation state. Source acquisition, staging and publication failures never certify a completed learning checkpoint. Successful protocols require the exact discovered test sequence and a final -trailer. Each case declares exactly one run and at most one terminal failure or +trailer. Discovery loads excluded classes without initializing them. Output from +test-class initializers and constructors is retained in the role's bounded raw +stderr, separately from protocol stdout and per-case diagnostics/timing. Discovery +errors restore the original streams and fail collection without inventing cases. +Each case declares exactly one run and at most one terminal failure or error; contradictory counters cause a protocol error rather than a normalized test outcome. Malformed/partial protocols, timeouts, output limits and process errors retain bounded raw evidence without promoting partial cases into assertions. diff --git a/docs/releases/4.6.0.md b/docs/releases/4.6.0.md index 298aa93b..ad4d85c0 100644 --- a/docs/releases/4.6.0.md +++ b/docs/releases/4.6.0.md @@ -104,7 +104,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,268 tests** and the **95% combined +The reviewed implementation passed **2,270 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/llms.txt b/llms.txt index 586c87d2..820e59cb 100644 --- a/llms.txt +++ b/llms.txt @@ -5809,7 +5809,11 @@ interrupted observation state. Source acquisition, staging and publication failures never certify a completed learning checkpoint. Successful protocols require the exact discovered test sequence and a final -trailer. Each case declares exactly one run and at most one terminal failure or +trailer. Discovery loads excluded classes without initializing them. Output from +test-class initializers and constructors is retained in the role's bounded raw +stderr, separately from protocol stdout and per-case diagnostics/timing. Discovery +errors restore the original streams and fail collection without inventing cases. +Each case declares exactly one run and at most one terminal failure or error; contradictory counters cause a protocol error rather than a normalized test outcome. Malformed/partial protocols, timeouts, output limits and process errors retain bounded raw evidence without promoting partial cases into assertions. @@ -8032,7 +8036,7 @@ v1 and reject missing, unknown and future versions. No automatic migration or reinterpretation of old results occurs. Harness changes require a reviewed recipe update. The domain remains independent of CLI, Docker and MCP imports. -The reviewed implementation passed **2,268 tests** and the **95% combined +The reviewed implementation passed **2,270 tests** and the **95% combined statement/branch coverage gate**, including a real paired source reproduction from a wheel installed outside the checkout. Versioned golden/round-trip fixtures, compatibility, units/missingness, nonfinite values, deterministic identities, diff --git a/tests/corpus/test_junit_harness.py b/tests/corpus/test_junit_harness.py new file mode 100644 index 00000000..396b42a9 --- /dev/null +++ b/tests/corpus/test_junit_harness.py @@ -0,0 +1,69 @@ +"""Execute the packaged Java harness against owned discovery side effects in the pinned offline JVM.""" + +import io +import os +from uuid import uuid4 + +import pytest + +from coleman.corpus import SourceCache +from coleman.corpus.source_views import SourceViewSpec, materialize_source_view, source_view_bytes +from coleman.transports.junit import load_junit_recipe +from coleman.transports.junit_capture import _run_role +from coleman.transports.junit_protocol import parsed_junit_stream +from coleman.transports.junit_source import owned_package, prepare_junit_inputs +from tests.corpus.test_source_views import changed, source_spec + + +@pytest.mark.parametrize("newline", [False, True]) +def test_real_harness_keeps_discovery_output_separate_from_protocol(tmp_path, newline): + location = os.environ.get("COLEMAN_JUNIT_REAL_CACHE") + if location is None: + pytest.skip("Explicit offline source cache and pinned local JVM image required") + cache = SourceCache(location) + recipe = load_junit_recipe() + environment = owned_package(cache, "owned-harness-environment.json", b"Owned harness regression", "owned-v1") + prepared = prepare_junit_inputs(recipe, cache, environment) + method = "println" if newline else "print" + case = ( + "package owned; public final class NoisyCase extends junit.framework.TestCase {" + "static { System.out." + method + '("static-out"); System.err.print("static-err"); }' + 'public NoisyCase(String name) { super(name); System.out.print("constructor-out"); }' + 'public void test_ci() { System.out.print("case-out"); System.err.print("case-err"); }' + "}" + ).encode() + excluded = b'package owned; public final class NotACase {static { System.out.print("excluded-out"); } }' + entries = (("src/test/owned/NoisyCase.java", case), ("src/test/owned/NotACase.java", excluded)) + inputs = tuple(source_spec(name, payload) for name, payload in entries) + output = source_spec( + "owned-noisy-fixture", + source_view_bytes(entries), + "zip", + [item.members[0].model_dump() for item in sorted(inputs, key=lambda item: item.members[0].name)], + ) + view = SourceViewSpec(schema_version=1, inputs=inputs, output=output) + data = dict(entries) + fixture = materialize_source_view(view, cache, lambda item: lambda: io.BytesIO(data[item.members[0].name])) + prepared = prepared._replace(fixture=fixture) + recipe = changed(recipe, test_ids=("owned.NoisyCase::test_ci",)) + config = tmp_path / "docker-config" + config.mkdir() + streams = _run_role( + ("docker", "--config", str(config)), + recipe, + prepared, + cache, + "buggy", + "coleman-junit-owned-noisy-" + uuid4().hex, + ) + assert streams.termination == "exited" + assert streams.exit_code == 0 + header, cases = parsed_junit_stream(streams.stdout, recipe) + assert header.excluded_classes == ("owned.NotACase",) + assert len(cases) == 1 + assert cases[0].failures == cases[0].errors == 0 + assert cases[0].diagnostics == "case-outcase-err" + assert b"static-out" in streams.stderr + assert b"static-err" in streams.stderr + assert b"constructor-out" in streams.stderr + assert b"excluded-out" not in streams.stdout + streams.stderr