Skip to content

Workshop 7: Live demo script

Share-screen guide. The whole workshop is hands-on, together, in session: we draft the policies as a group and we build the enforcement mechanism live, alongside the students, so every student leaves with a working installation. Nothing here is take-home. Total demo time: ~15 minutes.

Setup before the demo

  • Editor + terminal.
  • Repo state: clean. No husky installed yet.

Step 1: Install and wire up Husky + lint-staged (~8 min)

"We're going to install one specific enforcement mechanism together, right now, in session. Follow along on your own repo as I go so everyone has a working enforcement by the end of this block. Once you have it committed, note it in your logbook. If you'd rather build a different mechanism, that's an optional swap, but build it live with me here, not afterward."

  1. Prereq: Prettier is not installed in OrbitTasks yet. Add it and a config first, otherwise the prettier --write step below will fail:

    bash
    npm install --save-dev prettier
    echo '{ "singleQuote": true, "semi": true }' > .prettierrc
  2. Install:

    bash
    npm install --save-dev husky lint-staged
    npx husky init
  3. Open .husky/pre-commit. Replace its contents:

    sh
    #!/usr/bin/env sh
    npx lint-staged
  4. Open the root package.json. Add:

    json
    {
      "lint-staged": {
        "*.{ts,tsx}": [
          "eslint --fix",
          "prettier --write"
        ],
        "*.{json,md,yml}": [
          "prettier --write"
        ]
      }
    }
  5. Test it: stage a deliberately badly-formatted file:

    bash
    echo "const  x=1;const y=2 ;" >> apps/api/src/test-file.ts
    git add apps/api/src/test-file.ts
    git commit -m "test the hook"
  6. The hook runs, prettier reformats the file, the commit goes through with the formatted version. Show students the diff: the file got auto-fixed.

  7. Clean up: rm apps/api/src/test-file.ts && git commit -am 'remove test file'.


Step 2: Add the "test must be deterministic" lint rule (~5 min)

This one ties back to the flaky tests we identified in Workshop 2 and fixed in Workshop 5.

  1. First, make the tests directory lintable. Today every eslint.config.js has **/tests/** in its ignores block, and the lint scripts only scan src, so a rule scoped to tests would never fire. Remove tests from the ignores block (and lint the tests dir, e.g. eslint src tests) so the rule below can actually run.

  2. Open eslint.config.js. Add a custom rule banning the pattern that produced the flaky Login test:

    js
    {
      files: ['apps/**/tests/**/*.{ts,tsx}'],
      rules: {
        // Discourage fire-and-forget assertions after async actions.
        // We want students to use `await waitFor(...)` instead of bare
        // synchronous assertions on React state changes.
        'no-restricted-syntax': [
          'warn',
          {
            selector: "CallExpression[callee.name='expect'][arguments.0.type='CallExpression'][arguments.0.callee.object.name='screen']",
            message: 'After async actions, prefer await waitFor(...) or findByText. See workshops/REMEDIATION-PLAYBOOK.md.',
          },
        ],
      },
    },

    (In a real codebase you'd probably use eslint-plugin-testing-library and turn on await-async-utils and no-wait-for-side-effects. The custom rule above is a teaching version.)

  3. Run lint. Show that a few tests now produce warnings. Open one and walk through fixing it.


Step 3: Add a PR template with AI-disclosure (~2 min)

  1. Create .github/PULL_REQUEST_TEMPLATE.md:

    markdown
    ## What and why
    
    <!-- 1-2 sentences. Link any issue. -->
    
    ## How to test
    
    <!-- Steps a reviewer can follow. -->
    
    ## AI-assisted code
    
    - [ ] No AI involvement.
    - [ ] AI suggested code in [where?], reviewed line-by-line.
    - [ ] AI generated [tests / docs / module], reviewed against the rubric.
    
    ## Risk
    
    <!-- What's the worst case if this is wrong? -->
  2. Commit. Open a PR on a test branch to show students how the template appears on github.com.


After the live demo

"Everyone has one working enforcement now, committed and recorded in your logbook. For the next 15 minutes, we draft the three governance docs together using the templates in starter/, and you record each one in your logbook as we go. Then we'll come back and debate."

That's the handoff to block 3 (drafting), which we also do live, together.


What to do if a student's enforcement breaks

Common: the husky hook doesn't fire because of a permissions issue on macOS. Fix:

bash
chmod +x .husky/pre-commit

If the lint rule produces too many warnings to fix in the hour: that's also a real engineering moment. Tell them: "Real teams stage rule rollouts. Set it to 'warn' for two weeks, then promote to 'error'. Don't drop it into 'error' on day one."