feat: contract / definition-of-done + idempotent-write dedup + bench … - #42
Merged
Merged
Conversation
…diff Three additions inspired by jukefr/itsy (the downstream Rust port of SmallCode). All declared in MarrowScript where applicable per AGENTS.md; JS runtimes are hand-ports until the compiler emits Node output. Contract / Definition of Done ----------------------------- Per-project assertion list the agent commits to up-front. The model cannot deliver a final "I'm done"-shaped response while any assertion is `pending` or `failed`. State persists to `.smallcode/contracts/<id>/state.json` with re-rendered `contract.md`, `assertions.md`, and a `log.jsonl` audit trail. Files: - marrow/contract.marrow — MarrowScript declaration - src/session/contract.js — state model + rendering - src/session/contract_store.js — file-backed CRUD - src/session/contract_tools.js — tool dispatch - src/session/contract_guard.js — done-guard heuristic Tools (5): - contract_create - contract_status - contract_assert_pass - contract_assert_fail - contract_assert_skip Slash command: /contract (status / list / activate / deactivate / abort) Disable: SMALLCODE_CONTRACT=false Per-turn idempotent-write dedup ------------------------------- Closes the spam-loop gap where small models could call memory_remember (or memory_forget) with identical args 30+ times in one turn. PURE_TOOLS dedup is sliding-window across calls; this set is per-turn and resets between turns rather than between sessions. Files: - src/tools/dedup.js — IdempotentWriteSet + helpers - bin/smallcode.js — wired into executeTool wrapper + per-turn reset Disable: SMALLCODE_IDEMPOTENT_WRITE_DEDUP=false Inspired by itsy commit 32653f3. Benchmark diff tool + BDD skill ------------------------------- - bench/diff.js — exit-coded comparator (0 improved / 1 regressed / 2 noise) with --json for CI - skills/benchmark-driven-development.md — measure-first discipline - npm run bench:diff <baseline> <feature> — wired in package.json Adapted from itsy's same-named skill. Verification ------------ - 60/60 unit tests pass via `npm test` (14 SSRF + 46 new across test/contract.test.js, test/dedup_idempotent.test.js, test/bench_diff.test.js) - 11/11 E2E checks pass via `npm run test:e2e` against huihui-gemma-4-e4b-it-abliterated on http://10.0.0.20:1234/v1. Live trace: model created the contract, marked a01 passed, tried "All done — task is complete." — done-guard fired ("contract guard: 1 unresolved assertion") — model recovered by calling contract_status then contract_assert_skip on a02 — contract auto-completed. - Zero diagnostics on touched files. - All new modules under the 600-LoC ceiling. Docs ---- - CHANGELOG.md — [1.2.0] entry - README.md — Contract / Definition of Done section, extended dedup blurb, Benchmark Diff Tool section, /contract row, 5 contract tools added to tools table - package.json — bumped to 1.2.0; added test, test:e2e, bench:diff scripts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Kothulhu94
pushed a commit
to Kothulhu94/smallcode
that referenced
this pull request
May 29, 2026
…diff (Doorman11991#42) Three additions inspired by jukefr/itsy (the downstream Rust port of SmallCode). All declared in MarrowScript where applicable per AGENTS.md; JS runtimes are hand-ports until the compiler emits Node output. Contract / Definition of Done ----------------------------- Per-project assertion list the agent commits to up-front. The model cannot deliver a final "I'm done"-shaped response while any assertion is `pending` or `failed`. State persists to `.smallcode/contracts/<id>/state.json` with re-rendered `contract.md`, `assertions.md`, and a `log.jsonl` audit trail. Files: - marrow/contract.marrow — MarrowScript declaration - src/session/contract.js — state model + rendering - src/session/contract_store.js — file-backed CRUD - src/session/contract_tools.js — tool dispatch - src/session/contract_guard.js — done-guard heuristic Tools (5): - contract_create - contract_status - contract_assert_pass - contract_assert_fail - contract_assert_skip Slash command: /contract (status / list / activate / deactivate / abort) Disable: SMALLCODE_CONTRACT=false Per-turn idempotent-write dedup ------------------------------- Closes the spam-loop gap where small models could call memory_remember (or memory_forget) with identical args 30+ times in one turn. PURE_TOOLS dedup is sliding-window across calls; this set is per-turn and resets between turns rather than between sessions. Files: - src/tools/dedup.js — IdempotentWriteSet + helpers - bin/smallcode.js — wired into executeTool wrapper + per-turn reset Disable: SMALLCODE_IDEMPOTENT_WRITE_DEDUP=false Inspired by itsy commit 32653f3. Benchmark diff tool + BDD skill ------------------------------- - bench/diff.js — exit-coded comparator (0 improved / 1 regressed / 2 noise) with --json for CI - skills/benchmark-driven-development.md — measure-first discipline - npm run bench:diff <baseline> <feature> — wired in package.json Adapted from itsy's same-named skill. Verification ------------ - 60/60 unit tests pass via `npm test` (14 SSRF + 46 new across test/contract.test.js, test/dedup_idempotent.test.js, test/bench_diff.test.js) - 11/11 E2E checks pass via `npm run test:e2e` against huihui-gemma-4-e4b-it-abliterated on http://10.0.0.20:1234/v1. Live trace: model created the contract, marked a01 passed, tried "All done — task is complete." — done-guard fired ("contract guard: 1 unresolved assertion") — model recovered by calling contract_status then contract_assert_skip on a02 — contract auto-completed. - Zero diagnostics on touched files. - All new modules under the 600-LoC ceiling. Docs ---- - CHANGELOG.md — [1.2.0] entry - README.md — Contract / Definition of Done section, extended dedup blurb, Benchmark Diff Tool section, /contract row, 5 contract tools added to tools table - package.json — bumped to 1.2.0; added test, test:e2e, bench:diff scripts Co-authored-by: DanTheMan181 <283874042+Doorman11991@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…diff
Three additions inspired by jukefr/itsy (the downstream Rust port of SmallCode). All declared in MarrowScript where applicable per AGENTS.md; JS runtimes are hand-ports until the compiler emits Node output.
Contract / Definition of Done
Per-project assertion list the agent commits to up-front. The model cannot deliver a final "I'm done"-shaped response while any assertion is
pendingorfailed. State persists to.smallcode/contracts/<id>/state.jsonwith re-renderedcontract.md,assertions.md, and alog.jsonlaudit trail.Files:
Tools (5):
Slash command: /contract (status / list / activate / deactivate / abort)
Disable: SMALLCODE_CONTRACT=false
Per-turn idempotent-write dedup
Closes the spam-loop gap where small models could call memory_remember (or memory_forget) with identical args 30+ times in one turn. PURE_TOOLS dedup is sliding-window across calls; this set is per-turn and resets between turns rather than between sessions.
Files:
Disable: SMALLCODE_IDEMPOTENT_WRITE_DEDUP=false
Inspired by itsy commit 32653f3.
Benchmark diff tool + BDD skill
(0 improved / 1 regressed / 2 noise) with --json for CI
Adapted from itsy's same-named skill.
Verification
npm test(14 SSRF + 46 new across test/contract.test.js, test/dedup_idempotent.test.js, test/bench_diff.test.js)npm run test:e2eagainst huihui-gemma-4-e4b-it-abliterated on http://10.0.0.20:1234/v1. Live trace: model created the contract, marked a01 passed, tried "All done — task is complete." — done-guard fired ("contract guard: 1 unresolved assertion") — model recovered by calling contract_status then contract_assert_skip on a02 — contract auto-completed.Docs
blurb, Benchmark Diff Tool section, /contract row,
5 contract tools added to tools table
scripts