Target Shooter — a 3D target-clicking game built with React 19, TypeScript 6, Three.js (@react-three/fiber + @react-three/drei), Vite 8, and Howler.js. Node ≥ 25 required.
Security & Compliance: Aligned with Hack23 AB's ISMS. Every change MUST respect the ISMS. See ISMS Policy Mapping for the full feature-to-policy traceability matrix.
Before starting any non-trivial task, read:
.github/workflows/copilot-setup-steps.yml— Copilot environment & permissions.github/copilot-mcp.json— MCP server wiring (GitHub Insiders, filesystem, memory, sequential-thinking, playwright)README.md— project overview, features, security posture.github/agents/README.md&.github/skills/README.md— available specialists and patterns- The specific agent and skill files relevant to your task
- Hack23 ISMS-PUBLIC — authoritative security policies
npm install # Install dependencies
npm run dev # Dev server at http://localhost:5173
npm run build # TypeScript check + Vite build
npm run lint # ESLint
npm run test # Vitest unit tests
npm run coverage # Tests with coverage (≥80% lines, ≥70% branches)
npm run test:e2e # Cypress E2E tests
npm run test:licenses # License compliance check (Open Source Policy)
npm audit # Dependency vulnerability scansrc/
├── App.tsx # Root: game loop, audio, overlays
├── components/
│ ├── GameScene.tsx # 3D scene (targets, particles, lights)
│ ├── TargetSphere.tsx # Clickable 3D target
│ ├── BackgroundParticles.tsx # Particle effects
│ ├── ParticleExplosion.tsx # Hit explosion effect
│ ├── HUD.tsx # Score/time/combo display
│ └── GameOverlay.tsx # Controls, instructions, overlays
├── hooks/
│ ├── useGameState.ts # Game state management
│ └── useAudioManager.ts # Howler.js audio integration
├── utils/
│ ├── gameConfig.ts # Game constants and level progression
│ └── targetPhysics.ts # Target creation and movement
└── test/setup.ts # Vitest test setup
| Applies When… | Policy | Link |
|---|---|---|
| Any security-relevant code, governance, incident | Information Security Policy | ISP |
| SDLC, CI/CD, testing, deployment, threat modeling | Secure Development Policy | SDP |
| Adding / updating / removing dependencies, licenses, SBOM | Open Source Policy | OSP |
| Copilot agents, MCP, LLM-assisted changes | AI Policy | AI |
| Auth, identity, permissions, least privilege | Access Control Policy | ACP |
| Encryption, hashing, key material, TLS | Cryptography Policy | CP |
| Data handling, classification, storage, logs | Data Classification Policy | DCP |
| Personal data, analytics, telemetry | Privacy Policy | Privacy |
| Changes to agents, MCP, workflows | Change Management | CM |
| STRIDE, abuse cases, attack surface | Threat Modeling Policy | TM |
| Reporting / patching vulnerabilities | Vulnerability Management | VM |
Cite the applicable policy in code comments, commit messages, and PR descriptions for security-sensitive changes.
- Plan & Design — classify impact (CIA triad), threat model (STRIDE), link to ISMS policies
- Develop — OWASP-aligned coding, no hardcoded secrets, typed everywhere,
no-any - Test — SAST (CodeQL + ESLint), SCA (
npm audit), DAST (ZAP), unit + E2E, coverage ≥80%/70% - Deploy — CI/CD gates, SHA-pinned Actions, SLSA ≥ L3 attestations, SBOM + SBOMQS ≥ 7.0
- Operate — monitor CodeQL alerts, Dependabot, Scorecard ≥ 8.0, patch per Vulnerability Management SLAs
- AI outputs are proposals, never authoritative — human review required before merge
- No autonomous deployment — AI may not bypass CI gates, branch protections, or approvals
- Change attribution — document AI assistance in PR descriptions (e.g., "assisted by Copilot agent
game-developer") - Least privilege tooling — each agent has tools appropriate to its role; expansion is a Change Management event
- Curator-agent changes — edits to
.github/agents/*.md,.github/skills/*/SKILL.md,.github/copilot-mcp.json,.github/workflows/copilot-setup-steps.ymlare Normal Changes that require CEO or security-owner approval - Audit trail — all agent activity logged via GitHub; PRs preserve complete traceability
- MCP governance — MCP server config (
.github/copilot-mcp.json) usessecrets.COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN, never hard-coded tokens
- TypeScript strict:
strictNullChecks,noImplicitAny,noUncheckedIndexedAccess— do not disable - No
any: preferunknown+ narrowing; type every function signature - Functional components only with explicit return types:
function X(): JSX.Element - Props interfaces: always define, JSDoc-documented
- Import order: React → external libs → internal components → hooks → types → styles
- No secrets in code, logs, or errors — use environment /
secrets.*only - Validate every external input — client and server — per Security-by-Design skill
- Declarative JSX (
@react-three/fiber), not imperative Three.js API useFrame((state, delta) => …)for animation — neversetInterval/setTimeout- Type refs:
useRef<THREE.Mesh>(null)— never untyped - Mesh event props (
onClick,onPointerOver) — not DOM listeners - Dispose geometries/materials/textures on unmount
InstancedMeshfor > 10 similar objects- Target 60 fps (≤ 16.67 ms per frame)
- Vitest + jsdom for unit tests, Cypress for E2E
- Colocate tests:
ComponentName.test.tsxnext to source - ≥ 80% line, ≥ 70% branch coverage on every module
- ≥ 95% coverage on security-sensitive code (input validation, auth, encoding)
- AAA pattern (Arrange-Act-Assert), deterministic (mock
Date.now,Math.random, timers) - Mock
@react-three/fiberand@react-three/dreiin unit tests - Test behavior, not implementation
- Approved licenses: MIT, Apache-2.0, BSD-2/3-Clause, ISC, CC0-1.0, Unlicense
- Review required: LGPL 2.1/3.0, MPL 2.0, EPL 2.0 (weak copyleft)
- Prohibited without CEO approval: GPL 2.0/3.0, AGPL 3.0, advertising-clause, incompatible licenses
- Before adding a dependency:
npm audit+npm run test:licenses+ vulnerability check - All GitHub Actions pinned to full commit SHA, never tags/branches
- SBOM generated per release with SBOMQS ≥ 7.0 and SLSA L3 attestation
- Use TypeScript strict mode with explicit types
- Run
npm run lintandnpm run testbefore committing - Maintain ≥ 80% line / ≥ 70% branch coverage (≥ 95% on security code)
- Use
useFramewith delta time for animations - Dispose Three.js resources in cleanup functions
- Validate + sanitize all external input (see security-by-design skill)
- Cite ISMS policy in comments/PRs for security changes
- Document AI-assistance in PR descriptions when using Copilot agents
- Use
any— useunknownwith narrowing - Commit secrets, API keys, credentials, PII, or production data (including test data)
- Use
setInterval/setTimeoutfor game animations - Update state inside
useFrame(use refs for high-frequency updates) - Add dependencies without
npm audit+ license check - Use GPL/AGPL licensed dependencies without CEO approval
- Pin Actions to tags or branches — always full SHA
- Bypass CI security gates or branch protections (even with AI assistance)
- Components: PascalCase (
TargetSphere) - Hooks:
useprefix (useGameState) - Types/Interfaces: PascalCase (
GameState,Target) - Constants: UPPER_SNAKE_CASE (
GAME_DURATION) - Functions: camelCase (
incrementScore)
- Complete without asking when: pattern exists in codebase, requirements are clear, change is small and isolated, ISMS impact is understood
- Ask first when: multiple approaches with security/performance tradeoffs, new dependencies, new MCP/agent capability, changes to CI/security gates, potential privacy impact