Add the community health files ahead of going public

The repository has carried only a LICENSE and a README, which scores 42%
on GitHub's community profile against ihasmail's 85% and, more to the
point, leaves someone who finds a vulnerability with nowhere to send it
but a public issue.

SECURITY.md is the one that matters. It names cross-tenant data exposure
as the highest-severity class, since that is the guarantee this project
actually sells and the one hardest to be sure of. It also puts the two
knowingly unverified areas in front of a reporter -- Phase 4 beyond its
audit-logging guarantees, and the Windows agent, which has never run on
Windows -- so a finding there is not mistaken for a regression in a path
that was ever verified. And it declares the demo credential out of scope
explicitly: it is published on purpose, prefilled on the login page and
baked into the web bundle, so a report about it costs everyone time.

CONTRIBUTING.md is written for this tree rather than adapted loosely from
the other one: the storage/query split, PostgreSQL being control-plane
only, the enterprise/ module boundary core never imports across, and the
fact that the whole repository is AGPLv3 with no feature gate. Setup is
the compose path from the README, including COMPOSE_PROFILES, so the two
cannot drift into disagreeing.

CODE_OF_CONDUCT.md is Contributor Covenant 2.0, copied from ihasmail with
one fix: that copy never filled in the contact placeholder, so its
reporting sentence ends at "responsible for enforcement at ." -- a code of
conduct with no way to report anything. Worth fixing there too.

Signed-off-by: John Coffey <[email protected]>
This commit is contained in:
2026-08-29 00:17:48 -07:00
parent 7b690ad694
commit 233e0779b7
3 changed files with 291 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
# Contributing to Cairn OBS
Thanks for your interest in contributing to **Cairn OBS** — open-core, Kubernetes-native log aggregation and observability. Contributions of all kinds are welcome: bug reports, feature requests, code, documentation, and testing.
## Code of Conduct
By participating in this project you agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md). Be constructive, be patient with newcomers, and keep discussion focused on the project.
## Before You Start
- **Read [`docs/architecture.md`](docs/architecture.md) before changing any component.** The storage/query split in particular is deliberate: ClickHouse serves analytics, Tantivy serves full-text, and one query language compiles to a single plan across both. Changes that blur that line need discussion first.
- **PostgreSQL is control-plane only** — dashboards, panels, alert rules and state, notification targets, delivery log. Log data never touches it. That boundary is about transactional read-modify-write, not preference.
- **`enterprise/` is a separate Go module that core never imports from.** Since the Phase 6 relicensing that boundary is architectural rather than legal — it keeps core buildable and deployable standalone, and keeps tenant resolution server-side. Please don't reach across it.
- **The whole repository is AGPLv3, `enterprise/` included.** There is no feature gate and no paid tier holding code back. Anything you contribute is distributed under AGPL-3.0, including for hosted/SaaS deployments.
## How to Contribute
### Reporting Bugs
Search [existing issues](https://github.com/LINUXexpert-org/cairnobs/issues) first. When filing a bug, include:
- A clear, descriptive title
- Steps to reproduce, and expected vs. actual behaviour
- **Which component** — `agent`, `ingest`, `api`, `search`, `alerting`, `enterprise`, `web`, `cli`, `deploy`
- How you're running it: `docker compose`, the Helm chart, or something else, and which `COMPOSE_PROFILES` if compose
- Relevant logs from the component, and the query if the bug is in query behaviour
- Whether it reproduces from a clean `docker compose down -v && docker compose up`
Two areas are known to be unverified rather than broken — Phase 4 (RBAC and tenant isolation) beyond its audit-logging guarantees, and the Windows agent, which has never run on real Windows. Both are called out in the README. Reports against them are welcome; please say that's what you were testing.
### Suggesting Features
Open an issue describing:
- The problem you're trying to solve, not just the solution
- Where it sits relative to the architecture — which component owns it, and whether it crosses the storage/query split or the `enterprise/` boundary
- Roughly what it costs at volume, if it touches the ingest or query path. Cost-per-GB is a design goal, not an afterthought.
For larger changes, open an issue to discuss the approach **before** submitting a pull request — this saves everyone time if the direction needs adjusting.
### Submitting Pull Requests
1. **Fork** the repository and create your branch from `main`.
2. **Name your branch** descriptively, e.g. `fix/tantivy-merge-stall` or `feat/alert-absence-rules`.
3. **Keep PRs focused** — one logical change per PR.
4. **Write clear commit messages** describing what changed and why. The "why" matters more than the "what"; the diff already says what.
5. **Add or update tests** in the component you touched. Each top-level directory carries its own unit tests.
6. **Update documentation** if your change affects setup, configuration, the query language, or user-facing behaviour.
7. **Open the pull request** against `main`, with a summary, any related issue numbers, screenshots for UI changes, and what you actually ran to check it.
Please sign off your commits: `git commit -s` adds the `Signed-off-by` trailer, which is a statement that you have the right to submit the work under this project's licence. GitHub enforces it for commits made through the web interface; for everything else it is asked for rather than blocked.
### CI
Three workflows run on a pull request:
- **License compliance** — the dependency licence inventory under `docs/compliance/` must stay accurate. A new dependency with an incompatible licence fails the build.
- **Security scan**
- **Web route check** — the route lists are kept honest against the actual SvelteKit routes, so an unrouted path answers 404 rather than rendering something.
### Code Style
- Match the existing formatting and naming conventions in the component you're editing. It's a polyglot tree: Rust in `agent` and `search`, Go in `ingest`, `api`, `alerting`, `enterprise` and `cli`, TypeScript and Svelte in `web`.
- `cargo fmt` and `gofmt` output is the standard; don't hand-format around them.
- Prefer clarity over cleverness. This is infrastructure people page on.
- Comment the non-obvious, especially anything about query planning, tenant scoping, or the exactly-once/at-least-once properties of the ingest path — those are easy to get subtly wrong and expensive to debug later.
### Development Setup
1. Clone your fork:
```bash
git clone https://github.com/YOUR-USERNAME/cairnobs.git
cd cairnobs
```
2. Bring the stack up:
```bash
docker compose up
```
The web UI is on <http://localhost:3000> and the API on `:8080`; alerting is on `:8081` and enterprise auth on `:8082`. The agent connects to ingest over mTLS gRPC on `:4317`. `search` publishes no host port — it's reachable only on the compose network.
3. `COMPOSE_PROFILES` in `.env` selects the query-serving binary: `single-tenant` (default) or `enterprise` for the multi-tenant path. They're mutually exclusive, the same choice Helm's `enterprise.enabled` flag makes for a real cluster. Override per invocation with `COMPOSE_PROFILES=enterprise docker compose up`.
4. Exercise the path you changed end to end — for ingest or query work that means getting a real log line in and querying it back, not just a passing unit test.
## Review Process
- A maintainer will review your PR and may request changes.
- Please respond to review feedback in a timely manner; PRs with no activity for an extended period may be closed, and can be reopened once updated.
- Once approved, a maintainer will merge the PR.
## Reporting Security Issues
Please **do not** open a public issue for security vulnerabilities. See [SECURITY.md](SECURITY.md) for how to report privately, and for what is in and out of scope — cross-tenant data exposure is the class we most want to hear about.
## Questions?
If you're unsure whether something is a good fit, open an issue and ask, or start a [discussion](https://github.com/LINUXexpert-org/cairnobs/discussions). Discussion before you invest time in a PR is welcome.
Thanks again for helping improve Cairn OBS.