Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Core is the complete free product, with no sync, collaboration or access-control

**Any change that adds or changes a node type, field, relationship, structural rule or subtype MUST follow the [node type sequence](../nodespace-docs/development/node-type-sequence.md), the same way the startup sequence is followed.** No exceptions, not even for a single field or enum value. If you started without it, STOP, follow it, and restart.

Read first: [ADR-086](../nodespace-docs/decisions/086-core-node-types-defined-once-typed-by-category.md) (defined once, registry, categories), [ADR-087](../nodespace-docs/decisions/087-lifecycle-status-is-governance-and-one-participation-rule.md) (lifecycle is governance), [ADR-089](../nodespace-docs/decisions/089-structural-rules-children-and-parent.md) (structural rules), [ADR-088](../nodespace-docs/decisions/088-ai-chat-subtypes-and-message-nodes.md) for AI chats, and [`node-types.md`](../nodespace-docs/components/node-types.md). `node-types.md` is the one per-type reference, and it is updated in the same change. Recipes are in [`creating-node-types.md`](../nodespace-docs/components/creating-node-types.md).
Read first: [ADR-086](../nodespace-docs/decisions/086-core-node-types-defined-once-typed-by-category.md) (defined once, registry, categories), [ADR-087](../nodespace-docs/decisions/087-lifecycle-status-is-governance-and-one-participation-rule.md) (lifecycle is governance), [ADR-089](../nodespace-docs/decisions/089-structural-rules-children-and-parent.md) (structural rules), [ADR-088](../nodespace-docs/decisions/088-ai-chat-subtypes-and-message-nodes.md) for AI chats, and [`node-types.md`](../nodespace-docs/components/node-types.md). `node-types.md` is the one per-type reference, and it is updated in the same change: `bun run node-types:check` (the merge gate and `test:changed`'s Rust tier) fails when its type list or a type's field table differs from the registry and the seeded core schemas. `test:changed` reads the sheet from the docs working tree; the merge gate reads the docs remote's `main`, resolved to a commit when the gate starts, so push the sheet just before `bun run merge`. Until that PR lands, a merge round without it fails the check: if the PR is ejected, re-queue it at once or revert the sheet push, and once the type change has landed, re-queue unchanged any PR the check ejected that changes no core type. A docs checkout that can't give the published sheet ends the gate as a machine fault, blaming no PR. It finds the docs repository beside the primary checkout, or at `NODESPACE_DOCS_DIR`; on a machine without one the gate prints that the stage was skipped. Recipes are in [`creating-node-types.md`](../nodespace-docs/components/creating-node-types.md).

**Decision tree:**

Expand Down Expand Up @@ -252,7 +252,7 @@ IMPORTANT SUB-AGENT INSTRUCTIONS:

> ⚠️ **The gate has two modes (`scripts/test-gate.ts`, ADR-047).**
> - **`git push` runs lint only** — scripts lint/typecheck, the design-token check, the app-version drift check, the Pro-boundary hard ban, the literal node-type comparison check and the `lifecycle_status` read check. Seconds, no lock, no tests. A push needs no long timeout.
> - **`bun run merge <PR#>` queues the PR, and the merge queue runs the full pyramid once** on exactly what lands: the queued PRs stacked onto current main. That covers every unit tier plus the daemon build, the SKILL.md and generated-TypeScript drift checks, e2e and Tauri-seam tests, and the PRs are then squash-merged. It is the only automated test run, and how PRs are merged (see step 6).
> - **`bun run merge <PR#>` queues the PR, and the merge queue runs the full pyramid once** on exactly what lands: the queued PRs stacked onto current main. That covers every unit tier plus the daemon build, the SKILL.md, generated-TypeScript and `node-types.md` drift checks, e2e and Tauri-seam tests, and the PRs are then squash-merged. It is the only automated test run, and how PRs are merged (see step 6).
>
> The merge gate holds the machine-wide **machine slot** from its first compile until it exits, so no other Rust build or Rust test run (a `test:changed` Rust tier) shares the machine with it; a merge's ticket queues ahead of those. Neither ever runs without the slot: a merge gate that can't get it within two hours fails, and a `test:changed` Rust tier that can't get it within 30 minutes stops and asks you to re-run. Every stage has a timeout, printed when it starts (`▶ rust:test … (timeout 20m)`), sized to catch hangs, not slowness: a stage that exceeds it is killed with its whole process tree and fails the gate, releasing the slot. A waiting run prints a status line every minute naming the holder's pid and worktree and how long it has held — a wait with fresh status lines is a queue, not a hang. The gate prints one line per stage; full output goes to a log file whose path it prints (and the tail, on failure). The merge gate refuses to start with under 20 GB free — every worktree's `target/` holds its own build output, so remove finished worktrees rather than letting them accumulate. Always run `bun run merge` in the background and wait for it: a queued merge can wait hours, and a command that times out looks identical to a real failure but isn't one. `bun install` installs pinned cargo-nextest and sccache into the repo's `.tools/` (`scripts/setup-rust-tooling.ts`), shared by every worktree through a `.tools` link — nothing is installed or configured outside the repository. It also writes each checkout a gitignored `.cargo/config.toml` that routes every development cargo build (bare `cargo check` included) through sccache on the gate's shared cache, with a server per checkout, so a new worktree reuses llama.cpp's C/C++ build instead of compiling it cold (Rust crates only hit within one target dir; a moved worktree needs `bun install` again); sidecar binaries never need staging or copying in. Each crate's integration tests are one test binary (`tests/it/main.rs`, one module per file): add a test file as a module there, and run one file's tests with `.tools/bin/cargo-nextest nextest run -p <crate> --test it <module>::` (nextest, not plain `cargo test`, which runs the whole binary's tests in one process). `--no-verify` is reserved for WIP Handoff Commits and non-executable diffs.

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"skill:check": "cargo run -q -p nodespace-cli --example gen_skill_md -- --check",
"gen:types": "bun run scripts/gen-types.ts",
"types:check": "bun run scripts/gen-types.ts --check",
"node-types:check": "bun run scripts/check-node-types-doc.ts",
"build:skill": "bun run skill:check && bun run scripts/build-skill.ts",
"build:pkg:macos": "bash scripts/build-pkg.sh",
"pkg:verify-gatekeeper": "bun run scripts/verify-pkg-gatekeeper.ts",
Expand Down
24 changes: 24 additions & 0 deletions packages/core/examples/dump_core_schemas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//! Prints the core node type registry and the seeded core schemas as JSON, for
//! tooling that compares them with something outside the Rust workspace.
//!
//! `types` is each [`CoreNodeType`]'s id and kind, in registry order. `schemas` is
//! [`get_core_schemas`] as it is seeded: each schema's own fields, not the
//! ones it inherits through `extends`.
//!
//! Usage: `cargo run -q -p nodespace-core --example dump_core_schemas`

use nodespace_core::models::core_schemas::get_core_schemas;
use nodespace_types::CoreNodeType;
use serde_json::json;

fn main() {
let types: Vec<_> = CoreNodeType::ALL
.into_iter()
.map(|t| json!({ "id": t.as_str(), "kind": t.kind() }))
.collect();
let dump = json!({ "types": types, "schemas": get_core_schemas() });
println!(
"{}",
serde_json::to_string_pretty(&dump).expect("the registry and schemas serialize")
);
}
Loading