fix(kb): repair two unsound rules and drop captured runtime shims
Audited prolog-sessions/kb.pl, which had been appended to all session without
anyone checking it loads or reasons correctly. Four problems.
may_depend_on/2 was type-confused. It read
may_depend_on(A,B) :- crate(A,C,D), \+forbidden(A,B).
with C and D unused and B never constrained, so may_depend_on(improvise_core,
banana) succeeded. forbidden/2's second argument is a CONCERN (ui, io,
ratatui), not a crate, so the rule compared a crate against a concern and
called it a dependency check. Replaced by may_use/2 over an explicit
concern/1, plus crate_depends_on/2 facts read from the Cargo.toml files and
an illegal_dependency/2 rule that actually checks for inverted layering.
before_fixing/2 had a dead guard: `A=C` bound A to a fresh variable and
constrained nothing, so it succeeded for any first argument. It now requires
the subject to be a recorded bug fix.
The first sixteen lines were the MCP runtime's own predicates — sleep,
js_eval, future, await_any and friends — captured into the file by a
saveSession. Not project knowledge, and the reason every consult warned about
overwriting sleep/1.
Nine predicates are appended chronologically and so are scattered through the
file. Added :- discontiguous declarations rather than reordering, since the
chronological shape is what makes the file readable as a work log.
Also verified every location/3 fact still names a symbol that exists in the
tree, and that no predicate has conflicting values for the same key.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V69PGQfMJuGRmtSWpfVAqn
This commit is contained in:
+60
-24
@@ -1,19 +1,18 @@
|
||||
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)).
|
||||
% Improvise project knowledge base.
|
||||
%
|
||||
% Facts are appended chronologically as work happens, so most predicates are
|
||||
% spread through the file rather than grouped; these declarations keep that
|
||||
% shape without warnings on every consult.
|
||||
:- discontiguous crate/3.
|
||||
:- discontiguous layer/2.
|
||||
:- discontiguous location/3.
|
||||
:- discontiguous invariant/2.
|
||||
:- discontiguous doctrine/2.
|
||||
:- discontiguous work_done/3.
|
||||
:- discontiguous work_followup/3.
|
||||
:- discontiguous decision/3.
|
||||
:- discontiguous wire_carries/3.
|
||||
|
||||
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').
|
||||
@@ -85,14 +84,44 @@ 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).
|
||||
crate_of_layer(Layer,Crate) :-
|
||||
layer(Layer,Crate).
|
||||
where(What,File,Symbol) :-
|
||||
location(What,File,Symbol).
|
||||
|
||||
% The concerns a crate is allowed to touch. `forbidden/2`'s second argument is
|
||||
% a CONCERN, not a crate -- the old may_depend_on/2 conflated the two and so
|
||||
% accepted any term at all for its second argument.
|
||||
concern(ui).
|
||||
concern(io).
|
||||
concern(commands).
|
||||
concern(ratatui).
|
||||
concern(crossterm).
|
||||
|
||||
may_use(Crate,Concern) :-
|
||||
crate(Crate,_,_), concern(Concern), \+ forbidden(Crate,Concern).
|
||||
|
||||
% The real crate graph, read from the Cargo.toml files (2026-08-30).
|
||||
crate_depends_on(improvise_core,improvise_formula).
|
||||
crate_depends_on(improvise_io,improvise_core).
|
||||
crate_depends_on(improvise_io,improvise_formula).
|
||||
crate_depends_on(improvise_command,improvise_core).
|
||||
crate_depends_on(improvise_command,improvise_formula).
|
||||
crate_depends_on(improvise_command,improvise_io).
|
||||
crate_depends_on(improvise_main,improvise_core).
|
||||
crate_depends_on(improvise_main,improvise_formula).
|
||||
crate_depends_on(improvise_main,improvise_io).
|
||||
crate_depends_on(improvise_main,improvise_command).
|
||||
|
||||
depends_transitively(A,B) :- crate_depends_on(A,B).
|
||||
depends_transitively(A,B) :- crate_depends_on(A,X), depends_transitively(X,B).
|
||||
|
||||
% A dependency edge that would invert the layering.
|
||||
illegal_dependency(A,B) :-
|
||||
crate_depends_on(A,B), depends_transitively(B,A).
|
||||
|
||||
before_fixing(Bug,Step) :-
|
||||
work_done(Bug,bug_fix,_), doctrine(bug_first,Step).
|
||||
|
||||
|
||||
work_done('improvise-8tk',bug_fix,'ZZ/:wq quit even when the save failed, silently discarding the model. Save now aborts the effect batch on failure; save_to_current_path/1 returns Result<String,String>; three tests in ui/effect.rs.').
|
||||
@@ -228,3 +257,10 @@ groom_check(stale_citation,'file:line references rot; resolve each against the t
|
||||
groom_check(dissolved_premise,'grep for the pattern an issue targets before working it -- improvise-ont described 11 call sites of a pattern that no longer occurs anywhere').
|
||||
doctrine(mentions_are_not_edges,'never bulk-add dependency edges from prose mentions; direction must be read per pair, and blind addition can invert real edges or create cycles').
|
||||
work_done('backlog-groom-2026-08-30',groom,'closed improvise-ont as obsolete; raised 7 priority inversions to P2; added 2 verified dependency edges out of 21 candidates; corrected stale refs on ai7/ct5/gdl and stale assumptions on jb3/git.').
|
||||
|
||||
% ── KB hygiene (audited 2026-08-30) ─────────────────────────────────────────
|
||||
kb_issue_found(host_rpc_shims,'sleep/delay/console_log/js_eval/future/await_any/future_cancel were the MCP runtime own predicates, captured into this file by a saveSession. Removed: not project knowledge, and the source of an overwriting warning on every consult. If saveSession re-adds them, strip them again.').
|
||||
kb_issue_found(may_depend_on_type_confusion,'may_depend_on(A,B) :- crate(A,C,D), \\+forbidden(A,B). C and D were singletons and B was never constrained, so may_depend_on(improvise_core, banana) succeeded. forbidden/2 second argument is a CONCERN, not a crate. Replaced by may_use/2 over an explicit concern/1, plus real crate_depends_on/2 facts read from the Cargo.toml files.').
|
||||
kb_issue_found(before_fixing_dead_guard,'before_fixing(A,B) :- A=C, doctrine(bug_first,B). A=C bound A to a fresh variable and constrained nothing, so the rule succeeded for any first argument. Now requires work_done(Bug,bug_fix,_).').
|
||||
kb_issue_found(discontiguous,'nine predicates are appended chronologically and so are scattered; added :- discontiguous declarations rather than reordering, because the chronological shape is the point.').
|
||||
doctrine(kb_is_code,'the knowledge base is executable, so audit it like code: check rules actually reject what they should, and check location/3 symbols still exist in the tree').
|
||||
|
||||
Reference in New Issue
Block a user