framework: separate concerns