Rules System ============ A rule system should be able to evaluate conditions and perform actions, which include continuing to process rules, or stopping. The conditions will need to access configuration, exclusions, and tracking data. - A constraint on total tracking time, "do not spend more than 4 hours on x". - A constraint that only allows certain tags to be used together, to prevent client 1 from being billed for project 2. - A constraint that only allows multiples of 15-minute intervals. Ref: http://martinfowler.com/bliki/RulesEngine.html Instead of configuration, a rules system stores various settings and configuration data as rules. There are several different types of rules, which are loaded at launch time, and applied at various times during execution. Some rules can be manipulated at the command line ('exclusions'), but most will require editing the rules file. It is not intended that new users edit the rules file, therefore some rules are automatically maintained from the command line. The rules are a mechanism to apply late-bound logic and data to various functions. Whenever data changes, the rule system is run, which will run each rule in turn, if it applies, going from top to bottom in the rules file. There are no chained rules, but errors will terminate rule processing and program execution. As much functionality as possible is to be deferred to the rules. Format ------ The rules are written in a UTF8 text file, in a known location. Other rules files may be included: import /path/to/other/rule/file The syntax of rules is Python-like, in that indentation is significant. Types of Rules -------------- There are several different types of rules, for example there is the rule that defines all exclusions: define exclusions: ... There is a rule that contains all the general configuration data: define configuration: name1 value1 group1: group2: name2 value2 There are general rules triggered by changes to the data: define rule one: ... There are rules that define tags and their metadata: define tag "tag1": ... Rule Type: Exclusions --------------------- Because exclusions are resolved at run time, and only when needed, they should be stored in a form very close to the command line syntax, with no expansion. For example: $ timew define workweek mon - fri Should be stored in a rule, whose purpose is to return a set of exclusion intervals: define exclusions: workweek mon,tue,wed,thu,fri Further definitions will build on this rule: $ timew define workday start 8:30am Yields a combined: define exclusions: workweek mon,tue,wed,thu,fri workday start 8:30am Possible exclusions include: $ timew define holidays eng-USA $ timew define week mon-fri $ timew define day start 8:30am $ timew define day end 1730 $ timew define day tue end 3pm Yielding: define exclusions: holidays eng-USA work 2015-11-26 week mon,tue,wed,thu,fri day: start 8:30am end 1730 tue end 3pm If you want to track your lunch breaks, then you would make a tag for it, and track it like any other project. If you do not want to track that time, add an exclusion for it. Rule Type: General ------------------ There are rules triggered by changes to the data. In this example, rule 'one' is a constraint that prevents the value 'foo' from exceeding three. It is triggered by a change to 'foo', which is a DOM reference, and can prevent the update by failing: define rule one: tagset tag1 if foo > 3: error "The value of 'foo' may not exceed 3." Note that this rule is defined as applying to the tagset 'tag1'. Rule Type: Tag -------------- A defined tag is a way to associate metadata with a tag, such as a description and start/end dates for use: define tag "tag1": description "Description of tag1" start 2016-01-01 end 2016-06-30 budget 20 hours per week budget 400 hours total overlap yes Rule Type: Configuration ------------------------ Configuration settings are stored in the 'configuration' rule, which uses a hierarchy for grouping: define configuration: name1 value1 group1: group2: name2 value2 In the example, value2 can be referred to by it's normalized name 'group1.group2.name2'. An example is logging: define configuration: logging: file: /path/to/log/file categories: a b c !d Rule Type: Color Theme ---------------------- A color theme is defined by a rule, and consists of color definitions for various report and feedback elements: define color-theme: description "A monochrome, 256-color theme" color: today "black on rgb521" ... palette: 1 "white on red" 2 "white on blue" ... The palette group is a list (more is better) of themed colors for use when auto- coloring tags. Built-in Functions ------------------ There are several built-in functions, which may be used by rules: error("...") Logs, emits and terminates warning("...") Logs, emits and continues info("...") Logs, emits and continues log("...") Logs and continues sum_week("tag1") Sums minutes in the current week for "tag1" --- Raw Notes --- - Need to distinguish between regular time and over time, with different rates and limits. - The general form is: $ timew define A B C define A B C - A nice feature would be to define a ':keyword' using the rules, which would replace the notion of macros/aliases. - While there are no plans to add hooks, there could be rules that are triggered by events in a similar manner: define rule on_start: ... define rule on_stop: ... - Policy support involves things like: - warn after 40 hrs/wk - cut off tracking a tag at x hrs/wk - auto-tag intervals that exceed 40 hrs/wk - auto-tag intervals during exclusion time