mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-10-26 05:30:18 +00:00
3ecb954f28
* fix(gitops): guard automatic acceptance against stateful withdrawal Automatic GitOps acceptance had no stateful check: a candidate that removed, renamed, or stripped the volumes of a stateful service could be accepted and applied unattended, destroying or orphaning that service's data. The poll acceptance path and the automatic webhook apply path now share one guard that diffs the candidate's stateful service set against the generation in force, reading managed evidence only. When the candidate withdraws a stateful service, or when that cannot be proven, the candidate is held for review: nothing is accepted or applied, a durable block reason is recorded, and the projection names the block as its own attention reason, so the workplace shows it instead of an unexplained review. Webhook auto-apply reports the hold in its delivery result. Repeat pulls of the same held commit reuse the staged candidate, so the hold survives polling instead of churning generations, and a stored redelivery keeps its automated authority even if the policy moved since. First acceptance under a source with no accepted generation still defines the baseline, since there is no managed state to compare against. Validation: backend tsc, 9479 backend tests, frontend tsc, lint, and tests, with new coverage for the poll hold, rename, non-withdrawing acceptance, no re-evaluation, unreadable evidence, the webhook hold, a stored redelivery after a policy change, and repeat-pull reuse. The full backend run has one pre-existing environment failure in the SSH integration suite because port 22 is already in use on this machine. * security(gitops): contain generation reads under the managed root CodeQL flagged three path-injection sinks in the new stateful guard: the staged compose reads, the staged .env read, and the generation-in-force compose reads each joined a row- or user-derived relative path into a read without a containment check the analyzer can see. Each read now resolves its target and checks it inline at the sink, the pattern the repository already uses where CodeQL credits the guard, and every generation directory is contained under the managed root before anything inside it is read. Escapes are treated as unreadable evidence, so the guard holds rather than reads outside the managed area. No behavior change for legitimate paths. * test(gitops): cover stateful guard edge cases and review block lifecycle Pin the guard's hold on stripped volumes and unparseable candidates, the first-acceptance baseline, and every exit from the durable review block, including that automatic acceptance resumes once a newer candidate clears it.
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel (or oxc when used in rolldown-vite) for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])