20 KiB
CC Brief — Sprint 12 Task 1 Session 2
Datum: 2026-04-22 PM (post-Session-1 adjudication)
Sprint: 12 · Task 1 (Infra-build) · Session 2
Author: PM (Marko Marković)
Authority chain: Marko ratification → Session 1 adjudication doc → ovaj brief
Pre-Session-2 git state: a75dd25 + 620f018 autorizovani za push (per adjudication § 4)
Session 2 LLM spend ceiling: $0.00 (pure local engineering, isto kao Session 1)
Session 2 wall-clock estimate: 7-9h (3 commits, 3 sub-deliverables)
0. TL;DR
Session 2 zatvara tri od preostalih substrate blockera za C3 mikro-eval kickoff: Blocker #3 (pre-registration CLI surface + pino emitter za bench.preregistration.manifest_hash), Blocker #4 (judge model registry extension sa pinning_surface poljima per B3 addendum § 4), i B3 addendum § 4/§ 5 implementation (model_pinning_surface + model_pinning_carve_out_reason + model_revision_hash polja u JSONL + manifest payload).
Posle Session 2: ostaju Blocker #5 (Fleiss' κ + Wilson + cluster-bootstrap CI), Blocker #6 (failure taxonomy F1-F6), i smoke test suite — sve tri stavke su Session 3 scope. Task 1 closure gate (smoke test PASS) je Session 3 odgovornost, ne Session 2.
Session 2 nema runtime LLM calls, nema network calls van eventualnog git push na kraju sesije, nema dataset modifikacije. Sav rad je TypeScript surface + JSON config + new pino emitter module + unit tests.
1. Sources of truth (čitati pre kodiranja)
| Doc | Path | Why |
|---|---|---|
| A3 LOCK v1 | decisions/2026-04-22-bench-spec-locked.md + .manifest.yaml |
Pre-registration field set + manifest_hash payload schema |
| B3 LOCK addendum | decisions/2026-04-22-b3-lock-dashscope-addendum.md |
Pinning surface taxonomy + carve-out polje obligation |
| Session 1 exit ping | sessions/2026-04-22-cc-sprint-12-task1-session1-exit.md |
Session 1 deliverables baseline + canonical SHA 39e415e2…402a5b24 za Blocker #3 manifest hash payload |
| Session 1 adjudication | sessions/2026-04-22-cc-sprint-12-task1-session1-adjudication.md |
PM ratification + push authorization |
| Session 1 brief | briefs/2026-04-22-cc-sprint-12-task1-session1-brief.md |
Brief format precedent + Session 1 scope context |
| Sprint 12 scope draft | briefs/2026-04-22-sprint-12-scope-draft.md § Task 1 § 3 |
Blocker dependency DAG + Sprint-level context |
| C3 substrate gap origin | sessions/2026-04-22-c3-blocked-substrate-gap.md |
Originalna 6-blocker taxonomy iz koje #3 + #4 derivirani |
Ako bilo koji od tih dokumenata trenutno ima nejasnoću za bilo koji deo Session 2 scope-a, stop i traži PM clarifikaciju pre kodiranja — ne improvizuj.
2. Scope u + out
2.1 IN-scope (3 sub-deliverables, 3 commits)
Sub-deliverable A — Blocker #3 — Pre-registration CLI surface + pino emitter
Cilj: omogućiti npm run bench:locomo -- --manifest-hash <sha> --emit-preregistration-event --per-cell <cell> --judge-tiebreak <strategy> invocation patterns. Emit single pino event bench.preregistration.manifest_hash na početku svakog runOne() call-a, sa payload-om koji sadrži manifest hash + per-cell + judge-tiebreak izbore + canonical dataset SHA.
Files to touch:
benchmarks/harness/src/cli.ts(or wherever current CLI argv parsing lives — ako ne postoji jedan central file, kreirajbenchmarks/harness/src/cli.tsi refactor postojećirunner.tsargv block u taj modul). Add 4 new flags + validation.benchmarks/harness/src/preregistration.ts(NEW). Single export:emitPreregistrationManifest(payload: PreregistrationManifestPayload): void. Uses pino logger (existing instance, ne kreiraj novi). Event name:bench.preregistration.manifest_hash. Payload schema u § 3.1 ovog brief-a.benchmarks/harness/src/runner.ts. PozoviemitPreregistrationManifestjednom perrunOne()call, pre prvog ćelije iteration-a. Payload se konstruiše iz CLI args + canonical dataset version (već dostupan iz Session 1getDatasetVersion()) + bench-spec manifest hash (computed at-runtime prekocrypto.createHash('sha256').update(fs.readFileSync('decisions/2026-04-22-bench-spec-locked.manifest.yaml')).digest('hex')— ili equivalent helper-a umanifest-hash.tsmodulu ako želiš da ga ekstraktuješ).benchmarks/harness/src/manifest-hash.ts(NEW, optional akopreregistration.tspostaje preveliki). Single export:computeBenchSpecManifestHash(): string. Deterministic SHA-256 over the.manifest.yamlbytes.benchmarks/harness/tests/preregistration.test.ts(NEW). Minimum 8 tests: payload schema valid, pino emit called once per runOne, payload includes canonical dataset SHA, payload includes manifest hash, manifest hash deterministic across reads, CLI flag parsing of--manifest-hash, CLI flag parsing of--per-cell, CLI flag parsing of--judge-tiebreak.benchmarks/harness/tests/cli.test.ts(NEW or extend existing). Test sve 4 nove flag-ove kroz argv parser + invalid-input rejections.
Sub-deliverable B — Blocker #4 — Judge model registry extension
Cilj: Proširiti config/models.json (or wherever current judge model registry lives — verify lokaciju kroz rg "judge.*model" benchmarks/ packages/ pre nego što počneš) sa 4 nova model entry-ja: Opus 4.7, GPT-5.4, Gemini 3.1, Grok 4.20. Svaki entry mora imati polje pinning_surface po B3 addendum § 4 taxonomy-ju (anthropic_immutable | floating_alias | revision_hash_pinned) plus pinning_surface_carve_out_reason polje (string ili null).
Files to touch:
benchmarks/harness/config/models.json(verify path) ilipackages/server/src/benchmarks/config/models.tsako je TS source. Add 4 entries. Update existing Anthropic entries (Opus 4.6, Sonnet 4.6, Haiku 4.5) sapinning_surface: "anthropic_immutable"+pinning_surface_carve_out_reason: null.benchmarks/harness/src/types.ts. ExtendJudgeModelConfiginterface (or equivalent) sapinning_surface+pinning_surface_carve_out_reasonpolja.benchmarks/harness/tests/models-config.test.ts(NEW). Minimum 6 tests: svi judge model entries imajupinning_surface, valid enum values, Anthropic entries imajunullcarve-out reason, non-Anthropic entries imaju non-null carve-out reason, no duplicate model_id, JSON schema parse-clean.
Model entry payload skeleton (svaki novi entry):
{
"model_id": "anthropic/claude-opus-4-7",
"provider": "anthropic",
"context_window": 200000,
"pinning_surface": "anthropic_immutable",
"pinning_surface_carve_out_reason": null,
"judge_role": "primary"
}
Za non-Anthropic (npr. Gemini):
{
"model_id": "google/gemini-3.1-pro",
"provider": "google_via_openrouter",
"context_window": 1000000,
"pinning_surface": "floating_alias",
"pinning_surface_carve_out_reason": "Google does not expose immutable model snapshots; floating alias mandated by B3 addendum § 5",
"judge_role": "secondary"
}
Egzaktni model_id slug-ovi: confirm sa OpenRouter ili native provider naming convention pre commit-a. Ako ne možeš da potvrdiš slug bez network call-a, fallback na placeholder slug + komentar koji eksplicitno kaže "PLACEHOLDER — confirm pre Sprint 12 Task 2 kickoff" — ne blocking za Session 2 čišćenje.
Sub-deliverable C — B3 addendum § 4/§ 5 piggy-back
Cilj: Per-row model_pinning_surface + model_pinning_carve_out_reason + model_revision_hash polja u svakom JsonlRecord-u, plus istovetna polja u manifest payload-u koji ide u bench.preregistration.manifest_hash event.
Files to touch:
benchmarks/harness/src/types.ts. ExtendJsonlRecordinterface sa tri optional polja:model_pinning_surface?: 'anthropic_immutable' | 'floating_alias' | 'revision_hash_pinned'model_pinning_carve_out_reason?: string | nullmodel_revision_hash?: string | null
benchmarks/harness/src/runner.ts. Pri konstrukciji svakogJsonlRecord, populate tri nova polja iz judge model config registry-ja (lookupmodel_idumodels.json, copypinning_surface+pinning_surface_carve_out_reason, setmodel_revision_hashnanullosim ako je provider eksplicitno vraća — to je future hook, za Session 3 ili kasnije).benchmarks/harness/src/preregistration.ts(already touched in Sub-deliverable A). Manifest payload extends sa array svih judge model-a u play-u, sa per-modelpinning_surface+ carve-out reason.benchmarks/harness/tests/jsonl-record-schema.test.ts. Add 3 tests verifying nova polja u emit-ovanom record-u.benchmarks/harness/tests/preregistration.test.ts(već u scope iz Sub-deliverable A). Add 2 tests verifying per-judge-model pinning surface ulazi u manifest payload.
2.2 OUT-of-scope (NOT in Session 2 — defer to Session 3 or later)
- Blocker #5 — Fleiss' κ + Wilson + cluster-bootstrap CI u
metrics.ts. Ne dirati. Session 3 anchor. - Blocker #6 — Failure taxonomy F1-F6 + F-other u
judge-runner.ts+ JSONL schema extension. Ne dirati. Session 3. - Smoke test suite — 10-instance dry-run kroz full runner invocation shape per C3 brief § 4. Ne pisati. Session 3 closure gate.
- Bilo kakvi LLM API calls — bilo runtime, bilo unit-test mock-ovani sa real network. Sve mora biti
nockili pure local mock-ovi. $0 LLM spend constraint je hard. - Push to remote — push je PM odgovornost (već autorizovan u adjudication doc § 4). CC izvršava
git push origin mainna kraju Session 2 jedino ako PM eksplicitno potvrdi u closing exchange-u. - Doc scrub legacy cell names (Sprint 13 backlog stavka per adjudication § 3). Ne dirati
03B-SERVER_QUALITY.md,BACKLOG-MASTER, ili druge historical doc-e. .gitattributesextension za druge audit artifacts (Sprint 13 backlog stavka per adjudication § 3). Ne dodavati nove pin-ove.
3. Schemas + signatures (precision contracts)
3.1 PreregistrationManifestPayload schema
interface PreregistrationManifestPayload {
// Bench-spec lock
manifest_hash: string; // SHA-256 of decisions/2026-04-22-bench-spec-locked.manifest.yaml bytes
manifest_path: string; // 'decisions/2026-04-22-bench-spec-locked.manifest.yaml'
manifest_locked_at: string; // ISO-8601, copied from manifest yaml
// Canonical dataset
dataset_version: string; // From getDatasetVersion(), e.g. '39e415e2f3a0fa1bd3cb1804a58d0b440b50d3070b2100698437e4ec402a5b24'
dataset_path: string; // 'benchmarks/data/locomo/locomo-1540.jsonl'
dataset_instance_count: number; // 1531
// CLI choices (from runtime argv)
per_cell: string[]; // e.g. ['raw', 'filtered', 'compressed', 'full-context']
judge_tiebreak: string; // e.g. 'majority' | 'arithmetic-mean' | per A3 LOCK § B2
judge_models: Array<{
model_id: string;
provider: string;
judge_role: 'primary' | 'secondary' | 'tertiary';
pinning_surface: 'anthropic_immutable' | 'floating_alias' | 'revision_hash_pinned';
pinning_surface_carve_out_reason: string | null;
}>;
// Provenance
emitted_at: string; // ISO-8601 wall-clock at emit time
runner_version: string; // Git short SHA at runtime, fallback 'unknown' ako git ne dostupan
runner_invocation: {
argv: string[]; // process.argv kopija (sanitized — bez API keys)
cwd: string; // process.cwd()
};
}
Pino event signature:
logger.info(
{ ...payload, event: 'bench.preregistration.manifest_hash' },
'Pre-registration manifest hash emitted for benchmark run'
);
3.2 JsonlRecord extensions (Sub-deliverable C)
interface JsonlRecord {
// ... existing fields preserved unchanged
// ... dataset_version já existe iz Session 1
// NEW — Sub-deliverable C
model_pinning_surface?: 'anthropic_immutable' | 'floating_alias' | 'revision_hash_pinned';
model_pinning_carve_out_reason?: string | null;
model_revision_hash?: string | null;
}
3.3 CLI flag parsing surface (Sub-deliverable A)
Add 4 new flags, all optional sa defaults:
| Flag | Type | Default | Description |
|---|---|---|---|
--manifest-hash <sha> |
string | computed at-runtime | Allows override za test ili replication runs; default computes from .manifest.yaml bytes |
--emit-preregistration-event |
boolean | true |
If false, suppresses pino emit (useful za tests) |
--per-cell <cell> |
string[] | ['raw', 'filtered', 'compressed', 'full-context'] |
Subset of cells; multi-value (--per-cell raw --per-cell filtered) |
--judge-tiebreak <strategy> |
string | per A3 LOCK § B2 default | Override za tie-break strategy; validates against A3 LOCK enum |
Flag parsing library: koristi postojeći (verify which — vrlo verovatno commander ili yargs based on Sprint 11 codebase). Ako ne postoji centralizovani parser, kreiraj minimalni manual argv walker u cli.ts — ne uvodi novu dependency bez PM signoff-a.
4. Acceptance criteria (closure gate per sub-deliverable)
4.1 Sub-deliverable A acceptance
benchmarks/harness/tests/preregistration.test.ts— 8/8 pass.benchmarks/harness/tests/cli.test.ts— sve nove flag tests pass.tsc --noEmitclean onbenchmarks/harness.- Manual smoke:
npm run bench:locomo -- --manifest-hash test123 --per-cell raw --judge-tiebreak majority --emit-preregistration-event→ pino event emitted with payload matching schema § 3.1. - Single commit:
feat(benchmarks): Sprint 12 Task 1 Blocker #3 — pre-registration CLI surface + manifest_hash emitter
4.2 Sub-deliverable B acceptance
benchmarks/harness/tests/models-config.test.ts— 6/6 pass.tsc --noEmitclean onbenchmarks/harness+packages/serverako interfejs polja diraju server module.models.json(ili equivalent) parse-clean preko Node'sJSON.parse(fs.readFileSync(...)).- Svi judge model entries imaju non-empty
pinning_surface. Sve non-Anthropic entries imaju non-nullpinning_surface_carve_out_reason. - Single commit:
feat(benchmarks): Sprint 12 Task 1 Blocker #4 — judge model registry + pinning surface fields per B3 addendum § 4
4.3 Sub-deliverable C acceptance
benchmarks/harness/tests/jsonl-record-schema.test.ts— sve postojeće tests pass + 3 nova prolaze.benchmarks/harness/tests/preregistration.test.ts— 2 dodatna tests za per-judge-model pinning surface u manifest payload-u prolaze.- Manual smoke: emit-uj jedan record kroz mock runner invocation, verify tri nova polja prisutna.
tsc --noEmitclean.- Single commit:
feat(benchmarks): Sprint 12 Task 1 B3 addendum § 4/§ 5 — per-row pinning surface + carve-out reason + revision hash JSONL fields
4.4 Aggregate Session 2 acceptance
- Harness test suite total post-Session-2: ~96 tests (78 baseline + 8 preregistration + 4-6 cli + 6 models-config + 5 jsonl-record + 2 preregistration extension = ~99-103 ako sve idu lepo, target floor 96).
- Server test suite: 58/58 unchanged (ako Sub-deliverable B dotakne server, novi tests u server package).
tsc --noEmitclean on oba (benchmarks/harness+packages/server).- Grep:
rg "manifest_hash" benchmarks/mora pokazati hits inpreregistration.ts,runner.ts,cli.ts, tests, plus existing decision doc references. - Grep:
rg "pinning_surface" benchmarks/ packages/mora pokazati hits umodels.json+types.ts+ tests. - 3 commits, sva tri local na
main. Bez force-push, bez rebase. - LLM spend: $0.
5. Surprise-reporting protocol
Sledite Session 1 precedent — exit ping doc na kraju Session 2 sa istom strukturom kao Session 1 exit ping (sessions/2026-04-22-cc-sprint-12-task1-session1-exit.md):
- TL;DR sa per-blocker outcome
- Per-commit file table
- Acceptance criteria verification
- § 5 Surprises — bilo koji deviation od ovog brief-a, bilo koja ambiguous scope decision koju si morao da donosiš sam, bilo koja interface API break koju si uradio van eksplicitnog scope-a — sve sa "Why" line-om i "PM question" formulacijom.
PM ratifikuje exit ping pre nego što Session 3 brief može biti draftovan. Dakle ne pokušavaj da preempt-uješ Session 3 izvršenje "while you're at it" — drži se Session 2 scope-a.
Exit ping fajl: sessions/2026-04-22-cc-sprint-12-task1-session2-exit.md.
6. Time + cost ledger expectation
| Sub-deliverable | Wall-clock | LLM spend |
|---|---|---|
| A — Blocker #3 (pre-reg CLI + emitter) | 4-5h | $0 |
| B — Blocker #4 (judge model registry) | 2h | $0 |
| C — B3 addendum § 4/§ 5 (per-row + manifest) | 1-2h | $0 |
| Aggregate | 7-9h | $0 |
Ako u toku rada postaje očigledno da bilo koji sub-deliverable preti da pređe svoju budget allokaciju za >50%, stop i pošalji preliminary ping pre kompletiranja — bolje je da Marko odluči da li seče scope ili daje dodatno vreme nego da CC "tiho" pređe budget.
Sprint 11 + Session 1 cumulative LLM spend: $0.018893. Session 2 mora ostati exactly tu cifru — ni jedan cent dodatno.
7. Push protocol
Sub-deliverable A + B + C generišu 3 commit-a. Predlažem sledeći redosled commit + push pattern:
- Posle Sub-deliverable A merge u
mainlokalno → ne push. - Posle Sub-deliverable B merge u
mainlokalno → ne push. - Posle Sub-deliverable C merge u
mainlokalno + sve acceptance criteria § 4.4 prolaze → exit ping draft. - PM review exit ping → PM signal "push" → CC izvršava
git push origin main(push-uje sva 3 nova commit-a + neguranje Session 1 commit-ovea75dd25+620f018ako još nisu push-ovani po adjudication § 4).
Bez push-a u međusekucijama. Sve granular u jednoj push operaciji posle PM ratification.
8. Risks + watchpoints
R1 — Existing CLI parser shape (Sub-deliverable A). Ako Sprint 11 kod ima decentralizovan argv handling rasut po runner.ts + judge-runner.ts + sub-command files, refactor u central cli.ts može preći budget. Mitigation: ako refactor postaje neproporcionalan, zadrži new flags lokalno u runner.ts argv block i dokumentuj decision u exit ping § Surprises.
R2 — models.json ne postoji ili je u drugom format-u (Sub-deliverable B). Verify pre kodiranja. Ako je TS const u packages/server/src/benchmarks/config/models.ts, type-extend tamo. Ako ne postoji uopšte, kreiraj benchmarks/harness/config/models.json sa svim postojećim Anthropic entries + 4 nova non-Anthropic + extension polja.
R3 — pino logger instance lokacija (Sub-deliverable A). Verify postojeću pino setup. Ako je po-modulu instantiated, koristi shared util. Ako ne postoji shared util, kreiraj benchmarks/harness/src/logger.ts sa default pino instance + export-uj za reuse.
R4 — Manifest YAML parsing dependency (Sub-deliverable A). js-yaml ili yaml paket — verify postojeću dependency. Ne uvodi novu yaml lib; ako nijedan ne postoji, koristi JSON.parse na sidecar .json mirror file ako ga A3 LOCK ima, ili javi PM za scope expansion.
R5 — Test naming collision sa postojećim test fajlovima. Verify pre kreiranja cli.test.ts, preregistration.test.ts, models-config.test.ts da ne postoje već.
R6 — Drift od B3 addendum eksaktne taxonomy-je. Re-read decisions/2026-04-22-b3-lock-dashscope-addendum.md § 4 + § 5 pre kodiranja Sub-deliverable B i C. Ako tvoja implementacija odstupa od addendum tačno definisanih polja ili enum-a, zaustavi i clarify sa PM-om. Ne improvizuj naming.
9. Related artifacts
- A3 LOCK v1:
decisions/2026-04-22-bench-spec-locked.md+decisions/2026-04-22-bench-spec-locked.manifest.yaml - B3 LOCK addendum:
decisions/2026-04-22-b3-lock-dashscope-addendum.md - Session 1 brief:
briefs/2026-04-22-cc-sprint-12-task1-session1-brief.md - Session 1 exit ping:
sessions/2026-04-22-cc-sprint-12-task1-session1-exit.md - Session 1 adjudication:
sessions/2026-04-22-cc-sprint-12-task1-session1-adjudication.md - Sprint 12 scope draft:
briefs/2026-04-22-sprint-12-scope-draft.md - C3 substrate gap:
sessions/2026-04-22-c3-blocked-substrate-gap.md
10. Final reminders
- $0 LLM spend hard constraint.
- 3 commits, no force-push, no rebase, no push do PM signala.
- Surprises ping na kraju, no Session 3 preemption.
- Tests green + tsc clean = closure gate per sub-deliverable.
- Ako bilo šta postaje ambiguous, stop i pitaj PM — ne improvizuj.
Session 2 brief LOCKED. Standing by za CC pickup.