Goal-Driven Agents with Contracts
CoffeeScript
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
_domain
examples/Bouncer
rzr
README.md

README.md

####Personify

Goal-Driven Agents with Contracts

Personify enables you to model software modules as Agents: autonomous, goal-oriented (teleological) [Monads](http://en.wikipedia.org/wiki/Monad_(functional_programming). Agents use Contracts to declare and enforce their behavior both at design-time and at runtime. Changes to Contracts can result in side effects such as the generation or modification of Agent artifacts (services, actors and models) or a Statement of Work, for example.

Agents have only a small number of artifacts:

* actors - the proper nouns of your system- important actors or roles
* services - the verbs of of your user stories- immutable transformation steps
* models - the nouns of your system 

Agents use a module system with a design inspired by Domain-driven design and Clean Code. Agents (modules) are fractal, that is, an Agent can be composed of an arbitrary number of sub-Agents (which could be considered as the Agent's genetic code). For more in-depth theory check out the masterclass or the whitepaper. Example Agents can be found in examples.

For a demo, let's create a simple login system: Bouncer

We start by launching the Personify REPL:

me@./examples$ personify 
> new agent Bouncer
> cd Bouncer
Bouncer> ls
- Bouncer.contract.coffee

the REPL has created the Bouncer Agent and a contract template for it, and we've changed context to the Bouncer.

Now we can draft the Bouncer's contract:

./examples/Bouncer/Bouncer.contract.coffee

Bouncer:
  purpose: "control User access"

  actors:  
    User: "User of an application"

  services:    
    signup: "create a User"      
    login: "find user or error 'Invalid User'"

  ui:
    signup: "User can signup"
    login: "User can login"

if we now run 'build' on the Personify REPL:

Bouncer> build
  building Bouncer Agent
  actors: User
  services: signup, login
  ui: signup, login

Personify will scaffold out Bouncer's artifacts based on the contract which we can now flesh-out:

./examples/Bouncer/_actors/User.contract.coffee

# User of an application
User:
  name: @string
  user: @email 
  password: @password.atleast 10
  session: @string

sample:
  good:
    name: "Stephen Strange"
    user: "drstrange"
    password: "dsdsdsdsdsdsd"
    
#

./examples/Bouncer/_services/signup.contract.coffee

# create a User

signup:      
  in: 
    user: User
  sideFX: -> @create user #! in DB

./examples/Bouncer/_services/login.contract.coffee

# find User

login:
  in: 
    user: User
  out:
    user: -> @find user or @error "User not found"

ui widgets:

./examples/Bouncer/_ui/login.jade

#login.vbox.center

  #errors

  input.text @User.user
  input.text @User.password 

  button login @click -> Bouncer.login @User
   
  Not a member?  
    a(href=#) Sign up! @click -> @changeViewTo 'signup'

./examples/Bouncer/_ui/signup.jade

#signup.vbox.center

    #errors          

    @crud @User
    button @onClick -> Bouncer.signup @User