Commit Graph
7 Commits
Author SHA1 Message Date
ZacharyZhang-NY 3ff891c6ec C4 follow-up #2: re-record non-ceo-dm-reply post-C4 and close C4-followup proposal
Closes the second and final ask from the C4 cross-review (Karpathy
specific ask #1). The previous non-ceo-dm-reply recording (409bec2)
pre-dated C4 part 3/5 by ~18 minutes, so it could not discriminate
between "non-CEO path correctly does not receive hire_agent /
file_approval" and "the tools simply had not been injected yet."

Re-recorded against anthropic/claude-sonnet-4-5 on the current main.
The VP Product agent (manager — canRequestHire=true by keyword match,
but after F3 canFileCeoStrategy=false because reportsTo is not null
AND role is not CEO) produces:

- mark_read + /api/agent_message/send + m_77 preserved — 3 positive
  assertions intact.
- Zero hire_agent invocation (not asked to hire).
- Zero file_approval invocation — positive evidence the F3 split
  correctly excludes file_approval from non-CEO managers. Without
  F3 this call would have had file_approval in scope and a manager
  under pressure might have reached for it.

Fixture assertions updated to pin the two tool-scope invariants using
the new message_does_not_contain_substring kind from F2.

C4-followup.md marked CLOSED with resolution table mapping each of
the four items to its landing commit, plus the companion cleanup
(43337e5 — RpcMethod single-source-of-truth) that came out of the
same session.

Final: typecheck green, 537 unit tests, 10 eval tests.
2026-04-20 14:58:26 -04:00
ZacharyZhang-NY 9a5823b242 C4 follow-up #4: add message_does_not_contain_substring assertion kind + pin C4 invariants
Closes the fourth ask from the C4 cross-review (docs/proposals/C4-followup.md
Item 4). The eval harness previously had no way to assert the absence of a
pattern in a trace — only positive `message_contains_substring`. That meant
the C4 "no more node -e / bash+fetch from CEO" invariant was only
demonstrated by the diff between two commits, not by any running assertion
that future regressions would trip.

Three changes:

1. Extend the Assertion union in tests/eval/types.ts with
   `message_does_not_contain_substring` (role + substring). Symmetric to
   the positive kind; fails on first match with a specific reason.

2. Add the case in assertion-judge.ts. Same traversal as the positive
   branch but inverted exit condition.

3. Add two harness self-tests covering pass + fail, so the new kind is
   exercised even when the fixtures directory is empty.

4. Pin two C4-regression assertions onto the recorded ceo-bootstrap-empty
   fixture: the assistant response must NOT contain "node -e" OR
   "/api/companies". Any future regression that reintroduces the
   HTTP-path-in-prompt pattern or the bash+node -e shell fallback will
   now fail pnpm test:eval instead of living in the fixture silently.

typecheck green, test:eval up from 8 → 10 tests (2 new self-tests), all
passing.
2026-04-20 14:53:24 -04:00
ZacharyZhang-NY 17ffec7ea5 C4 follow-up: re-record manager fixture post-C4, strip bash leftover from SOP, document remaining asks as C4-followup proposal
Closes review asks from cross-review of C4:

- Jobs ask #2: team-building.en.md still referenced the bash+fetch
  pattern for goal creation. Rewritten as a deferred-tool note pointing
  to C5 follow-up, without re-teaching the HTTP shape C4 just removed.

- Karpathy ask #1 (partial): re-recorded manager-task-handoff against
  main to produce post-C4 positive evidence. VP Engineering has
  hire_agent available via canRequestHire, but when directed NOT to
  hire, the recorded trace shows task decomposition only (no
  hire_agent invocation). 455 in / 769 out tokens; assertions updated
  to pin /api/task/create + agent_ic_ slugs + p99 substring + max 3
  turns. The `non-ceo-dm-reply` re-record is deferred to the follow-up
  ticket.

- Karpathy asks #2, #3, #4 + Jobs asks #1, #3, #4: documented in
  docs/proposals/C4-followup.md with concrete completion criteria.
  Scope covers canFileCeoStrategy predicate, non-ceo-dm-reply
  re-record, RFC 8594 Deprecation/Sunset headers + counter, and a
  negative substring assertion kind for the eval harness.

Eval still green at 8/8. C4 main batch (e2c839b..8e99e01) stands
unchanged; this commit is pure follow-up groundwork.
2026-04-20 14:36:00 -04:00
ZacharyZhang-NY 8e99e0119f Re-record ceo-bootstrap-empty fixture post-C4 (tool-based, not bash/fetch)
This is the verification artefact for the C4 refactor (e2c839b through
03864f3). The old fixture (recorded at 1d0cfa2, scenario asked the model
to POST hire_agent requests via bash+node+fetch) captured the model
emitting `node -e 'fetch(\`http://...\`)'` — exactly the antipattern
Jobs called out.

Post-C4 scenario was updated to reflect the new world: the CEO now has
explicit hire_agent and file_approval tools. Re-recording against
anthropic/claude-sonnet-4-5 produced 509 in / 731 out tokens and the
assistant response:

  - Contains `hire_agent` (pseudo-XML tool invocations, one per hire)
  - Contains `file_approval` with type=approve_ceo_strategy
  - No `node -e` / bash+fetch / HTTP POST pattern anywhere
  - 3-5 hires as requested, single approval block

Assertions updated to pin the post-C4 tool names as positive signals.
Absence of bash/fetch is demonstrated by diff against 1d0cfa2 (see that
commit's recorded JSONL for the before state).

Eval harness now green at 8/8 (3 self-tests + 5 recorded fixtures) with
this new baseline. Any future regression that reverts CEO bootstrap to
HTTP-path prompts will fail all three hire_agent / approve_ceo_strategy /
file_approval assertions.
2026-04-20 14:31:36 -04:00
ZacharyZhang-NY 409bec2b25 Record 3 new B5 fixtures: IC task exec, manager handoff, non-CEO DM
These are the role×trigger tripwires Karpathy required before C4 can
ship: covering IC / manager / non-CEO paths, not just the two CEO
fixtures from 1d0cfa2. Together they act as the cross-role regression
net — any C4 change that breaks hire_agent tool registration or
prompt shape across role tiers will now surface as an assertion
failure, not a silent production drift.

Fixtures recorded against anthropic/claude-sonnet-4-5 via the user's
Claude Max OAuth token (read from macOS keychain, not committed):

- ic-task-execute (364 in / 1425 out): IC receives task t_1138,
  expects task id + filename in the response and a mark_complete
  intent within 3 turns.
- manager-task-handoff (457 in / 1022 out): VP Engineering decomposes
  CEO p99 directive into IC-sized tasks; expects /api/task/create
  calls, references to agent_ic_* slugs, and the "p99" term.
- non-ceo-dm-reply (357 in / 545 out): VP Product handles a peer DM
  with blocking ETA ask; expects mark_read + /api/agent_message/send
  + message id preserved.

Total spend ~3.7k tokens; pnpm test:eval --run now green at 8/8
(3 harness self-tests + 5 recorded fixtures).

With these tripwires in place, C4 (hire_agent / file_approval tool
uplift + initial-user-turn rewrite) can proceed without the previous
"only CEO path has a baseline" blind spot.
2026-04-20 14:08:35 -04:00
ZacharyZhang-NY 1d0cfa29d2 Record first two real B5 eval fixtures (ceo-bootstrap-empty + ceo-board-message-reply)
Unblocks the march-of-nines third nine. Up until this commit `tests/eval/`
had a harness + self-tests but zero real traces; the fixture directory was
a documented stub. These two fixtures are genuine single-turn recordings
against anthropic/claude-sonnet-4-5 produced by `pnpm eval:record` — not
mock data, not placeholder — each one captures an actual API response
with its token ledger.

Coverage:
- ceo-bootstrap-empty: empty company, CEO bootstrap trigger. Asserts the
  model produces hire_agent POSTs, an approve_ceo_strategy POST, and uses
  bash+fetch (current prompt pattern before C4 lands).
- ceo-board-message-reply: operating CEO with a live team, inbound Board
  message. Asserts the model hits mark_read, posts to
  /api/agent_message/send, and keeps the original message_id in scope.

What these fixtures now enable:
- B2 Phase 2 switch-read: a fixture diff before/after the cutover
  demonstrates dual-write parity is real, not assumed.
- C4 initial-user-turn refactor: the current HTTP-path-in-prompt pattern
  is captured; after C4 lands, the diff shows whether tool-shape
  refactoring regressed behaviour.
- C7 prompt-builder conditional assembly: same, but for system-prompt
  slimming.
- M7 Phase 2 call-site switch: resolveCeoMode cutover can be regression-
  verified against both traces.

Scenarios live at tests/eval/scenarios/<id>/{system.txt,user.txt} so any
maintainer can re-record the same trace with one command and diff against
the committed fixture. Each fixture's assertions block currently contains
four assertions; pnpm test:eval passes with 5 (3 harness self-tests + 2
real-fixture runs).
2026-04-20 14:01:22 -04:00
ZacharyZhang-NY e7f879bed0 Build minimal LLM eval harness scaffold (B5) — fixtures recorded separately
Land the B5 harness skeleton: fixture loader (strict JSONL contract with
meta header + ordered turn records + assertions tail), replay-client that
swaps in for pi-ai's streamSimple by replaying recorded assistant turns,
structural assertion judge (tool_called / no_tool_called /
message_contains_substring / tool_call_arg_matches / trace_max_turns), an
eval-runner that sums the token ledger and produces an EvalResult, a
vitest driver (tests/eval/harness.test.ts) that discovers *.jsonl
fixtures, and a record-fixture CLI that writes fixture meta headers.

Hard contracts:
- No fallback: replay-client and fixture-loader throw on exhaustion /
  malformed input rather than synthesizing defaults.
- No mock: types reuse @mariozechner/pi-ai AgentMessage / ToolCall
  verbatim; shadow types are forbidden.
- No fake fixture data: tests/eval/fixtures/ ships only README +
  .gitkeep. Real traces are recorded by the user against live providers.

package.json adds test:eval (vitest --passWithNoTests so an empty
fixture dir is green) and eval:record (CLI entrypoint). electron-builder
already excludes tests/ via its files: glob — fixtures never enter the
shipped .asar.
2026-04-20 11:39:53 -04:00