Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[SF Ruby Feb'26] The Silicon Heel

[SF Ruby Feb'26] The Silicon Heel

Does architecture still matter when AI writes the code?

Avatar for Vladimir Dementyev

Vladimir Dementyev

February 28, 2026
Tweet

More Decks by Vladimir Dementyev

Other Decks in Programming

Transcript

  1. "Does architecture still matter when AI writes the code?" V.Dementyev,

    Evil Martians THE SILICON HEEL #NotADystopia #NoVibedBS San Francisco, 2026
  2. Fizzy Authorization: base vs. action_policy Adding a new role: viewer

    The experiment Order No 2026 Add a new role: viewer. - Viewers can see accessible boards and cards on them - Viewers cannot be assigned to cards - Viewers can comment on cards but only on cards being triaged - Viewers cannot create cards or boards - Viewers has no access to other parts of the app - The restrictions hold even for user owned cards/comments Ensure there is no UI controls associated with actions not available to viewers.
  3. module User::Role extend ActiveSupport::Concern included do enum :role, %i[ owner

    admin member system ].index_by(&:itself), scopes: false end def can_change?(other) (admin? && !other.owner?) || other == self end def can_administer?(other) admin? && !other.owner? && other != self end def can_administer_board?(board) admin? || board.creator == self end def can_administer_card?(card) admin? || card.creator == self end end
  4. class CardPolicy < ApplicationPolicy authorize :board, optional: true relation_scope do

    |scope| scope.joins(board: :accesses).where(accesses: {user_id: user.id}) end def create? allowed_to?(:show?, board) end def manage? allowed_to?(:show?, record.board) end def destroy? allowed_to?(:manage?) && (admin? || record.creator == user) end end
  5. class CardsController < ApplicationController # ... private def set_board -

    @board = Current.user.boards.find params[:board_id] + @board = Current.account.boards.find(params[:board_id]) + authorize! @board, to: :show? end def set_card - @card = Current.user.accessible_cards.find_by!(number: params[:id]) + @card = Current.account.cards.find_by!(number: params[:id]) + authorize! @card end - def ensure_permission_to_administer_card - head :forbidden unless Current.user.can_administer_card?(@card) - end - end
  6. Viewer: naïve Base Unprotected actions: 7 UI gaps: 3 Files

    changed: 52 Layered Unprotected actions: 0 UI gaps: 6 Rule bugs: 1 Files changed: 33
  7. Viewer: compound Plan, work, review, repeat (Most) Bugs/gaps are identified

    during development https://github.com/EveryInc/compound-engineering-plugin
  8. 3-phased experiment Add a viewer role Add ability to hide

    columns from viewers Add ability to define a minimal role to see the column
  9. 3-phased experiment Files Changed 0 12.5 25 37.5 50 Base

    (C1) Layered (C1) Base (C2) Layered (C2) Base (C3) Layered (C3) Controllers Models Views Policies ! [Base] Scattered guards: 27 controllers with before_action :ensure_contributor — each is a maintenance point for new endpoints
  10. 3-phased experiment P1 bugs 0 0.25 0.5 0.75 1 Base

    (C1) Layered (C1) Base (C2) Layered (C2) Base (C3) Layered (C3)
  11. Layers win? Both authz architectures work well with AI Stricter

    separation of concerns reduces review surface significantly Without clear boundaries, bug can escape even when using smarter AI workflows Layers demonstrate stronger compounding effect
  12. Tokens Measured /usage, not tokens (Max plan) Layered version spent

    ~10% more than base Planning and reviewing are the most consuming Skills have a room for improvement
  13. ▐▛███▜▌ Claude Code v2.1.47 ▝▜█████▛▘ Opus 4.6 · Claude Max

    ▘▘ ▝▝ /Users/vladimirdementyev/dev/fizzy > /layered-rails:analyze • I'll run a comprehensive layered architecture analysis of the Fizzy codebase. Let me start by gathering structural information and running violation detection in parallel. • 3 Explore agents finished (ctrl+o to expand) ├─ Analyze model concerns/modules · 69 tool uses · 44.7k tokens │ 㽾 Done ├─ Analyze controllers for violations · 65 tool uses · 43.7k tokens │ 㽾 Done └─ Analyze jobs and helpers · 47 tool uses · 38.1k tokens 㽾 Done • Now I have all the data needed. Here's the full analysis:
  14. │ 㽾 Done └─ Analyze jobs and helpers · 47

    tool uses · 38.1k tokens 㽾 Done • Now I have all the data needed. Here's the full analysis: --- Layered Architecture Analysis Summary - Overall health: Good - Layer compliance: ~90% - God object candidates: 1 (Card, via concern proliferation) - Callback concerns: 3 (minor) - Anti-patterns detected: 3 (minor) The Fizzy codebase demonstrates strong layered architecture discipline, consistent with Basecamp's "vanilla Rails" philosophy. Controllers are thin, models are rich, and side effects are well-organized. The most notable pattern is namespace-scoped concerns (e.g., Card::Closeable) rather than a flat app/models/concerns/ bag ....
  15. Layered Design for Ruby on Rails Applications, Chapter 5, "When

    Rails Abstractions Are Not Enough", p.107
  16. > Specification test (inferred from the implementation) describe TrelloImport do

    describe "#process" do context "when import succeeds" do it "sets status to processing then completed" # ✅ Domain: state transition it "records started_at and completed_at" # ✅ Domain: state tracking it "delegates to Processor" # ✅ Domain: orchestration end context "when import fails" do it "sets status to failed with error message" # ✅ Domain: state transition it "re-raises the error" # ✅ Domain: error propagation end context "when system user does not exist" do it "creates a system user on the account" # ⚠ Belongs on Account — duplicates account.system_user end end # ... end
  17. > Existing Test Analysis class TrelloImportTest < ActiveSupport::TestCase test "process_later

    enqueues TrelloImportJob" # ✅ Domain test "process imports board from Trello JSON" # ⚠ Integration: runs full Processor, tests Processor behavior test "process imports columns from lists" # ⚠ Integration: same test "process imports cards" # ⚠ Integration: same # ... test "process sets status to failed on error" # ✅ Domain: state transition test "store_id_mapping and get_fizzy_id work correctly" # ✅ Domain: unit behavior test "accessible_to? returns true for owner"# ✅ Domain: unit behavior test "import with API credentials attempts attachment download" # ❌ Infrastructure: uses stub_request(:get, /trello\.com/) # ... end
  18. Pattern-oriented architecture 2026+ Order No 2026 Idioms ! ! !

    Design patterns ! ! % Architectural patterns ! % % AI orchestration patterns % % %