ONCE Campfire's own Minitest suite, run against a Roundhouse emit of the same commit. A failure here mostly names a Rails construct not yet modeled; some are answers that came out wrong with nothing raised, and some have not been triaged at all. That makes their tests the worklist generator — so the ranked causes below, not the pass count, are what this page is for.
This is the compiled lane: each test file compiled to its own native binary by spinel, then run. The same emitted source runs on the interpreted lane, so a difference between the two is the compiler's, not the app's — and this lane can report a status its sibling cannot. 9 of 54 files never linked, and their tests are counted against their first compile error rather than against anything the emit got wrong.
scripts/campfire-suite and is compiled by spinel a4b7238e78f8.
The app is pinned at 94a48aacb65a; the compiler is not.
This lane compiles 54 whole programs, which is too much to run per commit, so it runs on a schedule
and its spinel is whatever the publisher pulled and built that morning. That makes a movement here
two-sided: it belongs to a Roundhouse change or to a compiler change, and the two are told
apart by the spinel version recorded above — not by this page. Read a regression by checking that
version first.
The file list is theirs. Every test file campfire's own suite declares, read from the emitted Makefile's SPINEL_TESTS rather than restated here — a `find test -name '*_test.rb'` would also sweep in the scaffold's own tests, which are not campfire's.
Each run stands alone. There is no history here and no comparison to previous runs: a chart of a number that moves for a dozen reasons is not the point of a worklist.
Occurrences churn; causes are the unit of work, so each carries a stable slug you can still refer to forty commits later. Owner says who can act: most of this is Roundhouse's own modeling debt.
Counts are how many tests are currently stopped by each cause, not how many will pass when it lands: a test is attributed to the first thing that stopped it, so clearing one cause routinely reveals another behind it. Each unpassed test carries its own message; a file that never ran contributes its whole count against its load error.
| Blocked | Cause | Owner | |
|---|---|---|---|
| 16 | The emit ran and answered differentlysilent-divergence | untriaged | |
NOT a root cause — the bucket of tests that still need one. Nothing raised: the emitted code ran to completion and produced a different answer, so each of these has to be followed down its own chain. This is the most valuable cluster on the page and the most expensive: a missing method names itself, a wrong answer does not.
5 of 16 tests
| |||
| 4 | An emitted method's arity does not match its callerarity-divergence | roundhouse | |
The receiver exists and the name resolves; the shape does not. Usually a lowering that dropped or added a parameter — kwargs folded into a positional, a block-form helper emitted in its non-block shape. Each needs the emitted definition read against its call site.
4 tests
| |||
| 1 | `allow_browser` — the modern-browser gateallow-browser | roundhouse | |
campfire's own concern calls `allow_browser versions: VERSIONS, block: -> { render template: "sessions/incompatible_browser" }`, so the version FLOOR is the app's (`{ safari: 17.2, chrome: 120, … }`) and what is missing is ours: the macro, its `block:` fallback, and parsing a User-Agent into a browser plus version. Rails reads that last part from the `useragent` gem's rule table — PORT the table, do not derive it. The file is 7/8 on this one test.
1 test
| |||
| 119 | Not yet triagedunclassified | untriaged | |
No rule in bench/campfire/suite-causes.json matches these. Triage, then add a rule.
12 of 119 tests
| |||
A rule at zero is kept, not deleted: it is the tripwire that catches the fix coming undone. What it means depends on why it is at zero.
| Rule | Why it reads zero |
|---|---|
id-zero-sentinel | zero is the intended reading. This is a deliberate divergence rather than a gap, and the rule exists to catch the day it becomes visible again. |
pagination | landed in 0ef8fb79; the rule stays as a regression tripwire. |
conditional-get | `fresh_when` / `stale?` landed in 7ea262e2; the rule stays as a regression tripwire. |
turbo-streams-channel | the constant landed in fd1a3259; the rule stays as a regression tripwire. |
sti-becomes | `becomes!` landed in f2d42854; the rule stays as a regression tripwire. |
test-harness-surface | the family landed over several commits, `fixture_file_upload` last in f86ac0b6; the rule stays as a regression tripwire. |
Held at zero by the harness, not by the compiler — the stub ledger below covers what would otherwise fail here: belongs-to-autosave. Deleting the stub is what makes these counts real.
No explanation recorded, so these are the open question: either the cause is cleared and nobody wrote that down, or the failure's message changed and it is now being counted as untriaged above. params-hash-in-path, out-of-scope-gems, route-helper-takes-a-record, active-storage-attachments, view-helper-in-helper-module, broadcast-assertions, rails-module-facade, globalid-sgid, actiontext-attachment-from-node, relation-vs-array, params-object-representation, fixture-accessors.
Nothing: this run spliced no stubs (--no-stubs), so the numbers above are the emit's own.
A file that never ran is not the same as a file whose tests failed: it died at load, so its whole count is charged to one error and nothing behind that error has been seen yet.
And on this lane there is a third row: a file that never linked. Its tests are charged to its first compile error, and unlike a load failure it has not been observed to do anything at all — the emit may be perfectly correct behind it. Sort the work by asking which of the three a row is: didn't link, linked and diverged, linked and agreed.
| File | Tests | Pass | Fail | First error |
|---|---|---|---|---|
test/messages_by_bots_controller_test | 23 | 0 | 23 | never linked — runtime/cgi_io.rb:206: error: incompatible types when assigning to type ‘sp_int’ {aka ‘long int’} from type ‘sp_RbVal’ |
test/opengraph_fetch_test | 11 | 0 | 11 | never linked — spinel: test/opengraph_fetch_test.rb:139: unsupported equality: node 133105 (CallNode `!=`) recv=StringNode/ty6 argc=1 arg0ty1 |
test/opengraph_metadata_test | 10 | 0 | 10 | FAIL Opengraph::MetadataTest#test_successful_fetch: gem facade: Nokogiri.HTML is stubbed (write-path only; see runtime/gem_facades.rb) |
test/push_subscription_test | 17 | 10 | 7 | FAIL Push::SubscriptionTest#test_rejects_endpoint_whose_host_resolves_to_nothing_without_raising: mocha: Resolv.stubs(:getaddresses) with 1 chained link(s) is n |
test/accounts_logos_controller_test | 6 | 0 | 6 | never linked — spinel: test/accounts_logos_controller_test.rb:67: unsupported call: node 132636 (CallNode `new_from_buffer`) recv=ConstantPathNode/ty49 argc=2 arg0ty6 |
test/users_push_subscriptions_controller_test | 6 | 0 | 6 | never linked — test/users_push_subscriptions_controller_test.rb:35: error: cannot convert to a pointer type |
test/opengraph_location_test | 7 | 2 | 5 | FAIL Opengraph::LocationTest#test_url_validations: assertion failed |
test/room_push_test | 5 | 0 | 5 | FAIL Room::PushTest#test_deliver_new_message_to_other_room_users_with_push_subscriptions: uninitialized constant ThreadPoolExecutor |
test/users_bans_controller_test | 7 | 2 | 5 | FAIL Users::BansControllerTest#test_create_bans_user_and_creates_ban_records_from_sessions: undefined method 'each' for unknown |
test/account_test | 4 | 0 | 4 | never linked — runtime/active_storage.rb:201: error: incompatible types when assigning to type ‘sp_RbVal’ from type ‘sp_int’ {aka ‘long int’} |
test/messages_boosts_by_bots_controller_test | 12 | 8 | 4 | FAIL Messages::Boosts::ByBotsControllerTest#test_create_adds_a_boost_to_the_message_and_returns_it: undefined method 'rewind' for an instance of String |
test/unfurl_links_controller_test | 5 | 1 | 4 | FAIL UnfurlLinksControllerTest#test_create: gem facade: Nokogiri.HTML is stubbed (write-path only; see runtime/gem_facades.rb) |
test/action_text_attachment_test | 3 | 0 | 3 | never linked — spinel: test/action_text_attachment_test.rb:25: unsupported call: node 132495 (CallNode `from_node`) recv=ConstantPathNode/ty49 argc=1 arg0ty50 |
test/message_attachment_test | 3 | 0 | 3 | FAIL Message::AttachmentTest#test_creating_a_message_creates_image_thumbnail: undefined method 'image' for unknown |
test/message_searchable_test | 3 | 0 | 3 | FAIL Message::SearchableTest#test_message_body_is_indexed_and_searchable: assert_equal failed |
test/messages_controller_test | 15 | 12 | 3 | FAIL MessagesControllerTest#test_index_returns_a_page_before_the_specified_message: undefined method 'id' for unknown |
test/opengraph_document_test | 3 | 0 | 3 | FAIL Opengraph::DocumentTest#test_extract_opengraph_tags_using_property_attribute: gem facade: Nokogiri.HTML is stubbed (write-path only; see runtime/gem_facade |
test/rooms_controller_test | 5 | 2 | 3 | FAIL RoomsControllerTest#test_show: undefined method 'presence' for unknown |
test/rooms_direct_test | 3 | 0 | 3 | never linked — test/rooms_direct_test.rb:23: error: initialization of ‘sp_Relation *’ {aka ‘struct sp_Relation_s *’} from incompatible pointer type ‘sp_PolyArray *’ [-Werror=i |
test/searches_controller_test | 5 | 2 | 3 | FAIL SearchesControllerTest#test_index_initial_view: expected ".message" in response body |
test/user_avatar_test | 3 | 0 | 3 | never linked — runtime/active_storage.rb:201: error: incompatible types when assigning to type ‘sp_RbVal’ from type ‘sp_int’ {aka ‘long int’} |
test/users_sidebars_controller_test | 3 | 0 | 3 | FAIL Users::SidebarsControllerTest#test_show: assert_match failed: expected "<!DOCTYPE html>\n<html>\n <head>\n <title>Campfire</title>\n\n <meta name=\" |
test/webhook_test | 6 | 3 | 3 | FAIL WebhookTest#test_payload: undefined method 'with' for unknown |
test/rooms_open_test | 2 | 0 | 2 | never linked — runtime/active_record/connection.rb:143: error: invalid initializer |
test/sessions_controller_test | 8 | 6 | 2 | FAIL SessionsControllerTest#test_new_denied_with_incompatible_browser: expected "h1" in response body |
test/user_bot_test | 4 | 2 | 2 | FAIL User::BotTest#test_create_bot: mocha: SecureRandom.stubs(:alphanumeric) with 1 chained link(s) is not a stub shape this target serves |
test/accounts_bots_controller_test | 5 | 4 | 1 | FAIL Accounts::BotsControllerTest#test_update: no implicit conversion of User into Integer |
test/first_runs_controller_test | 4 | 3 | 1 | FAIL FirstRunsControllerTest#test_create_is_not_vulnerable_to_race_conditions: uninitialized constant CyclicBarrier |
test/membership_test | 9 | 8 | 1 | FAIL MembershipTest#test_removing_a_membership_resets_the_user_s_connections: undefined method 'expects' for an instance of User |
test/message_test | 3 | 2 | 1 | FAIL MessageTest#test_mentionees: assert_equal failed |
test/qr_code_controller_test | 1 | 0 | 1 | FAIL QrCodeControllerTest#test_show_renders_a_qr_code_as_a_cacheable_svg_image: gem facade: RQRCode::QRCode.new is stubbed (write-path only; see runtime/gem_fac |
test/room_test | 6 | 5 | 1 | FAIL RoomTest#test_revise_memberships: undefined method 'present?' for an instance of User |
test/rooms_closeds_controller_test | 9 | 8 | 1 | FAIL Rooms::ClosedsControllerTest#test_remove_yourself: no implicit conversion of Hash into String |
test/rooms_opens_controller_test | 9 | 8 | 1 | FAIL Rooms::OpensControllerTest#test_create: assert_equal failed |
test/user_test | 4 | 3 | 1 | FAIL UserTest#test_deactivating_a_user_deletes_push_subscriptions_searches_memberships_for_non_direct_rooms_and_changes_their_email_address: mocha: SecureRandom |
test/users_avatars_controller_test | 4 | 3 | 1 | FAIL Users::AvatarsControllerTest#test_show_image: assert_equal failed |
test/users_profiles_controller_test | 3 | 2 | 1 | FAIL Users::ProfilesControllerTest#test_show: undefined method 'presence' for unknown |
test/account_joinable_test | 2 | 2 | 0 | all green |
test/accounts_bots_keys_controller_test | 1 | 1 | 0 | all green |
test/accounts_controller_test | 4 | 4 | 0 | all green |
test/accounts_custom_styles_controller_test | 3 | 3 | 0 | all green |
test/accounts_join_codes_controller_test | 2 | 2 | 0 | all green |
test/accounts_users_controller_test | 3 | 3 | 0 | all green |
test/autocompletable_users_controller_test | 4 | 4 | 0 | all green |
test/block_banned_requests_test | 3 | 3 | 0 | all green |
test/first_run_test | 3 | 3 | 0 | all green |
test/messages_boosts_controller_test | 2 | 2 | 0 | all green |
test/rooms_directs_controller_test | 6 | 6 | 0 | all green |
test/rooms_involvements_controller_test | 5 | 5 | 0 | all green |
test/rooms_refreshes_controller_test | 1 | 1 | 0 | all green |
test/sessions_transfers_controller_test | 2 | 2 | 0 | all green |
test/user_role_test | 3 | 3 | 0 | all green |
test/users_controller_test | 6 | 6 | 0 | all green |
test/welcome_controller_test | 2 | 2 | 0 | all green |
From the transpile that produced the tree under test: 1,157 files, 0 errors, 893 warnings. Warnings are a modeling-debt ledger rather than a failure — the Ruby target emits through its gaps — so the COUNTS are not comparable to the test failures above.
They are not independent of them either. send_dispatch_failed in particular names a call the analyzer could not resolve, and three of the fixes on this lane came out of those lines before the suite reached them at all — the analyzer had already written the diagnosis. Read the emit log before the fail log.
| Diagnostic | Count |
|---|---|
gradual_untyped | 372 |
unresolved_type | 281 |
lower_residue | 150 |
unsupported | 53 |
blank_unlowered | 36 |
missing_preload | 1 |