docs: sync nexus repo truth and audit legacy matrix (#689)
Some checks failed
Deploy Nexus / deploy (push) Failing after 5s
Some checks failed
Deploy Nexus / deploy (push) Failing after 5s
This commit was merged in pull request #689.
This commit is contained in:
110
CLAUDE.md
110
CLAUDE.md
@@ -2,77 +2,79 @@
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
The Nexus is a Three.js environment — Timmy's sovereign home in 3D space. It serves as the central hub for all portals to other worlds. Stack: vanilla JS ES modules, Three.js 0.183, no bundler.
|
The Nexus is Timmy's canonical 3D/home-world repo.
|
||||||
|
Its intended role is:
|
||||||
|
- local-first training ground for Timmy
|
||||||
|
- wizardly visualization surface for the system
|
||||||
|
|
||||||
## Architecture
|
## Current Repo Truth
|
||||||
|
|
||||||
```
|
Do not describe this repo as a live browser app on `main`.
|
||||||
index.html # Entry point: HUD, chat panel, loading screen, live-reload script
|
|
||||||
style.css # Design system: dark space theme, holographic panels
|
|
||||||
app.js # Three.js scene, shaders, controls, game loop, WS bridge (~all logic)
|
|
||||||
portals.json # Portal registry (data-driven)
|
|
||||||
vision.json # Vision point content (data-driven)
|
|
||||||
server.js # Optional: proxy server for CORS (commit heatmap API)
|
|
||||||
```
|
|
||||||
|
|
||||||
No build step. Served as static files. Import maps in `index.html` handle Three.js resolution.
|
Current `main` does not ship the old root frontend files:
|
||||||
|
- `index.html`
|
||||||
|
- `app.js`
|
||||||
|
- `style.css`
|
||||||
|
- `package.json`
|
||||||
|
|
||||||
## WebSocket Bridge (v2.0)
|
A clean checkout of current `main` serves a directory listing if you static-serve the repo root.
|
||||||
|
That is world-state truth.
|
||||||
|
|
||||||
The Nexus connects to Timmy's backend via WebSocket for live cognitive state:
|
The live browser shell people remember exists in legacy form at:
|
||||||
|
- `/Users/apayne/the-matrix`
|
||||||
|
|
||||||
- **URL**: `?ws=ws://hermes:8765` query param, or default `ws://localhost:8765`
|
That legacy app is source material for migration, not a second canonical repo.
|
||||||
- **Inbound**: `agent_state`, `agent_move`, `chat_response`, `system_metrics`, `dual_brain`, `heartbeat`
|
|
||||||
- **Outbound**: `chat_message`, `presence`
|
|
||||||
- **Graceful degradation**: When WS is offline, agents idle locally, chat shows "OFFLINE"
|
|
||||||
|
|
||||||
## The Hard Rule — Read This First
|
Timmy_Foundation/the-nexus is the only canonical 3D repo.
|
||||||
|
|
||||||
**Every PR: net ≤ 10 added lines.** Add 40, remove 30. Can't remove? Import instead.
|
See:
|
||||||
You MUST plan your cuts BEFORE writing new code. See CONTRIBUTING.md.
|
- `LEGACY_MATRIX_AUDIT.md`
|
||||||
Do NOT self-merge. Do NOT submit a PR that violates this.
|
- issues `#684`, `#685`, `#686`, `#687`
|
||||||
|
|
||||||
## Conventions
|
## Architecture (current main)
|
||||||
|
|
||||||
- **ES modules only** — no CommonJS, no bundler
|
Current repo contents are centered on:
|
||||||
- **Single-file app** — logic lives in `app.js`; don't split without good reason
|
- `nexus/` — Python cognition / heartbeat components
|
||||||
- **Color palette** — defined in `NEXUS.colors` at top of `app.js`
|
- `server.py` — local websocket bridge
|
||||||
- **Line budget** — app.js should stay under 1500 lines
|
- `portals.json`, `vision.json` — data/config artifacts
|
||||||
- **Conventional commits**: `feat:`, `fix:`, `refactor:`, `test:`, `chore:`
|
- deployment/docs files
|
||||||
- **Branch naming**: `claude/issue-{N}` (e.g. `claude/issue-5`)
|
|
||||||
- **One PR at a time** — wait for merge-bot before opening the next
|
|
||||||
|
|
||||||
## Validation (merge-bot checks)
|
Do not tell contributors to run Vite or edit a nonexistent root frontend on current `main`.
|
||||||
|
If browser/UI work is being restored, it must happen through the migration backlog and land back here.
|
||||||
|
|
||||||
The `nexus-merge-bot.sh` validates PRs before auto-merge:
|
## Hard Rules
|
||||||
|
|
||||||
1. HTML validation — `index.html` must be valid HTML
|
1. One canonical 3D repo only: `Timmy_Foundation/the-nexus`
|
||||||
2. JS syntax — `node --check app.js` must pass
|
2. No parallel evolution of `/Users/apayne/the-matrix` as if it were the product
|
||||||
3. JSON validation — any `.json` files must parse
|
3. Rescue useful legacy Matrix work by auditing and migrating it here
|
||||||
4. File size budget — JS files must be < 500 KB
|
4. Telemetry and durable truth flow through Hermes harness
|
||||||
|
5. OpenClaw remains a sidecar, not the governing authority
|
||||||
|
6. Before claiming visual validation, prove the app being viewed actually comes from current `the-nexus`
|
||||||
|
|
||||||
**Always run `node --check app.js` before committing.**
|
## Validation Rule
|
||||||
|
|
||||||
## PR Rules
|
If you are asked to visually validate Nexus:
|
||||||
|
- prove the tested app comes from a clean checkout/worktree of `Timmy_Foundation/the-nexus`
|
||||||
|
- if current `main` only serves a directory listing or otherwise lacks the browser world, stop calling it visually validated
|
||||||
|
- pivot to migration audit and issue triage instead of pretending the world still exists
|
||||||
|
|
||||||
- **Net addition limit: ≤ 10 lines.** No exceptions. Plan cuts before writing.
|
## Migration Priorities
|
||||||
- **Do NOT self-merge.** Submit the PR, a different user merges it.
|
|
||||||
- Base every PR on latest `main`
|
|
||||||
- Squash merge only
|
|
||||||
- Include manual test plan + automated test output in PR body
|
|
||||||
- Include `Fixes #N` or `Refs #N` in commit message
|
|
||||||
|
|
||||||
## Running Locally
|
1. `#684` — docs truth
|
||||||
|
2. `#685` — legacy Matrix preservation audit
|
||||||
|
3. `#686` — browser smoke / visual validation rebuild
|
||||||
|
4. `#687` — restore wizardly local-first visual shell
|
||||||
|
5. then continue portal/gameplay work (`#672`, `#673`, `#674`, `#675`)
|
||||||
|
|
||||||
```bash
|
## Legacy Matrix rescue targets
|
||||||
npx serve . -l 3000
|
|
||||||
# open http://localhost:3000
|
|
||||||
# To connect to Timmy: http://localhost:3000?ws=ws://hermes:8765
|
|
||||||
```
|
|
||||||
|
|
||||||
## Gitea API
|
The old Matrix contains real quality work worth auditing:
|
||||||
|
- visitor movement and embodiment
|
||||||
|
- agent presence / bark / chat systems
|
||||||
|
- transcript logging
|
||||||
|
- ambient world systems
|
||||||
|
- satflow / economy visualization
|
||||||
|
- browser smoke tests and production build discipline
|
||||||
|
|
||||||
```
|
Preserve the good work.
|
||||||
Base URL: http://143.198.27.163:3000/api/v1
|
Do not preserve stale assumptions or fake architecture.
|
||||||
Repo: Timmy_Foundation/the-nexus
|
|
||||||
```
|
|
||||||
|
|||||||
141
LEGACY_MATRIX_AUDIT.md
Normal file
141
LEGACY_MATRIX_AUDIT.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# Legacy Matrix Audit
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Preserve useful work from `/Users/apayne/the-matrix` before the Nexus browser shell is rebuilt.
|
||||||
|
|
||||||
|
Canonical rule:
|
||||||
|
- `Timmy_Foundation/the-nexus` is the only canonical 3D repo.
|
||||||
|
- `/Users/apayne/the-matrix` is legacy source material, not a parallel product.
|
||||||
|
|
||||||
|
## Verified Legacy Matrix State
|
||||||
|
|
||||||
|
Local legacy repo:
|
||||||
|
- `/Users/apayne/the-matrix`
|
||||||
|
|
||||||
|
Observed facts:
|
||||||
|
- Vite browser app exists
|
||||||
|
- `npm test` passes with `87 passed, 0 failed`
|
||||||
|
- 23 JS modules under `js/`
|
||||||
|
- package scripts include `dev`, `build`, `preview`, and `test`
|
||||||
|
|
||||||
|
## Known historical Nexus snapshot
|
||||||
|
|
||||||
|
Useful in-repo reference point:
|
||||||
|
- `0518a1c3ae3c1d0afeb24dea9772102f5a3d9a66`
|
||||||
|
|
||||||
|
That snapshot still contains browser-world root files such as:
|
||||||
|
- `index.html`
|
||||||
|
- `app.js`
|
||||||
|
- `style.css`
|
||||||
|
- `package.json`
|
||||||
|
- `tests/`
|
||||||
|
|
||||||
|
## Rescue Candidates
|
||||||
|
|
||||||
|
### Carry forward into Nexus vNext
|
||||||
|
|
||||||
|
1. `agent-defs.js`
|
||||||
|
- agent identity definitions
|
||||||
|
- useful as seed data/model for visible entities in the world
|
||||||
|
|
||||||
|
2. `agents.js`
|
||||||
|
- agent objects, state machine, connection lines
|
||||||
|
- useful for visualizing Timmy / subagents / system processes in a world-native way
|
||||||
|
|
||||||
|
3. `avatar.js`
|
||||||
|
- visitor embodiment, movement, camera handling
|
||||||
|
- strongly aligned with "training ground" and "walk the world" goals
|
||||||
|
|
||||||
|
4. `ui.js`
|
||||||
|
- HUD, chat surfaces, overlays
|
||||||
|
- useful if rebuilt against real harness data instead of stale fake state
|
||||||
|
|
||||||
|
5. `websocket.js`
|
||||||
|
- browser-side live bridge patterns
|
||||||
|
- useful if retethered to Hermes-facing transport
|
||||||
|
|
||||||
|
6. `transcript.js`
|
||||||
|
- local transcript capture pattern
|
||||||
|
- useful if durable truth still routes through Hermes and browser cache remains secondary
|
||||||
|
|
||||||
|
7. `ambient.js`
|
||||||
|
- mood / atmosphere system
|
||||||
|
- directly supports wizardly presentation without changing system authority
|
||||||
|
|
||||||
|
8. `satflow.js`
|
||||||
|
- visual economy / payment flow motifs
|
||||||
|
- useful if Timmy's economy/agent interactions become a real visible layer
|
||||||
|
|
||||||
|
9. `economy.js`
|
||||||
|
- treasury / wallet panel ideas
|
||||||
|
- useful if later backed by real sovereign metrics
|
||||||
|
|
||||||
|
10. `presence.js`
|
||||||
|
- who-is-here / online-state UI
|
||||||
|
- useful for showing human + agent + process presence in the world
|
||||||
|
|
||||||
|
11. `interaction.js`
|
||||||
|
- clicking, inspecting, selecting world entities
|
||||||
|
- likely needed in any real browser-facing Nexus shell
|
||||||
|
|
||||||
|
12. `quality.js`
|
||||||
|
- hardware-aware quality tiering
|
||||||
|
- useful for local-first graceful degradation on Mac hardware
|
||||||
|
|
||||||
|
13. `bark.js`
|
||||||
|
- prominent speech / bark system
|
||||||
|
- strong fit for Timmy's expressive presence in-world
|
||||||
|
|
||||||
|
14. `world.js`, `effects.js`, `scene-objects.js`, `zones.js`
|
||||||
|
- broad visual foundation work
|
||||||
|
- should be mined for patterns, not blindly transplanted
|
||||||
|
|
||||||
|
15. `test/smoke.mjs`
|
||||||
|
- browser smoke discipline
|
||||||
|
- should inform rebuilt validation in canonical Nexus repo
|
||||||
|
|
||||||
|
### Archive as reference, not direct carry-forward
|
||||||
|
|
||||||
|
- demo/autopilot assumptions that pretend fake backend activity is real
|
||||||
|
- any websocket schema that no longer matches Hermes truth
|
||||||
|
- Vite-specific plumbing that is only useful if we consciously recommit to Vite
|
||||||
|
|
||||||
|
### Deliberately drop unless re-justified
|
||||||
|
|
||||||
|
- anything that presents mock data as if it were live
|
||||||
|
- anything that duplicates a better Hermes-native telemetry path
|
||||||
|
- anything that turns the browser into the system of record
|
||||||
|
|
||||||
|
## Concern Separation for Nexus vNext
|
||||||
|
|
||||||
|
When rebuilding inside `the-nexus`, keep concerns separated:
|
||||||
|
|
||||||
|
1. World shell / rendering
|
||||||
|
- scene, camera, movement, atmosphere
|
||||||
|
|
||||||
|
2. Presence and embodiment
|
||||||
|
- avatar, agent placement, selection, bark/chat surfaces
|
||||||
|
|
||||||
|
3. Harness bridge
|
||||||
|
- websocket / API bridge from Hermes truth into browser state
|
||||||
|
|
||||||
|
4. Visualization panels
|
||||||
|
- metrics, presence, economy, portal states, transcripts
|
||||||
|
|
||||||
|
5. Validation
|
||||||
|
- smoke tests, screenshot proof, provenance checks
|
||||||
|
|
||||||
|
6. Game portal layer
|
||||||
|
- Morrowind / portal-specific interaction surfaces
|
||||||
|
|
||||||
|
Do not collapse all of this into one giant app file again.
|
||||||
|
Do not let visual shell code become telemetry authority.
|
||||||
|
|
||||||
|
## Migration Rule
|
||||||
|
|
||||||
|
Rescue knowledge first.
|
||||||
|
Then rescue modules.
|
||||||
|
Then rebuild the browser shell inside `the-nexus`.
|
||||||
|
|
||||||
|
No more ghost worlds.
|
||||||
|
No more parallel 3D repos.
|
||||||
137
README.md
137
README.md
@@ -1,70 +1,101 @@
|
|||||||
# ◈ The Nexus — Timmy's Sovereign Home
|
# ◈ The Nexus — Timmy's Sovereign Home
|
||||||
|
|
||||||
A Three.js environment serving as Timmy's sovereign space — like Dr. Strange's Sanctum Sanctorum, existing outside time. The Nexus is the central hub from which all worlds are accessed through portals.
|
The Nexus is Timmy's canonical 3D/home-world repo.
|
||||||
|
|
||||||
## Features
|
It is meant to become two things at once:
|
||||||
|
- a local-first training ground for Timmy
|
||||||
|
- a wizardly visualization surface for the living system
|
||||||
|
|
||||||
- **Procedural Nebula Skybox** — animated stars, twinkling, layered nebula clouds
|
## Current Truth
|
||||||
- **Batcave Terminal** — 5 holographic display panels arranged in an arc showing:
|
|
||||||
- Nexus Command (system status, harness state, agent loops)
|
|
||||||
- Dev Queue (live Gitea issue references)
|
|
||||||
- Metrics (uptime, commits, CPU/MEM)
|
|
||||||
- Thought Stream (Timmy's current thoughts)
|
|
||||||
- Agent Status (all agent states)
|
|
||||||
- **Morrowind Portal** — glowing torus with animated swirl shader, ready for world connection
|
|
||||||
- **Admin Chat (Timmy Terminal)** — real-time message interface, ready for Hermes WebSocket
|
|
||||||
- **Nexus Core** — floating crystalline icosahedron on pedestal
|
|
||||||
- **Ambient Environment** — crystal formations, floating runestones, energy particles, atmospheric fog
|
|
||||||
- **WASD + Mouse Navigation** — first-person exploration of the space
|
|
||||||
- **Post-Processing** — Unreal Bloom + SMAA antialiasing
|
|
||||||
|
|
||||||
## Architecture
|
As of current `main`, this repo does **not** ship a browser 3D world.
|
||||||
|
In plain language: current `main` does not ship a browser 3D world.
|
||||||
|
|
||||||
```
|
A clean checkout of `Timmy_Foundation/the-nexus` on `main` currently contains:
|
||||||
the-nexus/
|
- Python heartbeat / cognition files under `nexus/`
|
||||||
├── index.html # Entry point with HUD overlay, chat panel, loading screen
|
- `server.py`
|
||||||
├── style.css # Nexus design system (dark space theme, holographic panels)
|
- protocol, report, and deployment docs
|
||||||
└── app.js # Three.js scene, shaders, controls, game loop
|
- JSON configuration files like `portals.json` and `vision.json`
|
||||||
```
|
|
||||||
|
It does **not** currently contain an active root frontend such as:
|
||||||
|
- `index.html`
|
||||||
|
- `app.js`
|
||||||
|
- `style.css`
|
||||||
|
- `package.json`
|
||||||
|
|
||||||
|
Serving the repo root today shows a directory listing, not a rendered world.
|
||||||
|
|
||||||
|
## One Canonical 3D Repo
|
||||||
|
|
||||||
|
`Timmy_Foundation/the-nexus` is the only canonical 3D repo.
|
||||||
|
In plain language: Timmy_Foundation/the-nexus is the only canonical 3D repo.
|
||||||
|
|
||||||
|
The old local browser app at:
|
||||||
|
- `/Users/apayne/the-matrix`
|
||||||
|
|
||||||
|
is legacy source material, not a second repo to keep evolving in parallel.
|
||||||
|
Useful work from it must be audited and migrated here.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- `LEGACY_MATRIX_AUDIT.md`
|
||||||
|
|
||||||
|
## Why this matters
|
||||||
|
|
||||||
|
We do not want to lose real quality work.
|
||||||
|
We also do not want to keep two drifting 3D repos alive by accident.
|
||||||
|
|
||||||
|
The rule is:
|
||||||
|
- rescue good work from legacy Matrix
|
||||||
|
- rebuild inside `the-nexus`
|
||||||
|
- keep telemetry and durable truth flowing through the Hermes harness
|
||||||
|
- keep OpenClaw as a sidecar, not the authority
|
||||||
|
|
||||||
|
## Verified historical browser-world snapshot
|
||||||
|
|
||||||
|
The commit the user pointed at:
|
||||||
|
- `0518a1c3ae3c1d0afeb24dea9772102f5a3d9a66`
|
||||||
|
|
||||||
|
still contains the old root browser files (`index.html`, `app.js`, `style.css`, `package.json`, tests/), so it is a useful in-repo reference point for what existed before the later deletions.
|
||||||
|
|
||||||
|
## Active migration backlog
|
||||||
|
|
||||||
|
- `#684` sync docs to repo truth
|
||||||
|
- `#685` preserve legacy Matrix quality work before rewrite
|
||||||
|
- `#686` rebuild browser smoke / visual validation for the real Nexus repo
|
||||||
|
- `#687` restore a wizardly local-first visual shell from audited Matrix components
|
||||||
|
- `#672` rebuild the portal stack as Timmy → Reflex → Pilot
|
||||||
|
- `#673` deterministic Morrowind pilot loop with world-state proof
|
||||||
|
- `#674` reflex tactical layer and semantic trajectory logging
|
||||||
|
- `#675` deterministic context compaction for long local sessions
|
||||||
|
|
||||||
|
## What gets preserved from legacy Matrix
|
||||||
|
|
||||||
|
High-value candidates include:
|
||||||
|
- visitor movement / embodiment
|
||||||
|
- chat, bark, and presence systems
|
||||||
|
- transcript logging
|
||||||
|
- ambient / visual atmosphere systems
|
||||||
|
- economy / satflow visualizations
|
||||||
|
- smoke and browser validation discipline
|
||||||
|
|
||||||
|
Those pieces should be carried forward only if they serve the mission and are re-tethered to real local system state.
|
||||||
|
|
||||||
## Running Locally
|
## Running Locally
|
||||||
|
|
||||||
```bash
|
### Current repo truth
|
||||||
npx serve . -l 3000
|
|
||||||
# Open http://localhost:3000
|
|
||||||
```
|
|
||||||
|
|
||||||
## Roadmap
|
There is no root browser app on current `main`.
|
||||||
|
Do not tell people to static-serve the repo root and expect a world.
|
||||||
|
|
||||||
- [ ] Wire chat to Hermes WebSocket (`/api/world/ws`)
|
### What you can run now
|
||||||
- [ ] Pull live data into terminal panels from Timmy's actual state
|
|
||||||
- [ ] Portal walk-through interaction to load destination worlds
|
|
||||||
- [ ] Timmy's avatar (lizard wizard body he designs himself)
|
|
||||||
- [ ] Connect to AlexanderWhitestone.com as public entry point
|
|
||||||
- [ ] Integrate existing Replit timmy-tower world code
|
|
||||||
|
|
||||||
## Related
|
- `python3 server.py` for the local websocket bridge
|
||||||
|
- Python modules under `nexus/` for heartbeat / cognition work
|
||||||
|
|
||||||
- **Gitea Issue**: [#1090 — EPIC: Nexus v1](http://143.198.27.163:3000/rockachopa/Timmy-time-dashboard/issues/1090)
|
### Browser world restoration path
|
||||||
- **Live Demo**: Deployed via Perplexity Computer
|
|
||||||
|
|
||||||
## Groq Worker
|
The browser-facing Nexus must be rebuilt deliberately through the migration backlog above, using audited Matrix components and truthful validation.
|
||||||
|
|
||||||
The Groq worker is a dedicated worker for the Groq API. It is designed to be used by the Nexus Mind to offload the thinking process to the Groq API.
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
To use the Groq worker, you need to set the `GROQ_API_KEY` environment variable. You can then run the `nexus_think.py` script with the `--groq-model` argument:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export GROQ_API_KEY="your-api-key"
|
|
||||||
python -m nexus.nexus_think --groq-model "groq/llama3-8b-8192"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Recommendations
|
|
||||||
|
|
||||||
Groq has fast inference, which makes it a good candidate for tasks like PR reviews. You can use the Groq worker to review PRs by a Gitea webhook.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Part of [The Timmy Foundation](http://143.198.27.163:3000/Timmy_Foundation)*
|
*One 3D repo. One migration path. No more ghost worlds.*
|
||||||
|
|||||||
35
tests/test_repo_truth.py
Normal file
35
tests/test_repo_truth.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def test_readme_states_repo_truth_and_single_canonical_3d_repo() -> None:
|
||||||
|
readme = Path("README.md").read_text()
|
||||||
|
|
||||||
|
assert "current `main` does not ship a browser 3D world" in readme
|
||||||
|
assert "Timmy_Foundation/the-nexus is the only canonical 3D repo" in readme
|
||||||
|
assert "/Users/apayne/the-matrix" in readme
|
||||||
|
assert "npx serve . -l 3000" not in readme
|
||||||
|
|
||||||
|
|
||||||
|
def test_claude_doc_matches_current_repo_truth() -> None:
|
||||||
|
claude = Path("CLAUDE.md").read_text()
|
||||||
|
|
||||||
|
assert "Do not describe this repo as a live browser app on `main`." in claude
|
||||||
|
assert "Timmy_Foundation/the-nexus is the only canonical 3D repo." in claude
|
||||||
|
assert "LEGACY_MATRIX_AUDIT.md" in claude
|
||||||
|
|
||||||
|
|
||||||
|
def test_legacy_matrix_audit_exists_and_names_rescue_targets() -> None:
|
||||||
|
audit = Path("LEGACY_MATRIX_AUDIT.md").read_text()
|
||||||
|
|
||||||
|
for term in [
|
||||||
|
"agent-defs.js",
|
||||||
|
"agents.js",
|
||||||
|
"avatar.js",
|
||||||
|
"ui.js",
|
||||||
|
"websocket.js",
|
||||||
|
"transcript.js",
|
||||||
|
"ambient.js",
|
||||||
|
"satflow.js",
|
||||||
|
"economy.js",
|
||||||
|
]:
|
||||||
|
assert term in audit
|
||||||
Reference in New Issue
Block a user