Skip to content

feat(repo): stamp and schema-check repo budget JSON as repo_budget.v1 - #205

Merged
napetrov merged 3 commits into
intel:mainfrom
antonwolfy:feat/repo-budget-json-schema
Oct 23, 2026
Merged

napetrov merged 3 commits into
intel:mainfrom
antonwolfy:feat/repo-budget-json-schema

Conversation

@antonwolfy

@antonwolfy antonwolfy commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the review of #71 (point 3). repo budget --json carried no schema stamp, while repo scan, repo inspect and repo reach stamp theirs. A CI gate on the JSON could not tell when its shape changed.

Changes

  • New schema repo_budget.v1 (dokimi/schemas/repo_budget.v1.json), registered in artifacts.SCHEMA_VERSIONS. It is closed at every level: the top level, as in repo_readiness and repo_environment, and also each entry, totals and each duplicate_skills pair, since budget() writes exactly those keys. It requires:
    • tree;
    • entries: {path, kind, when, chars}, where kind and when are the values budget() emits;
    • totals: per when;
    • skills;
    • duplicate_skills: {a, b, overlap}, with overlap in [0, 1];
    • mcp_servers, warnings.
  • --json and --out:
    • --json prints the payload stamped with schema_version;
    • --out writes through save_artifact, as repo scan --out does, so the file is validated and stamped, and a missing parent directory is created. A path that cannot be written still exits 1 with cannot write.
  • Fixture and docs:
    • a fixture under tests/fixtures/artifacts/, the real output on a populated toy tree, which schema_compat needs;
    • the contract and architecture.md name the schema.
  • Changelog fragment (Added).

Risk

  • The --json output gains one key, schema_version. Nothing else in the payload changes.
  • --out into a directory that does not exist used to fail; it now creates it. The existing test that relied on that failure now uses a parent that is a file.
  • A new kind or when value later needs a widening edit to the schema, which schema_compat allows.

Testing

On a Linux review host, at f6c71e9 (on main 506f7ba):

  • make ci-local: 29 passed, 0 failed, 7 skipped (the Docker catalog smoke, test-latest, the cli-surface packaging step, conda-forge-deps without micromamba, docs deploy, the pip-audit report, semgrep). 7,398 tests passed, 1 skipped; changed-line coverage 100% of 9 lines.
  • tests/test_repo_budget_schema.py (19 cases): the --json output and the --out file are the same valid stamped artifact; an empty tree is valid; a payload missing any required field, with a bad kind, when, chars or overlap, or with an extra key at the top, in an entry, in totals or in a pair, is rejected. Dropping the stamp fails 4 of them; dropping warnings from required fails 1; reopening any one nested object fails its case.
  • Rebased onto main 92d92d3 (test(llm): pin provider-call budgets for judge, panel, answer and validation paths #170, tests only) before opening; with the ten follow-up branches merged together, the full suite (7,447 passed, 1 skipped), the growth check, mypy and ruff pass.
  • Review fixes, at f959a6f: make ci-local 29 passed, 0 failed, 7 skipped; 7,427 tests passed, 1 skipped; changed-line coverage 100% of 9 lines.

Checklist

  • Tests added/updated and pytest passes
  • ruff, mypy, and schema checks pass
  • Docs updated (or N/A) — see the docs-drift checklist in CONTRIBUTING.md
  • No ad-hoc run artifacts committed
  • New files carry the SPDX license header (or are exempt in .github/.licenserc.yaml)

`repo budget --json` carried no schema field, unlike `repo scan`
(repo_readiness.v1), `repo inspect` (repo_environment.v1) and `repo reach`
(guidance_reach.v1), so nobody gating CI on the JSON could detect a shape
change. This settles that non-blocking review point on intel#71.

Add schemas/repo_budget.v1.json for the payload `budget()` returns,
register it in artifacts.SCHEMA_VERSIONS, stamp the `--json` output, and
write `--out` through save_artifact as the sibling commands do (it now
creates missing parent directories and validates before writing). Add the
schema fixture, tests, and name the schema in the contract and architecture
docs.

Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
@vchamarthi

Copy link
Copy Markdown
Contributor

@exai-bot /review

@exai-bot exai-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

AI-generated review of 5571756e718c, requested by @vchamarthi, using the default review skill. It can be wrong: verify a finding before acting on it. React with a thumbs up or down on a finding to tell the bot whether it helped.
Model us.anthropic.claude-sonnet-5-5, effort default, 8 of 94 turns, 0.5 of 48 minutes, 161k in / 3k out tokens.

This PR adds a repo_budget.v1 schema and registers it. repo budget --json now prints a stamped payload, and --out writes through save_artifact, as repo scan and repo inspect do. The schema matches what budget() emits: I checked the kind/when values, the top-level keys and the overlap rounding against repos/budget.py. The fixture and tests cover the new contract well. I found only minor edge-case issues.

2 findings are on the changed lines, as comments below.

_write_json(args.out, payload)
try:
save_artifact("repo_budget", payload, Path(args.out))
except OSError as exc:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor (confirmed, correctness): A schema-invalid payload under --out escapes as a traceback

  • Problem: only OSError is caught. save_artifact raises ArtifactValidationError, a ValueError, when the payload fails the schema. That includes a future kind or when value that nobody added to the schema.
  • Effect: the user gets a raw traceback and not the ✗ ... message with exit 1. The changelog says --out "refuses a payload that does not match the schema", but the refusal arrives as a crash.
  • Context: repo scan and repo inspect do the same, so this follows existing practice. --json without --out never validates the payload.

Suggested fix:

Catch (OSError, ArtifactValidationError) in the --out block, print ✗ ... to stderr and exit 1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left as is, on purpose:

  • A payload that fails the schema means budget() produced a shape the schema doesn't know. That's a dokimi bug, not a user error.
  • repo scan --out and repo inspect --out raise the same way, and a handler only budget had would make the three differ.

The changelog's "refuses a payload that does not match the schema" did read like a handled error, so c8a141b changes it to "validates the payload against the schema before writing".

payload = budget(tree, profile.guidance_names, profile.import_max_depth)
if args.out:
_write_json(args.out, payload)
try:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (confirmed, style): --out file no longer ends with a newline

The old _write_json appended "\n". save_artifact writes json.dumps(...) with no trailing newline. This only matters to tools or diffs that expect a final newline.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. It's what save_artifact writes for every artifact (repo scan --out, repo inspect --out and the rest), so this stays consistent with them rather than becoming a special case.

@codecov-commenter

codecov-commenter commented Oct 23, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.97%. Comparing base (92d92d3) to head (f959a6f).
⚠️ Report is 15 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #205      +/-   ##
==========================================
+ Coverage   91.78%   91.97%   +0.19%     
==========================================
  Files         223      223              
  Lines       27623    27714      +91     
  Branches     4549     4553       +4     
==========================================
+ Hits        25354    25491     +137     
+ Misses       1606     1574      -32     
+ Partials      663      649      -14     
Files with missing lines Coverage Δ
dokimi/dokimi/artifacts.py 95.12% <ø> (+1.37%) ⬆️
dokimi/dokimi/commands/repo.py 96.40% <100.00%> (+0.05%) ⬆️

... and 14 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vchamarthi vchamarthi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers, not approving yet: CI at the head is not green (0 failing, 14 pending).

CI is still running at this head (20 checks pending, 2 passing); no defects found in the change. The schema's required keys, kind/when enums and overlap range match what budget() returns at dokimi/repos/budget.py:117-169, and the CLI wiring matches cmd_repo_inspect (save_artifact on --out, stamp on --json).

CI at send time: 0 failing, 14 pending.

@vchamarthi
vchamarthi requested a review from exai-bot October 23, 2026 16:41

@exai-bot exai-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

AI-generated review of 5571756e718c, requested by @vchamarthi, using the default review skill. It can be wrong: verify a finding before acting on it. React with a thumbs up or down on a finding to tell the bot whether it helped.
Model us.anthropic.claude-sonnet-5-5, effort default, 5 of 80 turns, 0.3 of 40 minutes, 117k in / 2k out tokens.

Re-review of 5571756e718c: nothing new.

…scan does

Review of intel#205 (exai-bot): "refuses a payload that does not match the
schema" read like a handled user error. A payload that fails the schema
is a bug in `budget()`, and `--out` raises on it as `repo scan --out`
and `repo inspect --out` do; the entry now says it validates.

Signed-off-by: Anton Volkov <antonwolfy@gmail.com>

@napetrov napetrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reuse of save_artifact/stamp matches repo scan, good. The summary says the schema is closed like repo_readiness/repo_environment, but only the top level has additionalProperties: false; the item objects in entries and duplicate_skills (and totals) accept extra keys. Suggest closing those too so a shape change is caught at every level.

Review of intel#205 (napetrov): only the top level had
`additionalProperties: false`, so an entry, `totals` or a
`duplicate_skills` pair could gain a key and still validate, and a CI
gate on the JSON would miss that shape change. `budget()` writes exactly
`{path, kind, when, chars}`, the four `when` totals and `{a, b,
overlap}` (the real-output fixture has no other key), so all three are
closed now. The sibling schemas close only their top level; this one is
new, so it can start strict.

Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
@antonwolfy

Copy link
Copy Markdown
Contributor Author

@napetrov done in f959a6f: each entry, totals and each duplicate_skills pair are closed too. budget() writes exactly those keys; the real-output fixture has no other. Three new cases reject an extra key in each, and the description now says the schema is closed at every level.

@napetrov napetrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed in f959a6f: entries, totals and duplicate_skills pairs closed, with rejection cases. LGTM.

@napetrov
napetrov merged commit 09be35b into intel:main Oct 23, 2026
29 checks passed
@antonwolfy
antonwolfy deleted the feat/repo-budget-json-schema branch October 24, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants