Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
686973b
Rebuild the PsychSift mark as exact vector geometry
claude Aug 28, 2026
296cf8d
Sharpen the mark's terminals: they are cusps, not rounded caps
claude Aug 28, 2026
255573d
Refit the mark against a high-resolution original; drop the blue points
claude Aug 28, 2026
130ca41
Correct the preview's palette table for the removed points
claude Aug 28, 2026
65515f9
Add the missing fifth arc: the tail hook that makes the stroke sharp
claude Aug 28, 2026
6b781e1
Draw the middle line from one circle, so the channel stops swelling
claude Aug 28, 2026
ec20920
Divide the two strokes with one straight cut
claude Aug 28, 2026
3b6fa2a
Correct the point, centre the mark in its tile, and make the symmetry…
claude Aug 28, 2026
c786ab1
Regenerate the repo-awareness snapshot for the brand docs
claude Aug 28, 2026
e0abe1d
Add clear space, misuse and file guidance to the brand preview
claude Aug 28, 2026
738ff91
Record the tail-tip decision: the clean cut stays
claude Aug 28, 2026
a35243a
Use the new mark for the site icon, favicon and app icons
claude Aug 28, 2026
eb3dcf9
Stop the stacked lockup clipping the wordmark descenders
claude Aug 28, 2026
a971dec
Rename the product to PsychSift and let the symbol stand on its own
claude Aug 28, 2026
8913d38
Merge the squash-merged brand PR back into the branch
claude Aug 28, 2026
9611e8d
Drop the point 7 units clear of the S's tip
claude Aug 28, 2026
60c6e73
Try "From question to source" as the strapline
claude Aug 28, 2026
42b1c39
Cradle the point in the S's throat, concentric with the arc that cups it
claude Aug 28, 2026
bfa9481
Bring the brand sheet up to date, link it from the hub, and set the s…
claude Aug 29, 2026
cc3e693
Merge main, and finish the rename where a person actually reads it
claude Aug 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/plugins/api_marketplace.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "clinical-kb-api-local",
"interface": {
"displayName": "Clinical KB local"
"displayName": "PsychSift local"
},
"plugins": [
{
Expand Down
2 changes: 1 addition & 1 deletion .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "clinical-kb-local",
"interface": {
"displayName": "Clinical KB local"
"displayName": "PsychSift local"
},
"plugins": [
{
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/database-skills.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Database skills catalog

Run `npm run skills` to render the current categories from `catalog.json` and explanations from each canonical skill's frontmatter.
Run `npm run check:skills` to prove that every canonical skill and compatibility alias has valid local metadata and that all Claude, Cursor, and Clinical KB plugin skills satisfy shared safety policies.
Run `npm run check:skills` to prove that every canonical skill and compatibility alias has valid local metadata and that all Claude, Cursor, and PsychSift plugin skills satisfy shared safety policies.

The `skills` skill uses this generated view, explains each unique skill in the chat, and recommends the smallest useful set for the current request. Compatibility aliases remain callable but are not counted or displayed as separate skills.
4 changes: 2 additions & 2 deletions .github/workflows/live-domain-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ jobs:
body="$(curl -sSL --fail --max-time 30 --retry 2 --retry-delay 10 --retry-all-errors "$LIVE_DOMAIN_URL/")"
# The dashboard hydrates client-side (ssr:false), so assert on the
# server-rendered document title, not client-rendered brand text.
echo "$body" | grep -q "<title>Clinical KB</title>" || {
echo "::error::Root responded but does not serve the Clinical KB document"
echo "$body" | grep -q "<title>PsychSift</title>" || {
echo "::error::Root responded but does not serve the PsychSift document"
echo "First 300 bytes of response for diagnosis:"
echo "$body" | head -c 300
exit 1
Expand Down
124 changes: 81 additions & 43 deletions docs/brand/preview.html

Large diffs are not rendered by default.

57 changes: 43 additions & 14 deletions docs/brand/psychsift-logo.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,24 +157,43 @@ approximately — true is what fixes the cut's position; see **The middle line**

### The point

A circle of radius **10.4586** centred at **(60.4716, 17.3581)**.

Measured against the cut, its centre sits **43.95 units along** the cut from the cut's midpoint and
**14.90 units off** it, on the lower stroke's side. Its nearest approach to the S is 13.65 units —
a little over three times the width of the cut, which is what keeps it reading as a separate
particle rather than part of the letter.
A circle of radius **10.4586** centred at **(44.8724, 20.0286)** — which is exactly the centre of
the throat arc.

That is the whole of the placement rule. Because the point shares its centre with the arc that cups
it, the crescent of white between them is a **constant 7.2646 units** all the way round — 17.7232
less the point's own 10.4586 — with zero variation. It is the same idea as the straight cut between
the two strokes: negative space of one measured width, not a gap that happens to look about right.
Move the point off that centre and the crescent immediately starts to taper. Its clearance to the
lower stroke is 8.18 units.

**The small-size point** sits 10 units further out, at **(54.8724, 20.0286)**, opening the crescent
from 7.26 to 11.55. It travels with the widened cut as a set — the wider ink box it produces also
needs its own centring transform, and mixing one variant's point with the other's placement puts
the glyph off-centre in the tile. Below about 20 px the crescent is under two pixels and the point
fuses into the S whatever is done; that is the size, not the placement.

Two earlier positions are worth recording, because both were wrong in instructive ways. It sat at
(60.4716, 17.3581) until 2026-08-28, well clear of the S to the upper right. The nearest point on
the entire S was the upper stroke's sharp tip, aimed straight at the circle from 13.65 units — 2.2
px at a 16 px icon, which antialiasing closes. A sharp point aimed at a circle reads as contact
even when the numbers say otherwise. Dropping it 7 units to (60.4716, 24.3581) fixed the contact
reading and opened the approach to 18.46 units, but left it floating: too far out, and unrelated to
any curve in the mark. Cradling it in the throat resolves both, and gives the mark a hint of the
**P** in PsychSift alongside the S.

An earlier draft of these files had it at (58.9234, 16.5279) with radius 10.2165. That was a
measurement error, not a decision: 1.8 units in and 2.3% small, which crowded the S's shoulder and
made the point look like a stray rather than a counterweight.

With the point included, the glyph spans 0 to 70.93 horizontally and 0 to 100.38 vertically.
With the point included, the glyph spans 0 to 55.33 horizontally and 0 to 100.38 vertically.
The small-size variant, whose point sits further out, spans 0 to 65.33 by the same 0 to 100.38.

### The tile

A square with a corner radius of **3/16 of its side** (18.75%). The glyph is scaled to **80% of the
tile height** and its ink bounding box — S and point together — is centred in the tile. At 512 px
that leaves 112 px clear on the left and right and 51 px top and bottom.
that leaves 143 px clear on the left and right and 51 px top and bottom.

An earlier draft weighted the placement 46% of the way from the S's own centre toward the glyph's
right edge, on the theory that the light point should not drag the heavy S leftward. It
Expand All @@ -183,18 +202,28 @@ bounding box is both simpler and visibly right.

### Small sizes

At 32 px and below the 4.2-unit cut closes up. `psychsift-favicon.svg` is a separate optical cut for
that range: the gap is widened to **7.2 units** by moving each facing edge 1.5 units away from the
other, and the blends are re-solved against the lines they now meet. Because only the facing edges
move, the outer silhouette is identical to the one in the primary file. Use it for favicons, browser
tabs, and anything rendered under 32 px.
At 32 px and below two things close up: the 4.2-unit cut between the strokes, and the 7.26-unit
crescent around the point. `psychsift-favicon.svg` is a separate optical variant for that range, and
it changes both.

The cut is widened to **7.2 units** by moving each facing edge 1.5 units away from the other, with
the blends re-solved against the lines they now meet. Because only the facing edges move, the outer
silhouette is identical to the one in the primary file.

The point slides **10 units out of its cradle**, to (54.8724, 20.0286), opening the crescent to
11.55 units. That widens the ink bounding box to 65.33, so this variant also carries its own
centring transform; the three changes are one set and must not be mixed with the primary variant's
placement. Below about 20 px the crescent is under two pixels and the point fuses into the S
whatever is done — that is the size, not the placement.

Use this variant for favicons, browser tabs, and anything rendered under 32 px.

### The maskable icon

`psychsift-mark-maskable.svg` is full-bleed, because Android crops adaptive icons to whatever shape
the launcher uses. Everything that must survive that crop has to sit inside a centred circle of
**66.7% of the icon's width**. The glyph is scaled to **62% of the height**, which puts its furthest
ink 168 px from the centre of a 512 px icon against the 171 px the safe circle allows. Do not raise
ink 160 px from the centre of a 512 px icon against the 171 px the safe circle allows. Do not raise
that 62%: an earlier draft used 58% with a different centring and still put ink 176 px out, outside
the safe circle.

Expand Down
32 changes: 26 additions & 6 deletions docs/design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,32 @@ image"}` — never a possibly-empty variable alone.
Do not re-draw the paths by hand: they are the exact output of the construction recorded in
`docs/brand/psychsift-logo.md`, whose master artwork is in `public/brand/`, and the two strokes
are one path plus its point reflection — which is the only reason the cut between them stays
parallel. `app/icon.svg` deliberately uses the mark's small-size cut (a wider gap), because that
is the file browsers render at 16–32 px.
- **The tile colour is not the brand's.** `BRAND_LIGHT.tile` / `BRAND_DARK.tile` are pinned to
`--clinical-accent` per theme by `tests/design-token-contract.test.ts`, so the mark rides the
application's accent rather than the brand sheet's Deep Navy. Putting the mark on navy means
moving that accent, which is an application-wide decision — not a brand-asset one.
parallel. `app/icon.svg` and `favicon.ico` deliberately use the mark's **small-size set**, because
they are the files browsers render at 16–32 px: the widened cut (`BRAND_STROKE_PATH_SMALL`), the
point slid out of its cradle (`BRAND_POINT_SMALL`), and the centring that the wider ink box needs
(`BRAND_GLYPH_TRANSFORM_SMALL`). Those three travel together — mixing one with the other
variant's placement puts the glyph off-centre in the tile — and `brandMarkInner(colors, true)`
selects all three from the single `small` flag so a caller cannot pick them apart.
- **The brand sheet is mirrored into `public/`.** `docs/brand/preview.html` is the generated
construction record; `public/brand/preview.html` is a byte-identical copy so the Developer Hub's
"Brand and design" card can link to it as a static file (`/brand/preview.html`). It is the one
hub panel that is not an app route, so `HubPanel.external` marks it, `PanelCard` renders it as a
real anchor rather than a `<Link>` (the client router has no entry for a file), and
`tests/developer-hub-panels.test.ts` both excludes it from the route-existence check and holds
the two copies identical by hash — a stale copy would show a retired mark to the one reader most
likely to trust it. Regenerate the doc, then copy it over the served one.
- **In the app the mark has no tile.** `BrandMark` draws the symbol alone, filled
`--clinical-accent`, standing directly on the page ground — so on a white page it reads as a
mark rather than an app-store tile pasted into the chrome. It uses
`BRAND_GLYPH_TRANSFORM_BARE`, which scales the glyph to fill its box, so it occupies the same
slot the tiled version did. The tiled form survives only where the format has no transparency
to fall back on: `favicon.ico`, `apple-icon`, and the PWA raster icons.
- **The tile is the ground, the ink is the brand.** `BRAND_*.ink` is pinned to `--clinical-accent`
and `BRAND_*.tile` to `--surface-raised`, per theme, by `tests/design-token-contract.test.ts`.
So the symbol rides the application's accent and the tile only ever matches the surface behind
it. The brand sheet's Deep Navy tile lives on in `public/brand/psychsift-mark.svg` for use off
the app; putting the in-app mark on navy would mean moving the accent, which is an
application-wide decision, not a brand-asset one.

## 11. What NOT to do

Expand Down
4 changes: 2 additions & 2 deletions docs/site-map.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Clinical KB Site Map
# PsychSift Site Map

This file is generated by `npm run docs:update` (or `npm run sitemap:update` directly). Run `npm run sitemap:check` to verify it is current.

## Main product routes

- `/` - Main Clinical KB shell. Source: `src/app/(search-app)/page.tsx`.
- `/` - Main PsychSift shell. Source: `src/app/(search-app)/page.tsx`.
- `/calculators` - Compatibility redirect to the shared home at `/?mode=calculators`; a submitted `?q=…&run=1` forwards to `/calculators/search`. Source: `src/app/(search-app)/calculators/page.tsx`.
- `/calculators/search` - Browsable calculator catalogue and scored results. An empty query lists every calculator; a submitted query narrows the same list. Source: `src/app/(search-app)/calculators/search/page.tsx`.
- `/caring-contacts` - Caring Contacts workspace — a synthetic, non-clinical demonstration of caring-contact follow-up. Standalone: it owns its own navigation and is entered from the Tools catalogue. Source: `src/app/caring-contacts/page.tsx`.
Expand Down
18 changes: 9 additions & 9 deletions plugins/clinical-kb/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"name": "clinical-kb",
"version": "0.1.0",
"description": "Repo guidance for Clinical KB, a Next.js clinical reference RAG app.",
"description": "Repo guidance for PsychSift, a Next.js clinical reference RAG app.",
"author": {
"name": "Clinical KB maintainers",
"name": "PsychSift maintainers",
"url": "https://github.com/BigSimmo"
},
"repository": "https://github.com/BigSimmo/Database",
"keywords": ["clinical-kb", "nextjs", "rag", "supabase", "clinical-safety", "local-development"],
"skills": "./skills/",
"interface": {
"displayName": "Clinical KB",
"shortDescription": "Work safely in the Clinical KB Next.js and Supabase RAG repo.",
"longDescription": "Clinical KB provides repo-specific Codex guidance for local server safety, Next.js 16 conventions, Supabase project safety, no-API verification, clinical governance checks, and focused verification choices.",
"developerName": "Clinical KB maintainers",
"displayName": "PsychSift",
"shortDescription": "Work safely in the PsychSift Next.js and Supabase RAG repo.",
"longDescription": "PsychSift provides repo-specific Codex guidance for local server safety, Next.js 16 conventions, Supabase project safety, no-API verification, clinical governance checks, and focused verification choices.",
"developerName": "PsychSift maintainers",
"category": "Developer Tools",
"capabilities": ["Read", "Write"],
"websiteURL": "https://github.com/BigSimmo/Database",
"defaultPrompt": [
"Run the safe Clinical KB local server.",
"Verify my Clinical KB change without API calls.",
"Review this Clinical KB RAG change."
"Run the safe PsychSift local server.",
"Verify my PsychSift change without API calls.",
"Review this PsychSift RAG change."
],
"brandColor": "#0B6F86"
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/clinical-kb/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Clinical KB Codex Plugin
# PsychSift Codex Plugin

This plugin follows the repo-local structure used by `openai/plugins`:

Expand Down
6 changes: 3 additions & 3 deletions plugins/clinical-kb/skills/clinical-kb-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
name: clinical-kb-workflow
description: Use when working in the D:\Repos\Database Clinical KB repo, especially for local run, UI/browser QA, Supabase/OpenAI/RAG changes, clinical governance, dependency/upload shortcuts, or choosing verification.
description: Use when working in the D:\Repos\Database PsychSift repo, especially for local run, UI/browser QA, Supabase/OpenAI/RAG changes, clinical governance, dependency/upload shortcuts, or choosing verification.
---

# Clinical KB Workflow
# PsychSift Workflow

Use this skill for `D:\Repos\Database`, the Clinical KB Next.js clinical reference RAG app.
Use this skill for `D:\Repos\Database`, the PsychSift Next.js clinical reference RAG app.
Root `AGENTS.md` remains authoritative. If these notes drift, inspect the repo before acting.

## Repo Basics
Expand Down
Loading
Loading