Rename the project spec and update every reference to it
The charter file carried a tool-specific name while being the repository's own document: mission, non-negotiable constraints, the pinned stack, repo conventions and phase status, cited as authority by thirty files across the agent, api, deploy, docs, search and terraform trees. PROJECT-SPEC.md says what it is. All 42 references are updated in the same commit, including the relative link in docs/status.md, so nothing points at a filename that no longer exists.
This commit is contained in:
+1
-1
@@ -211,7 +211,7 @@ escalation, not a footnote: think about whether your environment wants
|
|||||||
the log-shipping agent running with that level of access before turning
|
the log-shipping agent running with that level of access before turning
|
||||||
on the `etw` feature and an `[source] kind = "etw"` config. Event Log
|
on the `etw` feature and an `[source] kind = "etw"` config. Event Log
|
||||||
alone (no elevated privileges needed) covers the common case and is what
|
alone (no elevated privileges needed) covers the common case and is what
|
||||||
Phase 1's exit criteria in `/CLAUDE.md` actually requires to be running.
|
Phase 1's exit criteria in `/PROJECT-SPEC.md` actually requires to be running.
|
||||||
|
|
||||||
Providers are configured by **GUID**, not friendly name — ETW's own API
|
Providers are configured by **GUID**, not friendly name — ETW's own API
|
||||||
requires it. Look one up with `logman query providers "<Friendly Name>"`.
|
requires it. Look one up with `logman query providers "<Friendly Name>"`.
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ pub enum SourceConfig {
|
|||||||
// Dead-code-on-default-build, same reasoning as EventLog/Etw below:
|
// Dead-code-on-default-build, same reasoning as EventLog/Etw below:
|
||||||
// these fields are only read by the `file-tail`-gated arm in
|
// these fields are only read by the `file-tail`-gated arm in
|
||||||
// spawn_source (main.rs), which doesn't exist in the default build
|
// spawn_source (main.rs), which doesn't exist in the default build
|
||||||
// (`default = ["journald"]`). Pre-existing gap from Phase 0 — CLAUDE.md
|
// (`default = ["journald"]`). Pre-existing gap from Phase 0 — PROJECT-SPEC.md
|
||||||
// mandates plain `cargo clippy --all-targets -- -D warnings` (no
|
// mandates plain `cargo clippy --all-targets -- -D warnings` (no
|
||||||
// --all-features), which this broke silently since only
|
// --all-features), which this broke silently since only
|
||||||
// --all-features clippy was ever actually run.
|
// --all-features clippy was ever actually run.
|
||||||
@@ -202,7 +202,7 @@ impl Default for MetricsConfig {
|
|||||||
/// way. Kept as a small hand-rolled parser rather than pulling in a
|
/// way. Kept as a small hand-rolled parser rather than pulling in a
|
||||||
/// duration-parsing crate for this one field -- this is the
|
/// duration-parsing crate for this one field -- this is the
|
||||||
/// statically-linked edge agent every "no glibc runtime deps" constraint
|
/// statically-linked edge agent every "no glibc runtime deps" constraint
|
||||||
/// in CLAUDE.md is about keeping lean, and the grammar needed here is a
|
/// in PROJECT-SPEC.md is about keeping lean, and the grammar needed here is a
|
||||||
/// handful of lines.
|
/// handful of lines.
|
||||||
fn deserialize_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
|
fn deserialize_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ and `/docs/query-language-reference.md` for the user-facing syntax.
|
|||||||
|
|
||||||
## Why plain REST, not gRPC + REST gateway
|
## Why plain REST, not gRPC + REST gateway
|
||||||
|
|
||||||
CLAUDE.md pins the control plane to "Go, gRPC + REST gateway." This
|
PROJECT-SPEC.md pins the control plane to "Go, gRPC + REST gateway." This
|
||||||
service is plain `net/http` instead — a deliberate simplification, not a
|
service is plain `net/http` instead — a deliberate simplification, not a
|
||||||
change to the pinned stack. Wiring up a `.proto` service,
|
change to the pinned stack. Wiring up a `.proto` service,
|
||||||
`google.api.http` annotations, and `protoc-gen-grpc-gateway` codegen for
|
`google.api.http` annotations, and `protoc-gen-grpc-gateway` codegen for
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// login: a real login page and session-based auth covering both /api
|
// login: a real login page and session-based auth covering both /api
|
||||||
// and /alerting, plus a simple admin-managed user list, for deployments
|
// and /alerting, plus a simple admin-managed user list, for deployments
|
||||||
// reachable over the internet that can no longer rely on Phase 0-3's
|
// reachable over the internet that can no longer rely on Phase 0-3's
|
||||||
// "no auth yet" default (see /docs/architecture.md and CLAUDE.md's
|
// "no auth yet" default (see /docs/architecture.md and PROJECT-SPEC.md's
|
||||||
// Phase 4 section for the enterprise/ SSO alternative this is not --
|
// Phase 4 section for the enterprise/ SSO alternative this is not --
|
||||||
// this package has no tenant/RBAC-service concept, just "is this a
|
// this package has no tenant/RBAC-service concept, just "is this a
|
||||||
// valid logged-in user").
|
// valid logged-in user").
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
# deploy
|
# deploy
|
||||||
|
|
||||||
Kubernetes deployment for Cairn OBS, added in Phase 4 (`/deploy` was
|
Kubernetes deployment for Cairn OBS, added in Phase 4 (`/deploy` was
|
||||||
deliberately stubbed through Phase 3 -- see `/CLAUDE.md`'s Phase 3
|
deliberately stubbed through Phase 3 -- see `/PROJECT-SPEC.md`'s Phase 3
|
||||||
non-goals). Two pieces:
|
non-goals). Two pieces:
|
||||||
|
|
||||||
- `operator/` -- a small Go controller-runtime Operator managing one CRD
|
- `operator/` -- a small Go controller-runtime Operator managing one CRD
|
||||||
@@ -18,7 +18,7 @@ map of per-tenant ClickHouse connection pools via `internal/chrunner`;
|
|||||||
`search` holds a map of per-tenant Tantivy indices via
|
`search` holds a map of per-tenant Tantivy indices via
|
||||||
`src/registry.rs`) -- not at the Kubernetes layer. This directory is
|
`src/registry.rs`) -- not at the Kubernetes layer. This directory is
|
||||||
**not** "one Deployment per tenant" or a general multi-cluster system;
|
**not** "one Deployment per tenant" or a general multi-cluster system;
|
||||||
that's an explicit Phase 4 non-goal (see `/CLAUDE.md`). What it *does*
|
that's an explicit Phase 4 non-goal (see `/PROJECT-SPEC.md`). What it *does*
|
||||||
add:
|
add:
|
||||||
|
|
||||||
- A `Tenant` CRD + controller (`operator/internal/controller`) that
|
- A `Tenant` CRD + controller (`operator/internal/controller`) that
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ unconditional by design, no disable switch.
|
|||||||
both tenants reached `status.phase: Active` with real credentials.
|
both tenants reached `status.phase: Active` with real credentials.
|
||||||
|
|
||||||
This proves Phase 4's "two tenants... with their own users, roles,
|
This proves Phase 4's "two tenants... with their own users, roles,
|
||||||
dashboards" exit criteria (`/CLAUDE.md`) end to end at the deployment-
|
dashboards" exit criteria (`/PROJECT-SPEC.md`) end to end at the deployment-
|
||||||
topology layer: `-provision-tenant` (`enterprise/internal/
|
topology layer: `-provision-tenant` (`enterprise/internal/
|
||||||
tenantprovision`) is what actually creates each tenant's ClickHouse
|
tenantprovision`) is what actually creates each tenant's ClickHouse
|
||||||
database/user/grant and marks it active in `rbacstore`; running inside
|
database/user/grant and marks it active in `rbacstore`; running inside
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ search:
|
|||||||
# A second replica would form a second, independent consumer instance
|
# A second replica would form a second, independent consumer instance
|
||||||
# against the same partitions with no coordination -- correctness,
|
# against the same partitions with no coordination -- correctness,
|
||||||
# not just resource waste, is the reason this isn't a `replicas` knob
|
# not just resource waste, is the reason this isn't a `replicas` knob
|
||||||
# yet. Matches CLAUDE.md's Phase 4 non-goal: "no general multi-cluster
|
# yet. Matches PROJECT-SPEC.md's Phase 4 non-goal: "no general multi-cluster
|
||||||
# orchestration."
|
# orchestration."
|
||||||
replicas: 1
|
replicas: 1
|
||||||
resources: {}
|
resources: {}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
// internal/controller/tenant_controller.go's doc comment for how
|
// internal/controller/tenant_controller.go's doc comment for how
|
||||||
// TenantReconciler derives Phase/Conditions from those fields rather
|
// TenantReconciler derives Phase/Conditions from those fields rather
|
||||||
// than fabricating its own "provisioned" claim. This is the "lightweight
|
// than fabricating its own "provisioned" claim. This is the "lightweight
|
||||||
// unification" named in CLAUDE.md/docs/phase-4-runbook.md's "two
|
// unification" named in PROJECT-SPEC.md/docs/phase-4-runbook.md's "two
|
||||||
// independent provisioning mechanisms" gap: -provision-tenant stays the
|
// independent provisioning mechanisms" gap: -provision-tenant stays the
|
||||||
// real actor; this operator's reconcile loop never touches Postgres or
|
// real actor; this operator's reconcile loop never touches Postgres or
|
||||||
// ClickHouse and gained no new credentials.
|
// ClickHouse and gained no new credentials.
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ one instead of deferring it, and keeps Kafka credentials off the edge agent.
|
|||||||
family isn't a fit for this (no real row-level locking/transactional
|
family isn't a fit for this (no real row-level locking/transactional
|
||||||
read-modify-write).
|
read-modify-write).
|
||||||
|
|
||||||
This split is not to be changed without discussion — see CLAUDE.md.
|
This split is not to be changed without discussion — see PROJECT-SPEC.md.
|
||||||
|
|
||||||
## Component responsibilities
|
## Component responsibilities
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ both the Helm and docker-compose layers, the two provisioning
|
|||||||
mechanisms unified, both storage engines' write paths per-tenant-routed,
|
mechanisms unified, both storage engines' write paths per-tenant-routed,
|
||||||
and the tenant-picker frontend page now built and browser-verified
|
and the tenant-picker frontend page now built and browser-verified
|
||||||
(`web/src/routes/select-tenant`, `api/httpserver.WithCredentialedCORS`
|
(`web/src/routes/select-tenant`, `api/httpserver.WithCredentialedCORS`
|
||||||
— see `/CLAUDE.md`'s Phase 4 section and `/web/README.md`'s "Tenant
|
— see `/PROJECT-SPEC.md`'s Phase 4 section and `/web/README.md`'s "Tenant
|
||||||
picker" section), the remaining gaps in this phase are entirely the
|
picker" section), the remaining gaps in this phase are entirely the
|
||||||
already-disclosed live-verification caveats: the ClickHouse/Postgres-
|
already-disclosed live-verification caveats: the ClickHouse/Postgres-
|
||||||
backed pieces have never run against a real database in this
|
backed pieces have never run against a real database in this
|
||||||
@@ -244,18 +244,18 @@ plain HTTP instead (`api/authz.HTTPAuthorizer`, `web`'s
|
|||||||
`GET /auth/features`) — the same "network boundary, not import boundary"
|
`GET /auth/features`) — the same "network boundary, not import boundary"
|
||||||
shape `/alerting`↔`api` already used before `enterprise/` existed.
|
shape `/alerting`↔`api` already used before `enterprise/` existed.
|
||||||
|
|
||||||
## Non-negotiables carried from CLAUDE.md
|
## Non-negotiables carried from PROJECT-SPEC.md
|
||||||
|
|
||||||
- Rust agent: statically linked musl, `x86_64-unknown-linux-musl` and
|
- Rust agent: statically linked musl, `x86_64-unknown-linux-musl` and
|
||||||
`aarch64-unknown-linux-musl`, no glibc runtime deps.
|
`aarch64-unknown-linux-musl`, no glibc runtime deps.
|
||||||
- Windows support via native ETW/Event Log API, not WSL — designed
|
- Windows support via native ETW/Event Log API, not WSL — designed
|
||||||
(Phase 1) but still unverified on real Windows hardware.
|
(Phase 1) but still unverified on real Windows hardware.
|
||||||
- Every UI action maps to a documented REST/gRPC call — no UI-only logic.
|
- Every UI action maps to a documented REST/gRPC call — no UI-only logic.
|
||||||
- Pinned stack (see CLAUDE.md table) — no substitutions without discussion.
|
- Pinned stack (see PROJECT-SPEC.md table) — no substitutions without discussion.
|
||||||
|
|
||||||
## Explicitly out of scope (current, Phase 4)
|
## Explicitly out of scope (current, Phase 4)
|
||||||
|
|
||||||
Per `/CLAUDE.md`'s Phase 4 non-goals and `/docs/security/threat-model.md`:
|
Per `/PROJECT-SPEC.md`'s Phase 4 non-goals and `/docs/security/threat-model.md`:
|
||||||
deny-override permission grants, a data retention/deletion policy for
|
deny-override permission grants, a data retention/deletion policy for
|
||||||
deprovisioned tenants, general multi-cluster orchestration in `/deploy`,
|
deprovisioned tenants, general multi-cluster orchestration in `/deploy`,
|
||||||
and any defense against a privileged ClickHouse/Postgres administrator —
|
and any defense against a privileged ClickHouse/Postgres administrator —
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ Key facts, verified against primary sources:
|
|||||||
already speak. Real tradeoff: Redpanda was originally chosen partly
|
already speak. Real tradeoff: Redpanda was originally chosen partly
|
||||||
for its lightweight single-binary footprint (`docker-compose.yml`
|
for its lightweight single-binary footprint (`docker-compose.yml`
|
||||||
runs it with `--smp=1 --memory=1G --overprovisioned`, tuned for a
|
runs it with `--smp=1 --memory=1G --overprovisioned`, tuned for a
|
||||||
resource-constrained local/homelab deployment per `CLAUDE.md`'s
|
resource-constrained local/homelab deployment per `PROJECT-SPEC.md`'s
|
||||||
stated deployment targets); Kafka's JVM-based broker has a materially
|
stated deployment targets); Kafka's JVM-based broker has a materially
|
||||||
larger minimum memory/startup footprint. This is a real regression
|
larger minimum memory/startup footprint. This is a real regression
|
||||||
for the project's stated "docker-compose for local/homelab" use case,
|
for the project's stated "docker-compose for local/homelab" use case,
|
||||||
@@ -263,7 +263,7 @@ project's own logo package.
|
|||||||
|
|
||||||
**Before this audit**: no root `LICENSE` file existed anywhere in the
|
**Before this audit**: no root `LICENSE` file existed anywhere in the
|
||||||
repo — not at the root, not in `enterprise/`. The only license
|
repo — not at the root, not in `enterprise/`. The only license
|
||||||
declarations were prose statements in `CLAUDE.md`/`docs/architecture.md`
|
declarations were prose statements in `PROJECT-SPEC.md`/`docs/architecture.md`
|
||||||
and correct `license = "AGPL-3.0-only"` fields in the two Rust
|
and correct `license = "AGPL-3.0-only"` fields in the two Rust
|
||||||
workspaces' `Cargo.toml`s. `web/package.json` had no `license` field at
|
workspaces' `Cargo.toml`s. `web/package.json` had no `license` field at
|
||||||
all (npm's tooling reported the package itself as `UNLICENSED` as a
|
all (npm's tooling reported the package itself as `UNLICENSED` as a
|
||||||
@@ -324,10 +324,10 @@ assumed.
|
|||||||
- Every prose reference to `enterprise/` as "commercial license" or
|
- Every prose reference to `enterprise/` as "commercial license" or
|
||||||
"commercial-licensed" across the repo was updated. Present-tense
|
"commercial-licensed" across the repo was updated. Present-tense
|
||||||
claims (code comments, `README.md` files describing current state,
|
claims (code comments, `README.md` files describing current state,
|
||||||
`CLAUDE.md`'s non-negotiable constraints) were corrected outright.
|
`PROJECT-SPEC.md`'s non-negotiable constraints) were corrected outright.
|
||||||
Historical, phase-specific documents (`docs/phase-4-isolation-design.md`,
|
Historical, phase-specific documents (`docs/phase-4-isolation-design.md`,
|
||||||
`docs/phase-4-rbac-design.md`, `docs/phase-4-runbook.md`, and the
|
`docs/phase-4-rbac-design.md`, `docs/phase-4-runbook.md`, and the
|
||||||
relevant parts of `CLAUDE.md`'s and `docs/architecture.md`'s Phase 4
|
relevant parts of `PROJECT-SPEC.md`'s and `docs/architecture.md`'s Phase 4
|
||||||
sections) were given forward-pointing corrections — "commercial
|
sections) were given forward-pointing corrections — "commercial
|
||||||
license at the time this was written; AGPLv3 as of Phase 6" — rather
|
license at the time this was written; AGPLv3 as of Phase 6" — rather
|
||||||
than rewritten as if the commercial-license period never happened,
|
than rewritten as if the commercial-license period never happened,
|
||||||
@@ -400,7 +400,7 @@ Redpanda decision below, every item has one.
|
|||||||
|
|
||||||
**Every task-2 (c)/unresolved-(b) item now has an explicit resolution**
|
**Every task-2 (c)/unresolved-(b) item now has an explicit resolution**
|
||||||
— fixed, isolated, or, for Redpanda, flagged and decided. Phase 6's exit
|
— fixed, isolated, or, for Redpanda, flagged and decided. Phase 6's exit
|
||||||
criteria in `CLAUDE.md` are updated accordingly.
|
criteria in `PROJECT-SPEC.md` are updated accordingly.
|
||||||
|
|
||||||
## Legal disclaimer (repeated, deliberately)
|
## Legal disclaimer (repeated, deliberately)
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ curl -X POST http://localhost:8080/search -H 'Content-Type: application/json' \
|
|||||||
```
|
```
|
||||||
|
|
||||||
**The `record_id` in both responses should match.** That's the actual
|
**The `record_id` in both responses should match.** That's the actual
|
||||||
Phase 1 exit criterion (`/CLAUDE.md`) for the Linux half: the same
|
Phase 1 exit criterion (`/PROJECT-SPEC.md`) for the Linux half: the same
|
||||||
record, reachable both ways. If `/search` returns nothing yet, give it a
|
record, reachable both ways. If `/search` returns nothing yet, give it a
|
||||||
few more seconds — Tantivy commits on a timer (`COMMIT_INTERVAL_MS`,
|
few more seconds — Tantivy commits on a timer (`COMMIT_INTERVAL_MS`,
|
||||||
default 2s), so there's a small window where a record is in ClickHouse
|
default 2s), so there's a small window where a record is in ClickHouse
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ not a projection):
|
|||||||
| `SELECT count() FROM logs WHERE service='web'` (raw SQL) | Pure ClickHouse | 17.5ms |
|
| `SELECT count() FROM logs WHERE service='web'` (raw SQL) | Pure ClickHouse | 17.5ms |
|
||||||
|
|
||||||
All four "well under a second" — the Phase 2 exit criteria in
|
All four "well under a second" — the Phase 2 exit criteria in
|
||||||
`/CLAUDE.md`. The combined text+aggregation case (the one everyone should
|
`/PROJECT-SPEC.md`. The combined text+aggregation case (the one everyone should
|
||||||
be nervous about, since it's a two-backend query) came in at 46ms, not
|
be nervous about, since it's a two-backend query) came in at 46ms, not
|
||||||
meaningfully slower than the pure-ClickHouse case — the Tantivy prefilter
|
meaningfully slower than the pure-ClickHouse case — the Tantivy prefilter
|
||||||
step is fast, and 5,000 UUIDs (see below) is a small `IN` clause by
|
step is fast, and 5,000 UUIDs (see below) is a small `IN` clause by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Dashboard design
|
# Dashboard design
|
||||||
|
|
||||||
> **Status:** Approved, in progress. Task 2 of Phase 3 — see `/CLAUDE.md`'s
|
> **Status:** Approved, in progress. Task 2 of Phase 3 — see `/PROJECT-SPEC.md`'s
|
||||||
> "What done looks like for Phase 3" section for the exit criteria this is
|
> "What done looks like for Phase 3" section for the exit criteria this is
|
||||||
> built against. Task 3 (dashboard CRUD API + web UI) implements this
|
> built against. Task 3 (dashboard CRUD API + web UI) implements this
|
||||||
> doc; if implementation reveals this design is wrong somewhere, fix this
|
> doc; if implementation reveals this design is wrong somewhere, fix this
|
||||||
@@ -24,7 +24,7 @@ saved query itself.
|
|||||||
## Why not ClickHouse: PostgreSQL for control-plane config
|
## Why not ClickHouse: PostgreSQL for control-plane config
|
||||||
|
|
||||||
This phase adds PostgreSQL as a new pinned-stack component — flagged and
|
This phase adds PostgreSQL as a new pinned-stack component — flagged and
|
||||||
confirmed with the project owner before implementation, per CLAUDE.md's
|
confirmed with the project owner before implementation, per PROJECT-SPEC.md's
|
||||||
"ask before... making an architectural decision not already specified in
|
"ask before... making an architectural decision not already specified in
|
||||||
`/docs/architecture.md`." Scope is strictly control-plane config
|
`/docs/architecture.md`." Scope is strictly control-plane config
|
||||||
(dashboards, panels, and — per `/docs/phase-3-alerting-design.md` —
|
(dashboards, panels, and — per `/docs/phase-3-alerting-design.md` —
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ ships entirely in `enterprise/`, not AGPL core. Core (`/api`,
|
|||||||
`/alerting`, `/web`) stays genuinely single-tenant: no multi-tenant
|
`/alerting`, `/web`) stays genuinely single-tenant: no multi-tenant
|
||||||
mechanism present at all, not merely a missing management UI on top of
|
mechanism present at all, not merely a missing management UI on top of
|
||||||
otherwise-functional isolation. This was an explicit choice put to the
|
otherwise-functional isolation. This was an explicit choice put to the
|
||||||
project owner rather than assumed, because CLAUDE.md's licensing
|
project owner rather than assumed, because PROJECT-SPEC.md's licensing
|
||||||
boundary text names multi-tenancy as enterprise-gated, and a
|
boundary text names multi-tenancy as enterprise-gated, and a
|
||||||
"mechanism in core, feature in enterprise" split would have let a
|
"mechanism in core, feature in enterprise" split would have let a
|
||||||
sufficiently motivated self-hosting AGPL user wire up real isolation
|
sufficiently motivated self-hosting AGPL user wire up real isolation
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Design choices worth calling out explicitly:
|
|||||||
| Hardware floor | Runs on CPU (slow) or a single consumer GPU via quantized (GGUF) models | Needs a real GPU; not practically CPU-viable |
|
| Hardware floor | Runs on CPU (slow) or a single consumer GPU via quantized (GGUF) models | Needs a real GPU; not practically CPU-viable |
|
||||||
| Deployment complexity | Single binary/container, `ollama pull <model>`, built-in REST API | Python server, CUDA/driver management, more moving parts |
|
| Deployment complexity | Single binary/container, `ollama pull <model>`, built-in REST API | Python server, CUDA/driver management, more moving parts |
|
||||||
| Throughput under concurrency | Adequate for one-user-at-a-time interactive use; not built for high concurrent QPS | Purpose-built for high-throughput serving (continuous batching, PagedAttention) |
|
| Throughput under concurrency | Adequate for one-user-at-a-time interactive use; not built for high concurrent QPS | Purpose-built for high-throughput serving (continuous batching, PagedAttention) |
|
||||||
| Fit for this project | Matches `docker-compose for local/homelab` (CLAUDE.md's stated deployment target) — most self-hosters won't have a dedicated inference GPU | Fits a provisioned-GPU SaaS inference tier — not this phase's target (cloud is the opt-in secondary path, not primary) |
|
| Fit for this project | Matches `docker-compose for local/homelab` (PROJECT-SPEC.md's stated deployment target) — most self-hosters won't have a dedicated inference GPU | Fits a provisioned-GPU SaaS inference tier — not this phase's target (cloud is the opt-in secondary path, not primary) |
|
||||||
|
|
||||||
Cairn OBS's actual AI workload shape is one interactive query bar per user
|
Cairn OBS's actual AI workload shape is one interactive query bar per user
|
||||||
at a time, not a high-QPS inference-serving problem — vLLM's real
|
at a time, not a high-QPS inference-serving problem — vLLM's real
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ handler to call them from).
|
|||||||
|
|
||||||
## Known residual risks (explicitly out of scope, not silently assumed away)
|
## Known residual risks (explicitly out of scope, not silently assumed away)
|
||||||
|
|
||||||
Per `/CLAUDE.md`'s Phase 4 non-goals, restated here in threat-model
|
Per `/PROJECT-SPEC.md`'s Phase 4 non-goals, restated here in threat-model
|
||||||
terms:
|
terms:
|
||||||
|
|
||||||
- **A privileged ClickHouse/Postgres administrator is not defended
|
- **A privileged ClickHouse/Postgres administrator is not defended
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Phase-by-phase record of what was built, what "done" meant for each phase,
|
Phase-by-phase record of what was built, what "done" meant for each phase,
|
||||||
and how it was verified. Conventions and constraints live in
|
and how it was verified. Conventions and constraints live in
|
||||||
[`/CLAUDE.md`](../CLAUDE.md); the architecture spec is
|
[`/PROJECT-SPEC.md`](../PROJECT-SPEC.md); the architecture spec is
|
||||||
[`/docs/architecture.md`](architecture.md).
|
[`/docs/architecture.md`](architecture.md).
|
||||||
|
|
||||||
Each phase has a runbook in this directory recording the actual
|
Each phase has a runbook in this directory recording the actual
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ below) and Tantivy (`/search/README.md`'s "Per-tenant indices" section
|
|||||||
routing (does traffic actually reach `enterprise-api` instead of
|
routing (does traffic actually reach `enterprise-api` instead of
|
||||||
`api`), now a single-flag choice in both `deploy/helm/cairnobs` and
|
`api`), now a single-flag choice in both `deploy/helm/cairnobs` and
|
||||||
`docker-compose.yml` (`enterprise.enabled` / `COMPOSE_PROFILES`), see
|
`docker-compose.yml` (`enterprise.enabled` / `COMPOSE_PROFILES`), see
|
||||||
CLAUDE.md.
|
PROJECT-SPEC.md.
|
||||||
|
|
||||||
## Ingest tenant identity
|
## Ingest tenant identity
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
// Both Helm (deploy/helm/cairnobs/templates/api.yaml vs
|
// Both Helm (deploy/helm/cairnobs/templates/api.yaml vs
|
||||||
// enterprise-api.yaml) and docker-compose.yml (COMPOSE_PROFILES) now
|
// enterprise-api.yaml) and docker-compose.yml (COMPOSE_PROFILES) now
|
||||||
// make this the deployment-topology choice, not just a binary sitting
|
// make this the deployment-topology choice, not just a binary sitting
|
||||||
// unused alongside api's -- see this repo's CLAUDE.md. `search`'s write
|
// unused alongside api's -- see this repo's PROJECT-SPEC.md. `search`'s write
|
||||||
// side (ingest, and by extension the Redpanda consumer search itself
|
// side (ingest, and by extension the Redpanda consumer search itself
|
||||||
// runs) is still not tenant-aware -- see enterprise/internal/searchclient
|
// runs) is still not tenant-aware -- see enterprise/internal/searchclient
|
||||||
// and search/src/registry.rs's doc comments, and
|
// and search/src/registry.rs's doc comments, and
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Package tenantcrd syncs enterprise-api -provision-tenant's real
|
// Package tenantcrd syncs enterprise-api -provision-tenant's real
|
||||||
// provisioning result into the Tenant CRD (deploy/operator/api/
|
// provisioning result into the Tenant CRD (deploy/operator/api/
|
||||||
// v1alpha1) -- the "lightweight unification" named in CLAUDE.md's "two
|
// v1alpha1) -- the "lightweight unification" named in PROJECT-SPEC.md's "two
|
||||||
// independent provisioning mechanisms" gap: -provision-tenant stays the
|
// independent provisioning mechanisms" gap: -provision-tenant stays the
|
||||||
// sole real actor (rbacstore + tenantprovision.ProvisionClickHouse, see
|
// sole real actor (rbacstore + tenantprovision.ProvisionClickHouse, see
|
||||||
// runProvisionTenant's doc comment in cmd/enterprise-api/main.go); this
|
// runProvisionTenant's doc comment in cmd/enterprise-api/main.go); this
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ database, regardless of any `tenant_id` tag a message carries -- routing
|
|||||||
a tagged record into its own tenant's dedicated database is
|
a tagged record into its own tenant's dedicated database is
|
||||||
`enterprise/internal/chwriter` and `enterprise/cmd/enterprise-ingest`'s
|
`enterprise/internal/chwriter` and `enterprise/cmd/enterprise-ingest`'s
|
||||||
job (a separate module by architectural convention, not a licensing
|
job (a separate module by architectural convention, not a licensing
|
||||||
split -- both are AGPLv3, see `/CLAUDE.md`'s licensing boundary), not
|
split -- both are AGPLv3, see `/PROJECT-SPEC.md`'s licensing boundary), not
|
||||||
this package's. `consumer` and `clickhousewriter` live outside
|
this package's. `consumer` and `clickhousewriter` live outside
|
||||||
`internal/` (moved there once `enterprise/internal/chwriter` needed to
|
`internal/` (moved there once `enterprise/internal/chwriter` needed to
|
||||||
import them directly -- Go's compiler-enforced `internal/` visibility
|
import them directly -- Go's compiler-enforced `internal/` visibility
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
// tenant the call's bearer credential belongs to and attaches it as a
|
// tenant the call's bearer credential belongs to and attaches it as a
|
||||||
// "tenant_id" Kafka message header on every record produced -- the first
|
// "tenant_id" Kafka message header on every record produced -- the first
|
||||||
// step of Phase 4's ingest tenant-awareness (see
|
// step of Phase 4's ingest tenant-awareness (see
|
||||||
// /docs/phase-4-runbook.md and CLAUDE.md's "ingest itself has no tenant
|
// /docs/phase-4-runbook.md and PROJECT-SPEC.md's "ingest itself has no tenant
|
||||||
// concept" gap). Deliberately scoped no further than that for now:
|
// concept" gap). Deliberately scoped no further than that for now:
|
||||||
// nothing downstream (this package's own consumer, or `search`'s
|
// nothing downstream (this package's own consumer, or `search`'s
|
||||||
// separate Redpanda consumer) reads that header yet to route a record's
|
// separate Redpanda consumer) reads that header yet to route a record's
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- Additive-only per-resource grant: lets a specific user exceed their
|
-- Additive-only per-resource grant: lets a specific user exceed their
|
||||||
-- tenant-baseline role on one dashboard (e.g. an Editor granted Admin on
|
-- tenant-baseline role on one dashboard (e.g. an Editor granted Admin on
|
||||||
-- a dashboard they don't own). No deny-overrides -- named non-goal in
|
-- a dashboard they don't own). No deny-overrides -- named non-goal in
|
||||||
-- /docs/phase-4-rbac-design.md and CLAUDE.md's Phase 4 exit criteria.
|
-- /docs/phase-4-rbac-design.md and PROJECT-SPEC.md's Phase 4 exit criteria.
|
||||||
CREATE TABLE IF NOT EXISTS dashboard_permissions
|
CREATE TABLE IF NOT EXISTS dashboard_permissions
|
||||||
(
|
(
|
||||||
id UUID PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ type LogRecord struct {
|
|||||||
Severity Severity `protobuf:"varint,4,opt,name=severity,proto3,enum=sentry.logs.v1.Severity" json:"severity,omitempty"`
|
Severity Severity `protobuf:"varint,4,opt,name=severity,proto3,enum=sentry.logs.v1.Severity" json:"severity,omitempty"`
|
||||||
// Original, unparsed log line. Always populated, even when structured
|
// Original, unparsed log line. Always populated, even when structured
|
||||||
// fields below are also present, per the schema-on-read fallback
|
// fields below are also present, per the schema-on-read fallback
|
||||||
// requirement in CLAUDE.md.
|
// requirement in PROJECT-SPEC.md.
|
||||||
Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"`
|
Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"`
|
||||||
// Structured fields extracted by the agent's parser (e.g. RFC 5424
|
// Structured fields extracted by the agent's parser (e.g. RFC 5424
|
||||||
// syslog header fields), plus source-provided fields (e.g. Windows
|
// syslog header fields), plus source-provided fields (e.g. Windows
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ message LogRecord {
|
|||||||
|
|
||||||
// Original, unparsed log line. Always populated, even when structured
|
// Original, unparsed log line. Always populated, even when structured
|
||||||
// fields below are also present, per the schema-on-read fallback
|
// fields below are also present, per the schema-on-read fallback
|
||||||
// requirement in CLAUDE.md.
|
// requirement in PROJECT-SPEC.md.
|
||||||
string message = 5;
|
string message = 5;
|
||||||
|
|
||||||
// Structured fields extracted by the agent's parser (e.g. RFC 5424
|
// Structured fields extracted by the agent's parser (e.g. RFC 5424
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ aggregation queries.
|
|||||||
|
|
||||||
Tantivy is a Rust library with no maintained Go bindings — using it from
|
Tantivy is a Rust library with no maintained Go bindings — using it from
|
||||||
`ingest` (Go) would mean cgo-bridging to a compiled Rust cdylib, exactly
|
`ingest` (Go) would mean cgo-bridging to a compiled Rust cdylib, exactly
|
||||||
the fragile FFI complexity CLAUDE.md's "prefer boring, well-understood
|
the fragile FFI complexity PROJECT-SPEC.md's "prefer boring, well-understood
|
||||||
dependencies... operators need to trust it" principle steers away from.
|
dependencies... operators need to trust it" principle steers away from.
|
||||||
It would also couple ClickHouse-write latency to Tantivy-write latency in
|
It would also couple ClickHouse-write latency to Tantivy-write latency in
|
||||||
the same request path. See `/docs/architecture.md` for the fuller
|
the same request path. See `/docs/architecture.md` for the fuller
|
||||||
|
|||||||
+1
-1
@@ -76,7 +76,7 @@ no CVE, no known exploit, nothing to patch.
|
|||||||
|
|
||||||
It reaches us only transitively (tantivy 0.22.1 -> measure_time 0.8.3 ->
|
It reaches us only transitively (tantivy 0.22.1 -> measure_time 0.8.3 ->
|
||||||
instant 0.1.13), so it cannot be dropped without moving off the pinned
|
instant 0.1.13), so it cannot be dropped without moving off the pinned
|
||||||
Tantivy version, and CLAUDE.md pins the stack deliberately.
|
Tantivy version, and PROJECT-SPEC.md pins the stack deliberately.
|
||||||
|
|
||||||
The advisory's substance does not apply to this build either: `instant`
|
The advisory's substance does not apply to this build either: `instant`
|
||||||
exists to paper over std::time::Instant being unavailable on wasm, and
|
exists to paper over std::time::Instant being unavailable on wasm, and
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# terraform-provider-cairnobs
|
# terraform-provider-cairnobs
|
||||||
|
|
||||||
Cairn OBS's Terraform provider -- `CLAUDE.md`'s "Repo conventions" section
|
Cairn OBS's Terraform provider -- `PROJECT-SPEC.md`'s "Repo conventions" section
|
||||||
names this a first-class deliverable alongside `cairnobsctl`
|
names this a first-class deliverable alongside `cairnobsctl`
|
||||||
("CLI and Terraform provider are first-class, not afterthoughts"), but
|
("CLI and Terraform provider are first-class, not afterthoughts"), but
|
||||||
no phase before this one had actually built any of it. Four resources
|
no phase before this one had actually built any of it. Four resources
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// built on HashiCorp's terraform-plugin-framework (not the legacy
|
// built on HashiCorp's terraform-plugin-framework (not the legacy
|
||||||
// SDKv2 -- the framework is the actively-developed, currently-
|
// SDKv2 -- the framework is the actively-developed, currently-
|
||||||
// recommended library for a provider started from scratch, matching
|
// recommended library for a provider started from scratch, matching
|
||||||
// CLAUDE.md's "prefer boring, well-understood dependencies" read
|
// PROJECT-SPEC.md's "prefer boring, well-understood dependencies" read
|
||||||
// forward rather than backward).
|
// forward rather than backward).
|
||||||
package provider
|
package provider
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// Command terraform-provider-cairnobs is Cairn OBS's Terraform provider --
|
// Command terraform-provider-cairnobs is Cairn OBS's Terraform provider --
|
||||||
// CLAUDE.md names it a first-class deliverable alongside cairnobsctl
|
// PROJECT-SPEC.md names it a first-class deliverable alongside cairnobsctl
|
||||||
// ("CLI and Terraform provider are first-class, not afterthoughts"),
|
// ("CLI and Terraform provider are first-class, not afterthoughts"),
|
||||||
// but this is the first phase to actually build any of it.
|
// but this is the first phase to actually build any of it.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user