Module 6: Putting It Together

In this capstone module, you'll build a complete legal model combining everything you've learned.

Learning Objectives

By the end of this module, you will be able to:

  • Design a complete L4 model from requirements
  • Organize code with sections
  • Apply best practices
  • Debug common issues
  • Know where to go next

Capstone Project: Charity Registration

We'll build a simplified charity registration system based on real legislation. This combines:

  • Type definitions
  • Eligibility rules
  • Regulative obligations
  • Testing

The complete working implementation:

-- Module 6: Putting It Together - Capstone Example
-- A complete charity registration system
-- All examples are validated and use natural language identifiers

IMPORT prelude

-- =============================================================================
-- SECTION 1: Type Definitions
-- =============================================================================

-- Charitable purposes (from legislation)
DECLARE Purpose IS ONE OF
    `prevention or relief of poverty`
    `advancement of education`
    `advancement of religion`
    `advancement of health`
    `advancement of animal welfare`
    `other purpose` HAS `the description` IS A STRING

-- Legal status of a charity
DECLARE Status IS ONE OF
    Active
    Suspended HAS `the reason` IS A STRING
    Deregistered

-- Criminal conviction record
DECLARE Conviction
    HAS `the description` IS A STRING
        `the conviction is spent` IS A BOOLEAN

-- Governor of a charity
DECLARE Governor
    HAS `the governor's name` IS A STRING
        `the governor's age` IS A NUMBER
        `the governor is bankrupt` IS A BOOLEAN
        `the governor's convictions` IS A LIST OF Conviction

-- The main charity record
DECLARE `Registered Charity`
    HAS `the charity's name` IS A STRING
        `the registration number` IS A STRING
        `the charity's status` IS A Status
        `the charity's purposes` IS A LIST OF Purpose
        `the charity's governors` IS A LIST OF Governor

-- =============================================================================
-- SECTION 2: Eligibility Rules
-- =============================================================================

-- A governor must be an adult (at least 18)
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `the governor is an adult` IF
    governor's `the governor's age` >= 18

-- Check for disqualifying convictions (unspent convictions)
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `the governor has a disqualifying conviction` IF
    any (GIVEN c YIELD c's `the conviction is spent` EQUALS FALSE) (governor's `the governor's convictions`)

-- A person can be a governor if they meet all criteria
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `the person can be a governor` IF
    `the governor is an adult` governor
    AND NOT governor's `the governor is bankrupt`
    AND NOT `the governor has a disqualifying conviction` governor

-- A purpose is charitable if it's from the approved list
GIVEN purpose IS A Purpose
GIVETH A BOOLEAN
DECIDE `the purpose is charitable` IS
    CONSIDER purpose
    WHEN `prevention or relief of poverty` THEN TRUE
    WHEN `advancement of education` THEN TRUE
    WHEN `advancement of religion` THEN TRUE
    WHEN `advancement of health` THEN TRUE
    WHEN `advancement of animal welfare` THEN TRUE
    WHEN `other purpose` description THEN FALSE

-- A charity is valid if it has valid purposes and valid governors
GIVEN charity IS A `Registered Charity`
GIVETH A BOOLEAN
DECIDE `the charity is valid` IF
    charity's `the charity's status` EQUALS Active
    AND NOT null (charity's `the charity's purposes`)
    AND all (GIVEN p YIELD `the purpose is charitable` p) (charity's `the charity's purposes`)
    AND NOT null (charity's `the charity's governors`)
    AND all (GIVEN g YIELD `the person can be a governor` g) (charity's `the charity's governors`)

-- =============================================================================
-- SECTION 3: Filing Obligations
-- =============================================================================

-- Actors and actions for the regulatory system
DECLARE Actor IS ONE OF
    `the Charity`
    `the Commissioner`

DECLARE Action IS ONE OF
    `file the annual return`
    `issue a Required Steps Notice`
    `correct the deficiencies`

-- Annual return filing obligation
GIVEN charity IS A `Registered Charity`
GIVETH A DEONTIC Actor Action
`the annual return obligation` MEANS
    IF charity's `the charity's status` EQUALS Active
    THEN
        PARTY `the Charity`
        MUST `file the annual return`
        WITHIN 60
        HENCE FULFILLED
        LEST
            PARTY `the Commissioner`
            MUST `issue a Required Steps Notice`
            WITHIN 14
            HENCE `the correction period`
            LEST BREACH BY `the Commissioner` BECAUSE "failed to issue notice"
    ELSE FULFILLED

-- After notice is issued, charity has time to correct
GIVETH A DEONTIC Actor Action
`the correction period` MEANS
    PARTY `the Charity`
    MUST `correct the deficiencies`
    WITHIN 30
    HENCE FULFILLED
    LEST BREACH BY `the Charity` BECAUSE "failed to correct after notice"

-- =============================================================================
-- SECTION 4: Test Data
-- =============================================================================

-- Valid governor
`Jane Smith` MEANS Governor "Jane Smith" 45 FALSE (LIST)

-- Governor with issues
`John Doe (bankrupt)` MEANS Governor "John Doe" 50 TRUE (LIST)

`unspent conviction` MEANS Conviction "Fraud conviction 2020" FALSE
`Bob Jones (with conviction)` MEANS Governor "Bob Jones" 40 FALSE (LIST `unspent conviction`)

`Young Person` MEANS Governor "Young Person" 16 FALSE (LIST)

-- Valid charity
`Jersey Animal Welfare` MEANS `Registered Charity` "Jersey Animal Welfare" "CH001" Active (LIST `advancement of animal welfare`, `advancement of education`) (LIST `Jane Smith`)

-- Charity with invalid governor
`Problem Charity` MEANS `Registered Charity` "Problem Charity" "CH002" Active (LIST `advancement of education`) (LIST `John Doe (bankrupt)`)

-- Suspended charity
`Suspended Charity` MEANS `Registered Charity` "Suspended Charity" "CH003" (Suspended "Financial irregularities") (LIST `advancement of health`) (LIST `Jane Smith`)

-- =============================================================================
-- SECTION 5: Tests
-- =============================================================================

-- Governor eligibility tests
#EVAL `the governor is an adult` `Jane Smith`
#EVAL `the governor is an adult` `Young Person`
#EVAL `the person can be a governor` `Jane Smith`
#EVAL `the person can be a governor` `John Doe (bankrupt)`
#EVAL `the person can be a governor` `Bob Jones (with conviction)`
#EVAL `the person can be a governor` `Young Person`

-- Charity validity tests
#EVAL `the charity is valid` `Jersey Animal Welfare`
#EVAL `the charity is valid` `Problem Charity`
#EVAL `the charity is valid` `Suspended Charity`

-- Test filing obligation scenarios

-- Happy path: charity files on time
#TRACE `the annual return obligation` `Jersey Animal Welfare` AT 0 WITH
    PARTY `the Charity` DOES `file the annual return` AT 30

-- Suspended charity: no filing required
#TRACE `the annual return obligation` `Suspended Charity` AT 0 WITH

-- Late filing: notice issued, then charity corrects
#TRACE `the annual return obligation` `Jersey Animal Welfare` AT 0 WITH
    PARTY `the Commissioner` DOES `issue a Required Steps Notice` AT 70
    PARTY `the Charity` DOES `correct the deficiencies` AT 90

Requirements

  1. Charities have names, purposes, governors, and financial records
  2. Purposes must be from an approved list
  3. Governors must be adults without disqualifying convictions
  4. Registered charities must file annual returns within 60 days of year-end
  5. Late filing triggers a Required Steps Notice

Step 1: Define Types

Start by modeling the domain:

-- Charitable purposes (from legislation)
DECLARE Purpose IS ONE OF
    `prevention or relief of poverty`
    `advancement of education`
    `advancement of religion`
    `advancement of health`
    `advancement of animal welfare`
    other HAS description IS A STRING

-- Governor of a charity
DECLARE Governor
    HAS name IS A STRING
        age IS A NUMBER
        isBankrupt IS A BOOLEAN
        convictions IS A LIST OF Conviction

Key design decisions:

  1. Use natural language field names: `the governor's name` reads like legal text
  2. Use enumerations for fixed categories: Prevents typos and invalid values
  3. Use lists for multiple items: governors, purposes, convictions

Step 2: Define Eligibility Rules

Rules for who can be a governor and what makes a valid charity:

-- A governor must be an adult
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `is adult` IF governor's age >= 18

-- Check for disqualifying convictions
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `has disqualifying conviction` IF
    any (GIVEN c YIELD c's isSpent EQUALS FALSE) (governor's convictions)

-- Combined eligibility check
GIVEN governor IS A Governor
GIVETH A BOOLEAN
DECIDE `can be governor` IF
    `is adult` governor
    AND NOT governor's isBankrupt
    AND NOT `has disqualifying conviction` governor

Key patterns:

  1. Simple predicates: `is adult`
  2. Using any with predicates: checking for disqualifying convictions
  3. Combining conditions: using AND and NOT

Note: These functions require IMPORT prelude for any, all, etc.


Step 3: Define Regulative Rules

The filing obligations:

-- Annual return filing obligation
GIVEN charity IS A RegisteredCharity
GIVETH A DEONTIC Actor Action
`annual return obligation` MEANS
    IF charity's status EQUALS Active
    THEN
        PARTY Charity charity
        MUST `file annual return`
        WITHIN 60
        HENCE FULFILLED
        LEST
            PARTY Commissioner
            MUST `issue Required Steps Notice` 30
            WITHIN 14
            HENCE `correction period` charity
            LEST BREACH BY Commissioner BECAUSE "failed to issue notice"
    ELSE FULFILLED

Key patterns:

  1. Actor and Action types: Define who can act and what actions exist
  2. Conditional obligations: Only active charities must file
  3. Chained obligations: Non-compliance triggers Commissioner action
  4. Clear blame assignment: BREACH BY ... BECAUSE ...

Step 4: Create Test Data

-- Valid governor
validGovernor MEANS Governor "Jane Smith" 45 FALSE (LIST)

-- Governor with issues
bankruptGovernor MEANS Governor "John Doe" 50 TRUE (LIST)

-- Valid charity
validCharity MEANS RegisteredCharity
    "Jersey Animal Welfare"
    "CH001"
    Active
    (LIST `advancement of animal welfare`, `advancement of education`)
    (LIST validGovernor)
    (LIST FinancialRecord 2023 50000 45000)
    365

Create governors and charities with various characteristics for testing.


Step 5: Test Everything

Unit Tests with #EVAL

#EVAL `is adult` validGovernor              -- TRUE
#EVAL `can be governor` validGovernor       -- TRUE
#EVAL `can be governor` bankruptGovernor    -- FALSE
#EVAL `is valid charity` validCharity       -- TRUE

Scenario Tests with #TRACE

-- Happy path: charity files on time
#TRACE `annual return obligation` validCharity AT 0 WITH
    PARTY (Charity validCharity) DOES `file annual return` AT 30
-- Result: FULFILLED

-- Late filing: notice issued, then charity corrects
#TRACE `annual return obligation` validCharity AT 0 WITH
    PARTY Commissioner DOES `issue Required Steps Notice` 30 AT 70
    PARTY (Charity validCharity) DOES `correct deficiencies` AT 90
-- Result: FULFILLED

Organizing Code with Sections

Use sections (§) to organize larger files:

§ `Charity Registration System`

§§ `Type Definitions`
-- Types go here

§§ `Eligibility Rules`
-- Eligibility functions go here

§§ `Filing Obligations`
-- Regulative rules go here

§§ `Tests`
-- Test cases go here

Sections create a hierarchy:

  • § - Top-level section
  • §§ - Sub-section
  • §§§ - Sub-sub-section

Best Practices

1. Start with Types

-- ✅ Good: Clear domain model
DECLARE Application
    HAS applicant IS A LegalEntity
        purposes IS A LIST OF Purpose
        documents IS A LIST OF Document

2. Small, Focused Functions

-- ✅ Good: Single responsibility
DECIDE `is adult` IF person's age >= 18
DECIDE `is not bankrupt` IF NOT person's isBankrupt

-- Combine them
DECIDE `can be governor` IF
    `is adult` person
    AND `is not bankrupt` person

3. Test Every Path

-- Happy path
#EVAL `can be governor` validGovernor        -- TRUE

-- Error cases
#EVAL `can be governor` bankruptGovernor     -- FALSE
#EVAL `can be governor` minorGovernor        -- FALSE

4. Use Descriptive Names

-- ✅ Good: Clear, readable names
DECIDE `charity meets filing requirements` IF ...

-- ❌ Bad: Cryptic names
DECIDE check1 IF ...

5. Document Complex Logic

-- The charity test requires:
-- 1. All purposes must be from the statutory list (Art 5)
-- 2. The charity must provide public benefit (Art 7)
-- 3. All governors must be fit and proper (Art 19)
DECIDE `meets charity test` IF ...

Debugging Checklist

When something doesn't work:

Error Likely Cause Fix
"Type not in scope" Type not declared Add DECLARE before use
"Unexpected 's" Missing parentheses length (x's field) not length x's field
"Expected BOOLEAN" Wrong type in condition Check IF conditions return BOOLEAN
"Not enough arguments" Missing function args Count parameters in GIVEN
"Indentation error" Inconsistent spacing Align all fields under HAS

Where to Go Next

Immediate Next Steps

  1. Advanced Course - Complex patterns, real legislation, multi-instrument integration

  2. Tutorials - Task-focused guides:

    • Building web forms
    • LLM integration
    • Contract automation
  3. Practice - Try encoding a real document:

    • Your employment contract
    • Your lease agreement
    • A regulation you work with

Reference Materials

Example Code

Explore the examples in the repository:

  • jl4/examples/legal/ - Real legal documents
  • jl4/examples/ok/ - Working syntax examples
  • jl4/experiments/ - Experimental features

Summary: What You've Learned

  • GIVEN, PARTY, MUST
  • IF conditions
  • WITHIN deadlines
  • HENCE and LEST consequences
  • DECLARE with HAS for records
  • IS ONE OF for enumerations
  • Field access with 's

Module 3: Control Flow

  • IF/THEN/ELSE
  • CONSIDER pattern matching
  • AND, OR, NOT operators
  • List operations

Module 4: Functions

  • GIVEN and GIVETH
  • DECIDE and MEANS
  • WHERE for local definitions
  • Recursion

Module 5: Regulative Rules

  • MUST, MAY, SHANT
  • HENCE, LEST
  • PROVIDED conditions
  • RAND and ROR combinators
  • #TRACE testing

Module 6: Putting It Together

  • Project structure
  • Best practices
  • Debugging

Congratulations! 🎉

You've completed the L4 Foundation Course. You now have the skills to:

  • Model legal entities and relationships
  • Write legal rules and eligibility criteria
  • Create contracts with obligations and consequences
  • Test your models with simulations

Next recommended step: Try the Advanced Course to learn about real regulatory schemes, cross-cutting concerns, and production patterns.