-
Notifications
You must be signed in to change notification settings - Fork 1
Phase 4 jitos kernel #140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Phase 4 jitos kernel #140
Conversation
- Create new crates: echo-sched, echo-kernel, echo-tasks, echo-workers, echo-net - Create new binaries: jitosd, jitos-cli - Implement basic Scheduler and Kernel core - Implement jitosd daemon with HTTP API placeholder - Update rmg-core to derive Serde for graph types - Update Cargo.toml workspace members - Ensure all new crates have required metadata, READMEs, and docs - Restore dev-dependencies and features in rmg-core
- Add reqwest dependency to rmg-viewer - Refactor scene.rs to expose store_to_wire_graph - Initialize Tokio runtime in rmg-viewer main - Spawn background task in App::new to poll jitosd /rmg_state - Update viewer state with fetched graph
- Define SwsId and SwsContext in echo-kernel - Implement create_sws (fork), apply_rewrite_sws, collapse_sws (merge) - Expose SWS endpoints in jitosd (create, collapse)
- Add SLAPS v2 data models - Add HTN Method v1 data models - Implement basic Planner for loading methods and matching intent - Add serde_yaml dependency
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughThis PR expands the JITOS workspace by introducing seven new crates (echo-sched, echo-kernel, echo-tasks, echo-workers, echo-net) and two binaries (jitosd daemon, jitos-cli), adds serialization support to rmg-core types, and integrates async daemon polling into rmg-viewer. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as JITOS CLI/Client
participant Daemon as Jitosd Daemon<br/>(HTTP API)
participant Kernel as Kernel<br/>(Arc<Mutex>)
participant Sched as Scheduler
participant Planner as Planner<br/>(HTN)
participant SWS as SWS Pool
CLI->>Daemon: POST /intent (Slaps)
activate Daemon
Daemon->>Kernel: submit_intent(slaps)
activate Kernel
Kernel->>Planner: plan(slaps)
activate Planner
Planner-->>Kernel: planning result
deactivate Planner
Kernel->>SWS: create_sws()
activate SWS
SWS-->>Kernel: SwsId
deactivate SWS
Kernel-->>Daemon: SwsId
deactivate Kernel
Daemon-->>CLI: 200 OK (SwsId)
deactivate Daemon
Daemon->>Sched: run() [concurrent]
activate Sched
Sched->>Sched: tick() every interval
Sched->>Kernel: [future task execution]
deactivate Sched
sequenceDiagram
participant Viewer as RMG Viewer
participant PollTask as Background Poll Task<br/>(Tokio)
participant Daemon as Jitosd Daemon
participant Kernel as Kernel
Note over Viewer,Kernel: Async Runtime Initialization
Viewer->>Viewer: create Tokio runtime
activate Viewer
Viewer->>PollTask: spawn background task
activate PollTask
deactivate Viewer
loop Every interval
PollTask->>Daemon: GET /rmg_state
activate Daemon
Daemon->>Kernel: get_rmg_state()
activate Kernel
Kernel-->>Daemon: GraphStore (serialized JSON)
deactivate Kernel
Daemon-->>PollTask: 200 OK (GraphStore)
deactivate Daemon
PollTask->>PollTask: deserialize GraphStore
PollTask->>PollTask: convert to WireGraph
PollTask->>Viewer: send via graph_rx channel
activate Viewer
Viewer->>Viewer: update wire_graph & graph
deactivate Viewer
end
deactivate PollTask
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra scrutiny:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| tokio::spawn(async { | ||
| axum::serve(listener, app) | ||
| .await | ||
| .expect("HTTP server failed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move axum listener into spawned task
The HTTP server task is spawned with tokio::spawn(async { axum::serve(listener, app)… }), which borrows listener and app from the stack. tokio::spawn requires a 'static future, so this code does not compile because the future holds non‑'static references to those locals, preventing the daemon from building or starting. Make the task async move (or otherwise move the values) so the server can run.
Useful? React with 👍 / 👎.
- Add echo-tasks dependency to echo-kernel and jitosd - Implement Kernel::submit_intent using Planner - Add /intent endpoint to jitosd - Connect SLAPS parsing to SWS creation - Implement epoch tracking for Kernel (system_epoch) and SwsContext (base_epoch)
c8bd98f to
1503874
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 45
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/rmg-viewer/src/scene.rs (1)
236-259: Public function lacks mandatory documentation and contains dead code.Two violations:
Missing rustdoc: Per project learnings, all public APIs must document intent, invariants, and usage. Your new
store_to_wire_graphfunction is completely naked.Useless binding (line 245):
let _ = node;serves no purpose. Either use the binding or delete this line.Based on learnings, public API documentation is mandatory.
Apply this diff:
+/// Converts a `GraphStore` into a wire-format `WireGraph` for rendering. +/// +/// Iterates over all nodes and edges in the store, constructing corresponding +/// `RenderNode` and `RenderEdge` entries with empty payloads. Node and edge +/// identifiers are converted to u64 representation for wire transmission. +/// +/// # Arguments +/// * `store` - The graph store to convert +/// +/// # Returns +/// A `WireGraph` ready for serialization or rendering pub fn store_to_wire_graph(store: &GraphStore) -> WireGraph { let mut nodes = Vec::new(); let mut edges = Vec::new(); for (id, node) in store.iter_nodes() { + let _ = node; // FIXME: payload conversion not yet implemented nodes.push(echo_graph::RenderNode { id: id_to_u64(&id.0), kind: echo_graph::NodeKind::Generic, data: echo_graph::NodeData { raw: Vec::new() }, }); - let _ = node; }
♻️ Duplicate comments (3)
bins/jitos-cli/README.md (1)
1-3: Another stub README. Is this a pattern?Identical problem to
crates/echo-kernel/README.md: a three-line stub for a binary that presumably has actual functionality. A CLI tool especially needs:
- Command synopsis: What commands/subcommands exist?
- Usage examples: Common workflows
- Installation instructions: How to build and run
If you're going to ship placeholder READMEs, at least add a TODO comment acknowledging the debt.
bins/jitosd/src/main.rs (2)
69-73: Missingasync move— this code does not compile.Already flagged in a previous review. The spawned future borrows
listenerandappfrom the stack, buttokio::spawnrequires'static. Addasync moveto transfer ownership.- tokio::spawn(async { + tokio::spawn(async move {
84-88: Response lacksContent-Type: application/jsonheader.
get_rmg_state()returns a JSON string, but returning(StatusCode, String)sends it astext/plain. Useaxum::Jsonor set the header explicitly.-async fn get_rmg_state_handler(State(kernel): State<Arc<Mutex<Kernel>>>) -> impl IntoResponse { - let kernel_locked = kernel.lock().await; - let state = kernel_locked.get_rmg_state(); - (StatusCode::OK, state) +async fn get_rmg_state_handler( + State(kernel): State<Arc<Mutex<Kernel>>>, +) -> impl IntoResponse { + let kernel_locked = kernel.lock().await; + let state = kernel_locked.get_rmg_state(); + (StatusCode::OK, [(axum::http::header::CONTENT_TYPE, "application/json")], state) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (33)
Cargo.toml(1 hunks)bins/jitos-cli/Cargo.toml(1 hunks)bins/jitos-cli/README.md(1 hunks)bins/jitos-cli/src/main.rs(1 hunks)bins/jitosd/Cargo.toml(1 hunks)bins/jitosd/README.md(1 hunks)bins/jitosd/src/main.rs(1 hunks)crates/echo-kernel/Cargo.toml(1 hunks)crates/echo-kernel/README.md(1 hunks)crates/echo-kernel/src/lib.rs(1 hunks)crates/echo-net/Cargo.toml(1 hunks)crates/echo-net/README.md(1 hunks)crates/echo-net/src/lib.rs(1 hunks)crates/echo-sched/Cargo.toml(1 hunks)crates/echo-sched/README.md(1 hunks)crates/echo-sched/src/lib.rs(1 hunks)crates/echo-tasks/Cargo.toml(1 hunks)crates/echo-tasks/README.md(1 hunks)crates/echo-tasks/src/lib.rs(1 hunks)crates/echo-tasks/src/method.rs(1 hunks)crates/echo-tasks/src/planner.rs(1 hunks)crates/echo-tasks/src/slaps.rs(1 hunks)crates/echo-workers/Cargo.toml(1 hunks)crates/echo-workers/README.md(1 hunks)crates/echo-workers/src/lib.rs(1 hunks)crates/rmg-core/Cargo.toml(1 hunks)crates/rmg-core/src/graph.rs(1 hunks)crates/rmg-core/src/ident.rs(1 hunks)crates/rmg-core/src/record.rs(2 hunks)crates/rmg-viewer/Cargo.toml(1 hunks)crates/rmg-viewer/src/app.rs(6 hunks)crates/rmg-viewer/src/main.rs(1 hunks)crates/rmg-viewer/src/scene.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Every source file must start with exactly
// SPDX-License-Identifier: Apache-2.0and// © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots>
Files:
crates/rmg-core/src/record.rscrates/rmg-viewer/src/main.rscrates/rmg-viewer/src/scene.rscrates/rmg-core/src/graph.rscrates/echo-tasks/src/lib.rscrates/echo-net/src/lib.rscrates/rmg-viewer/src/app.rscrates/rmg-core/src/ident.rsbins/jitos-cli/src/main.rsbins/jitosd/src/main.rscrates/echo-workers/src/lib.rscrates/echo-tasks/src/planner.rscrates/echo-kernel/src/lib.rscrates/echo-tasks/src/method.rscrates/echo-tasks/src/slaps.rscrates/echo-sched/src/lib.rs
🧠 Learnings (6)
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Applies to packages/echo-core/src/**/*.rs : Public APIs across crates (`rmg-core`, `rmg-ffi`, `rmg-wasm`) must carry rustdoc comments explaining intent, invariants, and usage
Applied to files:
crates/echo-net/README.mdcrates/echo-kernel/README.mdcrates/echo-workers/README.mdcrates/echo-kernel/Cargo.tomlcrates/echo-tasks/src/lib.rscrates/echo-net/src/lib.rscrates/echo-sched/README.mdcrates/echo-workers/Cargo.tomlcrates/echo-tasks/README.mdcrates/echo-workers/src/lib.rscrates/echo-tasks/Cargo.tomlcrates/echo-kernel/src/lib.rscrates/echo-net/Cargo.tomlcrates/echo-sched/Cargo.tomlcrates/echo-tasks/src/slaps.rscrates/echo-sched/src/lib.rscrates/rmg-core/Cargo.toml
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Consult `docs/architecture-outline.md` before touching runtime code in `packages/echo-core`
Applied to files:
crates/echo-net/README.mdcrates/echo-kernel/README.mdcrates/echo-kernel/Cargo.tomlcrates/echo-net/Cargo.tomlcrates/echo-sched/Cargo.toml
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Applies to **/*.rs : Every source file must start with exactly `// SPDX-License-Identifier: Apache-2.0` and `// © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots>`
Applied to files:
crates/echo-workers/README.mdcrates/echo-tasks/README.md
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Applies to packages/echo-core/src/**/*.rs : Tests and benchmarks are mandatory for runtime changes once the harness exists
Applied to files:
crates/echo-kernel/Cargo.tomlcrates/echo-workers/Cargo.tomlcrates/echo-tasks/Cargo.tomlcrates/echo-kernel/src/lib.rsCargo.tomlcrates/echo-sched/Cargo.tomlcrates/echo-sched/src/lib.rscrates/rmg-core/Cargo.toml
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Applies to packages/echo-core/src/**/*.rs : Respect determinism: preferably use Echo PRNG instead of random seeds without mitigation
Applied to files:
crates/echo-kernel/Cargo.tomlcrates/echo-sched/Cargo.tomlcrates/rmg-core/Cargo.toml
📚 Learning: 2025-12-10T11:22:22.785Z
Learnt from: CR
Repo: flyingrobots/echo PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-10T11:22:22.785Z
Learning: Formatting is auto-fixed with `cargo fmt` by default; set `ECHO_AUTO_FMT=0` to run check-only
Applied to files:
crates/echo-workers/Cargo.tomlcrates/echo-tasks/Cargo.tomlcrates/echo-net/Cargo.tomlcrates/echo-sched/Cargo.tomlcrates/rmg-core/Cargo.toml
🧬 Code graph analysis (5)
crates/rmg-viewer/src/app.rs (1)
crates/rmg-viewer/src/scene.rs (2)
store_to_wire_graph(236-259)scene_from_wire(178-229)
bins/jitos-cli/src/main.rs (1)
bins/jitosd/src/main.rs (1)
main(38-82)
bins/jitosd/src/main.rs (2)
crates/echo-kernel/src/lib.rs (1)
new(51-66)crates/echo-sched/src/lib.rs (1)
new(21-26)
crates/echo-kernel/src/lib.rs (2)
crates/echo-sched/src/lib.rs (2)
new(21-26)run(32-41)bins/jitosd/src/main.rs (1)
format(66-66)
crates/echo-sched/src/lib.rs (1)
crates/echo-kernel/src/lib.rs (2)
new(51-66)run(72-76)
🪛 LanguageTool
bins/jitos-cli/README.md
[grammar] ~3-~3: Il y a peut-être une erreur ici
Context: ...https://github.com/flyingrobots --> # JITOS CLI
(QB_NEW_FR)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Security Audit
- GitHub Check: Cargo Audit (stable)
🔇 Additional comments (22)
crates/echo-tasks/Cargo.toml (1)
14-20: Dependencies look reasonable.The dependency set for an HTN task planner is appropriate:
- Serde stack for serialization (YAML, JSON)
thiserror+anyhowfor structured error handlingtracingfor observabilityVersion specifiers use ranges, allowing patch updates automatically. This is sensible for a new crate.
crates/echo-workers/Cargo.toml (1)
1-14: Scaffolding looks correct.Empty dependencies section is acceptable for Phase 0 crate setup. Ensure dependencies are added before implementing actual worker runtime logic.
crates/echo-tasks/src/lib.rs (1)
1-2: License headers verified.Correct SPDX and copyright headers present.
crates/echo-sched/Cargo.toml (1)
1-18: Manifest structure is acceptable.Dependencies and metadata are properly configured for the scheduler crate.
crates/rmg-viewer/src/scene.rs (1)
231-234: Refactoring is correct.Delegating to the new
store_to_wire_graphhelper is a clean separation of concerns.bins/jitos-cli/src/main.rs (1)
1-2: License headers verified.Correct SPDX and copyright headers present.
crates/rmg-core/src/graph.rs (1)
13-13: Serde derives are correctly applied and transitive serializability is satisfied.All contained types implement the required traits:
NodeIdderivesserde::Serializeandserde::Deserialize(ident.rs:15),NodeRecordderives both (record.rs:17), andEdgeRecordderives both (record.rs:32). The addition toGraphStorewill compile without issues and integrates cleanly with the daemon HTTP API.crates/rmg-core/src/record.rs (2)
17-23: LGTM — serde derives cleanly extend serialization support.The
NodeRecordstruct correctly derivesserde::Serializeandserde::Deserialize. TheOption<Bytes>payload will serialize properly given thebytescrate'sserdefeature is enabled in your dependency configuration.
32-44: LGTM —EdgeRecordserialization is correctly implemented.Same pattern as
NodeRecord. The nested identifier types (EdgeId,NodeId,TypeId) must also derive serde traits for this to compile—which, per the related changes inident.rs, they do.bins/jitosd/Cargo.toml (1)
1-26: LGTM — manifest structure is sound.Package metadata is complete, path dependencies are correctly specified relative to the workspace, and feature selections (e.g.,
tokio = { version = "1.0", features = ["full"] }) are appropriate for a daemon binary.crates/rmg-viewer/src/app.rs (2)
184-187: LGTM — non-blocking receive correctly drains the channel.The
while let Ok(...)pattern withtry_recv()properly drains all pending messages without blocking the UI event loop. Updating bothwire_graphandgraphviascene_from_wireon each received message is correct.
81-101: Runtime is correctly initialized —tokio::spawnwill not panic.
main()establishes a Tokio runtime at lines 32–35 and callsrt.enter()to establish the runtime context guard before instantiatingApp::new()at line 38. The spawned task will execute within this active runtime without panic.However, the hardcoded daemon address
http://127.0.0.1:3000/rmg_stateand polling interval remain inflexible and should be configurable. Consider also replacingeprintln!with thetracingcrate for consistency with the rest of the codebase.Likely an incorrect or invalid review comment.
crates/rmg-core/src/ident.rs (4)
14-17: LGTM —NodeIdserde derives are correctly added.The
Hashtype ([u8; 32]) serializes natively with serde. The derive ordering (std traits → serde traits) is consistent and the multi-line formatting improves readability.
23-24: LGTM —TypeIdserde derives.Consistent with
NodeId.
27-28: LGTM —EdgeIdserde derives.Consistent with
NodeIdandTypeId.
51-52: Intentional omission of serde onCompactRuleIdis well-documented.The doc comment at lines 46-50 explicitly states "These handles are never serialized; they are purely an in-process acceleration." This is correct design—process-local handles should not leak across serialization boundaries.
bins/jitosd/src/main.rs (1)
1-6: License header and module documentation are correct.SPDX identifier and copyright line match the coding guidelines for
.rsfiles.crates/echo-sched/src/lib.rs (2)
1-2: License header: Compliant.The SPDX license identifier and copyright notice are correctly placed at the top of the file as per the coding guidelines.
43-51: No action required —is_multiple_ofis stable.The
u64::is_multiple_of()method was stabilized in Rust 1.87 (released December 2024) and is fully available on stable Rust without any feature gates. This code compiles and runs without issues.Likely an incorrect or invalid review comment.
crates/echo-tasks/src/planner.rs (1)
1-2: License header: Compliant.The SPDX license identifier and copyright notice are correctly placed.
crates/echo-tasks/src/method.rs (1)
1-2: License header: Compliant.The SPDX license identifier and copyright notice are correctly placed.
crates/echo-kernel/src/lib.rs (1)
1-2: License header: Compliant.The SPDX license identifier and copyright notice are correctly placed.
| [dependencies] | ||
| clap = { version = "4.0", features = ["derive"] } | ||
| anyhow = "1.0" | ||
| tokio = { version = "1.0", features = ["full"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Tokio "full" features are overkill for a CLI.
Line 17 enables all Tokio features with features = ["full"]. This is lazy and bloats your binary with unused functionality:
- Process management? Probably not.
- Signal handling? Maybe, but do you use it?
- File I/O? Depends on your CLI's actual needs.
- Time utilities? Maybe.
Be selective. Analyze what your CLI actually uses and specify only those features:
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
# Add "fs", "io-util", "net", etc. as neededSmaller compile times, smaller binaries, clearer intent.
🤖 Prompt for AI Agents
In bins/jitos-cli/Cargo.toml around line 17, the tokio dependency uses features
= ["full"] which unnecessarily inflates the CLI binary; replace the "full"
feature set with only the features your CLI actually needs (for example "macros"
and "rt-multi-thread" for async runtime and #[tokio::main], and add specific
features like "fs", "io-util", "net", or "time" only if your code uses file I/O,
extra I/O utilities, networking, or timing), updating the Cargo.toml features
list accordingly to reduce binary size and compile time.
| #[tokio::main] | ||
| async fn main() -> Result<()> { | ||
| let args = Args::parse(); | ||
|
|
||
| match args.cmd { | ||
| Some(Command::Status) => { | ||
| println!("Status: Online (Placeholder)"); | ||
| } | ||
| None => { | ||
| println!("JITOS CLI. Use --help for usage."); | ||
| } | ||
| } | ||
|
|
||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Placeholder CLI is structurally sound but incomplete.
The scaffolding is acceptable for Phase 0, but this Status command must eventually query the jitosd HTTP API (see bins/jitosd/src/main.rs lines 37-81 for the daemon's API server). The current placeholder output provides no value.
Do you want me to generate a proper HTTP client implementation that calls http://localhost:<port>/rmg_state or another jitosd endpoint? This would make the Status command functional and provide a template for future commands.
🤖 Prompt for AI Agents
In bins/jitos-cli/src/main.rs around lines 24 to 38, the Status command
currently prints a placeholder string instead of querying the jitosd HTTP API;
replace the placeholder with an async HTTP client call to the daemon (e.g., GET
http://localhost:<port>/rmg_state), using reqwest async and serde to deserialize
the JSON response into a small status struct, handle configurable port via CLI
flag or JITOS_PORT env var, add proper timeout and error handling (log/fail
gracefully on network or parse errors), and print a concise formatted status
summary from the returned fields.
|
|
||
| [dependencies] | ||
| echo-kernel = { path = "../../crates/echo-kernel" } | ||
| echo-tasks = { path = "../../crates/echo-tasks" } # Added dependency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Remove the redundant inline comment.
The # Added dependency comment is noise. Git history is the authoritative record of what was added and when. These "I did a thing" comments rot instantly and clutter the manifest.
-echo-tasks = { path = "../../crates/echo-tasks" } # Added dependency
+echo-tasks = { path = "../../crates/echo-tasks" }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo-tasks = { path = "../../crates/echo-tasks" } # Added dependency | |
| echo-tasks = { path = "../../crates/echo-tasks" } |
🤖 Prompt for AI Agents
In bins/jitosd/Cargo.toml around line 16, remove the redundant inline comment "
# Added dependency" after the echo-tasks dependency so the dependency line reads
only the key and path; ensure no trailing whitespace remains and save the file
so the manifest contains only the dependency declaration without the noisy
comment.
| <!-- SPDX-License-Identifier: Apache-2.0 OR MIND-UCAL-1.0 --> | ||
| <!-- © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots> --> | ||
| # JITOS Daemon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
README is effectively empty; add at least minimal usage and role description.
You’ve got the license/title, but nothing about how to run jitosd, what it serves (HTTP endpoints, ports), or its relationship to the kernel. Even a short “what it does / how to start it” section would massively reduce friction for anyone touching this crate next.
🤖 Prompt for AI Agents
In bins/jitosd/README.md around lines 1 to 3 the README is effectively empty;
add a short but useful README that states what jitosd is (its role and
relationship to the kernel), minimal usage instructions for running the daemon
(command-line invocation and any important flags or env vars), what it serves
(HTTP endpoints/ports or IPC methods and default port numbers), and a brief
example of starting it and checking status so a developer can quickly run and
verify it.
| #[clap(short, long, default_value_t = 1000)] | ||
| tick_interval: u64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code: tick_interval CLI argument is never used.
You parse tick_interval from CLI args but then Kernel::new() hardcodes its own interval (1000ms per the code snippet from echo-kernel/src/lib.rs). This is either a missed integration or vestigial code. Either wire it through or remove it.
- let kernel = Arc::new(Mutex::new(Kernel::new()));
+ let kernel = Arc::new(Mutex::new(Kernel::with_tick_interval(args.tick_interval)));Or if Kernel::new() should accept the interval:
// In echo-kernel/src/lib.rs
pub fn with_tick_interval(interval_ms: u64) -> Self { ... }🤖 Prompt for AI Agents
In bins/jitosd/src/main.rs around lines 29-30, the CLI arg tick_interval is
parsed but never used; either thread it into kernel creation or remove it. Fix
option A: pass tick_interval into the kernel constructor (add a new
Kernel::with_tick_interval(u64) or change Kernel::new to accept u64) and call
that with the parsed value; Fix option B: if the kernel should keep its
hardcoded default, delete the tick_interval field from the clap struct and any
related parsing to avoid dead code. Ensure imports and tests compile after the
change.
| tokio::spawn(async move { | ||
| loop { | ||
| // Poll the JITOS daemon | ||
| match reqwest::get("http://127.0.0.1:3000/rmg_state").await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded daemon URL is inflexible and environment-hostile.
http://127.0.0.1:3000/rmg_state is baked in. What if the daemon runs on a different port? A different host? In a container? This should be configurable via environment variable, CLI arg, or config file.
+const JITOS_DAEMON_URL: &str = "http://127.0.0.1:3000";
+// TODO: Make configurable via env var or configOr better, accept it as a parameter to App::new().
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
crates/rmg-viewer/src/app.rs around line 85: the daemon URL is hardcoded to
"http://127.0.0.1:3000/rmg_state", making the app inflexible for different
hosts/ports or containerized environments; modify App so the base daemon URL is
configurable (preferred: add a parameter to App::new(base_url: String) that is
stored on the App struct and used to build the request URL, or alternatively
read from an environment variable or CLI/config and pass it into App::new);
update the code at this line to use the stored base_url (e.g.
format!("{}/rmg_state", base_url)) when calling reqwest::get and adjust any
tests/constructors to supply the new parameter.
| break; | ||
| } | ||
| } | ||
| Err(e) => eprintln!("Failed to parse RMG state: {}", e), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Use tracing instead of eprintln! for consistency.
The rest of this codebase uses tracing for structured logging. eprintln! bypasses log levels, filtering, and any configured subscribers.
- Err(e) => eprintln!("Failed to parse RMG state: {}", e),
+ Err(e) => tracing::warn!("Failed to parse RMG state: {}", e),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Err(e) => eprintln!("Failed to parse RMG state: {}", e), | |
| Err(e) => tracing::warn!("Failed to parse RMG state: {}", e), |
🤖 Prompt for AI Agents
In crates/rmg-viewer/src/app.rs around line 93, replace the direct stderr write
using eprintln! with structured logging via tracing (e.g., tracing::error!(
"Failed to parse RMG state: {}", e )); ensure tracing is in scope (either add
use tracing::error; or call tracing::error! directly) so the error goes through
the tracing subscriber and respects log levels and filters.
| Err(_) => { | ||
| // Suppress connection errors (daemon might not be up) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent suppression of all connection errors masks debugging.
The comment says "daemon might not be up," but this catches all reqwest errors—DNS failures, TLS errors, timeouts, everything. At minimum, log at trace! or debug! level so operators can diagnose connectivity issues when needed.
- Err(_) => {
- // Suppress connection errors (daemon might not be up)
- }
+ Err(e) => {
+ tracing::trace!("Daemon poll failed (may not be running): {}", e);
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Err(_) => { | |
| // Suppress connection errors (daemon might not be up) | |
| } | |
| Err(e) => { | |
| tracing::trace!("Daemon poll failed (may not be running): {}", e); | |
| } |
🤖 Prompt for AI Agents
In crates/rmg-viewer/src/app.rs around lines 95 to 97, the Err(_) arm currently
swallows all reqwest errors silently; change this to log the error (at trace! or
debug! level) rather than suppressing it entirely so operators can diagnose
DNS/TLS/timeouts/etc. Capture the error value (e) in the Err arm and call trace!
or debug! with a short contextual message and the error (e) so the failure to
connect to the daemon is recorded without altering control flow.
| // Suppress connection errors (daemon might not be up) | ||
| } | ||
| } | ||
| tokio::time::sleep(std::time::Duration::from_millis(500)).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Hardcoded 500ms polling interval.
Magic numbers are a maintenance liability. Extract to a constant or make configurable alongside the daemon URL.
+const POLL_INTERVAL_MS: u64 = 500;
...
- tokio::time::sleep(std::time::Duration::from_millis(500)).await;
+ tokio::time::sleep(std::time::Duration::from_millis(POLL_INTERVAL_MS)).await;🤖 Prompt for AI Agents
crates/rmg-viewer/src/app.rs around line 99: the polling interval uses a
hardcoded 500ms magic number; replace it with a named constant or make it
configurable alongside the daemon URL (e.g., define a const POLL_INTERVAL_MS:
u64 = 500 at the top of the module or add a PollInterval configuration field
next to the daemon URL), update the sleep call to use
Duration::from_millis(POLL_INTERVAL_MS) or the configured value, and ensure any
tests or documentation reference the new constant/config option.
| let rt = tokio::runtime::Builder::new_multi_thread() | ||
| .enable_all() | ||
| .build()?; | ||
| let _guard = rt.enter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, check the SPDX header compliance and view the main.rs file
head -5 crates/rmg-viewer/src/main.rsRepository: flyingrobots/echo
Length of output: 259
🏁 Script executed:
# Get the full context of the runtime and event loop code
sed -n '1,50p' crates/rmg-viewer/src/main.rsRepository: flyingrobots/echo
Length of output: 905
🏁 Script executed:
# Search for tokio::spawn calls in the viewer crate
rg -n 'tokio::spawn' crates/rmg-viewer/src/Repository: flyingrobots/echo
Length of output: 126
🏁 Script executed:
# Search for event_loop and run_app patterns
rg -n -C5 'run_app|event_loop' crates/rmg-viewer/src/Repository: flyingrobots/echo
Length of output: 5452
🏁 Script executed:
# Check what's being spawned at app.rs:82
sed -n '75,95p' crates/rmg-viewer/src/app.rsRepository: flyingrobots/echo
Length of output: 999
🏁 Script executed:
# Get more context around the spawn to understand the pattern
sed -n '70,110p' crates/rmg-viewer/src/app.rsRepository: flyingrobots/echo
Length of output: 1576
🏁 Script executed:
# Check if there's any explicit task cancellation or join on shutdown
rg -n -C8 'shutdown_requested|exit' crates/rmg-viewer/src/app.rs | head -40Repository: flyingrobots/echo
Length of output: 1386
🏁 Script executed:
# Verify what rx receiver is used for and if it's properly dropped
rg -n 'graph_rx' crates/rmg-viewer/src/app.rs | head -20Repository: flyingrobots/echo
Length of output: 198
🏁 Script executed:
# Check the App struct definition to see how graph_rx is stored
sed -n '1,135p' crates/rmg-viewer/src/app.rs | tail -80Repository: flyingrobots/echo
Length of output: 2795
🏁 Script executed:
# Check if there's a proper async main or task join pattern elsewhere in similar code
rg -n 'tokio::main|tokio::spawn|JoinHandle' crates/ --type rs | grep -v rmg-viewer | head -20Repository: flyingrobots/echo
Length of output: 87
🏁 Script executed:
# Verify the event_loop.run_app() behavior - is it blocking or non-blocking?
rg -n 'run_app' crates/rmg-viewer/src/ -A2Repository: flyingrobots/echo
Length of output: 207
Spawned polling task lacks explicit cancellation; shutdown window is unguarded.
The JITOS daemon polling task spawned at app.rs:82-103 runs indefinitely in the background and depends on channel closure for clean termination. However, there's a potential race condition:
When shutdown_requested is set, event_loop.exit() is called, which returns event_loop.run_app(), drops App, and closes graph_rx. If the spawned task is mid-sleep in the 500ms polling interval when the receiver closes, the task will be abruptly terminated when the tokio runtime drops on main() exit, rather than checking tx.send() failure gracefully.
In practice this works—the task will exit one way or another—but it lacks an explicit shutdown ceremony. The pattern is unconventional for background async tasks that expect the runtime to remain alive.
Suggested fix: Store a JoinHandle to the spawned task and explicitly .await cancellation before dropping the receiver, or use tokio::select! with a cancellation token for deterministic task shutdown.
🤖 Prompt for AI Agents
In crates/rmg-viewer/src/main.rs around lines 32 to 35, the background polling
task in app.rs (lines ~82–103) is spawned without an explicit
cancellation/await, risking abrupt termination when the runtime is dropped;
capture the task's JoinHandle when spawning, arrange to signal shutdown (either
via a oneshot/cancellation token) and then await the JoinHandle (or select! on
the cancellation token inside the task) before returning from main so the task
can observe the shutdown, flush its final send attempt, and exit
deterministically rather than relying on runtime drop or channel closure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
| /// The JITOS Kernel Core. | ||
| /// Owns the system RMG(s) and manages the overall state. | ||
| pub struct Kernel { | ||
| system_rmg: GraphStore, // The canonical system RMG | ||
| system_epoch: u64, | ||
| sws_pool: HashMap<SwsId, SwsContext>, | ||
| next_sws_id: SwsId, | ||
| scheduler: Scheduler, | ||
| planner: Planner, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
No accessor for system_epoch or SWS pool introspection.
The kernel tracks system_epoch and maintains an sws_pool, but external code (including tests) has no way to query the current epoch or list active SWS IDs. This makes the kernel a black box.
+ /// Returns the current system epoch.
+ pub fn system_epoch(&self) -> u64 {
+ self.system_epoch
+ }
+
+ /// Returns an iterator over active SWS IDs.
+ pub fn active_sws_ids(&self) -> impl Iterator<Item = &SwsId> {
+ self.sws_pool.keys()
+ }
+
+ /// Returns the number of active Shadow Working Sets.
+ pub fn sws_count(&self) -> usize {
+ self.sws_pool.len()
+ }Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In crates/echo-kernel/src/lib.rs around lines 29 to 38, add public accessor
methods so callers can read the current system_epoch and inspect the SWS pool:
expose a pub fn system_epoch(&self) -> u64 that returns the current epoch, and
expose a pub fn list_sws_ids(&self) -> Vec<SwsId> (or an iterator) that returns
the keys of sws_pool so callers/tests can enumerate active SWS IDs; ensure
methods are simple, take &self, are public, and avoid cloning the full
SwsContext (only return IDs or references as appropriate).
| /// Placeholder for a simple API to submit rewrites to the system RMG directly. | ||
| #[instrument(skip(self))] | ||
| pub fn submit_rewrite(&mut self, _rewrite: String) -> Result<()> { | ||
| info!("Rewrite submitted to System RMG (placeholder)."); | ||
| // This should also advance the system_epoch | ||
| self.system_epoch += 1; | ||
| info!("System RMG epoch advanced to {}", self.system_epoch); | ||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
submit_rewrite increments epoch without doing anything.
This method logs "Rewrite submitted" and increments system_epoch, but the _rewrite parameter is completely ignored. A caller would reasonably expect their rewrite to have been... applied. Instead, they get a lie and a monotonically increasing counter.
Either implement it, or make the placeholder nature aggressively obvious:
pub fn submit_rewrite(&mut self, _rewrite: String) -> Result<()> {
- info!("Rewrite submitted to System RMG (placeholder).");
- // This should also advance the system_epoch
- self.system_epoch += 1;
- info!("System RMG epoch advanced to {}", self.system_epoch);
- Ok(())
+ // TODO: Implement rewrite application
+ anyhow::bail!("submit_rewrite is not yet implemented")
}🤖 Prompt for AI Agents
In crates/echo-kernel/src/lib.rs around lines 156 to 164, submit_rewrite
currently ignores its _rewrite parameter while claiming the rewrite was
submitted and advancing system_epoch; either implement applying the rewrite or
make the placeholder explicit. Fix options: (A) implement behavior by removing
the leading underscore, validate and apply the rewrite to the appropriate state
(e.g., call the existing rewrite application routine or update relevant fields),
log the rewrite (or a summary) and only advance system_epoch after successful
application, returning an Err on failure; or (B) keep it as a placeholder but
make it explicit by returning an Err or NotImplemented response, remove the
misleading info! log, and/or change the log to clearly state this is a no-op
placeholder (e.g., include a TODO and do not advance system_epoch). Choose one
approach and update tests/docs accordingly.
| /// Type of subtask ("method" or "primitive"). | ||
| #[serde(rename = "type")] | ||
| pub kind: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kind as String is type-unsafe nonsense.
The doc says it's "method" or "primitive", yet you've typed it as String. Nothing prevents someone from setting kind: "banana". This is begging for runtime bugs that a proper enum would catch at deserialization time.
+/// The type of a subtask.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum SubtaskKind {
+ Method,
+ Primitive,
+}
+
pub struct Subtask {
// ...
- #[serde(rename = "type")]
- pub kind: String,
+ #[serde(rename = "type")]
+ pub kind: SubtaskKind,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// Type of subtask ("method" or "primitive"). | |
| #[serde(rename = "type")] | |
| pub kind: String, | |
| /// The type of a subtask. | |
| #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] | |
| #[serde(rename_all = "lowercase")] | |
| pub enum SubtaskKind { | |
| Method, | |
| Primitive, | |
| } | |
| pub struct Subtask { | |
| /// Type of subtask ("method" or "primitive"). | |
| #[serde(rename = "type")] | |
| pub kind: SubtaskKind, | |
| } |
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||
| pub struct FailureAction { | ||
| /// Type of action (e.g., "Rollback"). | ||
| pub action: String, | ||
| /// Reference to the rollback method. | ||
| #[serde(rename = "ref")] | ||
| pub ref_: String, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
FailureAction.action should also be an enum.
Same problem as Subtask.kind. The comment says "e.g., Rollback" but nothing enforces it. Another stringly-typed time bomb.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
+pub enum FailureActionKind {
+ Rollback,
+ Retry,
+ Abort,
+ // Extend as needed
+}
+
pub struct FailureAction {
- pub action: String,
+ pub action: FailureActionKind,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #[derive(Debug, Clone, Serialize, Deserialize)] | |
| pub struct FailureAction { | |
| /// Type of action (e.g., "Rollback"). | |
| pub action: String, | |
| /// Reference to the rollback method. | |
| #[serde(rename = "ref")] | |
| pub ref_: String, | |
| } | |
| #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] | |
| #[serde(rename_all = "PascalCase")] | |
| pub enum FailureActionKind { | |
| Rollback, | |
| Retry, | |
| Abort, | |
| // Extend as needed | |
| } | |
| #[derive(Debug, Clone, Serialize, Deserialize)] | |
| pub struct FailureAction { | |
| /// Type of action (e.g., "Rollback"). | |
| pub action: FailureActionKind, | |
| /// Reference to the rollback method. | |
| #[serde(rename = "ref")] | |
| pub ref_: String, | |
| } |
| fn find_matching_method(&self, slaps: &Slaps) -> Option<&Method> { | ||
| // Simple exact intent match | ||
| // In the future: implement robust `applicable_when` logic | ||
| self.methods.values().find(|m| m.intent == slaps.intent) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
O(n) linear scan with non-deterministic match selection.
find_matching_method iterates over values() and returns the first match. HashMap iteration order is non-deterministic, so if multiple methods match the same intent, you get whichever one the hash gods decide. This is especially egregious given that Applicability has a priority field that is completely ignored.
Either:
- Index methods by intent for O(1) lookup.
- Collect all matches and sort by
priority. - Both.
fn find_matching_method(&self, slaps: &Slaps) -> Option<&Method> {
- // Simple exact intent match
- // In the future: implement robust `applicable_when` logic
- self.methods.values().find(|m| m.intent == slaps.intent)
+ // Collect all matching methods and select by priority (lower is better)
+ self.methods
+ .values()
+ .filter(|m| m.intent == slaps.intent)
+ .min_by_key(|m| m.applicable_when.priority)
}🤖 Prompt for AI Agents
In crates/echo-tasks/src/planner.rs around lines 53–57, find_matching_method
currently does a single linear scan over self.methods and returns the first
intent match, which is non-deterministic and ignores Applicability.priority;
change it to collect all methods whose intent == slaps.intent, sort those
matches by their Applicability.priority (highest priority first) and
deterministic tie-breaker (e.g., method name or insertion order), then return
the top result. For better performance also consider building an index
(HashMap<Intent, Vec<MethodId>> or HashMap<Intent, Vec<&Method>>) at planner
construction for O(1) intent lookups and apply the same priority-sort on the
indexed list before returning the winner.
This Pull Request represents a significant leap towards establishing the JITOS Causal Operating System by implementing Phases 0 through 4 of
the defined roadmap. The existing Go-based TASKS architecture has been conceptually migrated to Rust, with
echoserving as the foundationakernel.
Summary of Implemented Phases:
Phase 0: Repo + Minimal Kernel Skeleton
echo-tasks(a worktree ofecho) and scaffold the core kernel components.echo-sched,echo-kernel,echo-tasks,echo-workers,echo-net.jitosd(daemon),jitos-cli(CLI client).echo-schedimplements a basic tick-based scheduler.echo-kernelimplements the coreKernelstruct, owning the system'sGraphStoreand delegating to the scheduler.jitosdruns theecho-kerneland exposes a basic HTTP API.rmg-coreupdated to deriveserde::Serializeandserde::Deserializefor core graph types (NodeId,TypeId,EdgeId,NodeRecord,EdgeRecord,GraphStore) to enable state serialization.Cargo.tomlmetadata (description, license, repository, readme, keywordcategories) and basic documentation.
Phase 1: Echo Viewer Wired to the Daemon
rmg-viewerto fetch live RMG state fromjitosd.rmg-viewer'sCargo.tomlupdated withreqwestandtokio.rmg-viewer/src/scene.rsrefactored to exposestore_to_wire_graphforGraphStoretoWireGraphconversion.rmg-viewer/src/main.rsupdated to initialize atokioruntime.rmg-viewer/src/app.rsmodified to spawn a backgroundtokiotask that pollsjitosd's/rmg_stateendpoint every 500ms andupdates the viewer's graph.
Phase 2: Add SWS (Shadow Working Sets)
echo-kernel.SwsId(u64) andSwsContextstructs defined inecho-kernel.echo-kernel'sKernelstruct extended withsws_poolandnext_sws_id.echo-kernel:create_sws(forks the system RMG),apply_rewrite_sws(placeholder),collapse_sws(mergSWS into system RMG).
jitosdHTTP API extended with endpoints:POST /sws/create,POST /sws/:id/collapse.Phase 3:
echo-tasks(SLAPS + HTN Logic)crates/echo-tasks/Cargo.tomlupdated withserde_yaml,thiserror,anyhow,tracing.crates/echo-tasks/src/slaps.rsimplements theSlaps(Intent Definition Language) data model.crates/echo-tasks/src/method.rsimplements theMethod(HTN Method) data model.crates/echo-tasks/src/planner.rsimplements a basicPlannerstruct capable of loading methods and performing a simplisticintent match to suggest a plan (currently returns a string).
Phase 4: Integrate
echo-tasksinto Kernelecho-kernel/Cargo.tomlandbins/jitosd/Cargo.tomlupdated to includeecho-tasksas a dependency.echo-kernel'sKernelstruct now holds an instance ofecho_tasks::Planner.echo-kernelimplementssubmit_intent(slaps: Slaps)which uses thePlannerto generate a plan description and then createsnew SWS for the task.
jitosdHTTP API extended withPOST /intentendpoint, which takes aSlapsJSON payload and triggers theKernel::submit_intentAPI.Rationale:
This work lays the essential groundwork for the JITOS Causal OS. By migrating core planning and execution logic to Rust within the
echoecosystem, we gain determinism, performance, and safety. The integration of SLAPS and HTN provides a structured, extensible, and auditable w
to manage mixed-intelligence workflows, paving the way for the envisioned "conversational OS." The live viewer integration dramatically
improves introspection and debugging capabilities for the kernel state.
Testing Notes:
cargo test) for existingechocrates pass.Future Work / Next Steps:
echo-tasksto generate concrete DAGs of primitives.GraphStoreto support more efficient delta/overlay SWS.