chore: add coding standards (ESLint, Prettier), theme check script, and gated workflow documentation
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# Gated Development Workflow
|
||||
|
||||
Each phase must be completed and signed off before the next phase begins.
|
||||
The gatekeeper is the stakeholder (Shreyas Kamat) unless otherwise noted.
|
||||
|
||||
## 1. Ideation (Steve)
|
||||
- **Goal:** Capture high‑level requirements and success criteria.
|
||||
- **Entry:** None (project kickoff).
|
||||
- **Exit:** Approved PRD outline (stakeholder sign‑off).
|
||||
- **Artifact:** PRD draft in `.hermes/plans/`.
|
||||
- **Verification:** Stakeholder confirms requirements are complete.
|
||||
|
||||
## 2. PRD Documentation (Turing)
|
||||
- **Goal:** Expand ideas into a formal Product Requirements Document.
|
||||
- **Entry:** Approved Ideation output.
|
||||
- **Exit:** PRD approved by stakeholder.
|
||||
- **Artifact:** `.hermes/plans/PRD-<date>-<slug>.md`
|
||||
- **Verification:** Stakeholder review & sign‑off.
|
||||
|
||||
## 3. Design & Planning (Ada)
|
||||
- **Goal:** Produce technical design (SAD) and implementation plan.
|
||||
- **Entry:** Approved PRD.
|
||||
- **Exit:** Approved Technical Plan (this document) and SAD.
|
||||
- **Artifacts:**
|
||||
- Technical Plan (`.hermes/plans/<timestamp>-<slug>.md`)
|
||||
- Solution Architecture Document (`.hermes/docs/SAD-<date>-<slug>.md`)
|
||||
- **Verification:** Stakeholder reviews both documents; sign‑off required.
|
||||
|
||||
## 4. Orchestration (Woz)
|
||||
- **Goal:** Break technical plan into bite‑sized tasks and assign to specialist agents.
|
||||
- **Entry:** Approved Technical Plan & SAD.
|
||||
- **Exit:** Task backlog ready for development (each task 2‑5 min).
|
||||
- **Artifact:** Task list in `.hermes/plans/` or a Kanban board (if used).
|
||||
- **Verification:** Woz confirms each task is clear, estimable, and independent.
|
||||
|
||||
## 5. Development (Specialists: Linus, Sergey, Zaha, Craig, Gilfoyle, etc.)
|
||||
- **Goal:** Implement tasks using TDD and strict adherence to coding standards.
|
||||
- **Entry:** Task backlog from Orchestration.
|
||||
- **Exit:** All tasks completed, code passes lint, tests, and security review.
|
||||
- **Artifacts:**
|
||||
- Feature branches with incremental commits.
|
||||
- Unit/test files alongside source.
|
||||
- **Verification:**
|
||||
- **Spec Compliance Review** (Satya) – each task must satisfy its acceptance criteria.
|
||||
- **Code Quality Review** (Sundar) – lint passes, tests pass, security scan clean.
|
||||
- **Gilfoyle Security Review** – embedded from first commit; any security finding blocks progress.
|
||||
|
||||
## 6. Independent Review (Satya & Sundar)
|
||||
- **Goal:** Objective evaluation of the completed implementation.
|
||||
- **Entry:** Development complete, all tests pass, lint clean.
|
||||
- **Exit:** Review sign‑off from both specialists.
|
||||
- **Artifacts:** Review reports (`.hermes/reviews/<date>-<feature>.md`).
|
||||
- **Verification:** No open critical issues; all review comments addressed.
|
||||
|
||||
## 7. Deployment (Jenson)
|
||||
- **Goal:** Release the artifact to the target environment (local testing server/Gitea).
|
||||
- **Entry:** Review sign‑off obtained.
|
||||
- **Exit:** Application deployed and smoke‑tested.
|
||||
- **Artifacts:** Deployment log, built assets in `dist/`, Gitea repo update.
|
||||
- **Verification:** Stakeholder performs final sanity check; gives go/no‑go.
|
||||
|
||||
## 8. Post‑Deployment Monitoring (Optional)
|
||||
- **Goal:** Capture feedback and log any issues for next iteration.
|
||||
- **Entry:** Deployment complete.
|
||||
- **Exit:** Stakeholder accepts product or opens new issues.
|
||||
- **Artifact:** Feedback log.
|
||||
|
||||
### Gate Enforcement Mechanisms
|
||||
- **Coding Standards:** Enforced via `lint-staged` + husky pre‑commit; CI runs `npm run lint` and `npm run theme-check`.
|
||||
- **Security:** Gilfoyle’s review is triggered automatically on each PR via label‑based workflow (or manual checkpoint) – no merge without his approval.
|
||||
- **Theme:** `npm run theme-check` runs in CI; failure blocks merge.
|
||||
- **Documentation:** Each phase requires a markdown artifact stored under `.hermes/plans/` or `.hermes/docs/`; missing artifact blocks progression.
|
||||
|
||||
### Definition of Done (DoD) for a Task
|
||||
1. Code written and passes ESLint + Prettier.
|
||||
2. Unit test written (if applicable) and passes.
|
||||
3. Commit message follows conventional format (`feat:`, `fix:`, `chore:`).
|
||||
4. No lint or theme‑check warnings.
|
||||
5. Security scan clean (Gilfoyle’s checklist).
|
||||
6. Specification acceptance criteria met (verified by Satya).
|
||||
7. Code reviewed and approved by Sundar.
|
||||
8. Change merged to `main` only after all gates satisfied.
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import globals from 'globals';
|
||||
import pluginJs from '@eslint/js';
|
||||
import pluginReact from 'eslint-plugin-react';
|
||||
import pluginSecurity from 'eslint-plugin-security';
|
||||
import babelParser from '@babel/eslint-parser';
|
||||
|
||||
export default [
|
||||
{ ignores: ['node_modules/', 'dist/'] },
|
||||
{
|
||||
files: ['**/*.js', '**/*.jsx'],
|
||||
languageOptions: {
|
||||
parser: babelParser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 2021,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
presets: ['@babel/preset-react']
|
||||
}
|
||||
},
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.es2021,
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
react: pluginReact,
|
||||
security: pluginSecurity,
|
||||
},
|
||||
rules: {
|
||||
...pluginJs.configs.recommended.rules,
|
||||
...pluginReact.configs.recommended.rules,
|
||||
...pluginSecurity.configs.recommended.rules,
|
||||
'no-var': 'error',
|
||||
'prefer-const': 'error',
|
||||
'eqeqeq': ['error', 'always'],
|
||||
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||
'react/react-in-jsx-scope': 'off', // React 17+
|
||||
'security/detect-object-injection': 'error',
|
||||
'security/detect-non-literal-fs-filename': 'error',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
Generated
+4933
-822
File diff suppressed because it is too large
Load Diff
+32
-4
@@ -6,15 +6,43 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
|
||||
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,md}\"",
|
||||
"prepare": "husky install",
|
||||
"theme-check": "node src/theme/theme-check.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"framer-motion": "^10.12.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"framer-motion": "^10.12.0"
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^8.0.1",
|
||||
"@babel/preset-react": "^8.0.1",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"eslint": "^9.39.5",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-security": "^4.0.1",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^17.2.0",
|
||||
"prettier": "^3.9.6",
|
||||
"prop-types": "^15.8.1",
|
||||
"vite": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{css,md}": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
:root {
|
||||
--bg-primary: #121212;
|
||||
--text-primary: #E0E0E0;
|
||||
--accent: #FF9800;
|
||||
/* Light-mode overrides are intentionally omitted */
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
const rootCss = fs.readFileSync(path.join(import.meta.dirname, 'dark-only.css'), 'utf8');
|
||||
const lightPatterns = [/background:\s*#ffffff/i, /color:\s*#000000/i, /--bg-primary\s*:\s*#ffffff/i];
|
||||
const files = [];
|
||||
function collectFiles(dir) {
|
||||
const items = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const item of items) {
|
||||
const full = path.join(dir, item.name);
|
||||
if (item.isDirectory()) collectFiles(full);
|
||||
else if (item.name.endsWith('.css') || item.name.endsWith('.js') || item.name.endsWith('.jsx')) files.push(full);
|
||||
}
|
||||
}
|
||||
collectFiles(path.join(import.meta.dirname, '..')); // src directory
|
||||
const violations = [];
|
||||
for (const file of files) {
|
||||
const content = fs.readFileSync(file, 'utf8');
|
||||
for (const pattern of lightPatterns) {
|
||||
if (pattern.test(content)) violations.push(`${file}: light-mode pattern detected`);
|
||||
}
|
||||
}
|
||||
if (violations.length) {
|
||||
console.error('Theme violation detected (light-mode styles found):');
|
||||
violations.forEach(v => console.error(' -', v));
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log('✅ Theme check passed – only dark-mode variables used.');
|
||||
}
|
||||
Reference in New Issue
Block a user