Skip to content

Commit bc9ba9b

Browse files
Jonathan D.A. Jewellclaude
andcommitted
feat: integrate glambot into fleet ecosystem
Add .bot_directives/ with per-bot constraint files matching the standard pattern from echidna/language-bridges. Add Logtalk findings bridge in bot-integration/src/ for Hypatia neurosymbolic learning loop integration, enabling pattern detection across repos for presentation debt, fleet-wide patterns, accessibility regressions, and SEO coverage gaps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6c129b6 commit bc9ba9b

File tree

9 files changed

+206
-0
lines changed

9 files changed

+206
-0
lines changed

.bot_directives/README.scm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
;; .bot_directives — per-bot rules and constraints
3+
;; Media-Type: application/vnd.bot-directives+scm
4+
5+
(bot-directives
6+
(version "1.0")
7+
(notes
8+
"Repo-specific bot constraints."
9+
"Bots must follow these directives in addition to global policies."))

.bot_directives/echidnabot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "echidnabot")
4+
(scope "formal verification and fuzzing")
5+
(allow ("analysis" "fuzzing" "proof checks"))
6+
(deny ("write to core modules" "write to analyzers"))
7+
(notes "May open findings; code changes require explicit approval"))

.bot_directives/finishbot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "finishbot")
4+
(scope "release readiness")
5+
(allow ("release checklists" "docs updates" "metadata fixes"))
6+
(deny ("code changes without approval"))
7+
(notes "Focus on polish, licensing, and packaging"))

.bot_directives/glambot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "glambot")
4+
(scope "presentation + accessibility + SEO + machine-readability")
5+
(allow ("docs" "readme badges" "accessibility fixes" "seo improvements" "git-seo metadata"))
6+
(deny ("logic changes" "dependency updates"))
7+
(notes "Self-scan: glambot validates its own presentation quality"))

.bot_directives/rhodibot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "rhodibot")
4+
(scope "rsr-compliance")
5+
(allow ("metadata" "docs" "repo-structure checks"))
6+
(deny ("destructive edits without approval"))
7+
(notes "Auto-fix allowed only for formatting in docs and metadata"))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "robot-repo-automaton")
4+
(scope "automated fixes")
5+
(allow ("low-risk automated edits"))
6+
(deny ("core logic changes without approval"))
7+
(notes "Only apply fixes backed by explicit rule approval"))

.bot_directives/seambot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "seambot")
4+
(scope "integration health")
5+
(allow ("analysis" "contract checks" "docs updates"))
6+
(deny ("code changes without approval"))
7+
(notes "May add integration test suggestions"))

.bot_directives/sustainabot.scm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
(bot-directive
3+
(bot "sustainabot")
4+
(scope "eco/economic standards")
5+
(allow ("analysis" "reporting" "docs updates"))
6+
(deny ("code changes without approval"))
7+
(notes "Focus on measurement and recommendations"))
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
%% SPDX-License-Identifier: PMPL-1.0-or-later
2+
%% Glambot findings bridge for the Hypatia neurosymbolic learning loop
3+
%%
4+
%% Transforms glambot presentation findings into Logtalk facts consumable
5+
%% by the Hypatia rules engine, enabling pattern detection across repos.
6+
%%
7+
%% Finding categories:
8+
%% presentation/visual - VIS-* (badges, formatting, layout)
9+
%% presentation/accessibility - ACC-* (WCAG, ARIA, contrast)
10+
%% presentation/seo - SEO-* (metadata, descriptions, topics)
11+
%% presentation/machine-readability - MACH-* (structured data, schema.org)
12+
%% presentation/git-seo - GS-* (repo topics, description, URL)
13+
14+
:- object(glambot_findings,
15+
implements(bot_integration)).
16+
17+
:- info([
18+
version is 1:'0':'0',
19+
author is 'glambot',
20+
date is 2026-02-08,
21+
comment is 'Glambot presentation findings bridge for Hypatia learning loop'
22+
]).
23+
24+
%% ============================================================
25+
%% FINDING FACT GENERATION
26+
%% ============================================================
27+
28+
%% glambot_finding(Repo, File, RuleId, Category, Severity, Fixable)
29+
:- public(glambot_finding/6).
30+
:- dynamic(glambot_finding/6).
31+
32+
%% Parse JSON findings into Logtalk facts
33+
:- public(ingest_findings/2).
34+
ingest_findings(Repo, FindingsJson) :-
35+
json_to_findings(FindingsJson, Findings),
36+
forall(
37+
member(Finding, Findings),
38+
assert_finding(Repo, Finding)
39+
).
40+
41+
assert_finding(Repo, Finding) :-
42+
get_field(Finding, rule_id, RuleId),
43+
get_field(Finding, file, File),
44+
get_field(Finding, category, Category),
45+
get_field(Finding, severity, Severity),
46+
get_field(Finding, fixable, Fixable),
47+
assertz(glambot_finding(Repo, File, RuleId, Category, Severity, Fixable)).
48+
49+
%% ============================================================
50+
%% PATTERN DETECTION PREDICATES
51+
%% ============================================================
52+
53+
%% Detect repos with recurring presentation issues
54+
:- public(presentation_debt/2).
55+
presentation_debt(Repo, Count) :-
56+
findall(RuleId, glambot_finding(Repo, _, RuleId, _, _, _), Findings),
57+
length(Findings, Count),
58+
Count > 5.
59+
60+
%% Detect cross-repo patterns (same rule firing in 3+ repos)
61+
:- public(fleet_wide_pattern/2).
62+
fleet_wide_pattern(RuleId, Repos) :-
63+
findall(Repo,
64+
glambot_finding(Repo, _, RuleId, _, _, _),
65+
AllRepos),
66+
sort(AllRepos, Repos),
67+
length(Repos, N),
68+
N >= 3.
69+
70+
%% Detect unfixed fixable issues (low-hanging fruit)
71+
:- public(low_hanging_fruit/3).
72+
low_hanging_fruit(Repo, RuleId, File) :-
73+
glambot_finding(Repo, File, RuleId, _, _, true).
74+
75+
%% Accessibility regression detection
76+
:- public(accessibility_regression/2).
77+
accessibility_regression(Repo, Count) :-
78+
findall(RuleId,
79+
glambot_finding(Repo, _, RuleId, 'presentation/accessibility', error, _),
80+
Findings),
81+
length(Findings, Count),
82+
Count > 0.
83+
84+
%% SEO coverage gaps
85+
:- public(seo_coverage_gap/2).
86+
seo_coverage_gap(Repo, Missing) :-
87+
findall(RuleId,
88+
glambot_finding(Repo, _, RuleId, 'presentation/seo', _, _),
89+
Findings),
90+
length(Findings, Missing),
91+
Missing > 0.
92+
93+
%% ============================================================
94+
%% FLEET DISPATCH TRIGGERS
95+
%% ============================================================
96+
97+
%% Generate sustainabot alert for repos with high presentation debt
98+
:- public(sustainabot_alert/2).
99+
sustainabot_alert(Repo, Alert) :-
100+
presentation_debt(Repo, Count),
101+
Count > 10,
102+
format(atom(Alert),
103+
'Repo ~w has ~d presentation issues (high visual debt)',
104+
[Repo, Count]).
105+
106+
%% Generate finishbot trigger when glambot finds release blockers
107+
:- public(finishbot_trigger/2).
108+
finishbot_trigger(Repo, Trigger) :-
109+
glambot_finding(Repo, _, RuleId, _, error, _),
110+
format(atom(Trigger),
111+
'Glambot error ~w blocks release for ~w',
112+
[RuleId, Repo]).
113+
114+
%% ============================================================
115+
%% LEARNING LOOP FEEDBACK
116+
%% ============================================================
117+
118+
%% Record fix outcome for learning engine
119+
:- public(record_fix_outcome/4).
120+
:- dynamic(fix_outcome/4).
121+
record_fix_outcome(Repo, RuleId, Success, Timestamp) :-
122+
assertz(fix_outcome(Repo, RuleId, Success, Timestamp)).
123+
124+
%% Calculate fix success rate for a rule
125+
:- public(fix_success_rate/2).
126+
fix_success_rate(RuleId, Rate) :-
127+
findall(1, fix_outcome(_, RuleId, true, _), Successes),
128+
findall(1, fix_outcome(_, RuleId, _, _), All),
129+
length(Successes, S),
130+
length(All, A),
131+
A > 0,
132+
Rate is S / A.
133+
134+
%% ============================================================
135+
%% HELPERS
136+
%% ============================================================
137+
138+
%% Placeholder for JSON parsing (actual implementation via FFI)
139+
json_to_findings(_, []) :-
140+
write('JSON parsing requires FFI integration'), nl.
141+
142+
get_field(Finding, Key, Value) :-
143+
( is_list(Finding) ->
144+
member(Key=Value, Finding)
145+
; arg(Key, Finding, Value)
146+
).
147+
148+
:- end_object.

0 commit comments

Comments
 (0)