Closes the three specific_asks from Jobs's T1 review of the workspace
architecture fix (7829acc..15e3863):
1. docs/architecture/workspace-concurrency.md: decision table
upgraded from a code block to a real Markdown table so it reads
consistently with the failure-modes table lower in the file.
2. docs/architecture/workspace-concurrency.md + resolve-workspace.ts:
added "Sunset coding-role inference" section and a TODO marker on
CODING_ROLE_PATTERN tying the regex to the v52 transition window
(target 2026-05-20). Both documents now name the end-state
explicitly so a future engineer knows why the regex exists and
when it dies.
3. resolve-workspace.ts: enriched the WorkspaceConfigurationError
message to include taskId / agentId / projectId alongside the
existing companyId, so a misconfigured setup points operators at
the offending row instead of just the company.
No behaviour change, no fallback, no mock. typecheck green, 540 unit
tests green, 10 eval tests green.
New doc (docs/architecture/workspace-concurrency.md) explains:
- why lockMode='none' is the default (cognitive tasks run in
parallel with no lock)
- what tasks.requires_filesystem means and how v52 backfills it
- the coding-role inference safety net during the v52 transition
- the per-task decision table the resolver implements
- why company_fallback was removed and what replaces it
- the type-enforced invariants on the resolution pair
- failure modes and how heartbeat/task-runner recover
Also adds /docs/architecture/*.md to the .gitignore allowlist so the
docs directory is tracked the same way /docs/*.md and
/docs/proposals/*.md already are.
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.
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.
Append a "Phase 2 considerations" section capturing the two
unresolved architecture debates Linus and Jobs surfaced in T1
review:
- Linus: drop the status->phase TRIGGER in favour of explicit
dual-write at every call site. Deferred to Phase 2 with explicit
rationale (existing two-layer guard + 5-commit blast radius).
- Jobs: flip reads from legacy columns to phase / task_leases.
Deferred until B5 eval harness can baseline agent behaviour.
Also records the four entry criteria for Phase 2 and the four gates
for Phase 3 drop-old-columns, so the next iteration has a concrete
checklist rather than a re-argument.
Address T2 review asks from Karpathy (request_changes) + Jobs
(approve with minor asks) without touching published commits:
- scripts/codemod/README.md (new): records remove-appdatabase-passthrough.mjs
usage, the completeness proof for METHOD_TO_MODULE (typecheck-clean +
524 tests green at 118e3d8 = no orphaned call sites), and the sequential
revert recipe for C1 (3 -> 2 -> 1, not independent because 118e3d8
bundled vault simplification).
- CONTRIBUTING.md (new): pass-through ban + codemod usage + sequential
revert recipe + file-size ceiling + C6 wave cap. Whitelisted in
.gitignore alongside the existing doc exceptions.
- docs/proposals/C6.2-error-taxonomy-phase2.md: wave 2 scope boundary
names renderer-adjacent / api-server / browser / automation / skills
explicitly and excludes src/main/database/** + src/main/worker/runtime/**
(B2 / M10 high-churn zones). Wave 2 and wave 3 each capped at 30
catch sites so C6 cannot expand without bound.
- src/main/agent-runtime/artifact-projector.ts, runtime-bridge.ts:
N-scan TODOs now carry a death date ("TODO(M-followup by 2026-05-20)").
If the date passes without decomposition, a follow-up session MUST
revisit or justify the exception.
Karpathy T2 asks #1 and #2 (split part 3 / "independent revert" language)
are addressed in CONTRIBUTING + codemod README as documentation, not
history rewrites, because 118e3d8 is already published.
Typecheck clean. No structural code changes; pure docs + comment edits.
- backup.ts: log.warn when `git rev-parse HEAD` fails so sandbox/CI runs
with no git show diagnosably instead of silently emitting gitSha:null
(Karpathy review ask).
- backup.ts: expand comment on VACUUM INTO to pin the WAL-mode invariant
— future readers must not "helpfully" add a wal_checkpoint call
(Karpathy review ask).
- C6.2 proposal: add hard coordination gate before wave 3 because
commit 0db6e42 already demonstrated the race hazard when two agents
touch scripts/ / connector-definitions/ in the same window
(Linus review ask).
Partitions the remaining catch sites into three waves (worker +
orchestration, IPC surfaces, database + credentials) so each wave is
one coherent review and can land in parallel with the B2 migration
precondition work that depends on classified DB catches.
Non-goals are explicit: no observable behaviour change, no renderer-
side coverage, no Result<T, AppError> envelope. The proposal exists
so the error taxonomy reaches the 95%+ coverage a lint rule needs.
- harness.test.ts: add in-memory self-test layer (pass + fail + purity), guard
fixtures dir with existsSync so absent dir yields empty list without
crashing the runner. Empty-fixture pnpm test:eval now carries real signal.
- replay-client.ts: remove dead if (!turn) branch; cursor bounds-check above
already guarantees the element. Use non-null assertion with a comment.
- assertion-judge.ts: drop unnecessary (turn as AssistantTurn | { content:
unknown[] }) cast. turn.role === assertion.role already narrows to
UserTurn | AssistantTurn and both expose .content.
- _BLOCKED-BY-CONSTRAINT.md: correct electron-builder note. files: is a
whitelist, so tests/eval is automatically excluded and no new rule is
required.
Document the follow-up tier on top of the B5 assertion harness: thin
single-call rubric judge, additive RubricDimension/RubricVerdict types,
cost cap ($2/run) with loud-skip behavior, per-fixture rubric cap (8
dimensions), baseline acceptance workflow, and explicit trigger
conditions (10+ fixtures / 2 incidents / structural-miss / 50-run zero
catch) — do not build speculatively.
Roundtable outcome: 2-1 to defer tonight. Linus — don't bolt a second
LLM to an empty harness. Jobs — single signal first. Karpathy — fixture
accumulation is what will tell us which rubric dimensions matter; the
schema stays extensible so we can add rubric-per-fixture without
breaking B5.