Output
This page defines the artifact contract under results/.
Directory layout
Per repository and per extractor:
results/<owner>@<repo>/<tool>.parquet
results/<owner>@<repo>/<tool>.json
Per run:
results/runs/<run-id>/summary.json
<run-id> is UTC time in YYYYMMDDTHHMMSSZ format.
Per-tool artifact contract
An extractor result is considered present only when both files exist:
<tool>.parquet<tool>.json
This matters for cache reuse. If only one file exists, JOSSeph treats the result as missing and reruns the extractor.
Metadata JSON contract
Every successful extractor writes:
{
"commit_hash": "abc123",
"requested_commit_hash": "abc123",
"metric_binding": "revision-bound",
"collected_at_utc": "2026-03-22T12:34:56Z"
}
Rules:
commit_hashis the resolvedHEADfor checkout-based extractorscommit_hashis""for checkout-free runs such asgithubrequested_commit_hashrecords the repository input revision when one was pinnedmetric_bindingidentifiesrevision-boundvsobservation-boundcollected_at_utcis UTC and truncated to whole seconds
Run summary contract
Example:
{
"run_id": "20260322T150000Z",
"status": "failed",
"started_at_utc": "2026-03-22T15:00:00Z",
"finished_at_utc": "2026-03-22T15:00:12Z",
"duration_seconds": 12.0,
"exit_code": 1,
"config": {
"config_path": "/workspace/configs/config.yaml",
"repositories": [
{
"repo_url": "https://github.com/example/repo.git",
"requested_commit_hash": null
}
],
"tools": [
"github",
"sonar"
],
"extractor_settings": {
"sonar": {
"host_url": "http://localhost:9234"
}
},
"github_token": "***redacted***",
"workers": 2
},
"summary": {
"repository_count": 1,
"affected_repository_count": 1,
"repository_failure_count": 1,
"extractor_failure_count": 1,
"failed_run_count": 2,
"skipped_run_count": 0
},
"repository_failures": [
{
"scope": "repository",
"repo_url": "https://github.com/example/repo.git",
"project_name": "example@repo",
"requested_commit_hash": null,
"reason": "clone failed",
"recorded_at_utc": "2026-03-22T15:00:01Z"
}
],
"extractor_failures": [
{
"scope": "extractor",
"repo_url": "https://github.com/example/repo.git",
"project_name": "example@repo",
"extractor": "github",
"requested_commit_hash": null,
"metric_binding": "observation-bound",
"reason": "api failed",
"recorded_at_utc": "2026-03-22T15:00:02Z"
}
],
"failed_runs": [
{
"scope": "repository",
"repo_url": "https://github.com/example/repo.git",
"project_name": "example@repo",
"requested_commit_hash": null,
"reason": "clone failed",
"recorded_at_utc": "2026-03-22T15:00:01Z"
},
{
"scope": "extractor",
"repo_url": "https://github.com/example/repo.git",
"project_name": "example@repo",
"extractor": "github",
"requested_commit_hash": null,
"metric_binding": "observation-bound",
"reason": "api failed",
"recorded_at_utc": "2026-03-22T15:00:02Z"
}
],
"skipped_runs": [
{
"scope": "extractor",
"repo_url": "https://github.com/example/repo.git",
"project_name": "example@repo",
"extractor": "ck",
"requested_commit_hash": null,
"metric_binding": "revision-bound",
"reason": "cached_result",
"recorded_at_utc": "2026-03-22T15:00:03Z"
}
]
}
How to interpret summary
| Field | Meaning |
|---|---|
repository_count |
number of unique repositories in the loaded config |
affected_repository_count |
number of repositories with at least one skip or failure event |
repository_failure_count |
count of repository-level failures |
extractor_failure_count |
count of extractor-level failures |
failed_run_count |
total length of failed_runs |
skipped_run_count |
total length of skipped_runs |
Missing file rules
Missing output files are meaningful:
- missing
<tool>.parquetand<tool>.jsonusually means the extractor failed or was not selected - missing only one of the pair means the result is incomplete and is not treated as cached
- missing
results/runs/<run-id>/summary.jsonusually means config loading failed before reporting started - results are stored per repository, not per repository revision; a later run for the same repository can overwrite earlier artifacts
Consumer guidance
If you build downstream jobs on top of results/, do not assume the directory
tree is complete. Use summary.json as the run manifest and fail your consumer
when expected extractor outputs are absent or listed in failed_runs.