3 Commits

Author SHA1 Message Date
a797966f3a Update README.md 2026-09-18 02:20:36 +00:00
31d6729fe6 Update README.md 2026-08-24 00:09:17 +00:00
KS Jannette
1dd17f76f6 hot 2026-08-23 18:19:04 -04:00

View File

@@ -4,13 +4,10 @@
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. 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. 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. 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. These are rankable, editable and exportable to sprint project planning tools.
## Clustering and evaluation: methodology ## 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: Average silhouette width is a widely-used measure of clustering quality. Higher values indicate:
1. The qualitative semantic cohesiveness of clusters, and: 1. The qualitative semantic cohesiveness of clusters, and:
2. How well-separated each cluster is from its nearest neighboring cluster. 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. 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,11 +70,13 @@ 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. 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 |
| --- | --- | --- | | 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/notes` | `Authorization: Bearer <api key>` | Bulk push notes. Body `{ notes: [{ id, text, author, x?, y?, color? }] }`, max 5000 per request. |
| `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. | | `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. 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.
@@ -98,7 +96,7 @@ Deliveries are deduplicated on `(provider, external_id)` in the `ingest_events`
### Ingestion — pulling tagged artifacts in ### 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. - [ ] **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.) - [ ] **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. - [ ] **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: 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`. - **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 ### 1. Create the Slack app
@@ -182,7 +180,7 @@ SLACK_CAPTURE_REACTION=pushpin
EOF EOF
``` ```
`SLACK_SIGNING_SECRET` is already in the integration variables above. There is no OAuth flow here on purpose: a single workspace reading credentials from the environment is far less machinery than an install dance, and the OAuth endpoints in the provider registry stay unused until multi-workspace support is actually needed. `SLACK_SIGNING_SECRET` is already in the integration variables above. There is no OAuth flow here on purpose: a single workspace reading credentials from the environment is a simple, and the OAuth endpoints in the provider registry stay unused until multi-workspace support is actually needed.
### 2. Expose backend ### 2. Expose backend
@@ -253,7 +251,7 @@ npm run build
npm run start 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 ### Start the backend — Development mode
@@ -285,7 +283,7 @@ From the `frontend/` directory:
npm run dev 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 ## Running tests
@@ -312,3 +310,4 @@ This runs Vitest with jsdom. For watch mode during development:
```bash ```bash
npm run test:watch npm run test:watch
``` ```