This commit is contained in:
KS Jannette
2026-08-23 18:19:04 -04:00
parent df128c3683
commit 1dd17f76f6

View File

@@ -1,16 +1,13 @@
# kongruity: Signal from noise - 2025-2026 @sjDev - LICENSE: MIT
![kongruity demo image.](kongruity_with_frame.jpg)
![kongruity demo image.](kongruity_demo_image.png)
kongruity pulls in unstructured artifacts of the creative-engineering process, capturing "AHA!" moments scattered across an engineering team's disparate tools: action items or backlog in Atlassian/Jira, user story comments, Slack discussions, retrospective feedback.
It stores and synthesizes these into semantically coherent, prioritized clusters that can be incorporated into implementation planning.
In kongruity, artifacts become "sticky notes." A board full looks chaotic. With a click, a RAG-pipeline levearges Models trained to semantically evaluate, group, cluster and add descriptive cluster headers.
These are rankable, editable and exportable to sprint project planning tools.
## Clustering and evaluation: methodology
@@ -36,7 +33,6 @@ Note that: before scoring, structural validation confirms that each note landed
Average silhouette width is a widely-used measure of clustering quality. Higher values indicate:
1. The qualitative semantic cohesiveness of clusters, and:
2. How well-separated each cluster is from its nearest neighboring cluster.
Although the coefficient is mathematically bounded by [−1, 1], cosine distance between high-dimensional text embeddings is compressed: unrelated notes sit close to orthogonal, so both the within-cluster and nearest-cluster distances land near 0.8. Because silhouette divides the gap between them by the larger of the two, the practical range on embedding data is roughly [−0.05, 0.10] rather than the full interval.
@@ -74,12 +70,14 @@ Developers may swap in other LLM SDKs/APIs and alter prompt syntax in `backend/s
The shared infrastructure that third-party integrations are built on. See [ARCHITECTURE.md](ARCHITECTURE.md) for the design, [ROADMAP.md](ROADMAP.md) for milestones, and [LOW_LEVEL_DESIGN.md](LOW_LEVEL_DESIGN.md) for module contracts.
| Endpoint | Auth | Purpose |
| --- | --- | --- |
| ----------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `POST /v1/notes` | `Authorization: Bearer <api key>` | Bulk push notes. Body `{ notes: [{ id, text, author, x?, y?, color? }] }`, max 5000 per request. |
| `POST /v1/webhooks/:provider` | Per-provider request signature | Inbound provider deliveries. Acks immediately, inserts in the background. |
| `POST /v1/slack/commands` | Slack `v0` request signature | The `/sticky` slash command. Form-encoded rather than JSON, and its response body is shown to the user in Slack. |
Registered providers live in `backend/config/providers.ts`. `rest`, `linear`, and `slack` carry payload mappings today; `github` and `jira` declare transport and OAuth endpoints only, so adding one of those integrations means writing a single normalizer rather than new plumbing.
A provider may also declare an async `enrich` hook. It runs inside the retry queue *after* the request is acknowledged, which is where any network call belongs: normalizers stay pure and synchronous so a delivery can be acked inside Slack's three-second budget. Slack needs this because a reaction event names a message without carrying its text.
@@ -98,7 +96,7 @@ Deliveries are deduplicated on `(provider, external_id)` in the `ingest_events`
### Ingestion — pulling tagged artifacts in
- [x] **Slack** — where decisions actually get made; `/sticky` captures a new note, and an emoji reaction (`:pushpin:` by default) fires an Events API webhook that pulls an existing message in.
- [x] **Slack** — where decisions are made; `/sticky` captures a new note, and an emoji reaction (`:pushpin:` by default) fires an Events API webhook that pulls an existing message in.
- [ ] **Microsoft Teams** — same capture gesture for enterprise shops; message extension plus Graph change notifications.
- [ ] **Jira** — label- or mention-triggered webhook scoped by JQL. (This is where comments typically carry half the backlog's context.)
- [ ] **Linear** — engineering-side tickets and threads; label-triggered GraphQL webhook.
@@ -168,7 +166,7 @@ The key must decode to exactly 32 bytes; the backend refuses to encrypt otherwis
Two capture gestures, both landing in the same ingest pipeline:
- **`/sticky <your note>`** creates a note from what you type.
- `**/sticky <your note>**` creates a note from what you type.
- **Reacting with an emoji** captures the message someone already wrote. The trigger defaults to `:pushpin:` and is set by `SLACK_CAPTURE_REACTION`.
### 1. Create the Slack app
@@ -253,7 +251,7 @@ npm run build
npm run start
```
The API server starts on **http://localhost:3001** (configurable via the `PORT` environment variable).
The API server starts on **[http://localhost:3001](http://localhost:3001)** (configurable via the `PORT` environment variable).
### Start the backend — Development mode
@@ -285,7 +283,7 @@ From the `frontend/` directory:
npm run dev
```
The Vite dev server starts on **http://localhost:5173** by default. Open that URL in a browser.
The Vite dev server starts on **[http://localhost:5173](http://localhost:5173)** by default. Open that URL in a browser.
## Running tests
@@ -312,3 +310,4 @@ This runs Vitest with jsdom. For watch mode during development:
```bash
npm run test:watch
```