chore: scaffold Compass OSS monorepo — toolchain, workspace, compass.v1 pipeline, CI - #1
Conversation
…v1 pipeline, CI proto/devenv/moon toolchain; cargo+bun workspace; the compass.v1 contract as a single buf codegen pipeline (Rust prost/tonic + TS connect-es, checked in and drift-gated); compass-proto crate (permissive) + compassd skeleton (AGPL) + generated TS client + a minimal SolidJS UI. CI foundation: hk pre-push, the compass-ci image, and a Woodpecker bootstrap pipeline; moon run :ci green. Closes SEA-1027
This stack of pull requests is managed by Graphite. Learn more about stacking. |
📝 WalkthroughWalkthroughInitial Compass monorepo scaffold adding the ChangesCompass Monorepo Initial Scaffold
Sequence Diagram(s)sequenceDiagram
participant UI as SolidJS UI
participant client as createDaemonClient
participant transport as gRPC-Web transport
participant daemon as compassd
UI->>client: createDaemonClient(baseUrl)
client->>transport: createGrpcWebTransport({ baseUrl })
transport-->>client: Transport
client-->>UI: CompassClient
UI->>transport: getDaemonInfo()
transport->>daemon: GetDaemonInfo request
daemon-->>transport: GetDaemonInfoResponse { version, api_version }
transport-->>UI: response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR scaffolds the Compass OSS monorepo: it wires up the proto/devenv/moon toolchain, a Cargo + Bun workspace, the
Confidence Score: 4/5Safe to merge with the hk.pkl glob fix applied; the broken pre-push globs are a local developer-experience regression, not a CI correctness issue. The pre-push buf-lint and drift steps in hk.pkl silently skip on every proto change because the glob proto/**/*.proto does not match crates/compass-proto/proto/…. Developers editing the proto schema get no local gate; CI (compass-proto:ci) still catches it, so no broken code can land undetected — but the fast-feedback loop the hook exists to provide is absent for the most important class of change. hk.pkl — the buf-lint and drift step globs need updating to crates/compass-proto/proto/**/*.proto Important Files Changed
Reviews (5): Last reviewed commit: "fix(toolchain): provide exact Rust via f..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 16
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.envrc:
- Around line 8-10: Add rust-toolchain.toml to the direnv watch list in .envrc
so toolchain pin changes re-enter automatically. Update the existing watch setup
near the current watch_file .prototools entry to include rust-toolchain.toml as
another watched input. Keep the change aligned with the devenv/proto install
behavior so edits to either pin file refresh the shell.
In `@apps/ui/moon.yml`:
- Around line 19-21: The dev task in moon.yml is missing the same prerequisites
as typecheck/build/test, so `moon run ui:dev` can start before dependencies or
generated clients are ready. Update the `dev` task definition to depend on
`install` and `proto:gen`, matching the gating used by the other UI tasks so the
`dev` path is reliable on a fresh checkout.
In `@apps/ui/src/App.tsx`:
- Around line 4-8: Trim the block comment in App by removing the
roadmap/planning language and the multi-paragraph explanation; keep only a
short, non-obvious rationale or delete it entirely. Update the comment near the
walking-skeleton rendering logic so it does not restate what the UI shows or
mention future phases like “M3 UI work,” and keep any remaining note brief and
focused on why this component exists.
In `@apps/ui/src/client.test.ts`:
- Around line 4-6: The createDaemonClient test is only checking that
getDaemonInfo exists, which duplicates coverage and does not verify the
UI-specific forwarding behavior. Update the test around createDaemonClient in
client.test.ts to assert that the caller-provided baseUrl is actually passed
into the transport factory or reflected in the created client, so it fails if
the URL is hard-coded or ignored. Use createDaemonClient and its transport
wiring as the symbols to target, and make this a regression test for the
URL-passing behavior.
In `@apps/ui/tsconfig.json`:
- Around line 2-14: The apps/ui tsconfig is currently applying Bun types to all
source code because it includes src, which leaks bun:test types into browser app
code. Split test-only typing out of this config by creating a separate test
tsconfig or narrower include for the Bun-based test files, and keep the main app
tsconfig focused on browser code only; use the existing tsconfig.json settings
and the client.test.ts entry point to guide the split.
In `@ci/ci-toolchain.nix`:
- Around line 85-106: The CI toolchain image is missing gate binaries that are
already available in the local devenv setup, so add the missing tools to the
paths list used by the CI image. Update the ci-toolchain setup to include
actionlint, nixfmt-rfc-style, shellcheck, shfmt, and taplo alongside the
existing moon/Rust/contract tools, so any moon run :ci task that invokes them
can succeed in Woodpecker as well.
- Around line 89-97: CI is using nixpkgs-provided Rust binaries instead of the
repo-pinned toolchain, so update the Rust setup in ci-toolchain.nix to source
the compiler, clippy, and rustfmt from the rust-toolchain.toml pinned version
rather than pkgs.rustc/pkgs.clippy/pkgs.rustfmt. Keep the existing cargo plugins
and sccache, but make sure moon run :ci resolves the same Rust version locally
and in CI by referencing the toolchain configuration used for the rest of the
repo.
In `@ci/moon.yml`:
- Around line 24-31: The Biome task inputs only track TypeScript files, so TSX
edits in the Solid UI components can be missed and the cached result reused
incorrectly. Update the biome task in moon config to include TSX file patterns
alongside the existing TypeScript and JSON inputs, keeping the task name and
command unchanged so `moon run :ci` invalidates properly when `.tsx` files
change.
- Around line 17-23: The deny gate cache key is missing Cargo manifest files, so
Moon can reuse stale `cargo deny check` results after workspace edits. Update
the `deny` task inputs in `moon.yml` to include the workspace Cargo manifests
alongside `deny.toml` and `Cargo.lock`, using the `deny` task definition as the
place to add `Cargo.toml` and any relevant workspace manifest paths.
In `@ci/woodpecker/ci.yml`:
- Around line 15-16: The ci step in the Woodpecker pipeline is using the latest
image tag without forcing a fresh pull, so it may reuse a cached runner image
instead of the newly published one. Update the ci job definition in
ci/woodpecker/ci.yml for the ghcr.io/sealedsecurity/compass-ci:latest image by
enabling image pulling on the ci step so the runner always fetches the newest
build produced by ci/publish-ci-image.sh.
In `@crates/compass-daemon/src/main.rs`:
- Around line 1-8: Trim the module-level docs in the compassd entry point so
they only give a brief, non-roadmap rationale for the file, and remove the
SEA-1025 milestone reference. Update the top-of-file doc comment in main.rs to
avoid restating obvious implementation details or planning metadata; keep it
short and focused on why this module exists, not what the daemon does or future
delivery phases.
In `@crates/compass-proto/src/lib.rs`:
- Around line 1-11: Trim the crate-level docs in the lib.rs docs block to keep
only the non-obvious contract and licensing rationale, and remove the
roadmap/planning reference to SEA-1025. Update the top-of-crate documentation so
it no longer restates what the crate contains in multiple paragraphs; keep the
concise why-focused summary tied to the generated gRPC contract and the
permissive licensing carve-out.
In `@deny.toml`:
- Around line 11-26: The global licenses allow list currently permits AGPL
everywhere, which bypasses the intended dependency fence. Remove "AGPL-3.0-only"
from the top-level allow list in deny.toml and instead add crate-specific
exceptions for the workspace-owned AGPL packages only, using the appropriate
cargo-deny per-crate/package override entries so third-party AGPL dependencies
remain blocked.
In `@proto/compass/v1/compass.proto`:
- Around line 1-12: Trim the top-of-file banner in compass.v1 so it only
describes the stable contract intent and versioning, and remove rollout/planning
details like M1, SEA-1024, “full surface,” and generated-client/breaking-gate
notes. Update the proto comment block near the file header to keep only the
non-obvious contract context that must live with compass.proto, and move any
roadmap or behavior-defining prose into external docs or PR context.
In `@proto/moon.yml`:
- Around line 52-61: The drift check in the moon task should not depend on the
gen task, because gen writes directly into tracked generated directories and can
leave the repo mutated if generation fails. Update the drift flow so it
generates into a temporary output location and compares that against the
checked-in trees, keeping moon run :ci read-only. Use the drift task and gen
task definitions as the main anchors when refactoring.
- Around line 62-67: The proto workspace ci task is missing the breaking-change
gate, so `moon run proto:ci` can succeed without validating wire compatibility.
Update the `ci` task in `moon.yml` to include the `breaking` task alongside the
existing `lint` and `drift` dependencies, using the `breaking` task definition
already present in the same file, so the repo readiness check covers proto
compatibility.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4078b052-beb7-4319-905d-421e62be8dd7
⛔ Files ignored due to path filters (7)
Cargo.lockis excluded by!**/*.lockbun.lockis excluded by!**/*.lockcrates/compass-proto/src/gen/compass/v1/compass.v1.rsis excluded by!**/gen/**crates/compass-proto/src/gen/compass/v1/compass.v1.tonic.rsis excluded by!**/gen/**devenv.lockis excluded by!**/*.lockhk.pklis excluded by!**/*.pklpackages/compass-client/src/gen/compass/v1/compass_pb.tsis excluded by!**/gen/**
📒 Files selected for processing (50)
.config/nextest.toml.envrc.gitignore.moon/workspace.yml.prototoolsAGENTS.mdCODEOWNERSCONTRIBUTING.mdCargo.tomlLICENSELICENSE-APACHELICENSE-MITREADME.mdapps/ui/index.htmlapps/ui/moon.ymlapps/ui/package.jsonapps/ui/src/App.tsxapps/ui/src/client.test.tsapps/ui/src/client.tsapps/ui/src/index.tsxapps/ui/tsconfig.jsonapps/ui/vite.config.tsbiome.jsonbuf.gen.yamlbuf.yamlci/ci-toolchain.nixci/moon.ymlci/publish-ci-image.shci/woodpecker/ci.ymlcrates/compass-daemon/Cargo.tomlcrates/compass-daemon/moon.ymlcrates/compass-daemon/src/main.rscrates/compass-proto/Cargo.tomlcrates/compass-proto/moon.ymlcrates/compass-proto/src/lib.rscrates/compass-proto/tests/contract.rsdeny.tomldevenv.nixdevenv.yamldocs/architecture/build-and-ci.mdpackage.jsonpackages/compass-client/moon.ymlpackages/compass-client/package.jsonpackages/compass-client/src/index.test.tspackages/compass-client/src/index.tspackages/compass-client/tsconfig.jsonproto/compass/v1/compass.protoproto/moon.ymlrust-toolchain.tomlrustfmt.toml
There was a problem hiding this comment.
20 issues found across 57 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="ci/ci-toolchain.nix">
<violation number="1" location="ci/ci-toolchain.nix:92">
P2: CI currently uses nixpkgs Rust binaries instead of the repository-pinned Rust toolchain, so compiler and lint behavior can drift from local development. Use the same Rust version source as `rust-toolchain.toml` for CI parity.</violation>
</file>
<file name="apps/ui/src/client.test.ts">
<violation number="1" location="apps/ui/src/client.test.ts:4">
P3: This test only checks that a method exists; it should assert that `createDaemonClient()` actually uses the provided `baseUrl` so regressions in URL wiring are caught.</violation>
</file>
<file name="ci/woodpecker/ci.yml">
<violation number="1" location="ci/woodpecker/ci.yml:16">
P2: CI image is unpinned (`latest`), making builds non-reproducible and vulnerable to silent image drift. Pin to an immutable digest (or fixed version tag) for deterministic CI.</violation>
</file>
<file name="crates/compass-daemon/Cargo.toml">
<violation number="1" location="crates/compass-daemon/Cargo.toml:16">
P3: Unused `tokio` direct dependency adds avoidable compile surface and maintenance noise. Remove it until async runtime APIs are actually used.</violation>
</file>
<file name="ci/publish-ci-image.sh">
<violation number="1" location="ci/publish-ci-image.sh:85">
P1: `GHCR_TOKEN` is stripped for build/scan but not for the publish step. This can allow pushing an image built under a different environment than the one that was scanned.</violation>
</file>
<file name=".config/nextest.toml">
<violation number="1" location=".config/nextest.toml:11">
P2: `ci` profile JUnit config is never activated by checked-in test commands. This leaves report generation effectively dead, so CI flaky/timing ingestion won’t receive `junit.xml`.</violation>
</file>
<file name="packages/compass-client/package.json">
<violation number="1" location="packages/compass-client/package.json:8">
P2: The package entrypoint exports a `.ts` source file instead of built JS. Publish/export compiled output (and types) so non-TS runtimes can consume `@compass/client` reliably.</violation>
</file>
<file name="devenv.nix">
<violation number="1" location="devenv.nix:59">
P2: PATH order is reversed for workspace JS tooling in the dev shell. Appending `node_modules/.bin` allows host-global binaries to override repo-pinned versions, causing local/CI drift.</violation>
</file>
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2fe9d48d34
ℹ️ 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".
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/compass-daemon/src/main.rs (1)
14-31: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
compassdexits immediately instead of serving the contract.After the startup log and banner,
mainreturnsOk(()), so there is no long-lived process bound to the local transport and no implementation forCompassService/GetDaemonInfo. As shipped, the binary is not actually a daemon yet.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/compass-daemon/src/main.rs` around lines 14 - 31, The main entrypoint in main should not return immediately after logging startup; it needs to start and await the daemon/runtime that serves the contract over the local transport. Update the main function to wire up the CompassService implementation, ensure CompassService/GetDaemonInfo is actually handled, and keep the process alive by awaiting the server or event loop instead of ending with Ok(()).
♻️ Duplicate comments (1)
proto/moon.yml (1)
56-62: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
driftstill rewrites the checked-in generated trees before validating them.Because
driftdepends ongen,moon run proto:cimutates/crates/compass-proto/src/genand/packages/compass-client/src/genbefore diffing them. If generation fails or is interrupted, the repo can still be left partially rewritten instead of keeping the gate read-only.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@proto/moon.yml` around lines 56 - 62, The drift target still invokes the gen task first, so the CI check can modify the checked-in generated outputs before validating them. Update the proto:ci flow around the drift and gen targets so drift only compares existing files and does not run generation itself; keep generation as a separate explicit step, and adjust the drift script to fail on differences without mutating crates/compass-proto/src/gen or packages/compass-client/src/gen.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ci/moon.yml`:
- Around line 66-69: The workflow-existence guard in the moon CI script is too
brittle because the combined ls check in the actionlint gate only succeeds when
both .github/workflows globs match, so actionlint may be skipped even if
workflows exist. Update the guard in the script that wraps actionlint to detect
workflow files more robustly by checking for any matching .yml or .yaml file
independently, then run actionlint whenever at least one workflow file is
present.
In `@proto/compass/v1/compass.proto`:
- Around line 1-4: Update the banner comment in compass.v1 to match the actual
proto surface: it should describe only the existing unary GetDaemonInfo RPC in
the CompassService, and remove any mention of a server-streaming event channel
until that RPC is actually defined. Keep the contract wording aligned with the
symbols in this file so the schema documentation reflects the current service
accurately.
In `@rust-toolchain.toml`:
- Around line 1-3: The Rust version is currently described as pinned in
rust-toolchain.toml, but CI still sources Rust from nixpkgs, so the workspace
and image can drift. Update the CI toolchain setup in ci/ci-toolchain.nix to use
the same Rust pin as rust-toolchain.toml, or if that split is intentional,
revise the comment so it no longer claims parity. Keep the change aligned with
the Rust toolchain selection logic rather than the individual version text.
---
Outside diff comments:
In `@crates/compass-daemon/src/main.rs`:
- Around line 14-31: The main entrypoint in main should not return immediately
after logging startup; it needs to start and await the daemon/runtime that
serves the contract over the local transport. Update the main function to wire
up the CompassService implementation, ensure CompassService/GetDaemonInfo is
actually handled, and keep the process alive by awaiting the server or event
loop instead of ending with Ok(()).
---
Duplicate comments:
In `@proto/moon.yml`:
- Around line 56-62: The drift target still invokes the gen task first, so the
CI check can modify the checked-in generated outputs before validating them.
Update the proto:ci flow around the drift and gen targets so drift only compares
existing files and does not run generation itself; keep generation as a separate
explicit step, and adjust the drift script to fail on differences without
mutating crates/compass-proto/src/gen or packages/compass-client/src/gen.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 18822ab8-d15c-49be-b345-f2b67358cba6
⛔ Files ignored due to path filters (2)
bun.lockis excluded by!**/*.lockpackages/compass-client/src/gen/compass/v1/compass_pb.tsis excluded by!**/gen/**
📒 Files selected for processing (21)
.envrcAGENTS.mdCargo.tomlapps/ui/moon.ymlapps/ui/package.jsonapps/ui/src/App.tsxapps/ui/src/client.tsapps/ui/tsconfig.jsonapps/ui/tsconfig.test.jsonci/ci-toolchain.nixci/moon.ymlci/woodpecker/ci.ymlcrates/compass-daemon/moon.ymlcrates/compass-daemon/src/main.rscrates/compass-proto/src/lib.rsdeny.tomlpackages/compass-client/package.jsonpackages/compass-client/src/index.tsproto/compass/v1/compass.protoproto/moon.ymlrust-toolchain.toml
There was a problem hiding this comment.
3 issues found across 23 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="ci/moon.yml">
<violation number="1" location="ci/moon.yml:69">
P2: Workflow-existence check is incorrect and can silently skip actionlint. Use a matcher that succeeds when either extension exists.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f069c106e
ℹ️ 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".
…ent hygiene Wire the buf breaking gate and nix/shell/toml/yaml lint tasks into moon :ci; add /bin/sh, coreutils, and those linters to the CI image; strip planning metadata from source comments (regenerating the TS client); make compassd async; scope the cargo-deny AGPL allowance to first-party crates via exceptions; plus cache-input, PATH, and typecheck-split fixes.
0f069c1 to
9b09844
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b09844dff
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06dc972aab
ℹ️ 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".
PR review found the Rust half of `moon run :ci` broke on a clean machine: the dev shell never provided cargo/rustc (proto pins only bun/node/moon, and ~/.cargo/bin was never on PATH), and the CI image lacked a C linker. fenix now builds the exact rust-toolchain.toml toolchain for both the dev shell and the CI image; stdenv.cc supplies cc. rust-toolchain.toml is the single source of truth (or rustup on the no-nix path).
Two review-loop test additions on the durable sink-ack handler (PR #43), both defending an invariant the first-round suite left to inference: - runnerhub/commit_frame_test.go: a hub UPDATE-arm test symmetric to the posted happy path. The ConversationUpdated dispatch arm was proven only at the comms layer + via the fake recorder, never through Hub.commitFrame itself; this asserts the arm forwards under the bound account with the key threaded and returns the UPDATE's own row id (m-99) — a mis-wire that returned the posted id or the wrong frame now fails here (verified red). - runnerhub/auth_test.go: TestAccountTokenRejectedOnEveryRPCPath gains a commit_conversation_frame subtest, replacing two dead duplicate relay_comms_call slots (Go suffixed #1/#2, so they ran but covered nothing new). The new RPC's door-interceptor wiring is now asserted Unauthenticated for an account token, closing the door-coverage gap. Refs SEA-1364 Co-Authored-By: seal <noreply@sealedsecurity.com>

proto/devenv/moon toolchain; cargo+bun workspace; the compass.v1 contract as a single buf codegen pipeline (Rust prost/tonic + TS connect-es, checked in and drift-gated); compass-proto crate (permissive) + compassd skeleton (AGPL) + generated TS client + a minimal SolidJS UI. CI foundation: hk pre-push, the compass-ci image, and a Woodpecker bootstrap pipeline; moon run :ci green.
Closes SEA-1027
Summary by cubic
Scaffolded the Compass OSS monorepo with the toolchain, workspace, the
compass.v1contract pipeline, and CI. Delivers typed clients (Rust/TS), an async daemon skeleton, and a minimal UI, withmoon run :cias the single local/CI gate. Addresses SEA-1027.New Features
bufpipeline forcompass.v1: generates Rust (prost/tonic) incrates/compass-protoand TS (connect-es) inpackages/compass-client(@compass/client); schema lives undercrates/compass-proto/proto(permissive license); code is checked in and drift‑gated; breaking-change gate againstmain.compass-daemonscaffold (compassd) with an async entrypoint and startup logging; contract smoke tests prove generated client/server stubs exist.@compass/uithat renders the service name and uses@compass/client; includes a gRPC‑Web client helper via@connectrpc/connect-web.protopinsbun,node, andmoon; Rust now comes fromfenixusingrust-toolchain.tomlin both the dev shell and CI image (with a C linker);devenvshell;moonworkspace with:ci; hk pre-push gate; CI image + Woodpecker bootstrap pipeline. CI runsbuf lint/breaking, Nextest with JUnit output, nix/shell/toml/yaml linters, and a tightenedcargo-denypolicy (AGPL allowed only for first‑party crates). JS task caches hashbun.lockto prevent stale builds.Migration
direnv allow, thenbun install.moon run :cilocally; CI runs the same graph.crates/compass-proto/proto/for API changes; regenerate viabufand commit results. Never hand-edit generated code undercrates/compass-proto/src/genorpackages/compass-client/src/gen.Written for commit ffcb1be. Summary will update on new commits.