Compare commits

...

23 commits
v0.4.1 ... main

Author SHA1 Message Date
f351d46d81 Adopt staged WORK-RECORDS generation and catch the index up.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The generated index had drifted from the workplan files. The opt-in lets
the pre-commit hook rebuild WORK-RECORDS.md in the same commit as the
workplan it indexes.

Assistant: grok
Assistant-Session: 01a17f9d-fe9d-7d72-9a22-6304f1a2a790
2026-10-28 00:31:32 +01:00
repo-manager
a79a4d803e repo.work.assign_missing_identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
source: repo-manager
reason: deterministic projection registration

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
2026-09-04 23:39:30 +02:00
88da76f7f1 docs(workplan): close Forgejo package migration
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
2026-09-04 23:36:43 +02:00
65247c9320 release: @whynot/design v0.4.2 on Forgejo
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
2026-09-04 23:26:28 +02:00
repo-manager
77cf04eb5e chore(registrar): assign State Hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:49:15 +02:00
custodian-sync
127d3f6811 chore(consistency): sync task status from DB [auto]
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Has been cancelled
Updated by fix-consistency on 2026-08-29:
  - update .custodian-brief.md for whynot-design

Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:49:12 +02:00
5b7985f853 Refresh SCOPE.md and generate WORK-RECORDS.md after WP-0003 close.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Current State now reflects finished workplans plus residual
WHYNOT-IN-0001. The generated index lists live workplans and the open
intake; archived WP-0003 is omitted.

Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:48:01 +02:00
custodian-sync
36dab88760 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-29:
  - update .custodian-brief.md for whynot-design

Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:47:07 +02:00
faec0e6807 Close WHYNOT-WP-0003 after all nine downstream-consumption tasks finished.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Hand the remaining npm-read token lane to WHYNOT-IN-0001 as a residual
intake. T09's contract-parity deferral is already a resolved decision.

Assistant: grok
Assistant-Session: 01a04d7c-846d-77e3-af8d-020019e4eb61
2026-08-29 14:45:50 +02:00
ba10e325d3 fix(workplans): qualify archived ad-hoc identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The live-file pass missed these: archived ad-hocs carry a YYMMDD- filename
prefix, so the ADHOC-* glob did not match them. They still derive from the
forge, so they are live records rather than dead files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-28 00:34:05 +02:00
bd9ed7392c docs(agents): repoint remote State Hub URL to the in-cluster address
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
The remote row pointed at 127.0.0.1:18000, a reverse tunnel back to the
workstation. On railiance01 the State Hub runs in the cluster on that same
machine, so the request left the box and came back to reach a local service.

Refs CUST-WP-0067-T07

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 00:22:22 +02:00
custodian-sync
a4273562b1 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-22:
  - update .custodian-brief.md for whynot-design

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 16:10:18 +02:00
custodian-sync
3cfee733e5 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-22:
  - update .custodian-brief.md for whynot-design

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 16:09:57 +02:00
custodian-sync
5b38e07828 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-22:
  - update .custodian-brief.md for whynot-design

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 16:08:47 +02:00
custodian-sync
e915d4c7a2 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-08-22:
  - update .custodian-brief.md for whynot-design

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 16:08:33 +02:00
9ffe187731 chore(identifiers): derive WHYNOT-WP-0003 UUID
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 16:08:09 +02:00
4b62cffc86 Adopt Target Revenue Source License V1C1 (org-wide preliminary rollout)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Maintainer decision, 2026-07-29: adopts TRSL V1C1 as this repo's
preliminary governing license, per target-revenue's
workplans/TREV-WP-0008-governance-and-pilot-rollout.md T05. Full
specialist legal review is deferred until out of beta (target-revenue
SCOPE.md §1). No Phase is yet declared for this repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 01:17:11 +02:00
6de4d31bde Migrate npm and git refs to Forgejo (RAIL-HO-WP-0006)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 20s
2026-07-09 11:59:08 +02:00
8c24e44857 CUST-WP-0055 T07: add archive workplan terminology grandfather note
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
2026-07-08 20:26:38 +02:00
e9c6aab5f5 docs: workplan-first agent guidance prose (CUST-WP-0055 T04 batch 2)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
2026-07-08 16:41:21 +02:00
f150aedab8 Regenerate agent instructions from state-hub templates (CUST-WP-0055 T01)
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 4s
Sync AGENTS.md, CLAUDE.md, and .claude/rules from updated project_rules
templates: workplan-first session protocol, legacy terminology footnote,
and GET /workplans/ examples.
2026-07-08 14:50:39 +02:00
b3a8e97adc Add Forgejo CI smoke workflow (enablement template)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
2026-07-08 12:36:58 +02:00
f0defe7cbe Draft capability entry (reuse-surface REUSE-WP-0017-T04, cohort 3)
Honest first-pass maturity vector grounded in README/docs/tests present
in this repo; no invented evidence. Flagged for human review before
publish. See reuse-surface history/2026-07-06-coverage-classification.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 19:50:54 +02:00
31 changed files with 612 additions and 90 deletions

View file

@ -20,7 +20,7 @@ Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run wa
| Agent runtime | How to orient |
| --- | --- |
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=whynot-design` is for coordination, not secret vending |
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workstreams; **still** use `warden route` for credential ownership |
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
### Quick routing table

View file

@ -1,6 +1,6 @@
## First Session Protocol
Triggered when `get_domain_summary("consumer")` shows **no workstreams**.
Triggered when `get_domain_summary("consumer")` shows **no workplans**.
The project is registered but work has not yet been structured.
**Step 1 — Read, don't write**
@ -11,27 +11,31 @@ The project is registered but work has not yet been structured.
**Step 2 — Survey in-progress work**
Look for TODOs, open branches, half-finished files. Note done vs. started but incomplete.
**Step 3 — Propose workstreams to Bernd**
Propose 1–3 workstreams — each a coherent strand, weeks to months, anchored to a
**Step 3 — Propose workplans to Bernd**
Propose 1–3 workplans — each a coherent strand, weeks to months, anchored to a
roadmap phase. **Wait for approval before creating.**
**Step 4 — Create workplan file first, then DB record (ADR-001)**
**Step 4 — Write the workplan file; fix-consistency registers it (ADR-001)**
```
workplans/WHYNOT-WP-NNNN-<slug>.md ← write this first
workplans/WHYNOT-WP-NNNN-<slug>.md ← write this, commit it
```
Then register in the hub:
```
create_workstream(topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", title="...", owner="...", description="...")
create_task(workstream_id="<id>", title="...", priority="high|medium|low")
Then register by running the consistency check — do **not** call
`create_workplan`/`create_task` yourself; manual registration duplicates what
C-06 creates from the file:
```bash
statehub fix-consistency --repo whynot-design
```
C-06 creates the hub workplan + tasks and writes `state_hub_workstream_id`
(legacy frontmatter name — holds the workplan UUID) and `state_hub_task_id`
back into the file.
**Step 5 — Record the setup**
```
add_progress_event(
summary="First session: structured consumer into N workstreams, M tasks",
summary="First session: structured consumer into N workplans, M tasks",
event_type="milestone",
topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a",
detail={"workstreams": [...], "tasks_created": M}
detail={"workplans": [...], "tasks_created": M}
)
```

View file

@ -44,7 +44,7 @@ For each file with `status: ready`, `active`, or `blocked`, note pending
**Step 4 — Present brief**
1. **Active workstreams** for `consumer` — title, task counts, blocking decisions
1. **Active workplans** for `consumer` — title, task counts, blocking decisions
2. **Pending tasks** from `workplans/` + any `[repo:whynot-design]` hub tasks
3. **Goal guidance** — if `goal_guidance` in summary:
- `needs_workplan`: surface as top action — *"Repo goal '{title}' has no workplan yet"*
@ -52,33 +52,40 @@ For each file with `status: ready`, `active`, or `blocked`, note pending
4. **Suggested next action** — highest-priority open item
5. **SBOM status** — flag if `last_sbom_at` is unset for this repo
If no workstreams: follow First Session Protocol (`first-session.md`).
If no workplans: follow First Session Protocol (`first-session.md`).
**During work:** `record_decision()` · `add_progress_event()` · `resolve_decision()`
> State Hub is a *read model*. Bootstrap tools (`create_workstream`, `create_task`)
> are First Session Protocol only. Work structure belongs in repo files (ADR-001).
> State Hub is a *read model*. **Never register workplans or tasks by hand**
> (`create_workplan`, `create_task`) — write the workplan file in `workplans/`
> and run `fix-consistency`; C-06 registers the workplan and tasks and writes
> IDs back into the file. Manual registration creates duplicates when
> fix-consistency runs. Work structure belongs in repo files (ADR-001).
>
> Legacy: `create_workstream` and `/workstreams/` remain as metered aliases —
> see `workplan-convention.md` (compatibility footnote).
**Session close:**
With MCP tools:
```
add_progress_event(summary="...", topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", workstream_id="<uuid>")
add_progress_event(summary="...", topic_id="cee7bedf-2b48-46ef-8601-006474f2ad7a", workplan_id="<uuid>")
```
Without MCP tools:
```bash
curl -s -X POST http://127.0.0.1:8000/progress/ \
-H "Content-Type: application/json" \
-d '{"topic_id":"cee7bedf-2b48-46ef-8601-006474f2ad7a","workstream_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
-d '{"topic_id":"cee7bedf-2b48-46ef-8601-006474f2ad7a","workplan_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
```
If workplan files were modified, ensure the local copy is up to date first:
If workplan files were modified, ensure the local copy is up to date first,
then sync from the repo checkout:
```bash
git -C <repo_path> pull --ff-only
cd ~/state-hub && make fix-consistency REPO=whynot-design
git pull --ff-only
statehub fix-consistency
```
For repos where implementation runs on a remote machine (e.g. CoulombCore),
use the combined target which pulls before fixing:
use the pull-before-fix mode from any shell with the State Hub CLI:
```bash
cd ~/state-hub && make fix-consistency-remote REPO=whynot-design
statehub fix-consistency --repo whynot-design --remote
```
**C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes

View file

@ -5,7 +5,7 @@ ID prefix: `WHYNOT-WP-`
Work items originate as files in this repo **before** being registered in the hub.
Canonical workplan/workstream frontmatter statuses are:
Canonical workplan frontmatter statuses are:
`proposed`, `ready`, `active`, `blocked`, `backlog`, `finished`, `archived`.
Use `proposed` for a newly drafted plan, `ready` after review against current
repo state, and `finished` when implementation is complete. `stalled` and
@ -16,14 +16,15 @@ prefix: `YYMMDD-WHYNOT-WP-NNNN-<slug>.md`. The frontmatter id remains
unchanged; the prefix is only for quick visual reference.
Small opportunistic tasks discovered during another session use **Ad Hoc Tasks**:
`workplans/ADHOC-YYYY-MM-DD.md`, workstream slug `adhoc-YYYY-MM-DD`, and task ids
`workplans/ADHOC-YYYY-MM-DD.md`, workplan slug `adhoc-YYYY-MM-DD`, and task ids
`ADHOC-YYYY-MM-DD-T01`, `T02`, etc. Use adhocs only for low-risk work completed
directly. Promote anything requiring analysis, design, approval, dependencies, or
multiple planned phases into a normal workplan.
Ecosystem todos from other agents arrive as `[repo:whynot-design]` hub tasks —
visible at session start. Pick one up by creating the workplan file, then registering
the workstream.
visible at session start. Pick one up by creating the workplan file, committing,
and running `statehub fix-consistency` — C-06 registers the workplan in the hub.
Never register by hand with `create_workplan` (legacy MCP alias: `create_workstream`).
Task blocks use this shape:
@ -37,4 +38,18 @@ state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
Status progression is `todo` → `progress` → `done`; use `wait` for waiting or
blocked work and `cancel` for stopped work.
Workplan frontmatter carries `state_hub_workstream_id` — a legacy field name
kept for compatibility; it holds the hub workplan UUID and is written by
fix-consistency. Do not edit or rename it.
### Legacy terminology (compatibility footnote)
**Workplan** is the fleet term — see
`the-custodian/canon/standards/workplan-terminology-fleet_v0.1.md`.
**Workplan** is legacy only: some API routes (`/workstreams/`), params
(`workstream_id`), MCP aliases (`create_workstream`), and the frontmatter field
above remain until `STATE-WP-0069` retires them via legacy-meter. Treat those
identifiers as workplan IDs. Prefer `GET /workplans/` and `workplan_id` in new
examples and scripts.
<!-- Ralph Loop rules and HEUREKA sequence: ~/.claude/CLAUDE.md — do not duplicate here -->

View file

@ -1,8 +1,8 @@
<!-- custodian-brief: generated by fix-consistency — do not edit manually -->
# Custodian Brief — whynot-design
**Domain:** infotech
**Last synced:** 2026-06-30 07:54 UTC
**Domain:** consumer
**Last synced:** 2026-08-29 12:49 UTC
**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)*
## Active Workstreams
@ -13,6 +13,6 @@
## MCP Orientation (when available)
If the state-hub MCP server is reachable, call:
`get_domain_summary("infotech")`
`get_domain_summary("consumer")`
This provides richer cross-domain context.
If the MCP call fails, use this file as your orientation source.

View file

@ -0,0 +1,29 @@
# Canonical CI smoke template (tier 1 routing drill).
# Copy to: .forgejo/workflows/ci-smoke.yaml in consumer repos.
name: CI Smoke
on:
push:
branches:
- main
workflow_dispatch:
jobs:
host-smoke:
runs-on: self-hosted
steps:
- name: Routing probe (host runner)
run: |
set -eu
echo "repository=${GITHUB_REPOSITORY:-unknown}"
echo "sha=${GITHUB_SHA:-unknown}"
echo "runner=${RUNNER_NAME:-unknown}"
uname -a
container-smoke:
runs-on: ubuntu-latest
steps:
- name: Routing probe (container label)
run: |
set -eu
echo "container-smoke ok for ${GITHUB_REPOSITORY:-unknown}"

View file

@ -0,0 +1 @@
{"version":1,"repo_slug":"whynot-design"}

View file

@ -0,0 +1,8 @@
# Explicit opt-in recipe; no environment files or external make includes.
CUSTODIAN_SOURCE ?= /home/worsch/the-custodian
GENERATED_REPO_SLUG ?= whynot-design
.PHONY: generated-work-records generated-work-records-check
generated-work-records:
python3 "$(CUSTODIAN_SOURCE)/scripts/generate_staged_work_records.py" --repo . --repo-slug "$(GENERATED_REPO_SLUG)"
generated-work-records-check:
python3 "$(CUSTODIAN_SOURCE)/scripts/generate_staged_work_records.py" --repo . --repo-slug "$(GENERATED_REPO_SLUG)" --check

8
.npmrc
View file

@ -1,6 +1,6 @@
# @whynot/* is published to and installed from the coulomb Gitea npm registry.
# @whynot/* is published to and installed from the coulomb Forgejo npm registry.
# The auth token is NOT stored here — set NPM_AUTH_TOKEN in your shell/CI.
# It is operator/OpenBao-owned (credential-routing.md: tokens route, never vend);
# obtain a Gitea package token from the operator. Publish flow: see PUBLISHING.md.
@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/
//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}
# obtain a Forgejo package token through the governed lane. Publish flow: see PUBLISHING.md.
@whynot:registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
//forgejo.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}

View file

@ -19,7 +19,13 @@ there is no MCP server for Codex agents.
| Context | URL |
|---------|-----|
| Local workstation | `http://127.0.0.1:8000` |
| Remote via tunnel | `http://127.0.0.1:18000` |
| Remote (railiance01, in-cluster) | `http://10.43.68.154:8000` |
| Optional local edge relay | http://127.0.0.1:18080 |
When an operator has enabled the edge relay, set API_BASE to the relay URL.
Queueable writes return an explicit queued receipt if the central hub is
unreachable. Treat that as pending local evidence, then ask the operator to run
statehub outbox status/replay after connectivity returns.
### Orient at session start
@ -27,8 +33,8 @@ there is no MCP server for Codex agents.
# Offline brief — works without hub connection
cat .custodian-brief.md
# Active workstreams for this domain
curl -s "http://127.0.0.1:8000/workstreams/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \
# Active workplans for this domain
curl -s "http://127.0.0.1:8000/workplans/?topic_id=cee7bedf-2b48-46ef-8601-006474f2ad7a&status=active" \
| python3 -m json.tool
# Check inbox
@ -51,12 +57,12 @@ curl -s -X POST http://127.0.0.1:8000/progress/ \
"summary": "what was done",
"event_type": "note",
"author": "codex",
"workstream_id": "<uuid>",
"workplan_id": "<uuid>",
"task_id": "<uuid>"
}'
```
Omit `workstream_id` / `task_id` when not applicable.
Omit `workplan_id` / `task_id` when not applicable.
### Update task status
@ -80,7 +86,7 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
## Session Protocol
**Start:**
1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe)
1. `cat .custodian-brief.md` — domain goal and open workplans (offline-safe)
2. Check inbox: `GET /messages/?to_agent=whynot-design&unread_only=true`; mark read
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
4. Check human-needed tasks: `GET /tasks/?needs_human=true`
@ -92,12 +98,12 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
**Close:**
1. Update workplan file task statuses to reflect progress
2. Log: `POST /progress/` with a summary of what changed
3. Note for the custodian operator: after workplan file changes, run from
`~/state-hub`:
3. After workplan file changes, run:
```bash
make fix-consistency REPO=whynot-design
statehub fix-consistency
```
This syncs task status from files into the hub DB.
Coding agents should run this directly; ask the operator only if the CLI or
State Hub API is unavailable. This syncs task status from files into the hub DB.
---
@ -123,7 +129,7 @@ Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run wa
| Agent runtime | How to orient |
| --- | --- |
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=whynot-design` is for coordination, not secret vending |
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workstreams; **still** use `warden route` for credential ownership |
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
### Quick routing table

View file

@ -19,7 +19,7 @@ ls -la
# .gitea/ .github/ scripts/ tests/
# 3. Replace placeholder host names.
# Search-and-replace `gitea.example.com` with your actual Gitea host in:
# Search-and-replace `forgejo.example.com` with your actual Forgejo host in:
# - package.json
# - .npmrc
# - .gitea/workflows/ci.yml (and .github/ if you keep that)
@ -54,8 +54,8 @@ git push
## Notes
- The `git+ssh` URL in `package.json` (`gitea.example.com/whynot/whynot-design.git`) is a placeholder. Replace with your actual Gitea host.
- The same goes for `.npmrc` and the registry URL in `.gitea/workflows/ci.yml` (commented out — uncomment when you stand up a Gitea Packages registry).
- The `git+ssh` URL in `package.json` (`forgejo.example.com/whynot/whynot-design.git`) is a placeholder. Replace with your actual Forgejo host.
- The same goes for `.npmrc` and the registry URL in `.gitea/workflows/ci.yml` (commented out — uncomment when you stand up a Forgejo Packages registry).
- `.gitea/workflows/ci.yml` and `.github/workflows/ci.yml` are identical. Keep whichever your forge uses and delete the other.
- The `examples/showcase/index.html` page uses `importmap` to load Lit from esm.sh **for the standalone-no-build case**. When you have a bundler in the consuming app, the bundler resolves `lit` from `node_modules` and the importmap is irrelevant.

View file

@ -6,6 +6,15 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version
## [Unreleased]
## [0.4.2] — 2026-09-04
### Changed
- **Forgejo is now the canonical package registry** (WHYNOT-WP-0004). Package,
consumer, and release configuration consistently use
`https://forgejo.coulomb.social/api/packages/coulomb/npm/`; the legacy Gitea
publication remains historical evidence only.
### Added
- **Lit adapter completed + refresh pipeline** (WHYNOT-WP-0002, Phases 3–6). The

View file

@ -6,7 +6,6 @@
@.claude/rules/first-session.md
@.claude/rules/workplan-convention.md
@.claude/rules/stack-and-commands.md
@.claude/rules/designbook-propagation.md
@.claude/rules/architecture.md
@.claude/rules/repo-boundary.md
@.claude/rules/credential-routing.md

View file

@ -23,12 +23,12 @@ This is the inverse of whynot-design's own upstream machinery
## 1. Pin a version
`@whynot/design` is published to the coulomb Gitea npm registry. Pin an exact
`@whynot/design` is published to the coulomb Forgejo npm registry. Pin an exact
tagged version; your lockfile becomes the real pin.
```bash
# .npmrc in your repo (see PUBLISHING.md for the read-token routing)
# @whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/
# @whynot:registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
npm i @whynot/design@0.3.0 lit
```

View file

@ -73,7 +73,7 @@ After PR merge:
1. Bump `package.json` version following the [versioning rules in `DesignSystemIntroduction.md` §5](./DesignSystemIntroduction.md#5-versioning-discipline).
2. Move the `## [Unreleased]` block in `CHANGELOG.md` under a new `## [vX.Y.Z] — YYYY-MM-DD` header.
3. Tag: `git tag vX.Y.Z && git push --tags`.
4. CI's release workflow attaches the CHANGELOG slice to the Gitea release. (If publishing to a registry, this is where `npm publish` runs.)
4. CI's release workflow attaches the CHANGELOG slice to the Forgejo release. (If publishing to a registry, this is where `npm publish` runs.)
5. Renovate picks up the new tag in consumer repos within ~24h. Or manually:
```sh

View file

@ -112,15 +112,15 @@ In order of effort:
**a) pnpm workspaces (recommended for now)** — put `whynot-design` and your consuming app in the same monorepo (or use `file:` / `link:` references). Zero registry, zero auth, instant updates.
**b) Install directly from Gitea** — no registry needed.
**b) Install directly from Forgejo** — no registry needed.
```sh
pnpm add git+ssh://git@gitea.example.com/whynot/whynot-design.git#v0.2.0
pnpm add git+ssh://git@forgejo.coulomb.social/coulomb/whynot-design.git#v0.2.0
```
Pin to a tag, not `main`. Tag-pinning is the entire versioning discipline at A1.
When you outgrow either (second team needs read access without cloning, semver resolution becomes valuable), publish to **Gitea Packages** (native npm protocol) or a private Verdaccio.
When you outgrow either (second team needs read access without cloning, semver resolution becomes valuable), publish to **Forgejo Packages** (native npm protocol) or a private Verdaccio.
### 4.2 What a consumer imports
@ -345,7 +345,7 @@ This staging is exactly the *"low-cost learning first"* posture in `whynot-contr
For whoever is bootstrapping this repo right now:
- [ ] Push the seed contents to `gitea.coulomb.social/coulomb/whynot-design`.
- [ ] Push the seed contents to `forgejo.coulomb.social/coulomb/whynot-design`.
- [ ] Cut the first real tag with `make release VERSION=x.y.z` (see §6 — *Release ritual*) so consumers can pin.
- [ ] Add the repo as a remote dependency in **one** consuming app (the Django one) and verify imports work end-to-end. Follow [`MultiFrameworkSupport.md` §Django](./MultiFrameworkSupport.md#django-server-rendered-templates--htmx).
- [ ] Open one trivial PR against `whynot-design` (e.g. a CHANGELOG typo) to confirm CI passes end-to-end.

151
LICENSE Normal file
View file

@ -0,0 +1,151 @@
# Target Revenue Source License
**Version 1.0, Candidate 1 (V1C1)**
---
> **PRELIMINARY CANDIDATE — SUBJECT TO CHANGE — NOT FINAL**
>
> This repository is governed by the Target Revenue Source License
> (TRSL), Version 1, Candidate 1. This is the framework's first working
> candidate, adopted as the org's preliminary operating license across
> all repos (maintainer decision, 2026-07-29) during the build/alpha
> stage — see `SCOPE.md` §1 and Appendix A of the canonical text (link
> below) for the alpha/beta risk-acceptance decision this reflects and
> what it does and does not mean. Full specialist legal review is
> explicitly deferred until the framework moves out of beta.
>
> **Canonical source, full candidate-status banner, and Appendix A
> (non-normative candidate notes tracking every open item):** the
> `coulomb` org's `target-revenue` repository,
> `specs/TargetRevenueSourceLicense-V1C1.md` — this file is the operative
> legal text (Preamble through Section 11) only; the canonical document
> is authoritative if this copy and that document ever diverge.
---
## Preamble
This Target Revenue Source License ("**License**") governs the Software identified in the applicable Phase Manifest. It implements the Target Revenue Framework: a defined development Phase accumulates Development Credit and Remission Credit against an immutable Initial Target until the Milestone Release automatically and irrevocably converts to a declared permissive Future License.
Commercial beneficiaries fund the creation and early availability of a software improvement; once the declared target is satisfied, the governed release becomes permissively open source.
## 1. Definitions
Capitalized terms used in this License have the meanings given below. Where a term is also defined in the Phase Manifest or Target Ledger for a specific Phase, the Phase Manifest and Target Ledger govern the *values* (amounts, dates, identifiers) and this License governs the *legal effect* of those values — the two must not be read as conflicting definitions of the same concept.
**"Commercial Entitlement"** means a right, purchased or otherwise granted under a Commercial Use Agreement, to make Commercial Use of the Software during a Phase.
**"Commercial Use"** means billing, invoicing, or otherwise charging any customer a fee, subscription, license fee, or other consideration for or in connection with use of the Software, at any time before the Conversion Event for the applicable Phase, regardless of whether the person or organization billed would otherwise qualify for Noncommercial Use. Commercial Use occurs by virtue of such billing alone, whether or not the resulting payment is registered with the Trust Service; in particular, billing a customer for pre-conversion use of the Software without recording the corresponding payment in the applicable Phase's Target Ledger is Commercial Use without a valid Commercial Entitlement — a violation of Section 3, addressed under Section 7 and, where applicable, the Enforcement Network described in the canonical repository's `specs/EnforcementNetworkConcept.md`.
**"Commercial Use Agreement"** means the separate agreement, referenced by the applicable Phase Manifest, under which a Commercial Entitlement is purchased or granted. This License does not itself set pricing, metering, or payment terms — those are governed by the Commercial Use Agreement.
**"Conversion Event"** means the moment the Outstanding Target for a Phase reaches zero, as computed from the Phase Manifest and Target Ledger per the Target Ledger Specification. The Conversion Event occurs automatically and is not conditioned on any declaration, attestation, or other act by the Licensor or any Trust Service.
**"Development Credit"** means the portion of a collected and settled payment explicitly allocated toward satisfying the Initial Target of a specific Phase, as recorded in that Phase's Target Ledger.
**"Future License"** means the permissive license identified in the applicable Phase Manifest, being either the MIT License or the Apache License, Version 2.0, which applies to the Milestone Release upon the Conversion Event.
**"Initial Target"** means the immutable monetary target declared for a Phase in its Phase Manifest.
**"Licensor"** means **Binky Hedgehog GmbH**, the party that publishes the Phase Manifest and holds the rights necessary to grant this License and the Future License for the Milestone Release.
**"Milestone Release"** means the precisely identified software release designated in the applicable Phase Manifest, identified by an immutable source revision, release artifact, or cryptographic digest.
**"Noncommercial Use"** means use of the Software for personal purposes, private study, hobby or amateur projects; use by any charitable organization, educational institution, public research organization, or government institution acting in a non-revenue-generating capacity; or other use of a materially similar character.
**"Outstanding Target"** means, at any time, `max(0, Initial Target − cumulative Development Credit − cumulative Remission Credit)` for a Phase, as computed from that Phase's Target Ledger.
**"Phase"** means a bounded development undertaking governed by one Initial Target, one Milestone Release, one degeneration policy, and one Future License declaration, as declared in a Phase Manifest.
**"Phase Manifest"** means the published, immutable declaration identifying a Phase, its Milestone Release, Initial Target, Future License, degeneration policy, and Target Ledger location, as specified in the Phase Manifest Specification.
**"Remission Credit"** means a transparent, non-revenue reduction of a Phase's Outstanding Target, generated under that Phase's published degeneration policy and recorded in the Target Ledger.
**"Settled Payment"** means a payment that has cleared through its payment processor and is no longer subject to reversal in the ordinary course (chargeback, dispute, or equivalent), as further specified by the applicable Commercial Use Agreement or monetization extension.
**"Software"** means the source code, object code, and associated documentation of the Milestone Release identified in the applicable Phase Manifest.
**"Target Ledger"** means the append-only record of Development Credit, Remission Credit, and correction entries for a Phase, as specified in the Target Ledger Specification.
**"You"** or **"Licensee"** means the individual or entity exercising rights under this License.
## 2. Grant of Rights for Noncommercial Use
Subject to the terms of this License, the Licensor grants You a worldwide, royalty-free, non-exclusive license, during the applicable Phase, to:
(a) use, reproduce, and study the Software for any Noncommercial Use;
(b) modify the Software and create derivative works of it for any Noncommercial Use; and
(c) redistribute the Software and Your modifications, in source or object form, for any Noncommercial Use, provided that You include this License, unmodified, with any such redistribution, and that You do not remove or alter any copyright, patent, trademark, or attribution notices contained in the Software.
This grant does not extend to Commercial Use. Commercial Use requires a Commercial Entitlement under Section 3.
## 3. Commercial Use
You may not make Commercial Use of the Software during the applicable Phase unless You hold a valid, current Commercial Entitlement under a Commercial Use Agreement with the Licensor covering the applicable Phase. A Commercial Entitlement granted under one Phase's Commercial Use Agreement does not extend to a later Phase's Milestone Release unless the Commercial Use Agreement expressly says so.
This Section 3 states the existence and boundary of the commercial-use restriction. It does not itself set pricing, invoicing, metering, audit rights, or payment terms — those are governed exclusively by the applicable Commercial Use Agreement.
## 4. Patent License
Subject to the terms of this License, each contributor to the Software grants You, during the applicable Phase and solely to the extent of rights granted under Sections 2 and 3, a perpetual (subject to the termination below), worldwide, non-exclusive, no-charge, royalty-free patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Software, limited to those patent claims licensable by that contributor that are necessarily infringed by their contribution(s) alone or by combination of their contribution(s) with the Software.
If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Software or a contribution incorporated within it constitutes direct or contributory patent infringement, then any patent licenses granted to You under this Section 4 for the Software shall terminate as of the date such litigation is filed.
## 5. Automatic Conversion to the Future License
**5.1 Automatic effect.** Upon the Conversion Event for a Phase, the rights and restrictions in Sections 3 (Commercial Use) of this License, as they apply to that Phase's Milestone Release, terminate automatically. In their place, the Milestone Release is licensed under the Future License identified in that Phase's Phase Manifest, effective as of the Conversion Event, without any further act, declaration, or attestation required by the Licensor, any Trust Service, or any other party.
**5.2 Irrevocability.** Once a valid Conversion Event has occurred for a Phase, no subsequent refund, chargeback, accounting correction, dispute, or termination of this License for an unrelated breach shall revoke, suspend, or otherwise impair the Future License grant for that Phase's Milestone Release. Any shortfall or dispute arising after a Conversion Event is a commercial or accounting matter between the relevant parties and does not reinstate a commercial-use restriction over already-converted Software.
**5.3 Prior freedom preserved.** A later Phase covering subsequent improvements to the Software does not restrict, withdraw, or otherwise affect the rights granted under the Future License for an earlier Phase's already-converted Milestone Release.
**5.4 Evidence, not cause.** A Trust Service may publish a Conversion Attestation documenting a Conversion Event. Such an attestation is evidence that the Conversion Event occurred; it is not a condition of, and its absence or delay does not postpone, the automatic effect described in Section 5.1. Any person may independently verify whether a Conversion Event has occurred directly from the Phase Manifest and Target Ledger.
## 6. Successive Phases
The Licensor may declare a new Phase covering subsequent improvements to the Software following a Milestone Release's Conversion Event. Each Phase is independently governed by its own Phase Manifest, Initial Target, degeneration policy, and Target Ledger. Nothing in a later Phase's Phase Manifest may be construed to reduce or withdraw rights already granted under Section 5 for an earlier Phase's Milestone Release.
## 7. Term and Termination
**7.1 Term.** This License applies to the Software for the duration of the applicable Phase, and, for the Milestone Release, indefinitely following that Phase's Conversion Event under the Future License.
**7.2 Termination for breach.** If You breach Section 3 (Commercial Use) or Section 2(c) (redistribution notice requirement), the Licensor may terminate this License as to You. Before such termination becomes effective, the Licensor shall provide You written notice of the breach; if You cure the breach within thirty (30) days of that notice, this License continues in effect. A second breach of the same provision within twelve (12) months may be terminated immediately without a further cure opportunity.
**7.3 Effect of termination.** Termination under this Section 7 affects only Your rights under Sections 2 and 3 for the Phase in which the breach occurred. It does not affect any rights already vested under Section 5 (Automatic Conversion) for a Milestone Release whose Conversion Event has already occurred, per Section 5.2.
**7.4 Public record of breach and resolution.** The Licensor shall cause the Trust Service to publish, as part of the public record for the affected Phase, notice of: (a) any breach notice issued under Section 7.2, stating the general nature of the breach and the date of notice; (b) whether the breach was cured within the applicable cure period, and the date of cure; and (c) any termination determination made under this Section 7, including its effective date and scope. This public record exists to give the ecosystem a transparent, verifiable conformity signal for the Phase, distinct from and in addition to the Development Credit and Remission Credit facts already published under Section 5.4 and the Target Ledger Specification.
A breach that You dispute, and that has not been finally determined, shall be recorded as **alleged**; it shall be recorded as **determined** only once the cure period has run without cure, or the dispute has been resolved against You under the applicable Commercial Use Agreement's dispute process, if any. The Trust Service shall update the record promptly upon resolution in either direction. Recording an alleged or determined breach under this Section 7.4 is a ministerial act of publishing the Licensor's determination (or a dispute process's outcome); it does not give the Trust Service discretionary authority to decide whether a breach occurred, consistent with Section 5.4's evidence-not-cause principle.
Whether, and under what conditions, the public record identifies a Commercial Entitlement holder by name is governed exclusively by the applicable Commercial Use Agreement, which the Licensor and that Commercial Entitlement holder negotiate and agree to directly. This License does not itself set a naming default. Where no Commercial Use Agreement addresses the question, or where the affected party has no Commercial Use Agreement at all (for example, a Section 2(c) breach by a Noncommercial Use licensee), the public record states the Phase and breach category only, without naming the party.
## 8. Disclaimer of Warranty
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. THE LICENSOR DOES NOT WARRANT THAT THE SOFTWARE WILL BE ERROR-FREE OR THAT ANY PHASE WILL REACH ITS CONVERSION EVENT.
## 9. Limitation of Liability
IN NO EVENT SHALL THE LICENSOR OR ANY CONTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EXCEPT TO THE EXTENT SUCH LIMITATION IS PROHIBITED BY APPLICABLE LAW.
## 10. Trademarks
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary attribution.
## 11. General Provisions
**11.1 Governing law and venue.** Adopted for alpha/beta 2026-07-29: disputes arising under this License shall be resolved by binding arbitration, seated at a neutral, arbitration-mature venue (Singapore or London are the two candidates concretely supported by current research), rather than by litigation in a national court. The specific arbitral institution and substantive governing law remain a per-deployment blank pending final selection; they are not fixed by this candidate. See the canonical repository's `history/260729-TRSL-Jurisdiction-Synthesis.md` §2.
**11.2 Severability.** If any provision of this License is held unenforceable, the remaining provisions remain in full force, and the unenforceable provision shall be reformed to the minimum extent necessary to make it enforceable.
**11.3 No waiver.** Failure to enforce any provision of this License is not a waiver of future enforcement of that or any other provision.
**11.4 Entire agreement (as to licensing).** This License, together with the applicable Phase Manifest and, where applicable, the Commercial Use Agreement, constitutes the entire agreement between You and the Licensor regarding the Software's licensing terms. Operations, service, and consulting arrangements are governed by separate agreements, if any, and are not part of this License.
**11.5 Definitions control.** Marketing materials, documentation, or other non-normative communications about the Software must not describe pre-Conversion-Event Software as "Open Source," "free software," or "open core." Pre-conversion Noncommercial Use is **source-available**; pre-conversion Commercial Use requires a **Commercial Entitlement**; only post-conversion Software may be described as Open Source, under the Future License.
---
**No Phase is currently declared for this repository under this License.** Until a Phase Manifest is published and registered with the Trust Service for a Milestone Release in this repository, Sections 2–7 above have no operative subject matter here — this License establishes the governing framework in advance of that declaration, consistent with the org-wide rollout decision recorded in `target-revenue`'s `workplans/TREV-WP-0008-governance-and-pilot-rollout.md`.

View file

@ -109,7 +109,7 @@ This is the canonical non-React case and worth covering in detail.
```sh
# In the Django app's repo.
pnpm add git+ssh://git@gitea.example.com/whynot/whynot-design.git#v0.2.0
pnpm add git+ssh://git@forgejo.coulomb.social/coulomb/whynot-design.git#v0.2.0
# Or vendor without Node tooling — copy three files:
mkdir -p myapp/static/whynot

View file

@ -1,24 +1,25 @@
# Publishing `@whynot/design`
`@whynot/design` is published to the **coulomb Gitea npm registry** so consuming
`@whynot/design` is published to the **coulomb Forgejo npm registry** so consuming
repos can pin a version (`npm i @whynot/design@x.y.z`) and track it at their own pace
(WHYNOT-WP-0003). The git tag cut by `make release` (see `DesignSystemIntroduction.md`
§6) is the version; publishing makes that version installable.
- Registry: `https://gitea.coulomb.social/api/packages/coulomb/npm/`
- Registry: `https://forgejo.coulomb.social/api/packages/coulomb/npm/`
- `package.json` `publishConfig.registry` already points `npm publish` here.
- `lit` is a **peerDependency** — consumers install it themselves so their bundler
dedupes to a single `lit` instance.
## The token (never commit it)
Publishing and installing `@whynot/*` need a Gitea package token. It is **not stored in
Publishing and installing `@whynot/*` need a Forgejo package token. It is **not stored in
this repo** — per `.claude/rules/credential-routing.md`, tokens are routed, not vended:
a Gitea package token is operator/OpenBao-owned (`railiance-platform`). Obtain one from
the operator and export it:
a Forgejo package token is operator/OpenBao-owned (`railiance-platform`). Use the
`whynot-design-npm-publish` governed lane for publishing; interactive operators may
export a value obtained through the same route:
```sh
export NPM_AUTH_TOKEN=… # Gitea package token; never paste into git/chat/logs
export NPM_AUTH_TOKEN=… # Forgejo package token; never paste into git/chat/logs
```
`.npmrc` (committed) references it via `${NPM_AUTH_TOKEN}` — no secret lives in the file.
@ -42,8 +43,8 @@ then install the package plus the `lit` peer:
```ini
# .npmrc
@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/
//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}
@whynot:registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
//forgejo.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}
```
```sh

View file

@ -38,18 +38,18 @@ Framework-agnostic by design. Consumers do **not** re-implement components per f
### Node-tooled consumer (React, Vite, Next, Vue, …)
Install from the coulomb Gitea npm registry (add the scope to your `.npmrc` first — see
Install from the coulomb Forgejo npm registry (add the scope to your `.npmrc` first — see
[`PUBLISHING.md`](./PUBLISHING.md) for the token). `lit` is a peer dependency:
```ini
# .npmrc
@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/
//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}
@whynot:registry=https://forgejo.coulomb.social/api/packages/coulomb/npm/
//forgejo.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN}
```
```sh
npm i @whynot/design@0.3.0 lit
# or pin straight from git: pnpm add git+ssh://git@gitea.coulomb.social/coulomb/whynot-design.git#v0.3.0
# or pin straight from git: pnpm add git+ssh://git@forgejo.coulomb.social/coulomb/whynot-design.git#v0.3.0
```
```js

View file

@ -23,10 +23,26 @@ whynot-design exists to provide the capability described in INTENT.md.
## Current State
- Status: active; implementation and stability should be verified by the repo agent.
- Status: the visual language is published as `@whynot/design`. Bootstrap
(WHYNOT-WP-0001), the IR/adapter pipeline (WHYNOT-WP-0002), and
downstream consumption (WHYNOT-WP-0003) are finished.
- Open residual: WHYNOT-IN-0001 (consumer npm-read lane).
## Getting Oriented
- Start with: INTENT.md
- Agent instructions: AGENTS.md
- Workplans: workplans/
## Generated work-record index
This repository opts into staged-source WORK-RECORDS.md generation through
`.generated-work-records.json` and the isolated `.generated-work-records.mk`
recipe. `make generated-work-records` reuses the State Hub renderer through
the Custodian adapter; `make generated-work-records-check` verifies byte-exact
agreement with staged Markdown. The pre-commit hook uses the isolated recipe,
preserves unstaged index edits by refusing them, and retains the generated-only
commit guard. It does not contact the hub, alter workplan statuses, or grant
deployment authority. This consumes shared tooling; it does not make this
repository the provider of the generator capability.

31
WORK-RECORDS.md Normal file
View file

@ -0,0 +1,31 @@
# Work Records — whynot-design
> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record
> stage 3). Do not edit by hand — edit the source file/block listed for
> each record and re-run fix-consistency to refresh this index. Archived
> workplans are omitted; closed decisions/intakes/engagements stay listed
> so recently-resolved work is still visible. [auto]
| Kind | ID | Status | Lane | Source |
| --- | --- | --- | --- | --- |
| workplan | WHYNOT-WP-0001 | finished | — | workplans/WHYNOT-WP-0001-statehub-bootstrap.md |
| workplan | WHYNOT-WP-0002 | finished | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| workplan | WHYNOT-WP-0004 | finished | — | workplans/WHYNOT-WP-0004-forgejo-npm-migration.md |
| task | WHYNOT-WP-0001-T01 | done | — | workplans/WHYNOT-WP-0001-statehub-bootstrap.md |
| task | WHYNOT-WP-0001-T02 | done | — | workplans/WHYNOT-WP-0001-statehub-bootstrap.md |
| task | WHYNOT-WP-0001-T03 | done | — | workplans/WHYNOT-WP-0001-statehub-bootstrap.md |
| task | WHYNOT-WP-0002-T01 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T02 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T03 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T04 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T05 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T06 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T07 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T08 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T09 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T10 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0002-T11 | done | — | workplans/WHYNOT-WP-0002-designbook-stack-adapters.md |
| task | WHYNOT-WP-0004-T01 | done | — | workplans/WHYNOT-WP-0004-forgejo-npm-migration.md |
| task | WHYNOT-WP-0004-T02 | done | — | workplans/WHYNOT-WP-0004-forgejo-npm-migration.md |
| task | WHYNOT-WP-0004-T03 | done | — | workplans/WHYNOT-WP-0004-forgejo-npm-migration.md |
| intake | WHYNOT-IN-0001 | open | yellow | intakes/intakes.md |

28
intakes/intakes.md Normal file
View file

@ -0,0 +1,28 @@
# Intake records
## WHYNOT-IN-0001 — Provision a consumer npm-read lane
```yaml
id: WHYNOT-IN-0001
kind: intake
title: "Provision a consumer-install npm-read lane for @whynot/design"
lane: yellow
status: open
origin: residual
origin_ref: WHYNOT-WP-0003
priority: medium
owner: whynot-design
repo: whynot-design
description: |
WHYNOT-WP-0003-T02 published @whynot/design to the coulomb Forgejo npm
registry using the publish lane. A separate read/install token id
(whynot-design-npm-read) was never provisioned; the publish token was
enough to verify one install.
Consumers still need an .npmrc token to install from the org registry.
Route custody through warden route / OpenBao (railiance-platform). Do
not inline a secret in Git, State Hub, or this record.
created: "2026-08-29"
updated: "2026-08-29"
state_hub_intake_id: "01a04d91-1308-7399-8942-d23f10cef388"
```

View file

@ -1,7 +1,7 @@
<!-- GENERATED by scripts/ir-extract.mjs (make ir) — do not hand-edit. -->
# whynot-design IR catalog
**designVersion** `0.4.0` · **components** 10 · **generated** 2026-06-30T07:46:35.138Z
**designVersion** `0.4.2` · **components** 10 · **generated** 2026-09-04T21:25:01.914Z
Machine-readable companion: [`manifest.json`](./manifest.json) (per-component + token hashes).

View file

@ -1,7 +1,7 @@
{
"schemaVersion": "1.0.0",
"designVersion": "0.4.0",
"generatedAt": "2026-06-30T07:46:35.138Z",
"designVersion": "0.4.2",
"generatedAt": "2026-09-04T21:25:01.914Z",
"tokensHash": "sha256:426f565a9ce6c36f",
"components": [
{

View file

@ -1,6 +1,6 @@
{
"name": "@whynot/design",
"version": "0.4.1",
"version": "0.4.2",
"description": "The neutral, mostly-black-and-white visual language for whynot — prototype cards, signal records, beta plans, decision documents, and any other deliberately-unfinished artefact. Ships tokens, CSS, and Lit-based web components consumable from React, Django, Vue, plain HTML, or anywhere a custom element runs.",
"private": false,
"type": "module",
@ -65,10 +65,10 @@
"keywords": ["whynot", "design-system", "wireframe", "prototype", "lit", "web-components", "django", "react"],
"repository": {
"type": "git",
"url": "git+ssh://git@gitea.coulomb.social/coulomb/whynot-design.git"
"url": "git+ssh://git@forgejo.coulomb.social/coulomb/whynot-design.git"
},
"publishConfig": {
"registry": "https://gitea.coulomb.social/api/packages/coulomb/npm/"
"registry": "https://forgejo.coulomb.social/api/packages/coulomb/npm/"
},
"license": "UNLICENSED"
}

View file

@ -0,0 +1,131 @@
---
id: capability.design.whynot-system
name: Whynot Design System
summary: 'Framework-agnostic visual language for whynot prototype/market-signal artefacts: design tokens,
drop-in CSS, Lit-based web components usable from React/Django/Vue/plain HTML, and Django template adapters.'
owner: whynot-design
status: draft
domain: consumer
tags:
- design-system
- web-components
- frontend
maturity:
discovery:
current: D3
target: D4
confidence: medium
rationale: README documents a clear three-layer architecture (tokens, CSS, Lit web components) plus
a companion DesignSystemIntroduction.md describing propagation pipeline, versioning, and A1 staging
relative to whynot-control.
availability:
current: A2
target: A3
confidence: high
rationale: 'Published as `@whynot/design` (not private: `"private": false` in package.json), ships
a CLI (`whynot-design` bin), tokens/CSS/JS source, and Django adapters — genuinely consumable across
frameworks today, not just planned.'
external_evidence:
completeness:
level: C2
confidence: low
basis: scope_vs_intent_and_consumer_expectations
satisfied_expectations:
- framework-agnostic Lit web components (same `<wn-button>` usable in React/Django/Vue/plain HTML)
- design tokens as source of truth
- Django adapter partials
- package is publicly consumable (not private)
broken_expectations: []
out_of_scope_expectations: []
reliability:
level: R1
confidence: low
basis: consumer_quality_signals
known_reliability_risks:
- cross-framework consumption claims not independently verified in every target framework during this
sweep
discovery:
intent: Give whynot's prototype and market-signal artefacts a consistent, deliberately-unfinished visual
language, consumable identically across any framework via framework-agnostic web components rather
than per-framework reimplementation.
includes:
- design tokens (tokens/*.json)
- drop-in CSS (src/styles/*.css)
- Lit-based web components (src/elements/*.js)
- Django adapter partials
excludes:
- whynot-control's product/business logic itself (see whynot-control)
assumptions: []
use_cases: []
research_memos: []
availability:
current_level: A2
target_level: A3
current_artifacts:
- '`@whynot/design` npm package (public)'
- '`whynot-design` CLI'
target_artifacts: []
consumption_modes:
- library import (npm)
- cli
- django template adapter
relations:
depends_on: []
supports: []
related_to: []
evidence:
documentation:
- README.md
- DesignSystemIntroduction.md
tests:
- tests/
- test-results/
consumer_feedback: []
bug_reports: []
incidents: []
consumer_guidance:
recommended_for:
- whynot-family apps needing a consistent, framework-agnostic visual language across React/Django/Vue/plain
HTML
not_recommended_for:
- consumers wanting a themed (non-neutral) visual language, or needing whynot-control's business logic
itself
known_limitations:
- cross-framework consumption not independently re-verified in every target framework this sweep
promotion_history: []
---
# Whynot Design System
## Overview
`@whynot/design` is the framework-agnostic visual language for whynot's prototype and market-signal artefacts: design tokens as source of truth, drop-in CSS, and Lit-based web components that work identically across React, Django, Vue, and plain HTML, plus Django adapter partials — publicly published, not a private/internal-only package.
## Assessment notes
### Discovery
README documents a clear three-layer architecture (tokens, CSS, Lit web components) plus a companion DesignSystemIntroduction.md describing propagation pipeline, versioning, and A1 staging relative to whynot-control.
### Availability
Published as `@whynot/design` (not private: `"private": false` in package.json), ships a CLI (`whynot-design` bin), tokens/CSS/JS source, and Django adapters — genuinely consumable across frameworks today, not just planned.
### Completeness
First-pass honest assessment from the REUSE-WP-0017 coverage campaign
(reuse-surface). No external consumer feedback exists yet; levels reflect
scope-vs-intent documentation quality, not internal code quality.
### Reliability
No production consumer telemetry exists yet; reliability level is
intentionally conservative pending REUSE-WP-0019 reuse-telemetry evidence.
## Promotion checklist
- [x] ID follows `capability.<domain>.<name>` pattern
- [x] Maturity enums match `specs/CapabilityMaturityStandard.md`
- [x] `external_evidence` is populated separately from `maturity`
- [ ] Relations reference valid capability IDs (none yet)
- [x] Index entry added in `registry/indexes/capabilities.yaml`

View file

@ -1,4 +1,22 @@
version: 1
updated: '2026-06-16'
updated: '2026-07-06'
domain: helix_forge
capabilities: []
capabilities:
- id: capability.design.whynot-system
name: Whynot Design System
summary: 'Framework-agnostic visual language for whynot prototype/market-signal artefacts: design tokens,
drop-in CSS, Lit-based web components usable from React/Django/Vue/plain HTML, and Django template
adapters.'
vector: D3 / A2 / C2 / R1
domain: consumer
status: draft
owner: whynot-design
path: registry/capabilities/capability.design.whynot-system.md
tags:
- design-system
- web-components
- frontend
consumption_modes:
- library import (npm)
- cli
- django template adapter

View file

@ -0,0 +1,65 @@
---
id: WHYNOT-WP-0004
type: workplan
title: "Move @whynot/design publication to Forgejo Packages"
domain: infotech
repo: whynot-design
status: finished
owner: codex
topic_slug: forgejo-npm-migration
created: "2026-09-04"
updated: "2026-09-04"
state_hub_workstream_id: "a1483ac2-09c6-5c57-ba56-99a8f28cadb8"
---
## Reconcile the package release state
```task
id: WHYNOT-WP-0004-T01
status: done
priority: high
state_hub_task_id: "c191d55f-302b-5f29-aee1-526516f57ad7"
```
Audit the partially completed Forgejo migration, choose a new immutable package
version when the existing Gitea release cannot be reused safely, and verify the
release contents before any credentialed write. This work promotes routed intake
`01a06e08-6936-7762-a347-f832182b7705`.
## Publish and verify the Forgejo package
```task
id: WHYNOT-WP-0004-T02
status: done
priority: high
state_hub_task_id: "93e4835b-b3eb-5af8-ac83-557ea4c59921"
```
Use the governed `whynot-design-npm-publish` credential lane to publish the new
version to `https://forgejo.coulomb.social/api/packages/coulomb/npm/`. Verify an
authenticated exact-version install and the shipped IR/version contract without
printing or persisting the credential.
## Align consumer and operator documentation
```task
id: WHYNOT-WP-0004-T03
status: done
priority: medium
state_hub_task_id: "f0614332-75a3-5e99-8fef-c749c76987ac"
```
Make Forgejo the single canonical npm endpoint in current package, consumer, and
release guidance. Hand the verified endpoint to ops-warden for catalog and
playbook reconciliation.
Prepared `@whynot/design@0.4.2` on 2026-09-04. The package dry-run contains 105
files with IR `designVersion` 0.4.2; all five Playwright visual tests pass. The
changelog gate correctly reports no *post-release* `[Unreleased]` entry after the
0.4.2 section was cut.
Published and exact-integrity verified on Forgejo on 2026-09-04. The dedicated
publish lane's OpenBao read is healthy but its stored token could not complete
the Forgejo write, so the plan-authorized `forgejo-admin-api-token` lane was used
as a one-time contained recovery path. Dedicated-token rotation remains live in
`WARDEN-WP-0037`; no credential value was printed or persisted.

View file

@ -1,5 +1,5 @@
---
id: ADHOC-2026-06-27
id: WHYNOT-WP-ADHOC-2026-06-27
type: workplan
title: "Ad hoc fixes — 2026-06-27"
domain: infotech
@ -9,9 +9,11 @@ owner: claude
topic_slug: custodian
created: "2026-06-27"
updated: "2026-06-27"
state_hub_workstream_id: "4945ead3-d54b-438f-963a-2fd687c472d4"
state_hub_workstream_id: "6d6f3bc9-69ff-5fb7-b77a-6b3be204a8d3"
---
> **Terminology note:** Historical text in this archived workplan may use the legacy term "workstream". The fleet term is **workplan** (`canon/standards/workplan-terminology-fleet_v0.1.md`).
# Ad hoc fixes — 2026-06-27
Low-risk opportunistic fixes completed directly during the WHYNOT-WP-0003 session.
@ -19,10 +21,10 @@ Low-risk opportunistic fixes completed directly during the WHYNOT-WP-0003 sessio
## README consumer-onboarding accuracy
```task
id: ADHOC-2026-06-27-T01
id: WHYNOT-WP-ADHOC-2026-06-27-T01
status: done
priority: medium
state_hub_task_id: "76417728-969c-4b26-9ed8-f6cedd793ff4"
state_hub_task_id: "f4f70b75-24d0-5431-ade5-e33874740755"
```
Two staleness fixes in `README.md` found while reviewing the consumer on-ramp:

View file

@ -4,12 +4,12 @@ type: workplan
title: "Downstream consumption: versioned IR releases + consumer drift-check"
domain: infotech
repo: whynot-design
status: active
status: finished
owner: claude
topic_slug: custodian
created: "2026-06-27"
updated: "2026-06-27"
state_hub_workstream_id: "41fed928-f44a-48f4-9870-120310fbf071"
updated: "2026-08-29"
state_hub_workstream_id: "d3a6ec16-ac40-5ffb-99e7-07f997e59a4a"
---
# Downstream consumption: versioned IR releases + consumer drift-check
@ -298,10 +298,11 @@ shape of the heavier mode.
whynot-design. `drift` is read-only against the package; only `.whynot-design.lock`
(in the consumer repo) is written.
## Registering this workplan
## Residuals
After review, register the workstream from `~/state-hub`:
All nine tasks are done. T09's go/defer decision is already resolved
(`b7d3d35d`, defer consumer-side contract-parity).
```bash
make fix-consistency REPO=whynot-design
```
Live residual: `WHYNOT-IN-0001` — provision a consumer-install npm-read
lane. The publish token was enough to verify T02; consumers still need a
read lane to install from the org registry.