diff --git a/.gitignore b/.gitignore index 09ae1ea4..76ac9878 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,6 @@ proptest-regressions/ /roadmap.html # prolog-mcp session files (server writes ./prolog-sessions relative to cwd) -prolog-sessions/ +# ...except the checked-in seed knowledge base, which agents load at session start. +prolog-sessions/* +!prolog-sessions/kb.pl diff --git a/prolog-sessions/kb.pl b/prolog-sessions/kb.pl new file mode 100644 index 00000000..6d6677c1 --- /dev/null +++ b/prolog-sessions/kb.pl @@ -0,0 +1,84 @@ +sleep(A) :- + wasm_generic:host_rpc(sleep(A)). +delay(A) :- + wasm_generic:host_rpc(delay(A)). +console_log(A) :- + wasm_generic:host_rpc(console_log(A)). +js_eval(A,B) :- + wasm_generic:host_rpc(js_eval(A,B)). +js_eval_json(A,B) :- + wasm_generic:host_rpc(js_eval_json(A,B)). +future(A,B) :- + wasm_generic:host_rpc(future(A,B)). +await_any(A,B,C) :- + wasm_generic:host_rpc(await_any(A,B,C)). +future_cancel(A) :- + wasm_generic:host_rpc(future_cancel(A)). +crate(improvise_core,'crates/improvise-core','Model, View, Workbook, formatting; no UI/IO'). +crate(improvise_formula,'crates/improvise-formula','formula parser, AST, parse_formula'). +crate(improvise_io,'crates/improvise-io','improv save/load, CSV/JSON import; no UI/commands'). +crate(improvise_command,'crates/improvise-command','command/effect layer + semantic App state; no ratatui'). +crate(improvise_main,src,'ratatui TUI rendering, draw loop, clap CLI'). +layer(model,improvise_core). +layer(view,improvise_core). +layer(formula,improvise_formula). +layer(io,improvise_io). +layer(command,improvise_command). +layer(rendering,improvise_main). +forbidden(improvise_core,ui). +forbidden(improvise_core,io). +forbidden(improvise_io,ui). +forbidden(improvise_io,commands). +forbidden(improvise_command,ratatui). +forbidden(improvise_command,crossterm). +location(add_keybinding,'crates/improvise-command/src/command/keymap.rs','default_keymaps()'). +location(add_command,'crates/improvise-command/src/command/cmd/registry.rs','default_registry()'). +location(add_effect,'crates/improvise-command/src/ui/effect.rs','impl Effect'). +location(formula_eval,'crates/improvise-core/src/model/types.rs','eval_formula / eval_expr'). +location(cell_storage,'crates/improvise-core/src/model/cell.rs','DataStore'). +location(category_behavior,'crates/improvise-core/src/model/category.rs','Category'). +location(view_axis_logic,'crates/improvise-core/src/view/types.rs','View'). +location(grid_layout,'crates/improvise-core/src/view/layout.rs','GridLayout'). +location(improv_format,'crates/improvise-io/src/persistence/improv.pest','PEG grammar, source of truth'). +location(number_display,'crates/improvise-core/src/format.rs',format_f64). +location(cli_args,'src/main.rs',clap). +location(import_logic,'crates/improvise-io/src/import/wizard.rs','ImportPipeline'). +location(frame_layout,'src/draw.rs','draw()'). +location(app_state_modes,'crates/improvise-command/src/ui/app.rs','App, AppMode'). +pipeline_step(1,keypress,keymap_lookup). +pipeline_step(2,keymap_lookup,cmd_execute). +pipeline_step(3,cmd_execute,effect_list). +pipeline_step(4,effect_list,effect_apply). +pure(cmd_execute). +mutating(effect_apply). +only_mutation_site('Effect::apply(&mut App)'). +invariant(cellkey_sorted,'CellKey coords always sorted by category; build via CellKey::new/with/without'). +invariant(display_rounding,'format_f64 is render-only; never feed rounded values back into eval'). +invariant(fixedpoint_eval,'recompute_formulas iterates to stability; circular -> CellValue::Error(\"circular\")'). +invariant(indexmap_order,'IndexMap insertion order is load-bearing for persistence'). +invariant(no_model_add_item,'No Model::add_item; use Workbook facade or category_mut().add_item()'). +invariant(stale_layout,'app.layout rebuilds only after a whole effect batch; prepend RebuildLayout when needed'). +invariant(minibuffer_spine,'Seven text-entry modes built by TextEntry builder in keymap.rs; SearchMode hand-written'). +doctrine(bug_first,'write a failing test demonstrating the bug before fixing it'). +doctrine(unit_over_e2e,'prefer small unit tests over integration/e2e'). +doctrine(suite_speed,'workspace suite must stay under 2 seconds'). +doctrine(coverage,'aim ~80% line/branch on logic; skip ratatui render paths'). +doctrine(test_contract,'test the observable contract, not the internal storage'). +doctrine(proptest_cases,'keep proptest at default 256 cases; constrain strategies instead of brute force'). +tracker(beads,bd,'bd ready / bd show / bd update --claim / bd close; no TodoWrite or markdown TODOs'). +session_close(1,'file issues for remaining work'). +session_close(2,'run quality gates if code changed'). +session_close(3,'update issue status'). +session_close(4,'git merge origin/main, bd dolt push, git push'). +session_close(5,'clean up stashes and pruned branches'). +session_close(6,'verify committed AND pushed'). +session_close(7,'hand off context'). +crate_of_layer(A,B) :- + layer(A,B). +may_depend_on(A,B) :- + crate(A,C,D), \+forbidden(A,B). +where(A,B,C) :- + location(A,B,C). +before_fixing(A,B) :- + A=C,doctrine(bug_first,B). +