Step 654: HiveMind job publisher model

This commit is contained in:
Bill
2026-02-17 21:57:28 -07:00
parent f4259d9864
commit 34455006a1
4 changed files with 88 additions and 0 deletions

View File

@@ -4765,4 +4765,13 @@ target_link_libraries(step653_test PRIVATE
tree_sitter_javascript tree_sitter_typescript
tree_sitter_java tree_sitter_rust tree_sitter_go)
add_executable(step654_test tests/step654_test.cpp)
target_include_directories(step654_test PRIVATE src)
target_link_libraries(step654_test PRIVATE
nlohmann_json::nlohmann_json
unofficial::tree-sitter::tree-sitter
tree_sitter_python tree_sitter_cpp tree_sitter_elisp
tree_sitter_javascript tree_sitter_typescript
tree_sitter_java tree_sitter_rust tree_sitter_go)
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)

View File

@@ -0,0 +1,29 @@
#pragma once
// Step 654: HiveMind job publisher from editor
#include <nlohmann/json.hpp>
#include <string>
using json = nlohmann::json;
struct DispatchPublishResult {
bool queuedInNexus = false;
bool publishedToTopic = false;
std::string topic;
std::string jobId;
};
class HiveMindJobPublisher {
public:
static DispatchPublishResult dispatch(const json& taskitem,
const std::string& topic = "borg/jobs/pending") {
DispatchPublishResult out;
if (!taskitem.is_object() || taskitem.value("id", "").empty()) return out;
out.jobId = taskitem.value("id", "");
out.queuedInNexus = true;
out.topic = topic;
out.publishedToTopic = !topic.empty();
return out;
}
};

View File

@@ -0,0 +1,26 @@
// Step 654: HiveMind job publisher from editor (12 tests)
#include "HiveMindJobPublisher.h"
#include <iostream>
static int p=0,f=0;
#define T(n) { std::cout<<" "<<#n<<"... "; }
#define P() { std::cout<<"PASS\n"; ++p; }
#define F(m) { std::cout<<"FAIL: "<<m<<"\n"; ++f; }
#define C(c,m) if(!(c)){F(m);return;}
static json task(){return {{"id","job-1"},{"type","refactor"}};}
void t1(){T(rejects_non_object_task);auto r=HiveMindJobPublisher::dispatch(json::array());C(!r.queuedInNexus,"should fail");P();}
void t2(){T(rejects_missing_id);auto r=HiveMindJobPublisher::dispatch({{"type","x"}});C(!r.queuedInNexus,"missing id");P();}
void t3(){T(queues_valid_job_in_nexus);auto r=HiveMindJobPublisher::dispatch(task());C(r.queuedInNexus,"queue");P();}
void t4(){T(publishes_valid_job_to_default_topic);auto r=HiveMindJobPublisher::dispatch(task());C(r.publishedToTopic,"publish");P();}
void t5(){T(default_topic_is_pending_jobs);auto r=HiveMindJobPublisher::dispatch(task());C(r.topic=="borg/jobs/pending","topic");P();}
void t6(){T(custom_topic_is_respected);auto r=HiveMindJobPublisher::dispatch(task(),"borg/jobs/custom");C(r.topic=="borg/jobs/custom","custom topic");P();}
void t7(){T(job_id_is_returned);auto r=HiveMindJobPublisher::dispatch(task());C(r.jobId=="job-1","job id");P();}
void t8(){T(empty_topic_disables_publish_flag);auto r=HiveMindJobPublisher::dispatch(task(),"");C(!r.publishedToTopic,"no publish");P();}
void t9(){T(queued_flag_true_even_with_empty_topic);auto r=HiveMindJobPublisher::dispatch(task(),"");C(r.queuedInNexus,"queued");P();}
void t10(){T(dispatched_job_keeps_topic_string);auto r=HiveMindJobPublisher::dispatch(task(),"x");C(r.topic=="x","topic string");P();}
void t11(){T(id_must_be_non_empty_string);auto r=HiveMindJobPublisher::dispatch({{"id",""}});C(!r.queuedInNexus,"empty id");P();}
void t12(){T(dispatched_job_returns_consistent_flags);auto r=HiveMindJobPublisher::dispatch(task());C(r.queuedInNexus&&r.publishedToTopic,"flags");P();}
int main(){std::cout<<"Step 654: HiveMind job publisher\n";t1();t2();t3();t4();t5();t6();t7();t8();t9();t10();t11();t12();std::cout<<"\nResults: "<<p<<"/"<<(p+f)<<" passed\n";return f?1:0;}

View File

@@ -13456,3 +13456,27 @@ within architecture size/function constraints.
- `editor/src/Sprint39IntegrationSummary.h` (`45` <= `600`)
- Sprint 39 test files remain within test-file size guidance.
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`
### Step 654: HiveMind job publisher from editor
**Status:** PASS (12/12 tests)
Adds a dispatch publisher model for `whetstone_dispatch_to_hivemind` style flow,
covering taskitem validation, nexus queue signal, and MQTT topic publish signal.
**Files added:**
- `editor/src/HiveMindJobPublisher.h` - dispatch publisher model
- `editor/tests/step654_test.cpp` - 12 tests for dispatch validation/publish flow
**Files modified:**
- `editor/CMakeLists.txt` - `step654_test` target
**Verification run:**
- `cmake -S editor -B editor/build-native` - PASS
- `cmake --build editor/build-native --target step654_test step653_test` - PASS
- `./editor/build-native/step654_test` - PASS (12/12)
- `./editor/build-native/step653_test` - PASS (8/8) regression coverage
**Architecture gate check:**
- `editor/src/HiveMindJobPublisher.h` (`29` <= `600`)
- `editor/tests/step654_test.cpp` within test-file size guidance (`26` lines)
- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`